7 - Site controller

Once the form is submitted you have to manage the data in the controller:

/ components / com_dealer / controllers / car.php


<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');

/**
 * The controller
 *
 * @since       1.6
 */
class DealerControllerCar extends JControllerForm
{    
    
/**
     * Class constructor.
     *
     * @param   array  $config  A named array of configuration variables.
     *
     * @since   1.6
     */
    
public function __construct($config = array())
    {
        
parent::__construct($config);
        
        
$this->registerTask('save',     'apply');
        
$this->registerTask('save',     'save2new');
    }

    
/**
     * Method override to check if you can add a new record.
     *
     * @param   array  $data  An array of input data.
     *
     * @return  boolean
     *
     * @since   1.6
     */
    
protected function allowAdd($data = array())
    {
        
$user JFactory::getUser();
        
$categoryId JArrayHelper::getValue($data'catid'$this->input->getInt('filter_category_id'), 'int');
        
$allow null;

        if (
$category_id): 
            
// If the category has been passed in the URL check create access on it and the object.
            
$allow $user->authorise('core.create''com_'.Bp::getComponent().'.category.'.$category_id) AND
                      
$user->authorise('core.create''com_'.Bp::getComponent());

            if(
$allow === null):            
                
// In the absense of better information, revert to the component permissions.
                
return parent::allowAdd($data);        
            else:
                return 
$allow;
            endif;
        
        else:
        
            
// In the absense of category id, revert to the component permissions.
            
return parent::allowAdd($data);        
        endif;
    }

    
/**
     * Method override to check if you can edit an existing record.
     *
     * @param   array   $data  An array of input data.
     * @param   string  $key   The name of the key for the primary key.
     *
     * @return  boolean
     *
     * @since   1.6
     */
    
protected function allowEdit($data = array(), $key 'your_db_id_key')
    {
        
$ownerField     'your_table_owner_id_field_name';

        
$record_id        = (int) isset($data[$key]) ? $data[$key] : 0;
        
$user            JFactory::getUser();
        
$user_id        $user->get('id');
        
$category_id    = (int) isset($data['catid']) ? $data['catid'] : 0;
        
$component        Bp::getComponent();
        
$view            Bp::getView();

        if (
$category_id): 
            
// If the category has been passed in the URL check it.
            
if(!$user->authorise('core.edit''com_'.$component.'.category.'.$category_id)):
                return 
false;
            endif;
        endif;

        
// Check general edit permission first.
        
if ($user->authorise('core.edit''com_'.$component.'.'.$view.'.'.$record_id)):
            return 
true;
        endif;
        
// Fallback on edit.own.
        // First test if the permission is available.
        
if ($user->authorise('core.edit.own''com_'.$component.'.'.$view.'.'.$record_id)):
        
            
// Now test the owner is the user.
            
$owner_id 0;

            if ( isset(
$data[$ownerField])):
                
$owner_id    = (int) $data[$ownerField];
            endif;

            if (
$owner_id == AND $record_id): 
                
// Need to do a lookup from the model.
                
$record        $this->getModel()->getItem($record_id);
                if (empty(
$record)): 
                    return 
false;
                endif;
                
$owner_id $record->{$ownerField};
            endif;

            
// If the owner matches 'me' then do the test.
            
if ($owner_id == $user_id) :
                return 
true;
            endif;
        endif;
        
// Since there is no asset tracking, revert to the component permissions.
        
return parent::allowEdit($data$key);
    }

    
/**
     * Method to run batch operations.
     *
     * @param   object  $model  The model.
     *
     * @return  boolean   True if successful, false otherwise and internal error is set.
     *
     * @since   1.6
     */
    
public function batch($model null)
    {
        
JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN'));

        
// Set the model
        
$model $this->getModel(ucfirst(Bp::getView()), '', array());

        
// Preset the redirect
        
$this->setRedirect(JRoute::_('index.php?option=com_'.Bp::getComponent().'&view='.Bp::getView().'s' $this->getRedirectToListAppend(), false));

        return 
parent::batch($model);
    }
    

    
/**
     * Method to override fabric save function.
     *
     * @since    1.0
     */
    //
    
public function save($key 'your_db_table_key_id'$urlVar null)
    {
        
JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN'));

        
$app     Bp::getApp();
        
$model     $this->getModel();
        
$form     $model->getForm();
        try
        {
            
$form $model->getForm();
        }
        catch (
Exception $e)
        {
            
JFactory::getApplication()->enqueueMessage($e->getMessage(), 'error');
            return 
false;
        }

        
// Get the post data.
        
$requestData $this->input->post->get('jform', array(), 'array');
        
// you can even use
        // $requestData = Bp::get( 'jform', array(), 'array', 'post');

        // if you altered the form with a plugin before display
        // you may want to alter it even here otherwise the
        // validation will fails. You can do it with an
        // 'onDealerCarBeforeSave' event in your plugin.
        // you can even perform some changes to the data or add
        // custom fields and data before the validation
// TRIGGER PLUGIN
        
JPluginHelper::importPlugin(Bp::getComponent());
        
$dispatcher     JDispatcher::getInstance();
        
$prms             = new stdClass();
        
$prms->context     Bp::getView();
        
$results         $dispatcher->trigger'on'.ucfirst(Bp::getComponent()).ucfirst(Bp::getView()).'BeforeSave', array(&$form, &$requestData, &$prms) );        

// VALIDATE DATA
        
$data $model->validate($form$requestData);

        
// Check for validation errors.
        
if ($data === false):
            
// Get the validation messages.
            
$errors $model->getErrors();
            
// Push up to three validation messages out to the user.
            
for ($i 0$n count($errors); $i $n && $i 3$i++):            
                if (
$errors[$i] instanceof Exception):                
                    
$app->enqueueMessage($errors[$i]->getMessage(), 'warning');            
                else:                
                    
$app->enqueueMessage($errors[$i], 'warning');
                endif;
            endfor;
            
// Save the data in the session.
            
$app->setUserState('com_'.strtolower(Bp::getComponent()).'.'.strtolower(Bp::getView()).'.edit.data'$data);
            
// Redirect back to the registration screen.
            
$this->setRedirect(JRoute::_('index.php?option=com_'.strtolower(Bp::getComponent()).'&view='.strtolower(Bp::getView()).'&layout=default&'.$key.'='.$data[$key], false));
            return 
false;
        endif;
        
// ATTEMPT TO SAVE THE DATA
        
$return $model->save($data);

        
// CHECK FOR ERRORS
        
$action 'index.php?option=com_'.strtolower(Bp::getComponent());

