-
"Fabrik 4" helpers needed!Dismiss Notice
You are invited to join other community members active in coding, maintaining and improving Fabrik. Please visit https://fabrik.help for more information!
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
- Do something on record deletion
- Get row ID of a form
- Check if submission was via Copy button
- Get Label for Dropdown Elements
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
- onDeleteRowsForm - the code is run on form delete and on list delete (see example below)
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';
$formModel->data['table___element_raw']='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();
}
Do something on record deletion(top)
The onDeleteRowsForm hook is called from the main list model deleteRows() method, which is called both when you do a list delete (potentially with multiple rows) and also from form controller when you delete from a form view.
In both case, the form PHP plugin's onDeleteRowsForm() method is triggered, with the row data in $data, which is an array of arrays (groups) of objects (rows). So you should always code it assuming that you may get called with multiple rows (deleting from a list will do that). Even if it's being called in the form context, it'll still be a two dimensional array of objects, it'll just be a single group with a single row in it.
So ...
Code (Text):Code (Text):
foreach ($data[0] as $group) {
foreach ($group as $row) {
// your rowid will be in $row->__pk_val
// elements will be in $row->tablename___fieldname
}
}
For element data, use full element names, like $row->tablename___fieldname, or with the _raw suffix, $row->tablename___fieldname_raw (if your element is one with the concept of "value" and "label", like join elements).
https://fabrikar.com/forums/index.p...leterowsform-trigger-works.48475/#post-252810
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.
Check if submission was via Copy button(top)
Code (Text):if ($formModel->copyingRow)Get Label for Dropdown Elements(top)
PHP:
$element_value = $formModel->data['yourtable___elementname_raw'];
$elementModel = $formModel->getElement('yourtable___elementname');
$element_label = $elementModel->getEmailValue($element_value, $formModel->formDataWithTableName, 0);
- Loading...
XenCarta PRO
© Jason Axelrod from 8WAYRUN.COM