Suppose we want to have a webform per-event node that contains event-specific registration information that isn't appropriate for storage in the user profile.
Currently the core profile.module adds its form fields to the attendee info form, those values are inserted into the $_SESSION and processed when the order is submitted. This is all hard-coded. Let's make it possible for any module to add its form elements to the attendee info form and make it easy to have the right code run at the right steps in order processing.
hook_form_alter makes it possible to add form elements, but I'm not sure whether we want to require an entire module, as opposed to a small include file, for each implementer of a new hook. Also, we're not using the submit function for this form to process the submissions. Rather, we place it's data into $_SESSION and process it when the order is submitted. While other modules could potentially get away with using hook_order to process submissions, it would be nicer if they could have their code run as part of uc_signup's order processing. This would be easy to implement by passing the uc_signup session data to each module that implements hook_uc_signup_order_submit() or similar.
Then, #527700: Optional Content Profile support, and make core profile optional as well would be implemented simply by implementing this api function and form_alter on behalf of profile (and content_profile) modules.
| Comment | File | Size | Author |
|---|---|---|---|
| #25 | uc_signup-623900-25.patch | 79.2 KB | artis |
| #20 | uc_signup.623900-20.patch | 10.74 KB | jhedstrom |
| #19 | uc_signup.623900-19.patch | 10.62 KB | jhedstrom |
| #16 | uc_signup.623900.patch | 10.62 KB | jhedstrom |
| #15 | uc_signup.623900.patch | 10.56 KB | jhedstrom |
Comments
Comment #1
recrit commentedI agree this needs a complete revamp look. My patch in #527700: Optional Content Profile support, and make core profile optional as well was really just a work around so I could implement the module on a client that was not using the profile module.
Independent of other user profile modules approach:
The signup module already has API to have form data specific to just the signup node. Look in (signup/theme/signup_form.inc) at the
function theme_signup_user_form($node). This is really meant for themes to add in their own fields. This is where signup adds in their default fields of Name and Phone number. The form can be altered at the module level withhook_form_signup_form_alterand adding fields to$form['collapse']['signup_user_form']['signup_form_data']. This data is stored on the signup node and not the user. However, altering the form alone only provides a single signup at a time.The main signup function
signup_sign_up_user($signup_form, $notify_user)looks for this extra data in$signup_form['signup_form_data']. uc_signup already spoofs this $signup_form argument, but only sends the uid and nid to perform the sign up. uc_signup could use $signup_form['signup_form_data'] to store other data collected either in uc_signup custom forms or somehow leverage the existing signup forms which already provide hooks for developers to add in custom fields. uc_signup could render the signup form for each sign up in a similar way that it currently does with the profile form.It would be nice if product attributes could somehow be worked into the per signup forms. For example, an event that has a meal selection attribute. Then each signup could have a different meal selection. Not really sure how to make that work since changing attributes makes it a different "product" with different skus.
[Off topic from form improvements]
In your post you mentioned using the $_SESSION and the data stored in it gets processed on order submit, so that got me thinking on this also.
Currently uc_signup hooks on order submit which makes sense in the normal order flow, however, the issues with PayPal seem to arise because when returning from PayPal (as with WP Standard) they go directly to checkout/complete which skips over submit. The order could be caught on
hook_uc_checkout_complete, but this is too late. If any errors happen in the signup processing, the customer has already paid but isn't signed up. Regular checkout form validation usually takes place in the "process" operation of the callback for yourhook_checkout_pane. In the "process" operation, you could validate all inputs, create new users if needed, and create the temporary signups. Then it doesn't matter what happens after that point such as going to PayPal. Once payment and the order is completed, uc_signups conditional action would still fire and triggeruc_signup_mark_paidto make the signup permanent.Comment #2
ezra-g commented"look in (signup/theme/signup_form.inc) "
Yes, I'm aware of the signup form. It's an intentional decision in UC_Signup not to use that form, in order to streamline the attendee info collection process. The signup.module form as some known drawbacks, including that it stores data in a serialized array in the database, making it hard to query. That's one reason why it would be helpful to be able to collect profile information or webform info.
Comment #3
joachim commentedIt has an API but using the theme layer is evil and wrong!
I'm working on something better here: #29568: Flexible number and type of fields, which would be in a 6--2 branch of signup.
Comment #4
ezra-g commentedMarked #527700: Optional Content Profile support, and make core profile optional as well as a duple.
Comment #5
joachim commentedI'm thinking it might be more logical to provide signup-profile and signup-content_profile integration separately and independently of signup-ubercart integration, all with the new signup form API.
In which case, #29568: Flexible number and type of fields needs work so more than one form can be included.
Comment #6
ezra-g commentedOn a practical level, how would you go about refactoring the current custom uc_signup checkout workflow to integrate the signup form?
Comment #7
ezra-g commentedAlso, that wouldn't make it possible to process the submitted information and prevent it from being stored if payment fails, or causing payment to fail if the submitted information somehow fails to validate after the order has been submitted.
Comment #8
joachim commentedRe: 7
Signup has a lot of hooks I've not yet properly looked into. From my cursory glance at them I am guessing they are observer hooks (as in they allow implementing modules to act on events), but since we are changing API anyway we could design something that allows implementing hooks to allow or deny signup. This would also have applications for modules that seek to implement more complex reservation systems (such as seating plans or something perhaps?).
Re: 6
I've not looked at that yet!
This is purely guesswork, but we need to either intercept the form submission with the information the user has entered, stash it, take a round trip to Ubercart and get the payment, then come back and give Signup the stashed data.
Or we need to alter Signup's system completely. It currently allows for the form to either be on a tab or in the node body. We could implement a third system where the form is only accessible to the user once they have paid. So you'd see the Ubercart 'add to cart' button, and following the UC procedure would eventually grant you access to the node's tab. This would make sense for subsequent alterations to signup data.
I'd like the API I'm working on for Signup to allow whatever it is this module needs -- my patch over on that other issue is only a first draft, so let's keep discussing it, rip it up, rewrite it, etc! :)
Comment #9
dboulet commentedInterested in this as well.
Comment #10
joachim commentedRe: 6
On reflection, I think maybe what we should aim for is neither of the two systems I described!
Rather, allow the user to sign up, but flag the signup as being temporary.
Then allow other modules (in our case, uc_signup) to process the signup (in this case, take payment) and at some point fire an API function to enable the signup. At this point, the signup is considered complete and live.
A temporary signup expires: perhaps a couple of hours, or even maybe weeks if UC is set up to accept cheque payments.
This way round means that a user gets to book their seat / ticket / whatever when they actually get to the site and enter their data, and they are allocated a place.
The other systems I described in #8 could mean a user hands over cash and then finds that users who were quicker to process payment have taken the last places!
About to post a big patch at #29568: Flexible number and type of fields by the way :)
Comment #11
iva2k commentedsubscribe
Comment #12
carwin commentedsubscribing.
Comment #13
joachim commentedUpdate: the code over at #29568: Flexible number and type of fields is now working live on several sites.
> Also, that wouldn't make it possible to process the submitted information and prevent it from being stored if payment fails, or causing payment to fail if the submitted information somehow fails to validate after the order has been submitted.
Signups get cancelled if the user removes the product from their cart; I've not looked at handling the case where payment fails. What doe Ubercart fire when this happens?
Comment #14
socialnicheguru commentedDoes this allow for content profile to be used with signup for ubercart?
Comment #15
jhedstromHere's a patch that needs a lot of work. In an attempt to lay the groundwork for an eventual API, it does the following now:
* Adds 2 new modules, uc_signup_profile and uc_signup_cp (for content_profile)
* Moves hook_requirements into relevant .install files
* Moves most core-profile-specific code into uc_signup_profile
* Provides update hook to enable uc_signup_profile for existing installs as this is an assumed dependency for existing sites
* Adds very limited integration with content_profile (this needs a lot of work--nodereference and filefields don't work atm)
This bit needs some thought:
Comment #16
jhedstromThat last patch broke this for install profiles. Here's the same patch with slight tweaks to hook_requirements (when these get moved to .install, they are run on a Drupal install, so they must return an array).
Comment #17
socialnicheguru commentedI tried it and it seems to work.
I can have multiple content profiles. How do I select which one I want to use for signup?
Comment #18
istryker commentedPatch fails when applied to beta5 supported version. and fails on the sept 25th dev file (but only the .info file). Looks like you created this patch on a dev version before sept 15th as there was a dependency added to the info file.
Comment #19
jhedstromHere's a patch that applies cleanly to the latest dev version.
Comment #20
jhedstromRe-roll that adds a placeholder node to $form_state prior to calling content_profile_registration_add_profile_form (this is needed because otherwise non-privileged users were being redirected to their own content profile when trying to register other users).
Comment #21
ambereyes commentedPatch worked for me in general, but I am not sure what I need to do to use fields from content profile. Some explanation would be helpful.
Comment #22
scotwith1tsubscribe
Comment #23
xeraseth commentedI also was able to patch (was an error when it was trying to remove profiles as a dependency for uc_sign.info), but I went in a manually patched that part), but am unable to find where I connect a Content Profile to a signup enabled Content Type
Comment #24
socialnicheguru commentedI am trying to apply this patch to the newest version of dev but have lots of errors.
Can this be rerolled?
Comment #25
artis commentedThis reroll should work again 6.x-1.0-beta6
Comment #26
zdean commentedsubscribe
Comment #27
socialnicheguru commentedWill this be officially part of the uc_signup module? Will this be it's own add-on module to uc_signup?
I prefer using content_profile over core profile for a number of reasons but I hate having to find this patch everytime a new uc_signup comes up.
I fear that the patch will not be compatible in the future.
Comment #28
kclarkson commentedI understand that this is mostly for uc_signup, but what about just a signup_content_profile module?
Basically I have one (content) profile that has conditional fields and would like to include that information on the signup so when we export the list the additional fields show. example: Do you have special dietary needs? If answered yes a selection of different types drops down. Well by using the profile fields they "have" to answer everything.
The reason content profile is so key is that it uses cck and you can have the flexibility of default values and conditional fields.
In addition, if content profile module was created a person only has to only fill out their profile fields once and they can signup for various events by just logging in and hitting the signup button and all of their information would be populated.
Comment #29
tevih commentedsubscribe
Comment #30
tevih commentedI'm going to wake this sleepy post. :)
Has this been included in latest releases?
Comment #31
socialnicheguru commentedIt hasn't been included.
Can it be?
EDIT:
I get this when I apply patch 20 above
http://drupal.org/comment/reply/623900#comment-3663728
I hit the signup button
I enter an email
press enter
taken to the content profile page
I get:
warning: Cannot use a scalar value as an array in /uc_signup/uc_signup.module on line 438.
warning: Cannot use a scalar value as an array in /uc_signup/uc_signup.module on line 439
here are the lines in question:
Comment #32
ambereyes commentedThis needs to be part of the recent release of uc_signup instead of constantly re-rolling the patch.
Comment #33
tevih commentedagreed