        if (
$return === false):

            
// Redirect back to the edit screen.
            
$this->setMessage($model->getError(), 'warning');
            
$this->setRedirect(JRoute::_($action.'&view='.Bp::getView().'&layout=default&'false));
            return 
false;

        else:
            
$app->setUserState('com_'.strtolower(Bp::getComponent()).'.'.strtolower(Bp::getView()).'.edit.data'null);
// TRIGGER PLUG IN
            
JPluginHelper::importPlugin(Bp::getComponent());
            
$dispatcher     JDispatcher::getInstance();
            
$prms             = new stdClass();
            
$prms->context     Bp::getView();
            
$results         $dispatcher->trigger'on'.ucfirst(Bp::getComponent()).ucfirst(Bp::getView()).'AfterSave', array(&$data, &$form, &$prms) );        


            
$this->setRedirect(  $action "&view=".Bp::getView().'s' );
        endif;
    
    }
}

As you can see you can copy and paste the whole script for all your controllers (pretty the same in both admin and site side). You have to update only 3 elements in each different controller.

The only 3 elements you have to update are:

$key = 'your_db_id_key'
and
$ownerField     = 'your_table_owner_id_field_name';

in allowEdith method

and
$key = 'your_db_table_key_id'
in save method.

All the rest is customized by the Bp class.

In the next chapter we will see what other action you can do over the database.

Using plugins

So far we've talked about to alter the form before display with a plugin. Let's talk about what else you can do faster before and after saving data.

You may want to alter a field attribute to hide it:

$form = BpForm->setAttribute($form, 'field_name', 'hidden', true);

or you may want to set it read only:

$form = BpForm->setAttribute($form, 'field_name', 'readonly', true);

You may want to add extra check over data submitted.

For example you may want to get a database name compatible:

$requestData['my_field_to_check'] = BpForm::clean($requestData['my_field_to_check'], 'DBFIELD');

The method 'clean' will check if DBFIELD is an available JForm filter: is so the method will perform it and return the result, if not will check if its class has a method named cleanDbfield() and if so will perform it otherwise will perform a generic JForm string filter (adopting the same JForm behavior). 

Once saved the data, you may want to perform other actions like send an email:

$email = new stdClass();
$email->to = Bp::getUser()->get('email');
$email->subj = "My email subject";
$email->body = "My email body message";
$sent = BpMail::send($email);

BpMail will take care to check if $email->to is a valid email address, sanitize it, complete the $email object with all other required info using Joomla configuration data and will attempt to send it in html mode, base64 encoded.

If you don't want the html mode just pass the information to the class adding it to the object:

$email->html = false;

Do the same if you don't want to encode the message:

$email->encode = false;

The class will return 'sent' on success or the mailer error message if fails.

if( $sent == 'sent'):
echo 'success';
else:
echo $sent;
endif;