Drupal 6.x port of signup_status
geodaniel - November 6, 2008 - 15:46
| Project: | Signup Status |
| Version: | 6.x-1.x-dev |
| Component: | Code |
| Category: | task |
| Priority: | normal |
| Assigned: | Unassigned |
| Status: | closed |
Description
The signup module saw an initial D6 port this morning. It would be great to have a D6 port of signup status to plug into it. Are there any plans for a port?

#1
Yes, planning is underway. This port will also address many of the outstanding issues / requests for the module. Please see the recently added road map on the project page.
#2
I would like to share with my thoughts on the signup status module. Would like to hear from you if I'm on the right direction.
The biggest design change we have talked about was making a one to many relations between signup_log sid and signup_status_code cid fields.
Suppose we have two status fields (groups):
Payment (paid, unpaid)
Invitation (invited, accepted, rejected)
This means we have five distinct statuses but they are grouped in two separate groups and within the same group user cannot be in several statuses (one can be in either paid or unpaid status). We will need a UI letting to collect statuses into groups and a table to store fields (groups). The first thing which comes to my head here is a CCK node field manage form where one can drag and drop cck fields to the groups. We could reuse this template and use similar table to arrange statuses to groups (fields). CCK table allows having cck field without a group, but in our case all statuses should belong to fields. Also we can introduce weights to the statuses (as cck fields have) and those weight can be use while rendering drop down box with available statuses for a particular field. The first status would become the default status when a user signs in if he cannot chose the status himself. The possible issue here is that the site will be messed up if the admin will rearange the codes and put them in different groups after signups already have been used. What do you think about this approach?
[Other alternative approach for this example is having only two codes - payment and invitation with various code states]
I think that Attendance field should go from the signup module to the signup status module as it is nothing more than an additional field with two statuses - attended/did not attend.
Currently signup status overwrites the administration sub tab of the signups tab on the node page and adds several form elements and have to use a separate theme for the node rendering (cannot alter signup theme). I have not yet decided if it is the best approach since the table does not scale horizontally when the number of fields will grow. But I don't see other UI option at the moment. The problem will arise if some other module will decide to alter the same form and will need to implement it's own theme function as it would conflict with the signup status.
What I don't yet know is how to deal with a total signup counts. Currently each status has a property telling if it should modify the total signups count. The problem is that theoretically a user can be in "paid" and "rejected" statuses from the example above and then it gets confusing as one field contradicts the other. Any ideas how to resolve that? Same is for the current "Auto-transition to Registered" feature. How can that work with multiple fields? Which field should be picked up for performing autotranzition?
There is a property "Show on the signup form", I think we should add additional property "Allow node author to change the field". This is needed for instance for the Invitation field above. Only subscribing user should be able to alter his status. Any objections?
Also currently don't know how to deal with a translations to other languages. Because the codes are stored in the database and are editable by the admin, they cannot be automatically translated to other languages with t() function.
Would appreciate your feedback, since it's kind of stopping me - don't know if this design approach would meet your expectations.
#3
The biggest design change we have talked about was making a one to many relations between signup_log sid and signup_status_code cid fields.
Historically, "status" made sense when it was a single field that was bolted into the {signup_log} table that could have only 1 possible value. If there's a 1 to N relationship, we're really talking about "fields", and in fact, each field could either be single-valued or multi-valued. I don't think "status" is very useful terminology anymore. Since it's going to be a fairly major re-write to D6, I propose we just start over with a new module called signup_fields, harvesting as much code as we can from signup_status (which probably won't be too much of it), and drop the "status" terminology entirely.
Suppose we have two status fields (groups):
Perhaps I'm being dense, but I find the "fields" vs. "groups" terminology in your message very confusing. In CCK, I associate "groups" with "fieldgroups", means a set of "fields". Sometimes your message seems to mean the same thing, in other cases, you seem to use "field" and "group" interchangeably, since a "field" is really a set of possible "status" values. Can we agree on and consistently use a common set of terminology so we don't hopelessly confuse each other? ;)
How about:
"field" == set of choices associated with a given signup. Appears as a single UI element on the signup form. Can be single/multi-valued, optional/required, etc.
"value" == a distinct possible value for a given field (in the 1:1 D5 signup_status, this would be called a "status", but we should drop that term entirely).
"group" == a set of fields that are grouped into a fieldset on the signup form (and perhaps displayed as a group in other places in the UI).
?? Is that clear? Can we all agree with that?
Payment (paid, unpaid)
Invitation (invited, accepted, rejected)
This means we have five distinct statuses but they are grouped in two separate groups and within the same group user cannot be in several statuses (one can be in either paid or unpaid status).
Ok, so you mean there are 5 total distinct "values" here, right? And in this case, they happen to be split into 2 fields, both of which are single-valued (radios or a drop-down, not checkboxes or a multi-select). And, for extra credit, the "payment" field is only relevant if the value of the invitation field is "accepted", right? That might be a level of complication we don't want to get into.
We will need a UI letting to collect statuses into groups and a table to store fields (groups). The first thing which comes to my head here is a CCK node field manage form where one can drag and drop cck fields to the groups.
I'm really worried about the explosion of complication for this. If we're going to go this far, why not just integrate with webform (or let EclipseGC do it, since he seems keen)?
That said, *if* we're going to implement a whole drag+drop UI for managing these fields, we should make it dependent on quicksketch's new FormBuilder UI:
http://drupal.org/project/form_builder
Otherwise, I'd say we should aim for a code-based solution, where sites can put files into a well-known directory to add fields or something (like views and panels allow a plugin system to add new pane types, panel layouts, view handlers, etc, etc). This port of signup_status is really meant to be just a temporary short-term measure until signup_webform (or whatever that turns into) exists and is stable, right? Maybe Jeff will protest, but I think it'd be reasonable to tell sites that wish to use 1:N signup fields in the short term that they have to write a little FAPI code to make it work. I'm not convinced this will save time in the end, instead of just integrating with form_builder, but we should definitely consider it before we invest unlimited effort trying to either write our own solution (*UGH!*), or trying to get it working with the (still alpha) form_builder code.
We could reuse this template and use similar table to arrange statuses to groups (fields). CCK table allows having cck field without a group, but in our case all statuses should belong to fields.
I don't understand this based on my confusion about terminology...
Also we can introduce weights to the statuses (as cck fields have) and those weight can be use while rendering drop down box with available statuses for a particular field. The first status would become the default status when a user signs in if he cannot chose the status himself. The possible issue here is that the site will be messed up if the admin will rearange the codes and put them in different groups after signups already have been used. What do you think about this approach?
I think that'd be overkill. I like how form_builder handles this. There's just a text area to define the "key|label" pairs for the options. You just order them how you want. Changing the order won't break any data as long as the keys don't change.
Of course, all of this means we're going to need a more complicated schema than just {signup_log} and {signup_status} or something. Without having looked too closely at the internals of form_builder yet, it seems like we'll need something like:
{signup_forms} to store data about each distinct form we create via the UI (set of fields)
{signup} might want to just alter the core signup schema to add a "formid" field so we know which signup form to use for any given signup-enabled node.
{signup_log} the core table from signup, with no altered schema at all.
{signup_form_values} to store (signup_id, form_id, field_name, value_key) for each signup form submission. I guess we could figure out the form_id indirectly from the signup_id which we could JOIN on {signup_log} to get the nid, which would let us JOIN on {signup} to get the form_id, but it seems like we'll need the form_id so often, a little denormalization to make the queries less complicated is worth doing.
This is starting to sound an AWFUL lot like what webform does...
[Other alternative approach for this example is having only two codes - payment and invitation with various code states]
I don't know what you mean.
I think that Attendance field should go from the signup module to the signup status module as it is nothing more than an additional field with two statuses - attended/did not attend.
That's almost true. Honestly, I just recently added that feature since I didn't yet know what the deal was with signup_status and where all this stuff was headed, and since Evgeny said he wanted it. ;) However, attendance is not just another field, since it's a field with an implicit ACL -- only people who can administer signups can view or record attendance. If "signup_fields" can enforce per-field permissions (or per field-group permissions, as we discussed in IRC), then yes, attendance could get removed from signup.module itself.
Currently signup status overwrites the administration sub tab of the signups tab on the node page and adds several form elements and have to use a separate theme for the node rendering (cannot alter signup theme). I have not yet decided if it is the best approach since the table does not scale horizontally when the number of fields will grow.
Definitely not the right approach at all. The only reason signup_status works this way is because Jeff wrote it in complete isolation from me, and we didn't discuss any of this in the first place. ;) I'm glad times have changed!
But I don't see other UI option at the moment. The problem will arise if some other module will decide to alter the same form and will need to implement it's own theme function as it would conflict with the signup status.
The right solution is to make this a view:
#352328: Replace (optionally?) node/N/signups/admin with a views bulk operations view?
What I don't yet know is how to deal with a total signup counts. Currently each status has a property telling if it should modify the total signups count. The problem is that theoretically a user can be in "paid" and "rejected" statuses from the example above and then it gets confusing as one field contradicts the other. Any ideas how to resolve that? Same is for the current "Auto-transition to Registered" feature. How can that work with multiple fields? Which field should be picked up for performing autotranzition?
I don't know anything about the "auto-transition" functionality, so it's hard for me to comment on that. In general, I think it makes sense that there would be somewhere in the form building UI/code to specify that "this field should impact the signup limit" and then for each value for that field, you specify how it should affect the limit. In the "invitation" field in your example, "invited" == 0, "rejected" == 0, and "accepted" == 1. In this particular case, I'd say that "rejected/paid" still doesn't count towards the limit. We obviously need to record that they paid in this case, but that's so the event organizer can figure out how to refund them (or not). ;) But, if they're not coming, it shouldn't count towards the limit. Or, depending on your use-case, *only* let paid/unpaid effect the limit, regardless of what they did with the invitation. But, I think the only sane way to do this is to expose it to the form builder. We might be able to let someone specify key|label|limit optionally when defining the choices for a given field. As in:
Invitation options:-1|Invited|0
0|Rejected|0
1|Accepted|1
Otherwise, you'd just have to have 2 separate text areas for this, one for the key|label map, and one for the key|limit map, and some validation, as in:
Invitation options:
-1|Invited
0|Rejected
1|Accepted
[x] Invitation effects signup limit
-1|0
0|0
1|1
"Invitation effects signup limit" would be a checkbox that reveals the 2nd text area via jQuery or something...
There is a property "Show on the signup form", I think we should add additional property "Allow node author to change the field". This is needed for instance for the Invitation field above. Only subscribing user should be able to alter his status. Any objections?
I guess that'd be the other way to solve the per-field ACL problem. It seems like there are only 3 possible "roles" that a user could have which would determine who can edit a field:
1) The user creating/editing their own signup
2) Someone who can edit the node they signed up to
3) Someone who can administer signups for the node they signed up to
#2 != #3 in general -- you can have one perm and not the other. So, either we could have a 3-way drop-down select, of these 3 choices, or make it explicitly permission based. But yes, each field needs to specify who should be allowed to edit it.
Also currently don't know how to deal with a translations to other languages. Because the codes are stored in the database and are editable by the admin, they cannot be automatically translated to other languages with t() function.
That is correct. :( Jeff raises a good question about how the i18n module handles taxonomies -- maybe there's a solution, I dunno. Note: if the fields were defined by plugin files instead of a GUI, then they could define their options via standard t() calls...
Would appreciate your feedback, since it's kind of stopping me - don't know if this design approach would meet your expectations.
Hope that helps.
p.s. Meta comment: after all that -- are you *really* sure you need 1:N relationships for your specific use-case? I thought the idea was that you were doing a stop-gap temporary measure. This is turning into basically a complete re-write of signup_status (and large parts of webform). That sounded like the longer-term solution. Don't get me wrong, I'd be thrilled if you just did the long-term solution now, but do you have time to do all this and is it really necessary? Wouldn't it be easier to just use a 1:1 relationship for the "Invited" field, keep more of signup_status as is (at least regarding its existing status definition UI and schema), and then handle the "paid/unpaid" separately via either one of the existing signup-payment modules, or your own custom solution that does its own 1:1 table mapping for sid:payment details? We'd still want to convert node/N/signups/admin into a view and just have signup_status export fields you could add to that view, and cleanup other spots in the code that are work-arounds to deal with the fact that the core signup module wasn't making life easy for signup_status. But, we could leave all the 1:N stuff, drag+drop form UI, etc to EclipseGC and the webform approach...
#4
OK, let's stick with the terminology you have proposed to make sure we understand each other. :)
I agree that for the short time solution we should keep form building UI as simple as possible (pipe delimiters might work just fine).
Views bulk operations views sounds like a right approach for the user listing. I haven't tried it yet so don't know how expandable it is, but it would be way better than reimplementing the theme. Anyway, the signup module should implement it first.
> p.s. Meta comment: after all that -- are you *really* sure you need 1:N relationships for your specific use-case?
Actually we don't at the moment. We might need it later, but what we really need now is just one invitations field with several values which can be achieved with current 1:1 relations. I just asked during the irc meeting if signup status suports 1:N relations then everybody picked it and were talking that it would be nice to have it in the D6 port :). I was thinking about 1:N relation cause that would have been our contribution to enhancing the module, not only the straight port.
However it looks that introducing 1:N relations is a major change and should go in the long term solution. So I'm leaning towards just a straight port of signup status with a 1:1 relations and leaving the 1:N relations to the status_fields module as the long term replacement of the signup_status.
#5
@Miglius: cool, that all basically sounds good. My only concern is that even as we do a "straight port" of signup_status and keep 1:1, we should ruthlessly purge code that was written as work-arounds to having better support in signup.module itself to extend it. Extending the signup API to better support extension like this, and a D6 port of 1:1 signup_status functionality, would already be a nice contribution to the community, and will give us time to work out a proper solution for signup_fields. Thanks!
p.s. Just making the title more specific so I can see which issue this is when it's bumped in my tracker page. ;) Also, looks like miglius is actually planning to work on the patch, so I'm unassigning jrbeeman for now...
#6
#352328: Replace (optionally?) node/N/signups/admin with a views bulk operations view? is really coming together nicely. I'd appreciate any reviews/testing/feedback in there before I commit, but it's basically done AFAIK.
Given that patch, here's a dummy version of code for signup_status D6 that adds an "Alter signup status" operation to the VBO-based view at node/%/signups/admin. You'd just download these files, remove the ".txt" endings, and install it in place of signup_status to get the idea. Obviously, this code would just go into signup_status.module itself once the rest of the code is working.
#7
Moved all talk of signup_status + Views2 over to #357565: Port signup_status to Views2. There's a patch there now for exposing the {signup_log}.status field to views, along with both a filter and an argument handler for it.
#8
FYI: after discussions with jrbeeman and miglius, I removed the DRUPAL-6--1 branch (which had no commits), synced the latest code from DRUPAL-5 back into HEAD, and rearranged the add-on modules into signup_status/modules/signup_status_(cert|log|mailer). If you do a "cvs up -dPA" in your D6 workspace, you should get all the code that's now ready for D6 porting. Miglius has the start of the port done, and should be committing parts of it soon.
#9
Several notes:
Replace (optionally?) node/N/signups/admin with a views bulk operations view? patch works nicely. I can inject other actions from the signup_status module. It also allows specifying in the view settings which actions should be available in the drop down list.
Port signup_status to Views2 works with some signup_status specific adoption. Thanks!
I would appreciate if Derek could work on Add a signup_send_broadcast() API call that can be shared which would allow simple implementation of the broadcasting messages to the users with specific statuses.
Derek, do you consider adding interface which would allow user to change his signup data? This is vital for us in the invites implementation. When the user is invited to the event (node), he is automatically signed up with a status 'invited', then he should come and change his signup details - signup data and status from 'invited' to other available statuses like 'confirmed', 'maybe', 'reject' or similar. If signup module would provide such an interface, signup_status could hook in via hook_form_alter() and add signup status to the form. It also would be nice if signup would allow to hook in into to the code where your signup data is displayed in the table and would let adding additional rows to the table, signup status in particular.
Other question I have is whether we need 'mod_signup_count' assigned to each status. I understand that some statuses are considered as the user is subscribed to the node and others might clearly indicate that the user will not attend the event, however, the counting is done in the signup module which implements a total limit of sign ups. I don't see a clear way how an integration to the signup module should be written that only statuses with a 'mod_signup_count' property set are compared against the total limit without overwritting some signup functions. Maybe we can drop this from the signup_status module so that later a contrib module could be build for this purpose if needed?
#10
Yes, I can put the finishing touches on #357655: Add a signup_send_broadcast() API call that can be shared and get that in ASAP.
#51226: allow users to edit their own signup -- sure, I'd be happy to work on this. signup_status might not even need to form alter anything new, since if all goes well, I'll just reuse the existing signup form exactly as-is. There's already a setting for if a given status should appear on the signup form, right? So, any status values users are allowed to set should be on the signup form already, and if they are, they'll show up on the signup edit form, too. We'll see once I write the code, there might still be a need for a little work in signup_status to make it work perfectly (e.g. to fill in the existing status as the correct default value if we already have one).
#209954: Allow other modules to alter signup data before it's displayed -- I had never understood what this issue was about until recently. I'd be open to it, though it's a little more complicated now than it was when that patch was first written, since all of the display of the current signup data is now themable...
jrbeeman would have to answer the full story on mod_signup_count, but I believe the idea is you can have separate limits for each status, in addition to the global signup limit for the node (or something). ;) I'll defer to his thoughts on this, but in general, I'd be in favor of moving complicated features to submodules so it's easy to not enable them on sites that don't need them.
Cheers,
-Derek
p.s. Miglius, do you know about the issue number link filter on d.o? You just have to write
[#357565]and it's converted into #357565: Port signup_status to Views2 and if you hover of the link, the title attribute will tell you the current status of the issue.#11
I've reviewed the D6 port Miglius already committed. Aside from what I pointed out over at #357565-4: Port signup_status to Views2, there are mostly just some cosmetic issues here:
A) http://drupal.org/node/144132#form-id-alter means that we don't need signup_status_form_alter() and that switch statement at all. We can just rename a few functions and do away with signup_status_form_alter() entirely. See 330943_11_signup_status_form_alter.patch.
B) To be consistent with the style used by core, I'd rather we laid out signup_status_menu() with the $items array. See 330943_11_signup_status_menu.patch.
Any objections before I commit these?
#12
Oh, and signup_status_codes() can just use db_fetch_array() and be much simpler.
#13
Or, if we don't mind the array signup_status_codes() returns including a 'cid' element, too, it can be even simpler.
#14
Hearing no objections, I committed both patches from #11 and the one from #13 to HEAD. The basic functionality is now working fine in D6, so I'm calling this "fixed", and we can address other things in other issues...
#15
Automatically closed -- issue fixed for 2 weeks with no activity.
#16
How usable is the 6.x dev branch at present?
#17
What happens to the great ideas about supporting 1:N (signup: Fields/Values/Groups) i comment#3.
Is it still alive? Is this a functiolnality to expect in the forseeable future?
#18
@greenbeans: Pretty usable.
@thureb: It's still potentially alive, but not via the 6.x-1.* series of signup_status. See #29568: Flexible number and type of fields.
@all: This issue is closed. Normally that means no one is looking at them any more. If you have new support questions, please search for existing open issues and comment there, or create new issues about them so people will see them.