PHP Scripts

Published in Convert Forms
Updated 27 May, 2020
Heads up! This article contains PHP code and is intended for developers. We offer this code as a courtesy, but don't provide support for code customizations or 3rd party development.

Are you looking for a way to do some extra field validation during form submission? Perhaps, you'd like to silently post submitted data to another URL? With the Convert Forms PHP Scripts section and the proper knowledge of PHP and MySQL you can do just about anything.

Joomla! Forms with Custom PHP Scripts execution support

The PHP Scripts area consits of the following 4 sections that are triggered on certain events.

1. Form Prepare

The PHP script added in this area is executed just before the form's data is prepared and send to the form display function. The main focus in this area is the $form (Array) variable which contains the form's settings. This area is rather useful when you need to populate dynamically a field, add more options to a dropdown listbox or modify the styling of the form.

Populate a Textbox Field

This example sets the default value of the field 'email'.

$form['fields']['email']['value'] = 'my@email.com';

Populate a Checkboxes Field

You can also add options to a Checkboxes Field using the method below:

$form['fields']['checkboxes']['choices']['choices'][] = [
    'value' => 'red',
    'label' => 'Red',
    'calc-value' => 'my_calc_value' // Optional
];

Add an extra option to a listbox

This example adds an extra option to a listbox dropdown field

$form['fields']['dropdown_45']['choices']['choices'][] = [
    'value' => 'my_value',
    'label' => 'My Label',
    'calc-value' => 'my_calc_value' // Optional
];

Find an Article's custom field value and set it to a hidden field

This example helps you set a hidden field with the value of an Article's custom field based on the custom field key. Simply replace mycustomfield with the Custom Field Name(not Label) and myHiddenFieldKey with the Field Key of your hidden field that you want to set the value to.

// Enter the Custom Field Name (not Label) to find its value
$customFieldName = 'mycustomfield';

// Enter the Hidden Field Key here to save the value
$hiddenFieldKey = 'myHiddenFieldKey';

// Do not edit below
$article_id = $app->input->get('id');

$jcfields = FieldsHelper::getFields('com_content.article', $article_id, true);
foreach($jcfields as $jcfield) {
    if ($jcfield->name == $customFieldName) {
        $query = $db
            ->getQuery(true)
            ->select('value')
            ->from($db->quoteName('#__fields_values'))
            ->where($db->quoteName('item_id') . " = " . $db->quote($article_id))
            ->where($db->quoteName('field_id') . " = " . $db->quote($jcfield->id));

        $db->setQuery($query);
        $form['fields'][$hiddenFieldKey]['value'] = $db->loadResult();
        break;
    }
}

2. Form Display

The PHP script added in this area is executed just before the form is displayed. The main focus in this area is the $formLayout (String) variable which contains the HTML code of the form. You can also access the form settings here using the $form (Array) variable.

Restrict access to a form

In this example guests will see a warning message while logged-in users will see the actual form.

if ($user->guest) {
	$formLayout = '<p>Please, log in to access this form.<p>';
}

Display form submissions count

The total number for form submissions can be helpful if you want to display the number of users who participated in a survey or have entered a content. This number can easily calculated with the example below:

$count = ConvertForms\Api::getFormSubmissionsTotal($form['id']);
$formLayout .= 'This form was submitted ' . $count . ' times.';

Hide form on mobile device

The example below uses the Convert Forms Api to detect if the user is browsing with a mobile device and removes completely the form from the page.

if (ConvertForms\Api::isMobile()) {
   $formLayout = "";
}

3. Form Process

The PHP code added in this area is executed just before the form data has been saved into the database regardless if the submission is valid or not. This area is rather useful when you need to process calculations, make advanced validation or modify the value of a field. Any modifications to $post (Array) variable performed here, will be reflected in the submission entry. You can also access the form settings here using the $form (Array) variable.

Populate a Field

This example changes the post variable for field name

$post['name'] = 'John Doe';

Populate a field using the value from another field

This example changes the post variable for field text_1 to the value of field text_2

$post['text_1'] = $post['text_2'];

Validate and limit characters allowed in a field

This example displays an error message when the field message exceeds the characters limit.

$max_chars = 50;
$error = "Maximum character limit reached.";

if (strlen($post["message"]) > $max_chars) {
   throw new Exception($error);
}

Unique Field Validation

The code below ensures that a unique email address has been entered into the email field. The example below makes use the getFormSubmissions() built-in API method to retrieve all form submissions from the database.

$unique_field = 'email';
$unique_field_error = 'A form with this value has already been submitted';
   
// Do not edit below
$unique_post_value = $post[$unique_field];

if (!$submissions = ConvertForms\Api::getFormSubmissions($form['id']))
{
    return;
}

foreach ($submissions as $key => $submission)
{
    if (!isset($submission->params->$unique_field))
    {
        continue;
    }

    $submission_unique_value = $submission->params->$unique_field;

    if ($unique_post_value == $submission_unique_value)
    {
        throw new Exception($unique_field_error);
    }
}

Block Submission on Specific Words (Bad Word Filter)

The code below allows you to create a list of words that when one or more are found in a specific field's value, it will prevent users from submitting and entering these specific words. You can display a helpful message as well as a list of the words found that are not allowed.

