1

I am developing a component that uses a standard list/edit form to create records in the database (all of which goes smoothly) based on the Hello World! tutorial here.

In addition to saving info to the database, however, I need to make a call to an external API and send out a couple of confirmation emails (which I will tackle later and probably come back here to ask about).

In my controller for the item (rather than the list), I have created my own save() method in which I add some data and change some other data. This is where I would make the call to my external API and get some sort of response.

In controllers/authorization.php:

public function save($key = null, $urlVar = null)
{
    if (isset($_POST['jform'])) {
        // Get the original POST data
        $jinput = JFactory::getApplication()->input;

        $original = $jinput->post->get('jform', array(), 'array');

        // Trim each of the fields
        foreach($original as $key=>$value) {
            $postData[$key] = trim($value);
        }

        // Set value of authorization date
        $postData['authDate'] = $this->prepareInputDate(time());

        // Create transaction ID based on date and time
        $postData['merchantTransId'] .= date('YmdHis', time());

        // Strip phone number of all but numeric digits
        $postData['phone'] = $this->prepareInputNumeric($original['phone']);

        // Make call to external API
        $response = $this->callApi($postData);

        // If bad response from external API, throw error
        if (!$response) {
            JFactory::getApplication()->enqueueMessage('There was an error with the API', 'error');
            return false;
        }

        // Only store last 4 digits of account number
        $postData['accountNo'] = substr($postData['accountNo'], -4);

        // Save everything back to the $_POST global variable
        $jinput->post->set('jform', $postData);
    }

    // Finally, save the processed form data
    return parent::save('id', $urlVar);
}

What I am having a problem with is when throwing the error, I lose my form and all the data that was entered into it. In most cases, when the external API returns a bad response, it will be due to a badly formed parameter that can easily be fixed and resubmitted (e.g. invalid credentials or invalid characters in the fullName field).

I would like to be able to display an informative error message on screen either while still showing the populated form on screen or after redirecting back to the populated form.

Can this be done from within the save() method or is there some method that is called after form validation but before save() where I can make the API call?

Three days ago, when I started this project, I knew absolutely nothing about Joomla development. Everything I have been able to do so far has been learned from the tutorial I mentioned above or from Google searches. So if there is any code that I should have included but didn't, just let me know what I should show and I'll edit my question to include it.

2 Answers 2

3

You should use a session to save the form data. In the CMS there is a special User State for this. Just before you return false you should save the current data into the user state:

// Save the form data in the session
JFactory::getApplication()->setUserState($this->option . '.edit.authorization.data', $postData);

$this->option here is the name of your component.

Then in the model you can retrieve it in your loadFormData() method:

// Check the session for previously entered form data
$data = JFactory::getApplication()->getUserState($this->option . '.edit.authorization.data', array());

if (empty($data))
{
    $data = $this->getItem();
}

If you have a success in your controller then you should flush the data from the session before return:

JFactory::getApplication()->setUserState($this->option . '.edit.authorization.data', null);
1

You are saving your form data too late. If there is an error, it returns false before it could save data. And you should save $original data, not already manipulated data.

// If bad response from external API, throw error
if (!$response) {
    // Save everything back to the $_POST global variable
    $jinput->post->set('jform', $original);

    JFactory::getApplication()->enqueueMessage('There was an error with the API', 'error');
    return false;
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.