Re: [development] Creating multiple login blocks with, different validation rules.
Hi Earnie, Thanks for the answer and that's one of the things to do, but my problem at the moment with that path is that in hook_form_alter there doesn't seem to be anything that I can use to identify which block it is. Am I missing something obvious? If there is nothing in the $form then what I think I actually want to do is use some code to generate the form and as I have access to the $form array to put in my own validation rule or hidden $form element or whatever to distinguish between the different blocks. So I'm trying to generate the user_login_block myself so I can alter the $form array but can't get it to work. In my block code if I call drupal_get_form('user_login_block') for the block content everything is fine but I can't alter the form object. So I'm trying to do the same steps as drupal_get_form, i.e. the code below and the user login block displays but there is a bunch of stuff missing from it so it doesn't actually submit. Am I making this harder than I need to for what I'm trying to achieve? Regards, Anthony. $form_state = array(); $form = drupal_retrieve_form('user_login_block', $form_state); drupal_prepare_form('user_login_block', $form, $form_state); $block['content'] = drupal_render_form('user_login_block', $form); On 14/05/2010 3:44 AM, development-request@drupal.org wrote:
Message: 1 Date: Thu, 13 May 2010 08:26:46 -0400 From: Earnie Boyd<earnie@users.sourceforge.net> Subject: Re: [development] Creating multiple login blocks with different validation rules. To:development@drupal.org Message-ID:<4BEBF006.9010907@users.sourceforge.net> Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Anth wrote:
Hi, Does anyone have ideas on how to implement the function in the subject? Basically I want a page with two login blocks, one for general users and one for premium users. I've used multiblock to get the two blocks up there but I need the two different blocks to work different for the different user types. That is if a general user tries to login on the premium login it fails and vice versa. Is there any easy way to do this or do I have to recreate my forms manually?
You don't need to start from scratch but you do need to code using hook_form_alter to add the appropriate form elements and also a hook_user to capture the user operations and operate on the appropriately.
-- Earnie -- http://progw.com -- http://www.for-my-kids.com
In Drupal 6, there are several problems with having 2 forms on a page using the same form id. You will probably need to implement hook_forms() to create a new form id (e.g., 'YOURMODULE_user_login_block_premium') that maps to the 'user_login_block' callback (see http://api.drupal.org/api/function/user_forms/6 for an example of how this is done). Then you can drupal_get_form() the two forms using different ids, and hook_form_alter() them differently based on the $form_id. I'm hoping Drupal 7 fixes the remaining bugs with multiple instances of the same form on a page. I'm not sure what all of them are yet, but for starters: http://drupal.org/node/766146. Alex. Anth wrote:
Hi Earnie,
Thanks for the answer and that's one of the things to do, but my problem at the moment with that path is that in hook_form_alter there doesn't seem to be anything that I can use to identify which block it is. Am I missing something obvious?
If there is nothing in the $form then what I think I actually want to do is use some code to generate the form and as I have access to the $form array to put in my own validation rule or hidden $form element or whatever to distinguish between the different blocks. So I'm trying to generate the user_login_block myself so I can alter the $form array but can't get it to work. In my block code if I call drupal_get_form('user_login_block') for the block content everything is fine but I can't alter the form object. So I'm trying to do the same steps as drupal_get_form, i.e. the code below and the user login block displays but there is a bunch of stuff missing from it so it doesn't actually submit.
Am I making this harder than I need to for what I'm trying to achieve?
Regards, Anthony.
$form_state = array(); $form = drupal_retrieve_form('user_login_block', $form_state); drupal_prepare_form('user_login_block', $form, $form_state); $block['content'] = drupal_render_form('user_login_block', $form);
On 14/05/2010 3:44 AM, development-request@drupal.org wrote:
Message: 1 Date: Thu, 13 May 2010 08:26:46 -0400 From: Earnie Boyd<earnie@users.sourceforge.net> Subject: Re: [development] Creating multiple login blocks with different validation rules. To:development@drupal.org Message-ID:<4BEBF006.9010907@users.sourceforge.net> Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Anth wrote:
Hi, Does anyone have ideas on how to implement the function in the subject? Basically I want a page with two login blocks, one for general users and one for premium users. I've used multiblock to get the two blocks up there but I need the two different blocks to work different for the different user types. That is if a general user tries to login on the premium login it fails and vice versa. Is there any easy way to do this or do I have to recreate my forms manually?
You don't need to start from scratch but you do need to code using hook_form_alter to add the appropriate form elements and also a hook_user to capture the user operations and operate on the appropriately.
-- Earnie -- http://progw.com -- http://www.for-my-kids.com
Anth wrote:
Hi Earnie,
Thanks for the answer and that's one of the things to do, but my problem at the moment with that path is that in hook_form_alter there doesn't seem to be anything that I can use to identify which block it is. Am I missing something obvious?
The third argument of hook_form_alter is the $form_id and for user_login_block that would be user_login_block. Both $form and $form_state are a pass-by-ref variable so any changes you do happen to the form and/or form_state before they get rendered.
If there is nothing in the $form then what I think I actually want to do is use some code to generate the form and as I have access to the $form array to put in my own validation rule or hidden $form element or whatever to distinguish between the different blocks.
You can add your own validation and submit handlers for the form using hook_form_alter as well. You just need to make sure that your hook_form_alter function uses a pass by ref for the $form parameter and add your validation or submit handlers as appropriate.
So I'm trying to generate the user_login_block myself so I can alter the $form array but can't get it to work. In my block code if I call drupal_get_form('user_login_block') for the block content everything is fine but I can't alter the form object. So I'm trying to do the same steps as drupal_get_form, i.e. the code below and the user login block displays but there is a bunch of stuff missing from it so it doesn't actually submit.
Am I making this harder than I need to for what I'm trying to achieve?
If you're doing the same code as drupal_get_form then you are most likely doing the wrong thing and making it harder than it needs to be. Be sure to look for the examples at api.drupal.org. -- Earnie -- http://progw.com -- http://www.for-my-kids.com
IIRC, he said he was using MultiBlock, which might change the form_id; it definitely changes the module name and delta for the block. I'm guessing the first problem is using MultiBlock for the user_login_block, as the user module is not multiblock enabled. I think the answer about using hook_forms is the way to go, but last I looked the API docs were really bad on that hook. Nancy E. Wichmann, PMP Injustice anywhere is a threat to justice everywhere. -- Dr. Martin L. King, Jr. ________________________________ From: Earnie Boyd Anth wrote:
Hi Earnie,
Thanks for the answer and that's one of the things to do, but my problem at the moment with that path is that in hook_form_alter there doesn't seem to be anything that I can use to identify which block it is. Am I missing something obvious?
The third argument of hook_form_alter is the $form_id and for user_login_block that would be user_login_block. Both $form and $form_state are a pass-by-ref variable so any changes you do happen to the form and/or form_state before they get rendered.
If there is nothing in the $form then what I think I actually want to do is use some code to generate the form and as I have access to the $form array to put in my own validation rule or hidden $form element or whatever to distinguish between the different blocks.
You can add your own validation and submit handlers for the form using hook_form_alter as well. You just need to make sure that your hook_form_alter function uses a pass by ref for the $form parameter and add your validation or submit handlers as appropriate.
So I'm trying to generate the user_login_block myself so I can alter the $form array but can't get it to work. In my block code if I call drupal_get_form('user_login_block') for the block content everything is fine but I can't alter the form object. So I'm trying to do the same steps as drupal_get_form, i.e. the code below and the user login block displays but there is a bunch of stuff missing from it so it doesn't actually submit.
Am I making this harder than I need to for what I'm trying to achieve?
If you're doing the same code as drupal_get_form then you are most likely doing the wrong thing and making it harder than it needs to be. Be sure to look for the examples at api.drupal.org. -- Earnie -- http://progw.com -- http://www.for-my-kids.com
For a decent Hook_forms example look to ubercart's uc_product, it uses hook_forms to register the 'add to cart' forms : http://api.lullabot.com/uc_product_forms
I think the answer about using hook_forms is the way to go, but last I looked the API docs were really bad on that hook.
Hi, Thanks for the tips everyone. Worked it out, will describe what I ended up doing in case it's useful to anyone. Nancy and Earnie, I was using MultiBlock and the core of the problem for me was that they *don't* change the $form_id so there is nothing to differentiate them. Alex, yep, I'd started to look at hook_forms so your tip was a good kick in the right direction. Lee, by the time I got your email I'd worked it out :) So as an example, I had to throw away MultiBlock and generate the blocks on my own but it was pretty easy to do. My application is a timesheet application and there is a role called 'candidate' that needed a separate login. The only real problems I had after getting the hang of all that is for some reason I had to shift my validation function into the first slot (see comments in hook_form_alter) to get it to fire, and if I do a form_set_error(), because the elements are the same name the red error border appears on both, but hey I can live with that. in my hook_block: case 'view': $block['subject'] = 'Candidate Login'; $block['content'] = drupal_get_form('candidate_login_block'); return $block; Now because 'candidate_login_block' doesn't exist as a function that can be called by drupal_get_form I want drupal_get_form to be called as drupal_get_form('user_login_block') and to make this happen I set up a hook_forms (note, not hook_form) as below: function timesheet_forms($form_id, $args) { $forms['candidate_login_block']['callback'] = 'user_login_block'; return $forms; } This all means that in my hook_form_alter I can do: switch($form_id) { case 'candidate_login_block': // $form['#validate'][] = '_timesheet_candidate_login_validate'; // The line above doesn't seem to result in my validation function getting called so had to use the form below. array_unshift($form['#validate'], '_timesheet_candidate_login_validate'); break; In my function _timesheet_candidate_login_validate I can do whatever I want to invalidate the form (I called user_load with the entered field and checked its roles). Done. Thanks, Anthony. On 14/05/2010 3:37 PM, Lee Rowlands wrote:
For a decent Hook_forms example look to ubercart’s uc_product, it uses hook_forms to register the ‘add to cart’ forms : http://api.lullabot.com/uc_product_forms
*>* I think the answer about using hook_forms is the way to go, but last I looked the API docs were really bad on that hook.
Great, Anthony. I suggest that you write up a little snippet page for the Handbooks so it can be found with a search. BTW, remember the array_unshift technique, because you will need it again, especially if you do any node_form alters. I worked that same one out some time ago and am amazed at how many times I have to get my submit handlers to fire first. I just had to do it again a couple of days ago on the comment_form. So documenting this in the handbooks could save people a lot of time in the future. Nancy E. Wichmann, PMP Injustice anywhere is a threat to justice everywhere. -- Dr. Martin L. King, Jr. ________________________________ From: Anth <malkouna@yahoo.com.au> To: development@drupal.org Sent: Fri, May 14, 2010 2:02:50 AM Subject: Re: [development] Creating multiple login blocks with, different validation rules. Hi, Thanks for the tips everyone. Worked it out, will describe what I ended up doing in case it's useful to anyone. Nancy and Earnie, I was using MultiBlock and the core of the problem for me was that they *don't* change the $form_id so there is nothing to differentiate them. Alex, yep, I'd started to look at hook_forms so your tip was a good kick in the right direction. Lee, by the time I got your email I'd worked it out :) So as an example, I had to throw away MultiBlock and generate the blocks on my own but it was pretty easy to do. My application is a timesheet application and there is a role called 'candidate' that needed a separate login. The only real problems I had after getting the hang of all that is for some reason I had to shift my validation function into the first slot (see comments in hook_form_alter) to get it to fire, and if I do a form_set_error(), because the elements are the same name the red error border appears on both, but hey I can live with that. in my hook_block: case 'view': $block['subject'] = 'Candidate Login'; $block['content'] = drupal_get_form('candidate_login_block'); return $block; Now because 'candidate_login_block' doesn't exist as a function that can be called by drupal_get_form I want drupal_get_form to be called as drupal_get_form('user_login_block') and to make this happen I set up a hook_forms (note, not hook_form) as below: function timesheet_forms($form_id, $args) { $forms['candidate_login_block']['callback'] = 'user_login_block'; return $forms; } This all means that in my hook_form_alter I can do: switch($form_id) { case 'candidate_login_block': // $form['#validate'][] = '_timesheet_candidate_login_validate'; // The line above doesn't seem to result in my validation function getting called so had to use the form below. array_unshift($form['#validate'], '_timesheet_candidate_login_validate'); break; In my function _timesheet_candidate_login_validate I can do whatever I want to invalidate the form (I called user_load with the entered field and checked its roles). Done. Thanks, Anthony. On 14/05/2010 3:37 PM, Lee Rowlands wrote:
For a decent Hook_forms example look to ubercart’s uc_product, it uses hook_forms to register the ‘add to cart’ forms : http://api.lullabot.com/uc_product_forms
*>* I think the answer about using hook_forms is the way to go, but last I looked the API docs were really bad on that hook.
Hi Nancy, OK, I'll do that :) I haven't written a handbook entry before, but having a look ist the best spot for it would under http://drupal.org/node/561062 do you think? A. On 6:59 AM, nan wich wrote:
Great, Anthony. I suggest that you write up a little snippet page for the Handbooks so it can be found with a search. BTW, remember the array_unshift technique, because you will need it again, especially if you do any node_form alters. I worked that same one out some time ago and am amazed at how many times I have to get my submit handlers to fire first. I just had to do it again a couple of days ago on the comment_form. So documenting this in the handbooks could save people a lot of time in the future.
/*Nancy E. Wichmann, PMP*/
Injustice anywhere is a threat to justice everywhere. -- Dr. Martin L. King, Jr.
------------------------------------------------------------------------ *From:* Anth <malkouna@yahoo.com.au> *To:* development@drupal.org *Sent:* Fri, May 14, 2010 2:02:50 AM *Subject:* Re: [development] Creating multiple login blocks with, different validation rules.
Hi,
Thanks for the tips everyone. Worked it out, will describe what I ended up doing in case it's useful to anyone.
Nancy and Earnie, I was using MultiBlock and the core of the problem for me was that they *don't* change the $form_id so there is nothing to differentiate them. Alex, yep, I'd started to look at hook_forms so your tip was a good kick in the right direction. Lee, by the time I got your email I'd worked it out :)
So as an example, I had to throw away MultiBlock and generate the blocks on my own but it was pretty easy to do. My application is a timesheet application and there is a role called 'candidate' that needed a separate login. The only real problems I had after getting the hang of all that is for some reason I had to shift my validation function into the first slot (see comments in hook_form_alter) to get it to fire, and if I do a form_set_error(), because the elements are the same name the red error border appears on both, but hey I can live with that.
in my hook_block:
case 'view': $block['subject'] = 'Candidate Login'; $block['content'] = drupal_get_form('candidate_login_block'); return $block;
Now because 'candidate_login_block' doesn't exist as a function that can be called by drupal_get_form I want drupal_get_form to be called as drupal_get_form('user_login_block') and to make this happen I set up a hook_forms (note, not hook_form) as below:
function timesheet_forms($form_id, $args) { $forms['candidate_login_block']['callback'] = 'user_login_block'; return $forms; }
This all means that in my hook_form_alter I can do:
switch($form_id) { case 'candidate_login_block': // $form['#validate'][] = '_timesheet_candidate_login_validate'; // The line above doesn't seem to result in my validation function getting called so had to use the form below. array_unshift($form['#validate'], '_timesheet_candidate_login_validate'); break;
In my function _timesheet_candidate_login_validate I can do whatever I want to invalidate the form (I called user_load with the entered field and checked its roles). Done.
Thanks, Anthony.
On 14/05/2010 3:37 PM, Lee Rowlands wrote:
For a decent Hook_forms example look to ubercart’s uc_product, it
uses hook_forms to register the ‘add to cart’ forms : http://api.lullabot.com/uc_product_forms
*>* I think the answer about using hook_forms is the way to go, but
last I looked the API docs were really bad on that hook.
Hi Nancy, OK, I'll do that :) I haven't written a handbook entry before, but having a look is the best spot for it would under http://drupal.org/node/561062 do you think? A. On 6:59 AM, nan wich wrote:
Great, Anthony. I suggest that you write up a little snippet page for the Handbooks so it can be found with a search. BTW, remember the array_unshift technique, because you will need it again, especially if you do any node_form alters. I worked that same one out some time ago and am amazed at how many times I have to get my submit handlers to fire first. I just had to do it again a couple of days ago on the comment_form. So documenting this in the handbooks could save people a lot of time in the future.
/*Nancy E. Wichmann, PMP*/
Injustice anywhere is a threat to justice everywhere. -- Dr. Martin L. King, Jr.
------------------------------------------------------------------------ *From:* Anth <malkouna@yahoo.com.au> *To:* development@drupal.org *Sent:* Fri, May 14, 2010 2:02:50 AM *Subject:* Re: [development] Creating multiple login blocks with, different validation rules.
Hi,
Thanks for the tips everyone. Worked it out, will describe what I ended up doing in case it's useful to anyone.
Nancy and Earnie, I was using MultiBlock and the core of the problem for me was that they *don't* change the $form_id so there is nothing to differentiate them. Alex, yep, I'd started to look at hook_forms so your tip was a good kick in the right direction. Lee, by the time I got your email I'd worked it out :)
So as an example, I had to throw away MultiBlock and generate the blocks on my own but it was pretty easy to do. My application is a timesheet application and there is a role called 'candidate' that needed a separate login. The only real problems I had after getting the hang of all that is for some reason I had to shift my validation function into the first slot (see comments in hook_form_alter) to get it to fire, and if I do a form_set_error(), because the elements are the same name the red error border appears on both, but hey I can live with that.
in my hook_block:
case 'view': $block['subject'] = 'Candidate Login'; $block['content'] = drupal_get_form('candidate_login_block'); return $block;
Now because 'candidate_login_block' doesn't exist as a function that can be called by drupal_get_form I want drupal_get_form to be called as drupal_get_form('user_login_block') and to make this happen I set up a hook_forms (note, not hook_form) as below:
function timesheet_forms($form_id, $args) { $forms['candidate_login_block']['callback'] = 'user_login_block'; return $forms; }
This all means that in my hook_form_alter I can do:
switch($form_id) { case 'candidate_login_block': // $form['#validate'][] = '_timesheet_candidate_login_validate'; // The line above doesn't seem to result in my validation function getting called so had to use the form below. array_unshift($form['#validate'], '_timesheet_candidate_login_validate'); break;
In my function _timesheet_candidate_login_validate I can do whatever I want to invalidate the form (I called user_load with the entered field and checked its roles). Done.
Thanks, Anthony.
On 14/05/2010 3:37 PM, Lee Rowlands wrote:
For a decent Hook_forms example look to ubercart’s uc_product, it
uses hook_forms to register the ‘add to cart’ forms : http://api.lullabot.com/uc_product_forms
*>* I think the answer about using hook_forms is the way to go, but
last I looked the API docs were really bad on that hook.
That would work. Nancy E. Wichmann, PMP Injustice anywhere is a threat to justice everywhere. -- Dr. Martin L. King, Jr. ________________________________ From: Anth <malkouna@yahoo.com.au> To: development@drupal.org Sent: Fri, May 14, 2010 8:38:54 PM Subject: Re: [development] Creating multiple login blocks with, different validation rules. Hi Nancy, OK, I'll do that :) I haven't written a handbook entry before, but having a look is the best spot for it would under http://drupal.org/node/561062 do you think? A. On 6:59 AM, nan wich wrote:
Great, Anthony. I suggest that you write up a little snippet page for the Handbooks so it can be found with a search. BTW, remember the array_unshift technique, because you will need it again, especially if you do any node_form alters. I worked that same one out some time ago and am amazed at how many times I have to get my submit handlers to fire first. I just had to do it again a couple of days ago on the comment_form. So documenting this in the handbooks could save people a lot of time in the future.
/*Nancy E. Wichmann, PMP*/
Injustice anywhere is a threat to justice everywhere. -- Dr. Martin L. King, Jr.
------------------------------------------------------------------------ *From:* Anth <malkouna@yahoo.com.au> *To:* development@drupal.org *Sent:* Fri, May 14, 2010 2:02:50 AM *Subject:* Re: [development] Creating multiple login blocks with, different validation rules.
Hi,
Thanks for the tips everyone. Worked it out, will describe what I ended up doing in case it's useful to anyone.
Nancy and Earnie, I was using MultiBlock and the core of the problem for me was that they *don't* change the $form_id so there is nothing to differentiate them. Alex, yep, I'd started to look at hook_forms so your tip was a good kick in the right direction. Lee, by the time I got your email I'd worked it out :)
So as an example, I had to throw away MultiBlock and generate the blocks on my own but it was pretty easy to do. My application is a timesheet application and there is a role called 'candidate' that needed a separate login. The only real problems I had after getting the hang of all that is for some reason I had to shift my validation function into the first slot (see comments in hook_form_alter) to get it to fire, and if I do a form_set_error(), because the elements are the same name the red error border appears on both, but hey I can live with that.
in my hook_block:
case 'view': $block['subject'] = 'Candidate Login'; $block['content'] = drupal_get_form('candidate_login_block'); return $block;
Now because 'candidate_login_block' doesn't exist as a function that can be called by drupal_get_form I want drupal_get_form to be called as drupal_get_form('user_login_block') and to make this happen I set up a hook_forms (note, not hook_form) as below:
function timesheet_forms($form_id, $args) { $forms['candidate_login_block']['callback'] = 'user_login_block'; return $forms; }
This all means that in my hook_form_alter I can do:
switch($form_id) { case 'candidate_login_block': // $form['#validate'][] = '_timesheet_candidate_login_validate'; // The line above doesn't seem to result in my validation function getting called so had to use the form below. array_unshift($form['#validate'], '_timesheet_candidate_login_validate'); break;
In my function _timesheet_candidate_login_validate I can do whatever I want to invalidate the form (I called user_load with the entered field and checked its roles). Done.
Thanks, Anthony.
On 14/05/2010 3:37 PM, Lee Rowlands wrote:
For a decent Hook_forms example look to ubercart’s uc_product, it uses hook_forms to register the ‘add to cart’ forms : http://api.lullabot.com/uc_product_forms
*>* I think the answer about using hook_forms is the way to go, but last I looked the API docs were really bad on that hook.
and if I do a form_set_error(), because the elements are the same name the red error border appears on both, but hey I can live with that.
For anyone what can't live with that, you may be interested in http://drupal.org/node/799356. Anth wrote:
Hi,
Thanks for the tips everyone. Worked it out, will describe what I ended up doing in case it's useful to anyone.
Nancy and Earnie, I was using MultiBlock and the core of the problem for me was that they *don't* change the $form_id so there is nothing to differentiate them. Alex, yep, I'd started to look at hook_forms so your tip was a good kick in the right direction. Lee, by the time I got your email I'd worked it out :)
So as an example, I had to throw away MultiBlock and generate the blocks on my own but it was pretty easy to do. My application is a timesheet application and there is a role called 'candidate' that needed a separate login. The only real problems I had after getting the hang of all that is for some reason I had to shift my validation function into the first slot (see comments in hook_form_alter) to get it to fire, and if I do a form_set_error(), because the elements are the same name the red error border appears on both, but hey I can live with that.
in my hook_block:
case 'view': $block['subject'] = 'Candidate Login'; $block['content'] = drupal_get_form('candidate_login_block'); return $block;
Now because 'candidate_login_block' doesn't exist as a function that can be called by drupal_get_form I want drupal_get_form to be called as drupal_get_form('user_login_block') and to make this happen I set up a hook_forms (note, not hook_form) as below:
function timesheet_forms($form_id, $args) { $forms['candidate_login_block']['callback'] = 'user_login_block'; return $forms; }
This all means that in my hook_form_alter I can do:
switch($form_id) { case 'candidate_login_block': // $form['#validate'][] = '_timesheet_candidate_login_validate'; // The line above doesn't seem to result in my validation function getting called so had to use the form below. array_unshift($form['#validate'], '_timesheet_candidate_login_validate'); break;
In my function _timesheet_candidate_login_validate I can do whatever I want to invalidate the form (I called user_load with the entered field and checked its roles). Done.
Thanks, Anthony.
On 14/05/2010 3:37 PM, Lee Rowlands wrote:
For a decent Hook_forms example look to ubercart’s uc_product, it uses hook_forms to register the ‘add to cart’ forms : http://api.lullabot.com/uc_product_forms
*>* I think the answer about using hook_forms is the way to go, but last I looked the API docs were really bad on that hook.
participants (5)
-
Alex Bronstein -
Anth -
Earnie Boyd -
Lee Rowlands -
nan wich