$not_allowed_words = [
	'dog',
	'cat',
	'elephant'
];

$field_key = 'text';
$error_message = 'Your text contains words that are not allowed.';
$found_not_allowed_words_message = 'Words found: ';
$display_found_not_allowed_words = false;

// Do not edit below
$post_value = $post[$field_key];
$contains = false;
$words_found = [];
foreach($not_allowed_words as $w) {
     if (stripos($post_value, $w) !== false) {
          $words_found[] = $w;
          $contains = true;
     }
}
if ($contains) {
     if ($display_found_not_allowed_words && count($words_found)) {
          $error_message .= $found_not_allowed_words_message . implode(', ', $words_found);
     }
     throw new Exception($error_message);
}

How to create a login form

The code below lets you authenticate your users and once they have entered a valid username and password, you can then redirect them to any page in your site and they will be logged in as they were to log in via Joomla's login form.

// Set your username and password fields below
$username = $post['username'];
$password = $post['password'];

// Do not edit below
if (empty($username) || empty($password))
{
    throw new Exception("Please enter a username and password");
}

$query = $db->getQuery(true)
	->select('id, password')
	->from('#__users')
	->where('username=' . $db->quote($username));

$db->setQuery($query);

if (!$result = $db->loadObject())
{
    throw new Exception("User does not exist");
}

/**
 * To authenticate, the username must exist in the database, and the password should be equal
 * to the password of the user in the database
 */
if ($match = JUserHelper::verifyPassword($password, $result->password, $result->id))
{
    $credentials['username'] = $username;
    $credentials['password'] = $password;

    //perform log in
    $error = $app->login($credentials);
    $logged_user = JFactory::getUser();
}
else
{
    throw new Exception("Invalid password");
}

To redirect the users to any page you need, you will need to go to Design > Advanced > Custom Code and enter the following Javascript snippet:

<script>
var form = document.querySelector("#cf_17");
form.addEventListener("success", function(event) {
     window.location.reload();
});
</script>

This will reload the page the form resides and your users will be logged in. Change 17 with your form's ID.

Allow submissions between 2 dates

This example allows you to set a start and end date and allow submissions only when a user submits your form between the 2 dates.

// Set start, end date as well as the error message when submission is done when not within range
$start_date = '2020-05-27 09:00';
$end_date = '2021-05-25 15:00';
$error = "Submission is available between {$start_date} and {$end_date}";

// Do not edit below
$now = date('Y-m-d H:i');
$now = date('Y-m-d H:i', strtotime($now));
NRFramework\Functions::fixDateOffset($start_date);
NRFramework\Functions::fixDateOffset($end_date);

if ($now < $start_date || $now > $end_date) {
    throw new Exception($error);
}

4. After Form Submission

The PHP code added in this area is executed after the form has been successfully submitted and the data has been saved into the database. This is rather useful when you are trying to run some extra tasks such as silently post data to another URL or feed data to third party applications. The $submission (Array) variable is available in this hook and contains all submitted values.

Delete submission from the database

There are cases when you'd like to delete the submitted data from the database after the submission has been processed. The example below, uses the submission_delete() built-in API method to delete the current submission from the database.

ConvertForms\Api::removeSubmission($submission->id);

Modify the form success message

The example below, modifies the success message that will be displayed in the form

$submission->form->successmsg = "We have received your request. Submission ID: #" . $submission->id;

Display a different success message based on a field value

The example below, modifies the success message based on the value of a submitted field

$field_value = $submission->params['somefieldkey'];
$message = $field_value == 'somevalue' ? 'some message' : 'alternative message';
$submission->form->successmsg = $message;

Save submission data to a file as JSON

The example below, reads the submitted data from the $submission object and stores specific info into a TXT file in the root of your webspace in JSON format.

$file = JPATH_SITE . '/submissions.txt';

$data = JFile::exists($file) ? json_decode(file_get_contents($file), true) : [];

if (!is_array($data)) {
    return;
}

array_push($data, [
	'ID'    => $submission->id,
	'Date'  => $submission->created,
	'Name'  => $submission->params['name'],
	'Email' => $submission->params['email']
]);

$data = json_encode($data, JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);
// Save the file again
JFile::write($file, $data);

Post submitted data to an external API or URL

Below you can find an example on how you can silently post submitted data to an external API endpoint or URL with the help of the HTTP Joomla package.

// Read submitted values and prepare data to POST
$data = [
	'first_name' => $submission->params['first_name'],
	'last_name'  => $submission->params['last_name'],
	'email' 	 => $submission->params['email']
];

$http = JHttpFactory::getHttp();
$url = 'http://api.example.com/accounts';

$response = $http->post($url, $data);

if ($response->code == 200)
{
	// Your code..
}

Frequently Asked Questions

Can I include PHP files within my code?

The PHP Scripts sections allows you to include any external file from within your joomla installation as long as you have the correct path. This is quite useful if you need to use the same PHP code on multiple forms, you can place the code in a php file and include it in your form's PHP Scripts section.

include 'file/to/path.php';
if (functionFromFile())
{
	// Do something...
}
Note: For debugging purposes you can always use die(); statements after echo or var_dump() commands. For example: var_dump($post); die();