joomla-platform / libraries / joomla / application / component / modelform.php

<?php
/**
 * @package     Joomla.Platform
 * @subpackage  Application
 *
 * @copyright   Copyright (C) 2005 - 2011 Open Source Matters, Inc. All rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE
 */

defined('JPATH_PLATFORM') or die;

jimport('joomla.application.component.model');
jimport('joomla.form.form');

/**
 * Prototype form model.
 *
 * @package     Joomla.Platform
 * @subpackage  Application
 * @since       11.1
 */
abstract class JModelForm extends JModel
{
    /**
     * Array of form objects.
     */
    protected $_forms = array();

    /**
     * Method to checkin a row.
     *
     * @param   integer $pk The numeric id of the primary key.
     *
     * @return  boolean False on failure or error, true otherwise.
     */
    public function checkin($pk = null)
    {
        // Only attempt to check the row in if it exists.
        if ($pk) {
            $user = JFactory::getUser();

            // Get an instance of the row to checkin.
            $table = $this->getTable();
            if (!$table->load($pk)) {
                $this->setError($table->getError());
                return false;
            }

            // Check if this is the user having previously checked out the row.
            if ($table->checked_out > 0 && $table->checked_out != $user->get('id') && !$user->authorise('core.manage', 'com_checkin')) {
                $this->setError(JText::_('JLIB_APPLICATION_ERROR_CHECKIN_USER_MISMATCH'));
                return false;
            }

            // Attempt to check the row in.
            if (!$table->checkin($pk)) {
                $this->setError($table->getError());
                return false;
            }
        }

        return true;
    }

    /**
     * Method to check-out a row for editing.
     *
     * @param   int     $pk The numeric id of the primary key.
     *
     * @return  boolean False on failure or error, true otherwise.
     */
    public function checkout($pk = null)
    {
        // Only attempt to check the row in if it exists.
        if ($pk) {
            $user = JFactory::getUser();

            // Get an instance of the row to checkout.
            $table = $this->getTable();
            if (!$table->load($pk)) {
                $this->setError($table->getError());
                return false;
            }

            // Check if this is the user having previously checked out the row.
            if ($table->checked_out > 0 && $table->checked_out != $user->get('id')) {
                $this->setError(JText::_('JLIB_APPLICATION_ERROR_CHECKOUT_USER_MISMATCH'));
                return false;
            }

            // Attempt to check the row out.
            if (!$table->checkout($user->get('id'), $pk)) {
                $this->setError($table->getError());
                return false;
            }
        }

        return true;
    }

    /**
     * Abstract method for getting the form from the model.
     *
     * @param   array   $data       Data for the form.
     * @param   boolean $loadData   True if the form is to load its own data (default case), false if not.
     * @return  mixed   A JForm object on success, false on failure
     * @since   11.1
     */
    abstract public function getForm($data = array(), $loadData = true);

    /**
     * Method to get a form object.
     *
     * @param   string      $name       The name of the form.
     * @param   string      $source     The form source. Can be XML string if file flag is set to false.
     * @param   array       $options    Optional array of options for the form creation.
     * @param   boolean     $clear      Optional argument to force load a new form.
     * @param   string      $xpath      An optional xpath to search for the fields.
     * @return  mixed       JForm object on success, False on error.
     */
    protected function loadForm($name, $source = null, $options = array(), $clear = false, $xpath = false)
    {
        // Handle the optional arguments.
        $options['control'] = JArrayHelper::getValue($options, 'control', false);

        // Create a signature hash.
        $hash = md5($source.serialize($options));

        // Check if we can use a previously loaded form.
        if (isset($this->_forms[$hash]) && !$clear) {
            return $this->_forms[$hash];
        }

        // Get the form.
        JForm::addFormPath(JPATH_COMPONENT.'/models/forms');
        JForm::addFieldPath(JPATH_COMPONENT.'/models/fields');

        try {
            $form = JForm::getInstance($name, $source, $options, false, $xpath);

            if (isset($options['load_data']) && $options['load_data']) {
                // Get the data for the form.
                $data = $this->loadFormData();
            } else {
                $data = array();
            }

            // Allow for additional modification of the form, and events to be triggered.
            // We pass the data because plugins may require it.
            $this->preprocessForm($form, $data);

            // Load the data into the form after the plugins have operated.
            $form->bind($data);

        } catch (Exception $e) {
            $this->setError($e->getMessage());
            return false;
        }

        // Store the form for later.
        $this->_forms[$hash] = $form;

        return $form;
    }

    /**
     * Method to get the data that should be injected in the form.
     *
     * @return  array   The default data is an empty array.
     * @since   11.1
     */
    protected function loadFormData()
    {
        return array();
    }

    /**
     * Method to allow derived classes to preprocess the form.
     *
     * @param   object  A form object.
     * @param   mixed   The data expected for the form.
     * @param   string  The name of the plugin group to import (defaults to "content").
     * @throws  Exception if there is an error in the form event.
     * @since   11.1
     */
    protected function preprocessForm(JForm $form, $data, $group = 'content')
    {
        // Import the approriate plugin group.
        JPluginHelper::importPlugin($group);

        // Get the dispatcher.
        $dispatcher = JDispatcher::getInstance();

        // Trigger the form preparation event.
        $results = $dispatcher->trigger('onContentPrepareForm', array($form, $data));

        // Check for errors encountered while preparing the form.
        if (count($results) && in_array(false, $results, true)) {
            // Get the last error.
            $error = $dispatcher->getError();

            // Convert to a JException if necessary.
            if (!JError::isError($error)) {
                throw new Exception($error);
            }
        }
    }

    /**
     * Method to validate the form data.
     *
     * @param   object      $form       The form to validate against.
     * @param   array       $data       The data to validate.
     * @return  mixed       Array of filtered data if valid, false otherwise.
     * @since   1.1
     */
    function validate($form, $data)
    {
        // Filter and validate the form data.
        $data   = $form->filter($data);
        $return = $form->validate($data);

        // Check for an error.
        if (JError::isError($return)) {
            $this->setError($return->getMessage());
            return false;
        }

        // Check the validation results.
        if ($return === false) {
            // Get the validation messages from the form.
            foreach ($form->getErrors() as $message) {
                $this->setError(JText::_($message));
            }

            return false;
        }

        return $data;
    }
}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.