Building a Multistep Registration Form in Drupal 7 using Ctools
This article provides a step-by-step tutorial for creating a custom, multistep registration form via the Ctools Form Wizard in Drupal 7. If you'd prefer to solely use the core Form API, take a look at Building a Multistep Registration Form in Drupal 7, a previous blog post. In the interest of saving time, I'm going to be lifting some text directly from that post, given that there are a number of overlapping tasks.
Why use the Chaos Tools module to build a multistep form? Well, Ctools offers a number of tools that build upon the core Form API, allowing you to create a multistep form faster. This includes providing a method for caching data in between steps, adding 'next' and 'back' buttons with associated callbacks, generating a form breadcrumb, etc.
The Tut
First things first— create a new, empty, custom module. In this example, the module will be named grasmash_registration. In the interest of reducing our bootstrapping footprint and keeping things organized, we're also going to create an include file. This will store the various construction and helper functions for our form. Let's name it grasmash_registration_ctools_wizard.inc.
We'll start by defining a "master" ctools form wizard callback. This will define all of the important aspects of our multistep form, such as the child form callbacks, titles, display settings, etc. Please take a look at the help document packaged with ctools in ctools/help/wizard.html for a full list of the available parameters.
<span style="color: #000000"><span style="color: #0000BB"><?php<br></span><span style="color: #FF8000">/**<br> * Create callback for standard ctools registration wizard.<br> */<br></span><span style="color: #007700">function </span><span style="color: #0000BB">grasmash_registration_ctools_wizard</span><span style="color: #007700">(</span><span style="color: #0000BB">$step </span><span style="color: #007700">= </span><span style="color: #DD0000">'register'</span><span style="color: #007700">) {<br> </span><span style="color: #FF8000">// Include required ctools files.<br> </span><span style="color: #0000BB">ctools_include</span><span style="color: #007700">(</span><span style="color: #DD0000">'wizard'</span><span style="color: #007700">);<br> </span><span style="color: #0000BB">ctools_include</span><span style="color: #007700">(</span><span style="color: #DD0000">'object-cache'</span><span style="color: #007700">);<br> <br> </span><span style="color: #0000BB">$form_info </span><span style="color: #007700">= array(<br> </span><span style="color: #FF8000">// Specify unique form id for this form.<br> </span><span style="color: #DD0000">'id' </span><span style="color: #007700">=> </span><span style="color: #DD0000">'multistep_registration'</span><span style="color: #007700">,<br> </span><span style="color: #FF8000">//Specify the path for this form. It is important to include space for the $step argument to be passed.<br> </span><span style="color: #DD0000">'path' </span><span style="color: #007700">=> </span><span style="color: #DD0000">"user/register/%step"</span><span style="color: #007700">,<br> </span><span style="color: #FF8000">// Show breadcrumb trail.<br> </span><span style="color: #DD0000">'show trail' </span><span style="color: #007700">=> </span><span style="color: #0000BB">TRUE</span><span style="color: #007700">,<br> </span><span style="color: #DD0000">'show back' </span><span style="color: #007700">=> </span><span style="color: #0000BB">FALSE</span><span style="color: #007700">,<br> </span><span style="color: #DD0000">'show return' </span><span style="color: #007700">=> </span><span style="color: #0000BB">FALSE</span><span style="color: #007700">,<br> </span><span style="color: #FF8000">// Callback to use when the 'next' button is clicked. <br> </span><span style="color: #DD0000">'next callback' </span><span style="color: #007700">=> </span><span style="color: #DD0000">'grasmash_registration_subtask_next'</span><span style="color: #007700">,<br> </span><span style="color: #FF8000">// Callback to use when entire form is completed.<br> </span><span style="color: #DD0000">'finish callback' </span><span style="color: #007700">=> </span><span style="color: #DD0000">'grasmash_registration_subtask_finish'</span><span style="color: #007700">,<br> </span><span style="color: #FF8000">// Callback to use when user clicks final submit button.<br> </span><span style="color: #DD0000">'return callback' </span><span style="color: #007700">=> </span><span style="color: #DD0000">'grasmash_registration_subtask_finish'</span><span style="color: #007700">,<br> </span><span style="color: #FF8000">// Callback to use when user cancels wizard.<br> </span><span style="color: #DD0000">'cancel callback' </span><span style="color: #007700">=> </span><span style="color: #DD0000">'grasmash_registration_subtask_cancel'</span><span style="color: #007700">,<br> </span><span style="color: #FF8000">// Specify the order that the child forms will appear in, as well as their page titles.<br> </span><span style="color: #DD0000">'order' </span><span style="color: #007700">=> array(<br> </span><span style="color: #DD0000">'register' </span><span style="color: #007700">=> </span><span style="color: #0000BB">t</span><span style="color: #007700">(</span><span style="color: #DD0000">'Register'</span><span style="color: #007700">),<br> </span><span style="color: #DD0000">'groups' </span><span style="color: #007700">=> </span><span style="color: #0000BB">t</span><span style="color: #007700">(</span><span style="color: #DD0000">'Connect'</span><span style="color: #007700">),<br> </span><span style="color: #DD0000">'invite' </span><span style="color: #007700">=> </span><span style="color: #0000BB">t</span><span style="color: #007700">(</span><span style="color: #DD0000">'Invite'</span><span style="color: #007700">),<br> ),<br> </span><span style="color: #FF8000">// Define the child forms. Be sure to use the same keys here that were user in the 'order' section of this array.<br> </span><span style="color: #DD0000">'forms' </span><span style="color: #007700">=> array(<br> </span><span style="color: #DD0000">'register' </span><span style="color: #007700">=> array(<br> </span><span style="color: #DD0000">'form id' </span><span style="color: #007700">=> </span><span style="color: #DD0000">'user_register_form'<br> </span><span style="color: #007700">),<br> </span><span style="color: #DD0000">'groups' </span><span style="color: #007700">=> array(<br> </span><span style="color: #DD0000">'form id' </span><span style="color: #007700">=> </span><span style="color: #DD0000">'grasmash_registration_group_info_form'</span><span style="color: #007700">,<br> </span><span style="color: #FF8000">// Be sure to load the required include file if the form callback is not defined in the .module file.<br> </span><span style="color: #DD0000">'include' </span><span style="color: #007700">=> </span><span style="color: #0000BB">drupal_get_path</span><span style="color: #007700">(</span><span style="color: #DD0000">'module'</span><span style="color: #007700">, </span><span style="color: #DD0000">'grasmash_registration'</span><span style="color: #007700">) . </span><span style="color: #DD0000">'/grasmash_registration_groups_form.inc'</span><span style="color: #007700">,<br> ),<br> </span><span style="color: #DD0000">'invite' </span><span style="color: #007700">=> array(<br> </span><span style="color: #DD0000">'form id' </span><span style="color: #007700">=> </span><span style="color: #DD0000">'grasmash_registration_invite_form'</span><span style="color: #007700">,<br> ),<br> ),<br> );<p> </p></span><span style="color: #FF8000">// Make cached data available within each step's $form_state array.<br> </span><span style="color: #0000BB">$form_state</span><span style="color: #007700">[</span><span style="color: #DD0000">'signup_object'</span><span style="color: #007700">] = </span><span style="color: #0000BB">grasmash_registration_get_page_cache</span><span style="color: #007700">(</span><span style="color: #DD0000">'signup'</span><span style="color: #007700">);<p> </p></span><span style="color: #FF8000">// Return the form as a Ctools multi-step form.<br> </span><span style="color: #0000BB">$output </span><span style="color: #007700">= </span><span style="color: #0000BB">ctools_wizard_multistep_form</span><span style="color: #007700">(</span><span style="color: #0000BB">$form_info</span><span style="color: #007700">, </span><span style="color: #0000BB">$step</span><span style="color: #007700">, </span><span style="color: #0000BB">$form_state</span><span style="color: #007700">);<br> <br> return </span><span style="color: #0000BB">$output</span><span style="color: #007700">;<br>}<br></span><span style="color: #0000BB">?></span></span>
As you can see, our registration form will have threes steps:
- the default user registration form
- the groups form
- the invite form
These have been respectively titled "Register," "Connect," and "Invite."
You should also see that we have referenced a number of, as of yet, non-existent callback functions, as well as a cache retreival function. Let's talk about that cache function first, then look at the callbacks.
Data caching
Ctools provides a specialized Object Cache feature that allows us to store arbitrary, non-volatile data objects. We will use this feature to store user-submitted form values in between the form's multiple steps. Once the entire form has been completed, we will use that data for processing.
To efficiently utilize the Object cache, we will define a few wrapper functions. These wrapper function will be used to create, retreive, and destroy cache objects.
<span style="color: #000000"><span style="color: #0000BB"><?php<br></span><span style="color: #FF8000">/**<br> * Retreives an object from the cache.<br> *<br> * @param string $name<br> * The name of the cached object to retreive.<br> */<br></span><span style="color: #007700">function </span><span style="color: #0000BB">grasmash_registration_get_page_cache</span><span style="color: #007700">(</span><span style="color: #0000BB">$name</span><span style="color: #007700">) {<br> </span><span style="color: #0000BB">ctools_include</span><span style="color: #007700">(</span><span style="color: #DD0000">'object-cache'</span><span style="color: #007700">);<br> </span><span style="color: #0000BB">$cache </span><span style="color: #007700">= </span><span style="color: #0000BB">ctools_object_cache_get</span><span style="color: #007700">(</span><span style="color: #DD0000">'grasmash_registration'</span><span style="color: #007700">, </span><span style="color: #0000BB">$name</span><span style="color: #007700">);<p> </p></span><span style="color: #FF8000">// If the cached object doesn't exist yet, create an empty object.<br> </span><span style="color: #007700">if (!</span><span style="color: #0000BB">$cache</span><span style="color: #007700">) {<br> </span><span style="color: #0000BB">$cache </span><span style="color: #007700">= new </span><span style="color: #0000BB">stdClass</span><span style="color: #007700">();<br> </span><span style="color: #0000BB">$cache</span><span style="color: #007700">-></span><span style="color: #0000BB">locked </span><span style="color: #007700">= </span><span style="color: #0000BB">ctools_object_cache_test</span><span style="color: #007700">(</span><span style="color: #DD0000">'grasmash_registration'</span><span style="color: #007700">, </span><span style="color: #0000BB">$name</span><span style="color: #007700">);<br> }<p> return </p></span><span style="color: #0000BB">$cache</span><span style="color: #007700">;<br>}<p></p></span><span style="color: #FF8000">/**<br> * Creates or updates an object in the cache.<br> *<br> * @param string $name<br> * The name of the object to cache.<br> *<br> * @param object $data<br> * The object to be cached.<br> */<br></span><span style="color: #007700">function </span><span style="color: #0000BB">grasmash_registration_set_page_cache</span><span style="color: #007700">(</span><span style="color: #0000BB">$name</span><span style="color: #007700">, </span><span style="color: #0000BB">$data</span><span style="color: #007700">) {<br> </span><span style="color: #0000BB">ctools_include</span><span style="color: #007700">(</span><span style="color: #DD0000">'object-cache'</span><span style="color: #007700">);<br> </span><span style="color: #0000BB">$cache </span><span style="color: #007700">= </span><span style="color: #0000BB">ctools_object_cache_set</span><span style="color: #007700">(</span><span style="color: #DD0000">'grasmash_registration'</span><span style="color: #007700">, </span><span style="color: #0000BB">$name</span><span style="color: #007700">, </span><span style="color: #0000BB">$data</span><span style="color: #007700">);<br>}<p></p></span><span style="color: #FF8000">/**<br> * Removes an item from the object cache.<br> *<br> * @param string $name<br> * The name of the object to destroy.<br> */<br></span><span style="color: #007700">function </span><span style="color: #0000BB">grasmash_registration_clear_page_cache</span><span style="color: #007700">(</span><span style="color: #0000BB">$name</span><span style="color: #007700">) {<br> </span><span style="color: #0000BB">ctools_include</span><span style="color: #007700">(</span><span style="color: #DD0000">'object-cache'</span><span style="color: #007700">);<br> </span><span style="color: #0000BB">ctools_object_cache_clear</span><span style="color: #007700">(</span><span style="color: #DD0000">'grasmash_registration'</span><span style="color: #007700">, </span><span style="color: #0000BB">$name</span><span style="color: #007700">);<br>}<br></span><span style="color: #0000BB">?></span></span>
Submit callbacks
Now, we will define the various callbacks that were referenced in our $form_info array. These callbacks are executed when a user clicks the 'next', 'cancel', or 'finish' buttons in the multi-step form.
<span style="color: #000000"><span style="color: #0000BB"><?php<br></span><span style="color: #FF8000">/**<br> * Callback executed when the 'next' button is clicked.<br> */<br></span><span style="color: #007700">function </span><span style="color: #0000BB">grasmash_registration_subtask_next</span><span style="color: #007700">(&</span><span style="color: #0000BB">$form_state</span><span style="color: #007700">) {<br> </span><span style="color: #FF8000">// Store submitted data in a ctools cache object, namespaced 'signup'.<br> </span><span style="color: #0000BB">grasmash_registration_set_page_cache</span><span style="color: #007700">(</span><span style="color: #DD0000">'signup'</span><span style="color: #007700">, </span><span style="color: #0000BB">$form_state</span><span style="color: #007700">[</span><span style="color: #DD0000">'values'</span><span style="color: #007700">]);<br>}<p></p></span><span style="color: #FF8000">/**<br> * Callback executed when the 'cancel' button is clicked.<br> */<br></span><span style="color: #007700">function </span><span style="color: #0000BB">grasmash_registration_subtask_cancel</span><span style="color: #007700">(&</span><span style="color: #0000BB">$form_state</span><span style="color: #007700">) {<br> </span><span style="color: #FF8000">// Clear our ctools cache object. It's good housekeeping.<br> </span><span style="color: #0000BB">grasmash_registration_clear_page_cache</span><span style="color: #007700">(</span><span style="color: #DD0000">'signup'</span><span style="color: #007700">);<br>}<p></p></span><span style="color: #FF8000">/**<br> * Callback executed when the entire form submission is finished.<br> */<br></span><span style="color: #007700">function </span><span style="color: #0000BB">grasmash_registration_subtask_finish</span><span style="color: #007700">(&</span><span style="color: #0000BB">$form_state</span><span style="color: #007700">) {<br> </span><span style="color: #FF8000">// Clear our Ctool cache object.<br> </span><span style="color: #0000BB">grasmash_registration_clear_page_cache</span><span style="color: #007700">(</span><span style="color: #DD0000">'signup'</span><span style="color: #007700">);<p> </p></span><span style="color: #FF8000">// Redirect the user to the front page.<br> </span><span style="color: #0000BB">drupal_goto</span><span style="color: #007700">(</span><span style="color: #DD0000">'<front>'</span><span style="color: #007700">);<br>}<br></span><span style="color: #0000BB">?></span></span>
Child Form callbacks
These forms comprise the individual steps in the multistep form.
<span style="color: #000000"><span style="color: #0000BB"><?php<br></span><span style="color: #007700">function </span><span style="color: #0000BB">grasmash_registration_group_info_form</span><span style="color: #007700">(</span><span style="color: #0000BB">$form</span><span style="color: #007700">, &</span><span style="color: #0000BB">$form_state</span><span style="color: #007700">) {<br> </span><span style="color: #0000BB">$form</span><span style="color: #007700">[</span><span style="color: #DD0000">'item'</span><span style="color: #007700">] = array(<br> </span><span style="color: #DD0000">'#markup' </span><span style="color: #007700">=> </span><span style="color: #0000BB">t</span><span style="color: #007700">(</span><span style="color: #DD0000">'This is step 2'</span><span style="color: #007700">),<br> );<p> return </p></span><span style="color: #0000BB">$form</span><span style="color: #007700">;<br>}<br>function </span><span style="color: #0000BB">grasmash_registration_invite_form</span><span style="color: #007700">(</span><span style="color: #0000BB">$form</span><span style="color: #007700">, &</span><span style="color: #0000BB">$form_state</span><span style="color: #007700">) {<br> </span><span style="color: #0000BB">$form</span><span style="color: #007700">[</span><span style="color: #DD0000">'item'</span><span style="color: #007700">] = array(<br> </span><span style="color: #DD0000">'#markup' </span><span style="color: #007700">=> </span><span style="color: #0000BB">t</span><span style="color: #007700">(</span><span style="color: #DD0000">'This is step 3'</span><span style="color: #007700">),<br> );<p> return </p></span><span style="color: #0000BB">$form</span><span style="color: #007700">;<br>}<br></span><span style="color: #0000BB">?></span></span>
You can use all of the magic of the Form API with your child forms, including separate submit and validation handlers for each step.
Integration with Drupal core user registration form
Now for the tricky part— we're going to override the Drupal core user registration form with our multistep ctools form, making user registration the first step.
We will do this by modifying the menu router item that controls the 'user/register' path via hook_menu_alter(). By default, the 'user/register' path calls drupal_get_form() to create the registration form. We're going to change that so that it calls our ctools multistep form callback instead.
Note, all hook implementations should be place in your .module file.
<span style="color: #000000"><span style="color: #0000BB"><?php<br></span><span style="color: #FF8000">/**<br> * Implements hook_menu_alter().<br> */<br></span><span style="color: #007700">function </span><span style="color: #0000BB">grasmash_registration_menu_alter</span><span style="color: #007700">(&</span><span style="color: #0000BB">$items</span><span style="color: #007700">) {<br> </span><span style="color: #FF8000">// Ctools registration wizard for standard registration.<br> // Overrides default router item defined by core user module.<br> </span><span style="color: #0000BB">$items</span><span style="color: #007700">[</span><span style="color: #DD0000">'user/register'</span><span style="color: #007700">][</span><span style="color: #DD0000">'page callback'</span><span style="color: #007700">] = array(</span><span style="color: #DD0000">'grasmash_registration_ctools_wizard'</span><span style="color: #007700">);<br> </span><span style="color: #FF8000">// Pass the "first" step key to start the form on step 1 if no step has been specified.<br> </span><span style="color: #0000BB">$items</span><span style="color: #007700">[</span><span style="color: #DD0000">'user/register'</span><span style="color: #007700">][</span><span style="color: #DD0000">'page arguments'</span><span style="color: #007700">] = array(</span><span style="color: #DD0000">'register'</span><span style="color: #007700">);<br> </span><span style="color: #0000BB">$items</span><span style="color: #007700">[</span><span style="color: #DD0000">'user/register'</span><span style="color: #007700">][</span><span style="color: #DD0000">'file path'</span><span style="color: #007700">] = </span><span style="color: #0000BB">drupal_get_path</span><span style="color: #007700">(</span><span style="color: #DD0000">'module'</span><span style="color: #007700">, </span><span style="color: #DD0000">'grasmash_registration'</span><span style="color: #007700">);<br> </span><span style="color: #0000BB">$items</span><span style="color: #007700">[</span><span style="color: #DD0000">'user/register'</span><span style="color: #007700">][</span><span style="color: #DD0000">'file'</span><span style="color: #007700">] = </span><span style="color: #DD0000">'grasmash_registration_ctools_wizard.inc'</span><span style="color: #007700">;<p> return </p></span><span style="color: #0000BB">$items</span><span style="color: #007700">;<br>}<br></span><span style="color: #0000BB">?></span></span>
We will also need to define a new menu router item to handle the subsequent steps of our multistep form. E.g., user/register/%step:
<span style="color: #000000"><span style="color: #0000BB"><?php<br></span><span style="color: #FF8000">/**<br> * Implements hook_menu().<br> */<br></span><span style="color: #007700">function </span><span style="color: #0000BB">grasmash_registration_menu</span><span style="color: #007700">() {<br> </span><span style="color: #0000BB">$items</span><span style="color: #007700">[</span><span style="color: #DD0000">'user/register/%'</span><span style="color: #007700">] = array(<br> </span><span style="color: #DD0000">'title' </span><span style="color: #007700">=> </span><span style="color: #DD0000">'Create new account'</span><span style="color: #007700">,<br> </span><span style="color: #DD0000">'page callback' </span><span style="color: #007700">=> </span><span style="color: #DD0000">'grasmash_registration_ctools_wizard'</span><span style="color: #007700">,<br> </span><span style="color: #DD0000">'page arguments' </span><span style="color: #007700">=> array(</span><span style="color: #0000BB">2</span><span style="color: #007700">),<br> </span><span style="color: #DD0000">'access callback' </span><span style="color: #007700">=> </span><span style="color: #DD0000">'grasmash_registration_access'</span><span style="color: #007700">,<br> </span><span style="color: #DD0000">'access arguments' </span><span style="color: #007700">=> array(</span><span style="color: #0000BB">2</span><span style="color: #007700">),<br> </span><span style="color: #DD0000">'file' </span><span style="color: #007700">=> </span><span style="color: #DD0000">'grasmash_registration_ctools_wizard.inc'</span><span style="color: #007700">,<br> </span><span style="color: #DD0000">'type' </span><span style="color: #007700">=> </span><span style="color: #0000BB">MENU_CALLBACK</span><span style="color: #007700">,<br> );<p> return </p></span><span style="color: #0000BB">$items</span><span style="color: #007700">;<br>}<br></span><span style="color: #0000BB">?></span></span>
Lastly, we need to make a slight alteration to the user_register_form. It will now have at least two submit handlers bound to it: user_register_submit, and ctools_wizard_submit. We need to make sure that the user_register_submit callback is called first!
<span style="color: #000000"><span style="color: #0000BB"><?php<br></span><span style="color: #FF8000">/**<br> * Implements hook_form_FORM_ID_alter().<br> */<br></span><span style="color: #007700">function </span><span style="color: #0000BB">hook_form_user_register_form_alter</span><span style="color: #007700">(&</span><span style="color: #0000BB">$form</span><span style="color: #007700">, &</span><span style="color: #0000BB">$form_state</span><span style="color: #007700">) {<br> </span><span style="color: #0000BB">$form</span><span style="color: #007700">[</span><span style="color: #DD0000">'#submit'</span><span style="color: #007700">] = array(<br> </span><span style="color: #DD0000">'user_register_submit'</span><span style="color: #007700">,<br> </span><span style="color: #DD0000">'ctools_wizard_submit'</span><span style="color: #007700">,<br> );<br>}<br></span><span style="color: #0000BB">?></span></span>
That's it! You should now be able to navigate to user/register and see the first step of your multistep form. Subsequent steps will take you to user/register/[step-name].
Now, for a bonus snippet snack, here's how you can take the first step of your form and put it into a block!
Displaying the first step of our form in a block
<span style="color: #000000"><span style="color: #0000BB"><?php<br></span><span style="color: #FF8000">/**<br> * Implements hook_block_info().<br> */<br></span><span style="color: #007700">function </span><span style="color: #0000BB">grasmash_registration_block_info</span><span style="color: #007700">() {<br> </span><span style="color: #0000BB">$blocks</span><span style="color: #007700">[</span><span style="color: #DD0000">'register_step1'</span><span style="color: #007700">] = array(<br> </span><span style="color: #DD0000">'info' </span><span style="color: #007700">=> </span><span style="color: #0000BB">t</span><span style="color: #007700">(</span><span style="color: #DD0000">'Grasmash Registration: Step 1'</span><span style="color: #007700">),<br> </span><span style="color: #DD0000">'cache' </span><span style="color: #007700">=> </span><span style="color: #0000BB">DRUPAL_NO_CACHE</span><span style="color: #007700">,<br> );<p> return </p></span><span style="color: #0000BB">$blocks</span><span style="color: #007700">;<br>}<br></span><span style="color: #FF8000">/**<br> * Implements hook_block_view().<br> *<br> * This hook generates the contents of the blocks themselves.<br> */<br></span><span style="color: #007700">function </span><span style="color: #0000BB">grasmash_registration_block_view</span><span style="color: #007700">(</span><span style="color: #0000BB">$delta </span><span style="color: #007700">= </span><span style="color: #DD0000">''</span><span style="color: #007700">) {<br> switch (</span><span style="color: #0000BB">$delta</span><span style="color: #007700">) {<br> case </span><span style="color: #DD0000">'register_step1'</span><span style="color: #007700">:<br> </span><span style="color: #0000BB">$block</span><span style="color: #007700">[</span><span style="color: #DD0000">'subject'</span><span style="color: #007700">] = </span><span style="color: #DD0000">'Create an Account'</span><span style="color: #007700">;<br> </span><span style="color: #0000BB">$block</span><span style="color: #007700">[</span><span style="color: #DD0000">'content'</span><span style="color: #007700">] = </span><span style="color: #0000BB">grasmash_registration_block_contents</span><span style="color: #007700">(</span><span style="color: #0000BB">$delta</span><span style="color: #007700">);<br> break;<br> }<br> return </span><span style="color: #0000BB">$block</span><span style="color: #007700">;<br>}<br></span><span style="color: #FF8000">/**<br> * A module-defined block content function.<br> */<br></span><span style="color: #007700">function </span><span style="color: #0000BB">grasmash_registration_block_contents</span><span style="color: #007700">(</span><span style="color: #0000BB">$which_block</span><span style="color: #007700">) {<br> global </span><span style="color: #0000BB">$user</span><span style="color: #007700">;<br> </span><span style="color: #0000BB">$content </span><span style="color: #007700">= </span><span style="color: #DD0000">''</span><span style="color: #007700">;<br> switch (</span><span style="color: #0000BB">$which_block</span><span style="color: #007700">) {<br> case </span><span style="color: #DD0000">'register_step1'</span><span style="color: #007700">:<br> if (!</span><span style="color: #0000BB">$user</span><span style="color: #007700">-></span><span style="color: #0000BB">uid</span><span style="color: #007700">) {<br> </span><span style="color: #0000BB">module_load_include</span><span style="color: #007700">(</span><span style="color: #DD0000">'inc'</span><span style="color: #007700">, </span><span style="color: #DD0000">'grasmash_registration'</span><span style="color: #007700">, </span><span style="color: #DD0000">'grasmash_registration_ctools_wizard'</span><span style="color: #007700">);<br> return </span><span style="color: #0000BB">grasmash_registration_ctools_wizard</span><span style="color: #007700">(</span><span style="color: #DD0000">'register'</span><span style="color: #007700">);<br> }<br> break;<br> }<br>}<br></span><span style="color: #0000BB">?></span></span>
Good luck!
7.x,
drupal, multistep, form, fapi, ctools, registration, register