-
Fabrik 3.8.1 has been released. It is mostly bug fixes and feature enhancements, but does include two new plugins (push notifications, and the sequence element). As usual we strongly recommend testing the new release on a sandbox if your application is mission critical, and always do an Akeeba backup before updating.
PHP form plugin
-
Contents
- Introduction
- Options
- Plugin Locations
- Refresh display
- Examples
- Accessing Form Data
- Accessing form's original data
- Updating a form's value on Save
- Conditionally updating a form's value on Save
- Updating a form's value before showing the form
- Stopping form submission
- Totalling radio buttons and placing the result in an element
- IP Check
- Insert a record in another table and update a form's field with the records primary key
- Decrease a value in another table
- Get row ID of a form
Introduction(top)
Sometimes you are going to need to run some specific code that is not provided for by one of the other form submission plug-ins. At this point the highly flexible Run PHP plug-in is a godsend.
Options(top)
- Process scripts - State where in the form submission process you would like the script to be executed.
- PHP File- Select the PHP file you would like to run. In Fabrik version 2 these files are located in /components/com_fabrik/plugins/forms/fabrik/php/scripts.
- In Fabrik 3 these files are located in /plugins/fabrik_form/php/scripts/ .
- In Fabrik 2, It is location in components/com_fabrik/plugins/form/fabrikphp
- The Joomla framework is available to these scripts, so for example you can access the Joomla database with :
PHP:$db = JFactory::getDBO(); - PHP code to execute on from submission - If no script is selected then the code entered here will be run instead.
For best security practices you should always add this to the top of your custom php scripts:
this stops the script from being executed outside of Joomla/Fabrik.
Plugin Locations (top)
The plug-in allows you to run your PHP at various locations/times within a fabrik form:
Locations :
- getTopContent - will insert anything that has been return'ed from your PHP script into the top of the form
- getBottomContent - will insert anything that has been return'ed from your PHP script into the bottom of the form
rather than echo statements.
Times :
The main "times" (or "hooks") that the PHP plugin can be set to run on are:
- onLoad - runs when the form has been loaded, after its data has been created and assigned
- onError - When the form is submitted it is first validated, if a validation error occurs then this hook is triggered allowing you to for example, alter the $model->_arErrors error array or log which validation errors were set.
- onBeforeProcess - occurs at the start of a form submission, before the posted data has been assigned to the form model, but after the form has been validated
- onBeforeStore - occurs after onBeforeProcess and occurs after any fileuploads have been dealt with
- onAfterProcess - occurs after onBeforeStore once the form has submitted its data to the database table
Validation :If any of the scripts running during the form submission return false, then the form submission is halted.
Refresh display (top)
If using onBeforeLoad(), and your script modifies the database used by your form, or your form fields, you should wish that your display reflects your modifications. In that case, Fabrik should be forced to re-read data from the database when call getData(), just after the onBeforeLoad() hook runs.
For this use :
PHP:Examples(top)
Accessing Form Data (top)
Usually, the best way to get an element's data is with the $formModel->getElementData() method, which takes the full element name, and three optional arguments:
PHP:
* @param string $fullName full element name
* @param bool $raw get raw data
* @param mixed $default value
* @param string $repeatCount repeat count if needed
Examples:
PHP:
// To get the content of a simple field element
$foo = $formModel->getElementData('mytable___foo');
// To get the content of the second occurence of an element in a repeat group (group repeats are numbered from 0)
$foo = $formModel->getElementData('my_repeat_table___foo', false, '', 1);
/*
*To get the raw value for a database join element, which is set to display as a dropdown.
* Note that the data in a join element, or any element which has multiple value (checkbox, radiom etc)
* will (almost always) be an array, as it can contain multiple values. For a single value dropdown, we
* will typically just want the first (and only) value in that array, so the second line here simply extracts
* the single result from the array.
* Also note the use of the second argument, $raw, which fetches the 'value' rather than the 'label'
*/
$foo = $formModel->getElementData('mytable___somejoin', true);
$foo = is_array($foo) ? $foo[0] : $foo;
/*
* During a submission hook (like onBeforeProcess, onAfterProcess, etc), get the number of times a
* group has been repeated, and fetch each value of foo. You'll need to know the group ID of your group
* which is in the rightmost column of the main list of groups on the backend. Here we'll use 123. On
* submit, the totals for each group's repeats are in a hidden form variable called fabrik_repeat_group,
* which we can fetch with the J! request API ($input->get()):
$app = JFactory::getApplication();
$input = $app->input; $group_id = 123;
$repeatTotals = $input->get('fabrik_repeat_group', array(0), 'array');
for ($repeats = 0; $repeats < $repeatTotals[$group_id]; $repeats++)
{
$foo = $formModel->getElementData('my_repeat_table___foo', false, $repeat);
// some code to do something with $foo goes here
}
/*
* An alternative approach to fetching all the repeated value for an element in a repeat group.
* This time, we'll just get the element's value, without specifying a repeatCount, in which case
* getElementData() will just hand us back an array which has all the repeated values.
* Typically when doing something like this, you will be wanting to fetch the coresponding value
* for another element in the same repeated instance of the group. So in this example, we'll use the key
* from a foreach() to grab another element's value. This example assumes we're going to do math on
* a 'cost' and 'qty', so specify $raw to make sure we get unformatted values.
*/
$costs = $formModel->getElementData('my_repeat_table___cost', true);
foreach ($costs as $key => $cost)
{
$qty = $formModel->getElementData('my_repeat_table___qty', true, 0, $key);
// do something with $cost and $qty
}
The form's data is stored as an array and can be accessed with
PHP:
$formModel->_data; // for getTopContent, getBottomContent, getEndContent - use full element names: 'table___element'
Fabrik 3.0:
$formModel->_formData // onBeforeStore: use full element names 'table___element'
//for onAfterProcess - use short element names: 'element' - no table name
Fabrik 3.1:
$formModel->data //onload: use full element names 'table___element' e.g. $formModel->data['table___element']='abc';
$formModel->formData // onBeforeStore: use full element names 'table___element'
//for onAfterProcess - use short element names: 'element' - no table name (has issues with joined tables with identical column names (Jan. 2015)
Fabrik 3.2 onBeforeCalculation, onAfterProcess (Jan 2015)
$data['table___element']
// All versions of Fabrik also have a $formModel->fullFormData, which will contain the data keyed by full name, even onAfterProcess.
To quickly see the structure of your form's data set this as your code:
PHP:
Joined elements (e.g. muliselect database joins, file uploads with multiple files being uploaded) and elements in joined groups. have their data nested in the array, so fore example to access the element 'countries___regions' in join id 6 you would do :
PHP:
$regions = $formModel->_data['join'][6]['countries___regions'] // for getTopContent, getBottomContent, getEndContent - full element names
$regions = $formModel->formData['join'][6]['countries___regions'] // for onAfterProcess - full element names
PHP:
$regions = $formModel->formData['countries___regions'];
Accessing form's original data(top)
only tested with Fabrik3.4.3 and onBeforeStore (check with var_dump($formModel->getOrigData()[0]);exit; )
Code (Text):$origData = $formModel->getOrigData()[0];
http://fabrikar.com/forums/index.php?threads/approve-form-before-pdf-generation.47518/#post-246324
Updating a form's value on Save(top)
Often you will want to update the data that has been submitted by the form, run your plugin onBeforeProcess. To do this the php would be:
PHP:
$formModel->updateFormData('tablename___elementname', 'string value', true);
// in Fabrik 3.0 or less, to update data in a join (with id = 1) use this syntax:
$formModel->updateFormData("join.1.tablename___elementname", 'string value', true);
Conditionally updating a form's value on Save(top)
Lets say we want to update the field 'sport's value to 'badminton' when the field name's value is 'rob'. To do this the php would be:
PHP:
$name = $formModel->formData['tablename___name'];
if ($name === 'rob')
{
$formModel->updateFormData('tablename___sport', 'badminton', true);
}
Updating a form's value before showing the form(top)
This would use the same code as the above example except you set the "plugin location" to onLoad
Fabrik 3.1. onward, use
Code (Text):$formModel->data['table___element']='abc'
Stopping form submission (top)
Set your plug-in to run 'onBeforeProcess' add this script:
For Fabrik 3.0
PHP:
// stop form being processed and close form without a message when saved
// will also close ajax modal form window
return false;
PHP:
/**
* this is a very simple example of a script to stop the form being processed
* The form is then redisplayed with an error
* notice at the top of the form (and the previously filled in data still visible)
*/
// The error message 'woops' will be assinged to the element 'tablename_elementname'
$formModel->_arErrors['tablename___elementname'][] = 'woops!';
return false;
PHP:
// stop form being processed and close form without a message when saved
// will also close ajax modal form window
return false;
PHP:
// The error message 'woops' will be assinged to the element 'tablename_elementname'
$formModel->errors['tablename___elementname'][] = 'woops!';
return false;
PHP:
$formModel->getForm()->error = "Sorry, that's not going to work.";
Totalling radio buttons and placing the result in an element (top)
Say you want to total the selected values of three radio buttons and store their total in another element when the form is submitted:
Lets say you have 3 radio elements, called listname___radio1, listname___radio2 and listname___radio3, with values 1,2,3 and labels one,two,three.
You want to total these and update a element 'listname___total'. You're php code would look like:
PHP:
$radio1 = (int)"{listname___radio1_raw}";
$radio2 = (int)"{listname___radio2_raw}";
$radio3 = (int)"{listname___radio3_raw}";
$total = $radio1 + $radio2 + $radio3;
$formModel->updateFormData("listname___total", $total, true);
IP Check(top)
Say you have a form where you only want to record one record per IP address. Your form saves to the database table 'contacts' and stores the user's IP address in an element called 'ip':
To stop the form from loading add an onLoad PHP form plugin with the following code:
PHP:
if (!$formModel->isNewRecord()) {
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$thisIp = $formModel->formData['contacts___ip'];
$query->select('COUNT(*)')->from('contacts')->where('ip = ' . $db->quote($thisIp));
$db->setQuery($query);
$total = $db->loadResult();
if ($total > 0)
{
return false;
}
}
return true;
Insert a record in another table and update a form's field with the records primary key(top)
PHP:
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query->insert('tablename')->set('field = ' . $db->quote('bar'))
->set('field2 = ' . $db->quote('{tablename___elementname}'));
$db->setQuery($query);
$db->execute();
$id = $db->insertid();
// Update form data with insert id
$formModel->updateFormData('tablename___elementname2', $id);
Decrease a value in another table(top)
I have a list called Courses which holds the available courses that a user can sign up for.
Courses have an element called spaces that is a number - example 20 spaces.
When a user signs up for a course I would like the value of spaces to be -1 space.
PHP:
// signup___course_id is the form field which contains the course Id you are signing up for
// We cast it to an array as it could be a select list or multiple select list.
$courseIds = (array) $formModel->formData['signup___course_id'];
// Get the db and the query
$db = JFactory::getDbo();
$query = $db->getQuery(true);
foreach ($courseIds as $courseId)
{
// Clear down any previous query
$query->clear();
// Update the query to decrease the value contained in the field "spaces" by 1 for the current course id.
$query->update('courses')->set('spaces = spaces - 1')->where('id = ' . (int) $courseId);
$db->setQuery($query);
$db->execute();
}
Get row ID of a form(top)
When a form is loaded, it's rowid is located in the querystring. To retreive it, for example for database manipulations, use : '{rowid}' in the PHP code. - Loading...
XenCarta PRO
© Jason Axelrod from 8WAYRUN.COM