Forums

Use a variable from the serverside validation

menchee 11 Aug, 2009
In a simple form, no redirecting, using serverside validation:

How can I use defined variables in the serverside script (lets say specific error flags per input), back in the form (lets say to manipulate the form elements)?

Thanks,
Emanuel.
GreyHead 11 Aug, 2009
Hi Emanuel,

I'm really not sure, I've never tried to do that. Things to explore, in this order:

1) add them to the $_POST array - I think that stays available.

2) declare them global - not sure this will work.

3) store them in the session

4) store them in a cookie

5) save them in a database table . . . (in case of desperation only)

Bob
menchee 11 Aug, 2009
Hey Bob,
How can you be available every time, so fast?? Amazing.

I tried global declaration before. It didn't work.
I tried posting them. It didn't work either, but here I'm not sure I used the right code.
In the validation part, before returning the message, I added the next code:
JRequest::setVar('myerror','yes','post','string','');

In the form html code:

if($_POST['myerror'])
{//do something;}

Anything wrong with that?

I won't go with cookie, but session is an option.
However, I was hoping to find a way without it, and then finally understand the logic of the validation.
Until Joomla, I always used one file to present the form, calling the same file with the posted data to trim, strip and validate it and then rebuild the form according to the results. With CC I'm not sure...
nml375 11 Aug, 2009
Hi Emanuel,
That should work fine, as long as you keep track of the run-order of blocks. Globals should work as well, although you might have to use the $_GLOBAL['varname'] approach.

As for the run order:
When the form is shown, the Form Code is evaluated.

As you then submit the form, serverside validation (along with a few sanity tests) is first run. Depending on the result, two things may happen:
Success; if we've enabled emails, the "before email" code is executed. Next the various segments in the run-order list (plugins, onsubmit after, auto-generated) are run, and the "thankyou page is shown to the user".
Failed; the showForm() method is called, passing the content of $MyForm->posted as submitted data to republish. Any php-code in the form code is executed.

/Fredrik
menchee 11 Aug, 2009
Hi Fredrik,

Thank your for explaining the logic. So at least theoretically it is similar to the method I used out of Joomla.
I will also try the $_GLOBAL.

I didn't change the default runorder, and it is in the order you mentioned (plugins>OnSubmit>Autogenerated).
Does a variable I set with JRequest::setVar as POST is available to the down coming code without loading the page again?
The answer here is relevant to the other thread you are trying to help me with (http://www.chronoengine.com/forums.html?cont=posts&f=5&t=15530&p=38760#p38760).

Where does the validation process occur? in the same page of the generated form (like with include()) or out of it?
I'm trying to understand why a variable I declare in the validation code is not available in the form code.

Maybe you can write a simple pair of code lines?
nml375 11 Aug, 2009
Hi Emanuel,
In this case, it's a two page process...
The first page is solely responsible for generating the initial form. In this case, the Serverside Validation is not evaluated.
The second page is when we process the user input'd data. Here, (apart from the sanity checks), we start off with the Serverside Validation. Depending on the success or failure of the serverside validation, we either move on to file upload, DB storage and sending emails (on success), or re-displaying the form (on failure).

Serverside Validation:
<?
JRequest::setVar('testval', JRequest::getVar('starttime', 'default', 'post'), 'post', true);
if (JRequest::getVar('starttime') != -1)
  return JRequest::getVar('starttime');

?>


Form code:
<div>
 <label for="starttime">Time of start</label>
 <select name="starttime" id="starttime">
  <option value="-1" selected></option>
<?
for ($i = 0; $i < 24; $i++)
{
  echo('  <option value="' . $i . '">' . $i . ":00</option>\n");
}
?>
 </select>
</div>
<input type="submit" /><br />
<? echo JRequest::getString('testval'); ?>


Given the above example, upon first loading the page, the form is displayed as normal. The value of testval is "unset", so the JRequest::getString returns an empty string.

Upon submitting the form, if we keep the default empty value, starttime will be -1, and testval will be set to the same. The validation will succeed, and we'll see an empty "thankyou-page".
If, however, we select any other value, starttime will be set to the very same value, testval will also be set to that value. The form will be redisplayed, and the value of testval (now an integer between 0 and 23) will be printed below the submit button. Tested with CF3.1rc5.3.

Hope this helps explaining the process a little further.
/Fredrik
menchee 13 Aug, 2009
Hi Fredrik.
I learned much more than I asked by your example. Thanks! I really appreciate your help every time.

After playing with your code, than with mine, I found that:
Both work fine when the form is published as a component.
They don't work when it is published using the plugin (as part of an article).
I'm talking about the setVar and then getString (or getVar).

I tested on CF V3.1RC5.5, Plugin_V3.1_RC5.2.

Emanuel.
nml375 13 Aug, 2009
Hi Emanuel,
That was interesting. I've never used the plugin myself, but had a look at the source of it now though. It does a few tricks with the pagetype property of the form object, which in turn adds a few session data. All in all, this alters the way the form is (re)shown; validation errors mean the page is redirected rather than just re-displayed (and any data not stored in a session is thus lost). The key here, lies in these lines from the plugin:
if($session->get('chrono_form_data_'.$formname, array(), md5('chrono'))){
  $posted = $session->get('chrono_form_data_'.$formname, array(), md5('chrono'));
  //print_r($posted);
}
ob_start();
$MyForm->showForm($formname, $posted);

So, instead of using the JRequest::get('post', ALLOW_RAW); call to fill the $posted value within the showForm() method, the plugin fetches the data from the session storage named 'chrono_form_data_FORMNAME'. For your case, you need to complement/replace the JRequest::setVar() with something like this:
 $session =& JFactory::getSession();
$_p =& $session->get('chrono_form_data_myform', array(), md5('chrono'));
$_p['myerror'] = 'yes';
$session->set('chrono_form_data_myform', $_p, md5('chrono'));

You'd then access your 'myerror' property through the $posted array in the "Form Code".

I have not tested this code myself, but from what I can gather of the sources, it should work.
/Fredrik
menchee 13 Aug, 2009
Thanks Patrik. I think we are almost there :-)

Using simple session method works ok. Setting code in the validation, getting code in the from.

$session->set('myerror', 'yes');
$session->get('myerror');

I can pass a variable which is good, but I can't modify the items in the $MyForm->posted array.

Using the code you wrote won't retrieve the $posted from session, so I modified it a little:

$session =& JFactory::getSession();
$MyForm =& CFChronoForm::getInstance('validationTest');//Now I can get the posted in the next line (I replaced the array()  )
$_p =& $session->get('chrono_form_data_validationTest', $MyForm->posted, md5('chrono'));
$_p['myerror'] = 'yes_error';
$session->set('chrono_form_data_validationTest', $_p, md5('chrono'));

What I still can't do (and I tried to dive into the component and plugin code, but without success), is setting back the new posted array in the session, so it will be ready to be submitted, sanitized by my control.

Emanuel.
This topic is locked and no more replies can be posted.