Source for file model.php

Documentation is available at model.php

  1. <?php
  2. /**
  3.  * @package     FrameworkOnFramework
  4.  * @subpackage  model
  5.  * @copyright   Copyright (C) 2010 - 2012 Akeeba Ltd. All rights reserved.
  6.  * @license     GNU General Public License version 2 or later; see LICENSE.txt
  7.  */
  8. // Protect from unauthorized access
  9. defined('_JEXEC'or die;
  10.  
  11. /**
  12.  * FrameworkOnFramework Model class. The Model is the worhorse. It performs all
  13.  * of the business logic based on its state and then returns the raw (processed)
  14.  * data to the caller, or modifies its own state. It's important to note that
  15.  * the model doesn't get data directly from the request (this is the
  16.  * Controller's business) and that it doesn't output anything (that the View's
  17.  * business).
  18.  *
  19.  * @package  FrameworkOnFramework
  20.  * @since    1.0
  21.  */
  22. class FOFModel extends JObject
  23. {
  24.     /**
  25.      * Indicates if the internal state has been set
  26.      *
  27.      * @var    boolean 
  28.      * @since  12.2
  29.      */
  30.     protected $__state_set = null;
  31.  
  32.     /**
  33.      * Database Connector
  34.      *
  35.      * @var    object 
  36.      * @since  12.2
  37.      */
  38.     protected $_db;
  39.  
  40.     /**
  41.      * The event to trigger after deleting the data.
  42.      * @var    string 
  43.      */
  44.     protected $event_after_delete = 'onContentAfterDelete';
  45.  
  46.     /**
  47.      * The event to trigger after saving the data.
  48.      * @var    string 
  49.      */
  50.     protected $event_after_save = 'onContentAfterSave';
  51.  
  52.     /**
  53.      * The event to trigger before deleting the data.
  54.      * @var    string 
  55.      */
  56.     protected $event_before_delete = 'onContentBeforeDelete';
  57.  
  58.     /**
  59.      * The event to trigger before saving the data.
  60.      * @var    string 
  61.      */
  62.     protected $event_before_save = 'onContentBeforeSave';
  63.  
  64.     /**
  65.      * The event to trigger after changing the published state of the data.
  66.      * @var    string 
  67.      */
  68.     protected $event_change_state = 'onContentChangeState';
  69.  
  70.     /**
  71.      * The event to trigger when cleaning cache.
  72.      *
  73.      * @var      string 
  74.      * @since    12.2
  75.      */
  76.     protected $event_clean_cache = null;
  77.  
  78.     /**
  79.      * Stores a list of IDs passed to the model's state
  80.      * @var array 
  81.      */
  82.     protected $id_list = array();
  83.  
  84.     /**
  85.      * The first row ID passed to the model's state
  86.      * @var int 
  87.      */
  88.     protected $id = null;
  89.  
  90.     /**
  91.      * Input variables, passed on from the controller, in an associative array
  92.      * @var array 
  93.      */
  94.     protected $input = array();
  95.  
  96.     /**
  97.      * The list of records made available through getList
  98.      * @var array 
  99.      */
  100.     protected $list = null;
  101.  
  102.     /**
  103.      * The model (base) name
  104.      *
  105.      * @var    string 
  106.      * @since  12.2
  107.      */
  108.     protected $name;
  109.  
  110.     /**
  111.      * The URL option for the component.
  112.      *
  113.      * @var    string 
  114.      * @since  12.2
  115.      */
  116.     protected $option = null;
  117.  
  118.     /**
  119.      * The table object, populated when saving data
  120.      * @var FOFTable 
  121.      */
  122.     protected $otable = null;
  123.  
  124.     /**
  125.      * Pagination object
  126.      * @var JPagination 
  127.      */
  128.     protected $pagination = null;
  129.  
  130.     /**
  131.      * The table object, populated when retrieving data
  132.      * @var FOFTable 
  133.      */
  134.     protected $record = null;
  135.  
  136.     /**
  137.      * A state object
  138.      *
  139.      * @var    string 
  140.      * @since  12.2
  141.      */
  142.     protected $state;
  143.  
  144.     /**
  145.      * The name of the table to use
  146.      * @var string 
  147.      */
  148.     protected $table = null;
  149.  
  150.     /**
  151.      * Total rows based on the filters set in the model's state
  152.      * @var int 
  153.      */
  154.     protected $total = null;
  155.  
  156.     /**
  157.      * Should I save the model's state in the session?
  158.      * @var bool 
  159.      */
  160.     protected $_savestate = null;
  161.  
  162.     /**
  163.      * Array of form objects.
  164.      *
  165.      * @var    array 
  166.      * @since  2.0
  167.      */
  168.     protected $_forms = array();
  169.  
  170.     /**
  171.      * The data to load into a form
  172.      *
  173.      * @var    array 
  174.      * @since  2.0
  175.      */
  176.     protected $_formData = array();
  177.  
  178.     /**
  179.      * An instance of FOFConfigProvider to provision configuration overrides
  180.      *
  181.      * @var    FOFConfigProvider 
  182.      */
  183.     protected $configProvider = null;
  184.  
  185.     /**
  186.      * FOFModelDispatcherBehavior for dealing with extra behaviors
  187.      *
  188.      * @var    FOFModelDispatcherBehavior 
  189.      */
  190.     protected $modelDispatcher = null;
  191.  
  192.     /**
  193.      *    Default behaviors to apply to the model
  194.      *
  195.      * @var      array 
  196.      */
  197.     protected $default_behaviors = array('filters');
  198.  
  199.     /**
  200.      * Returns a new model object. Unless overriden by the $config array, it will
  201.      * try to automatically populate its state from the request variables.
  202.      *
  203.      * @param   string  $type    Model type, e.g. 'Items'
  204.      * @param   string  $prefix  Model prefix, e.g. 'FoobarModel'
  205.      * @param   array   $config  Model configuration variables
  206.      *
  207.      * @return  FOFModel 
  208.      */
  209.     public static function &getAnInstance($type$prefix ''$config array())
  210.     {
  211.         // Make sure $config is an array
  212.         if (is_object($config))
  213.         {
  214.             $config = (array) $config;
  215.         }
  216.         elseif (!is_array($config))
  217.         {
  218.             $config array();
  219.         }
  220.  
  221.         $type preg_replace('/[^A-Z0-9_\.-]/i'''$type);
  222.         $modelClass $prefix ucfirst($type);
  223.         $result false;
  224.  
  225.         // Guess the component name and include path
  226.         if (!empty($prefix))
  227.         {
  228.             preg_match('/(.*)Model$/'$prefix$m);
  229.             $component 'com_' strtolower($m[1]);
  230.         }
  231.         else
  232.         {
  233.             $component '';
  234.         }
  235.  
  236.         if (array_key_exists('input'$config))
  237.         {
  238.             if (!($config['input'instanceof FOFInput))
  239.             {
  240.                 if (!is_array($config['input']))
  241.                 {
  242.                     $config['input'= (array) $config['input'];
  243.                 }
  244.  
  245.                 $config['input'array_merge($_REQUEST$config['input']);
  246.                 $config['input'new FOFInput($config['input']);
  247.             }
  248.         }
  249.         else
  250.         {
  251.             $config['input'new FOFInput;
  252.         }
  253.  
  254.         if (empty($component))
  255.         {
  256.             $component $config['input']->get('option''com_foobar');
  257.         }
  258.  
  259.         $config['option'$component;
  260.  
  261.         $needsAView true;
  262.  
  263.         if (array_key_exists('view'$config))
  264.         {
  265.             if (!empty($config['view']))
  266.             {
  267.                 $needsAView false;
  268.             }
  269.         }
  270.  
  271.         if ($needsAView)
  272.         {
  273.             $config['view'strtolower($type);
  274.         }
  275.  
  276.         $config['input']->set('option'$config['option']);
  277.  
  278.         // Get the component directories
  279.         $componentPaths FOFPlatform::getInstance()->getComponentBaseDirs($component);
  280.  
  281.         // Try to load the requested model class
  282.         if (!class_exists($modelClass))
  283.         {
  284.             $include_paths self::addIncludePath();
  285.  
  286.             $extra_paths array(
  287.                 $componentPaths['main''/models',
  288.                 $componentPaths['alt''/models'
  289.             );
  290.  
  291.             $include_paths array_merge($extra_paths$include_paths);
  292.  
  293.             // Try to load the model file
  294.             JLoader::import('joomla.filesystem.path');
  295.  
  296.             $path JPath::find(
  297.                     $include_pathsself::_createFileName('model'array('name' => $type))
  298.             );
  299.  
  300.             if ($path)
  301.             {
  302.                 require_once $path;
  303.             }
  304.         }
  305.  
  306.         // Fallback to the Default model class, e.g. FoobarModelDefault
  307.         if (!class_exists($modelClass))
  308.         {
  309.             $modelClass $prefix 'Default';
  310.  
  311.             if (!class_exists($modelClass))
  312.             {
  313.                 $include_paths self::addIncludePath();
  314.  
  315.                 $extra_paths array(
  316.                     $componentPaths['main''/models',
  317.                     $componentPaths['alt''/models'
  318.                 );
  319.  
  320.                 $include_paths array_merge($extra_paths$include_paths);
  321.  
  322.                 // Try to load the model file
  323.                 JLoader::import('joomla.filesystem.path');
  324.  
  325.                 $path JPath::find(
  326.                         $include_pathsself::_createFileName('model'array('name' => 'default'))
  327.                 );
  328.  
  329.                 if ($path)
  330.                 {
  331.                     require_once $path;
  332.                 }
  333.             }
  334.         }
  335.  
  336.         // Fallback to the generic FOFModel model class
  337.  
  338.         if (!class_exists($modelClass))
  339.         {
  340.             $modelClass 'FOFModel';
  341.         }
  342.  
  343.         $result new $modelClass($config);
  344.  
  345.         return $result;
  346.     }
  347.  
  348.     /**
  349.      * Adds a behavior to the model
  350.      *
  351.      * @param   string  $name    The name of the behavior
  352.      * @param   array   $config  Optional Behavior configuration
  353.      *
  354.      * @return  boolean  True if the behavior is found and added
  355.      */
  356.     public function addBehavior($name$config array())
  357.     {
  358.         // Sanity check: this objects needs a non-null behavior handler
  359.         if (!is_object($this->modelDispatcher))
  360.         {
  361.             return false;
  362.         }
  363.  
  364.         // Sanity check: this objects needs a behavior handler of the correct class type
  365.         if (!($this->modelDispatcher instanceof FOFModelDispatcherBehavior))
  366.         {
  367.             return false;
  368.         }
  369.  
  370.         // First look for ComponentnameModelViewnameBehaviorName (e.g. FoobarModelItemsBehaviorFilter)
  371.         $behaviorClass ucfirst($this->name'Model' FOFInflector::pluralize($this->name'Behavior' ucfirst(strtolower($name));
  372.  
  373.         if (class_exists($behaviorClass))
  374.         {
  375.             $behavior new $behaviorClass($this->modelDispatcher$config);
  376.  
  377.             return true;
  378.         }
  379.  
  380.         // Then look for FOFModelBehaviorName (e.g. FOFModelBehaviorFilter)
  381.         $behaviorClassAlt 'FOFModelBehavior' ucfirst(strtolower($name));
  382.  
  383.         if (class_exists($behaviorClassAlt))
  384.         {
  385.             $behavior new $behaviorClassAlt($this->modelDispatcher$config);
  386.  
  387.             return true;
  388.         }
  389.  
  390.         // Nothing found? Return false.
  391.  
  392.         return false;
  393.     }
  394.  
  395.     /**
  396.      * Returns a new instance of a model, with the state reset to defaults
  397.      *
  398.      * @param   string  $type    Model type, e.g. 'Items'
  399.      * @param   string  $prefix  Model prefix, e.g. 'FoobarModel'
  400.      * @param   array   $config  Model configuration variables
  401.      *
  402.      * @return FOFModel 
  403.      */
  404.     public static function &getTmpInstance($type$prefix ''$config array())
  405.     {
  406.         // Make sure $config is an array
  407.         if (is_object($config))
  408.         {
  409.             $config = (array) $config;
  410.         }
  411.         elseif (!is_array($config))
  412.         {
  413.             $config array();
  414.         }
  415.  
  416.         if (!array_key_exists('savesate'$config))
  417.         {
  418.             $config['savestate'false;
  419.         }
  420.  
  421.         $ret self::getAnInstance($type$prefix$config)
  422.             ->getClone()
  423.             ->clearState()
  424.             ->clearInput()
  425.             ->reset()
  426.             ->savestate(0)
  427.             ->limitstart(0)
  428.             ->limit(0);
  429.  
  430.         return $ret;
  431.     }
  432.  
  433.     /**
  434.      * Add a directory where FOFModel should search for models. You may
  435.      * either pass a string or an array of directories.
  436.      *
  437.      * @param   mixed   $path    A path or array[sting] of paths to search.
  438.      * @param   string  $prefix  A prefix for models.
  439.      *
  440.      * @return  array  An array with directory elements. If prefix is equal to '', all directories are returned.
  441.      *
  442.      * @since   12.2
  443.      */
  444.     public static function addIncludePath($path ''$prefix '')
  445.     {
  446.         static $paths;
  447.  
  448.         if (!isset($paths))
  449.         {
  450.             $paths array();
  451.         }
  452.  
  453.         if (!isset($paths[$prefix]))
  454.         {
  455.             $paths[$prefixarray();
  456.         }
  457.  
  458.         if (!isset($paths['']))
  459.         {
  460.             $paths[''array();
  461.         }
  462.  
  463.         if (!empty($path))
  464.         {
  465.             jimport('joomla.filesystem.path');
  466.  
  467.             if (!in_array($path$paths[$prefix]))
  468.             {
  469.                 array_unshift($paths[$prefix]JPath::clean($path));
  470.             }
  471.  
  472.             if (!in_array($path$paths['']))
  473.             {
  474.                 array_unshift($paths['']JPath::clean($path));
  475.             }
  476.         }
  477.  
  478.         return $paths[$prefix];
  479.     }
  480.  
  481.     /**
  482.      * Adds to the stack of model table paths in LIFO order.
  483.      *
  484.      * @param   mixed  $path  The directory as a string or directories as an array to add.
  485.      *
  486.      * @return  void 
  487.      *
  488.      * @since   12.2
  489.      */
  490.     public static function addTablePath($path)
  491.     {
  492.         FOFTable::addIncludePath($path);
  493.     }
  494.  
  495.     /**
  496.      * Create the filename for a resource
  497.      *
  498.      * @param   string  $type   The resource type to create the filename for.
  499.      * @param   array   $parts  An associative array of filename information.
  500.      *
  501.      * @return  string  The filename
  502.      *
  503.      * @since   12.2
  504.      */
  505.     protected static function _createFileName($type$parts array())
  506.     {
  507.         $filename '';
  508.  
  509.         switch ($type)
  510.         {
  511.             case 'model':
  512.                 $filename strtolower($parts['name']'.php';
  513.                 break;
  514.         }
  515.  
  516.         return $filename;
  517.     }
  518.  
  519.     /**
  520.      * Public class constructor
  521.      *
  522.      * @param   type  $config  The configuration array
  523.      */
  524.     public function __construct($config array())
  525.     {
  526.         // Make sure $config is an array
  527.         if (is_object($config))
  528.         {
  529.             $config = (array) $config;
  530.         }
  531.         elseif (!is_array($config))
  532.         {
  533.             $config array();
  534.         }
  535.  
  536.         // Get the input
  537.         if (array_key_exists('input'$config))
  538.         {
  539.             if ($config['input'instanceof FOFInput)
  540.             {
  541.                 $this->input = $config['input'];
  542.             }
  543.             else
  544.             {
  545.                 $this->input = new FOFInput($config['input']);
  546.             }
  547.         }
  548.         else
  549.         {
  550.             $this->input = new FOFInput;
  551.         }
  552.  
  553.         // Load the configuration provider
  554.         $this->configProvider = new FOFConfigProvider;
  555.  
  556.         // Load the behavior dispatcher
  557.         $this->modelDispatcher = new FOFModelDispatcherBehavior;
  558.  
  559.         // Set the $name/$_name variable
  560.         $component $this->input->getCmd('option''com_foobar');
  561.  
  562.         if (array_key_exists('option'$config))
  563.         {
  564.             $component $config['option'];
  565.         }
  566.  
  567.         // Set the $name/$_name variable
  568.         $this->input->set('option'$component);
  569.         $component $this->input->getCmd('option''com_foobar');
  570.  
  571.         if (array_key_exists('option'$config))
  572.         {
  573.             $component $config['option'];
  574.         }
  575.  
  576.         $this->input->set('option'$component);
  577.         $name str_replace('com_'''strtolower($component));
  578.  
  579.         if (array_key_exists('name'$config))
  580.         {
  581.             $name $config['name'];
  582.         }
  583.  
  584.         $this->name = $name;
  585.         $this->option = $component;
  586.  
  587.         // Get the view name
  588.         $className get_class($this);
  589.  
  590.         if ($className == 'FOFModel')
  591.         {
  592.             if (array_key_exists('view'$config))
  593.             {
  594.                 $view $config['view'];
  595.             }
  596.  
  597.             if (empty($view))
  598.             {
  599.                 $view $this->input->getCmd('view''cpanel');
  600.             }
  601.         }
  602.         else
  603.         {
  604.             $eliminatePart ucfirst($name'Model';
  605.             $view strtolower(str_replace($eliminatePart''$className));
  606.         }
  607.  
  608.         // Set the model state
  609.         if (array_key_exists('state'$config))
  610.         {
  611.             $this->state = $config['state'];
  612.         }
  613.         else
  614.         {
  615.             $this->state = new JObject;
  616.         }
  617.  
  618.         // Set the model dbo
  619.         if (array_key_exists('dbo'$config))
  620.         {
  621.             $this->_db = $config['dbo'];
  622.         }
  623.         else
  624.         {
  625.             $this->_db = JFactory::getDbo();
  626.         }
  627.  
  628.         // Set the default view search path
  629.         if (array_key_exists('table_path'$config))
  630.         {
  631.             $this->addTablePath($config['table_path']);
  632.         }
  633.         else
  634.         {
  635.             $componentPaths FOFPlatform::getInstance()->getComponentBaseDirs($this->option);
  636.  
  637.             $path $componentPaths['admin''/tables';
  638.             $altPath $this->configProvider->get($this->option . '.views.' FOFInflector::singularize($this->name'.config.table_path'null);
  639.  
  640.             if ($altPath)
  641.             {
  642.                 $path $componentPaths['main''/' $altPath;
  643.             }
  644.  
  645.             $this->addTablePath($path);
  646.         }
  647.  
  648.         // Assign the correct table
  649.         if (array_key_exists('table'$config))
  650.         {
  651.             $this->table = $config['table'];
  652.         }
  653.         else
  654.         {
  655.             $table $this->configProvider->get(
  656.                 $this->option . '.views.' FOFInflector::singularize($this->name.
  657.                 '.config.table'FOFInflector::singularize($view)
  658.             );
  659.             $this->table = $table;
  660.         }
  661.  
  662.         // Set the internal state marker - used to ignore setting state from the request
  663.  
  664.         if (!empty($config['ignore_request']|| !is_null(
  665.                 $this->configProvider->get(
  666.                     $this->option . '.views.' FOFInflector::singularize($this->name.
  667.                     '.config.ignore_request'null
  668.                 )
  669.         ))
  670.         {
  671.             $this->__state_set = true;
  672.         }
  673.  
  674.         // Get and store the pagination request variables
  675.         $defaultSaveState array_key_exists('savestate'$config$config['savestate': -999;
  676.         $this->populateSavestate($defaultSaveState);
  677.  
  678.         if (FOFPlatform::getInstance()->isCli())
  679.         {
  680.             $limit 20;
  681.             $limitstart 0;
  682.         }
  683.         else
  684.         {
  685.             $app JFactory::getApplication();
  686.  
  687.             if (method_exists($app'getCfg'))
  688.             {
  689.                 $default_limit $app->getCfg('list_limit');
  690.             }
  691.             else
  692.             {
  693.                 $default_limit 20;
  694.             }
  695.  
  696.             $limit $this->getUserStateFromRequest($component '.' $view '.limit''limit'$default_limit'int'$this->_savestate);
  697.             $limitstart $this->getUserStateFromRequest($component '.' $view '.limitstart''limitstart'0'int'$this->_savestate);
  698.         }
  699.  
  700.         $this->setState('limit'$limit);
  701.         $this->setState('limitstart'$limitstart);
  702.  
  703.         // Get the ID or list of IDs from the request or the configuration
  704.  
  705.         if (array_key_exists('cid'$config))
  706.         {
  707.             $cid $config['cid'];
  708.         }
  709.         elseif ($cid $this->configProvider->get(
  710.                 $this->option . '.views.' FOFInflector::singularize($this->name'.config.cid'null
  711.             )
  712.         )
  713.         {
  714.             $cid explode(','$cid);
  715.         }
  716.         else
  717.         {
  718.             $cid $this->input->get('cid'array()'array');
  719.         }
  720.  
  721.         if (array_key_exists('id'$config))
  722.         {
  723.             $id $config['id'];
  724.         }
  725.         elseif ($id $this->configProvider->get(
  726.                 $this->option . '.views.' FOFInflector::singularize($this->name'.config.id'null
  727.             )
  728.         )
  729.         {
  730.             $id explode(','$id);
  731.             $id array_shift($id);
  732.         }
  733.         else
  734.         {
  735.             $id $this->input->getInt('id'0);
  736.         }
  737.  
  738.         if (is_array($cid&& !empty($cid))
  739.         {
  740.             $this->setIds($cid);
  741.         }
  742.         else
  743.         {
  744.             $this->setId($id);
  745.         }
  746.  
  747.         // Populate the event names from the $config array
  748.         $configKey $this->option . '.views.' FOFInflector::singularize($view'.config.';
  749.  
  750.         // Assign after delete event handler
  751.  
  752.         if (isset($config['event_after_delete']))
  753.         {
  754.             $this->event_after_delete = $config['event_after_delete'];
  755.         }
  756.         else
  757.         {
  758.             $this->event_after_delete = $this->configProvider->get(
  759.                 $configKey 'event_after_delete',
  760.                 $this->event_after_delete
  761.             );
  762.         }
  763.  
  764.         // Assign after save event handler
  765.  
  766.         if (isset($config['event_after_save']))
  767.         {
  768.             $this->event_after_save = $config['event_after_save'];
  769.         }
  770.         else
  771.         {
  772.             $this->event_after_save = $this->configProvider->get(
  773.                 $configKey 'event_after_save',
  774.                 $this->event_after_save
  775.             );
  776.         }
  777.  
  778.         // Assign before delete event handler
  779.  
  780.         if (isset($config['event_before_delete']))
  781.         {
  782.             $this->event_before_delete = $config['event_before_delete'];
  783.         }
  784.         else
  785.         {
  786.             $this->event_before_delete = $this->configProvider->get(
  787.                 $configKey 'event_before_delete',
  788.                 $this->event_before_delete
  789.             );
  790.         }
  791.  
  792.         // Assign before save event handler
  793.  
  794.         if (isset($config['event_before_save']))
  795.         {
  796.             $this->event_before_save = $config['event_before_save'];
  797.         }
  798.         else
  799.         {
  800.             $this->event_before_save = $this->configProvider->get(
  801.                 $configKey 'event_before_save',
  802.                 $this->event_before_save
  803.             );
  804.         }
  805.  
  806.         // Assign state change event handler
  807.  
  808.         if (isset($config['event_change_state']))
  809.         {
  810.             $this->event_change_state = $config['event_change_state'];
  811.         }
  812.         else
  813.         {
  814.             $this->event_change_state = $this->configProvider->get(
  815.                 $configKey 'event_change_state',
  816.                 $this->event_change_state
  817.             );
  818.         }
  819.  
  820.         // Assign cache clean event handler
  821.  
  822.         if (isset($config['event_clean_cache']))
  823.         {
  824.             $this->event_clean_cache = $config['event_clean_cache'];
  825.         }
  826.         else
  827.         {
  828.             $this->event_clean_cache = $this->configProvider->get(
  829.                 $configKey 'event_clean_cache',
  830.                 $this->event_clean_cache
  831.             );
  832.         }
  833.  
  834.         // Apply model behaviors
  835.  
  836.         if (isset($config['behaviors']))
  837.         {
  838.             $behaviors = (array) $config['behaviors'];
  839.         }
  840.         elseif ($behaviors $this->configProvider->get($configKey 'behaviors'null))
  841.         {
  842.             $behaviors explode(','$behaviors);
  843.         }
  844.         else
  845.         {
  846.             $behaviors $this->default_behaviors;
  847.         }
  848.  
  849.         if (is_array($behaviors&& count($behaviors))
  850.         {
  851.             foreach ($behaviors as $behavior)
  852.             {
  853.                 $this->addBehavior($behavior);
  854.             }
  855.         }
  856.     }
  857.  
  858.     /**
  859.      * Sets the list of IDs from the request data
  860.      *
  861.      * @return FOFModel 
  862.      */
  863.     public function setIDsFromRequest()
  864.     {
  865.         // Get the ID or list of IDs from the request or the configuration
  866.         $cid $this->input->get('cid'array()'array');
  867.         $id $this->input->getInt('id'0);
  868.         $kid $this->input->getInt($this->getTable($this->table)->getKeyName()0);
  869.  
  870.         if (is_array($cid&& !empty($cid))
  871.         {
  872.             $this->setIds($cid);
  873.         }
  874.         else
  875.         {
  876.             if (empty($id))
  877.             {
  878.                 $this->setId($kid);
  879.             }
  880.             else
  881.             {
  882.                 $this->setId($id);
  883.             }
  884.         }
  885.  
  886.         return $this;
  887.     }
  888.  
  889.     /**
  890.      * Sets the ID and resets internal data
  891.      *
  892.      * @param   integer  $id  The ID to use
  893.      *
  894.      * @return FOFModel 
  895.      */
  896.     public function setId($id 0)
  897.     {
  898.         $this->reset();
  899.         $this->id = (int) $id;
  900.         $this->id_list = array($this->id);
  901.  
  902.         return $this;
  903.     }
  904.  
  905.     /**
  906.      * Returns the currently set ID
  907.      *
  908.      * @return  integer 
  909.      */
  910.     public function getId()
  911.     {
  912.         return $this->id;
  913.     }
  914.  
  915.     /**
  916.      * Sets a list of IDs for batch operations from an array and resets the model
  917.      *
  918.      * @param   array  $idlist  An array of item IDs to be set to the model's state
  919.      *
  920.      * @return  FOFModel 
  921.      */
  922.     public function setIds($idlist)
  923.     {
  924.         $this->reset();
  925.         $this->id_list = array();
  926.         $this->id = 0;
  927.  
  928.         if (is_array($idlist&& !empty($idlist))
  929.         {
  930.             foreach ($idlist as $value)
  931.             {
  932.                 $this->id_list[= (int) $value;
  933.             }
  934.  
  935.             $this->id = $this->id_list[0];
  936.         }
  937.  
  938.         return $this;
  939.     }
  940.  
  941.     /**
  942.      * Returns the list of IDs for batch operations
  943.      *
  944.      * @return  array  An array of integers
  945.      */
  946.     public function getIds()
  947.     {
  948.         return $this->id_list;
  949.     }
  950.  
  951.     /**
  952.      * Resets the model, like it was freshly loaded
  953.      *
  954.      * @return  FOFModel 
  955.      */
  956.     public function reset()
  957.     {
  958.         $this->id = 0;
  959.         $this->id_list = null;
  960.         $this->record = null;
  961.         $this->list = null;
  962.         $this->pagination = null;
  963.         $this->total = null;
  964.         $this->otable = null;
  965.  
  966.         return $this;
  967.     }
  968.  
  969.     /**
  970.      * Clears the model state, but doesn't touch the internal lists of records,
  971.      * record tables or record id variables. To clear these values, please use
  972.      * reset().
  973.      *
  974.      * @return  FOFModel 
  975.      */
  976.     public function clearState()
  977.     {
  978.         $this->state = new JObject;
  979.  
  980.         return $this;
  981.     }
  982.  
  983.     /**
  984.      * Clears the input array.
  985.      *
  986.      * @return  FOFModel 
  987.      */
  988.     public function clearInput()
  989.     {
  990.         $defSource array();
  991.         $this->input = new FOFInput($defSource);
  992.  
  993.         return $this;
  994.     }
  995.  
  996.     /**
  997.      * Set the internal input field
  998.      *
  999.      * @param $input 
  1000.      *
  1001.      * @return FOFModel 
  1002.      */
  1003.     public function setInput($input)
  1004.     {
  1005.         if (!($input instanceof FOFInput))
  1006.         {
  1007.             if (!is_array($input))
  1008.             {
  1009.                 $input = (array) $input;
  1010.             }
  1011.  
  1012.             $input array_merge($_REQUEST$input);
  1013.             $input new FOFInput($input);
  1014.         }
  1015.  
  1016.         $this->input = $input;
  1017.  
  1018.         return $this;
  1019.     }
  1020.  
  1021.     /**
  1022.      * Resets the saved state for this view
  1023.      *
  1024.      * @return  FOFModel 
  1025.      */
  1026.     public function resetSavedState()
  1027.     {
  1028.         JFactory::getApplication()->setUserState(substr($this->getHash()0-1)null);
  1029.  
  1030.         return $this;
  1031.     }
  1032.  
  1033.     /**
  1034.      * Returns a single item. It uses the id set with setId, or the first ID in
  1035.      * the list of IDs for batch operations
  1036.      *
  1037.      * @param   integer  $id  Force a primary key ID to the model. Use null to use the id from the state.
  1038.      *
  1039.      * @return  FOFTable  A copy of the item's FOFTable array
  1040.      */
  1041.     public function &getItem($id null)
  1042.     {
  1043.         if (!is_null($id))
  1044.         {
  1045.             $this->record = null;
  1046.             $this->setId($id);
  1047.         }
  1048.  
  1049.         if (empty($this->record))
  1050.         {
  1051.             $table $this->getTable($this->table);
  1052.             $table->load($this->id);
  1053.             $this->record = $table;
  1054.  
  1055.             // Do we have saved data?
  1056.             $session JFactory::getSession();
  1057.             $serialized $session->get($this->getHash('savedata'null);
  1058.  
  1059.             if (!empty($serialized))
  1060.             {
  1061.                 $data @unserialize($serialized);
  1062.  
  1063.                 if ($data !== false)
  1064.                 {
  1065.                     $k $table->getKeyName();
  1066.  
  1067.                     if (!array_key_exists($k$data))
  1068.                     {
  1069.                         $data[$knull;
  1070.                     }
  1071.  
  1072.                     if ($data[$k!= $this->id)
  1073.                     {
  1074.                         $session->set($this->getHash('savedata'null);
  1075.                     }
  1076.                     else
  1077.                     {
  1078.                         $this->record->bind($data);
  1079.                     }
  1080.                 }
  1081.             }
  1082.  
  1083.             $this->onAfterGetItem($this->record);
  1084.         }
  1085.  
  1086.         return $this->record;
  1087.     }
  1088.  
  1089.     /**
  1090.      * Alias for getItemList
  1091.      *
  1092.      * @param   boolean  $overrideLimits  Should I override set limits?
  1093.      * @param   string   $group           The group by clause
  1094.      *
  1095.      * @return  array 
  1096.      */
  1097.     public function &getList($overrideLimits false$group '')
  1098.     {
  1099.         return $this->getItemList($overrideLimits$group);
  1100.     }
  1101.  
  1102.     /**
  1103.      * Returns a list of items
  1104.      *
  1105.      * @param   boolean  $overrideLimits  Should I override set limits?
  1106.      * @param   string   $group           The group by clause
  1107.      *
  1108.      * @return  array 
  1109.      */
  1110.     public function &getItemList($overrideLimits false$group '')
  1111.     {
  1112.         if (empty($this->list))
  1113.         {
  1114.             $query $this->buildQuery($overrideLimits);
  1115.  
  1116.             if (!$overrideLimits)
  1117.             {
  1118.                 $limitstart $this->getState('limitstart');
  1119.                 $limit $this->getState('limit');
  1120.                 $this->list = $this->_getList((string) $query$limitstart$limit$group);
  1121.             }
  1122.             else
  1123.             {
  1124.                 $this->list = $this->_getList((string) $query00$group);
  1125.             }
  1126.         }
  1127.  
  1128.         return $this->list;
  1129.     }
  1130.  
  1131.     /**
  1132.      * A cross-breed between getItem and getItemList. It runs the complete query,
  1133.      * like getItemList does. However, instead of returning an array of ad-hoc
  1134.      * objects, it binds the data from the first item fetched on the list to an
  1135.      * instance of the table object and returns that table object instead.
  1136.      *
  1137.      * @param   boolean  $overrideLimits  Should I override set limits?
  1138.      *
  1139.      * @return  FOFTable 
  1140.      */
  1141.     public function &getFirstItem($overrideLimits false)
  1142.     {
  1143.         /**
  1144.          * We have to clone the instance, or when multiple getFirstItem calls occur,
  1145.          * we'll update EVERY instance created
  1146.          */
  1147.         $table clone $this->getTable($this->table);
  1148.  
  1149.         $list $this->getItemList($overrideLimits);
  1150.  
  1151.         if (!empty($list))
  1152.         {
  1153.             $firstItem array_shift($list);
  1154.             $table->bind($firstItem);
  1155.         }
  1156.  
  1157.         unset($list);
  1158.  
  1159.         return $table;
  1160.     }
  1161.  
  1162.     /**
  1163.      * Binds the data to the model and tries to save it
  1164.      *
  1165.      * @param   array|object   $data  The source data array or object
  1166.      *
  1167.      * @return  boolean  True on success
  1168.      */
  1169.     public function save($data)
  1170.     {
  1171.         $this->otable = null;
  1172.  
  1173.         $table $this->getTable($this->table);
  1174.  
  1175.         if (is_object($data))
  1176.         {
  1177.             $data clone($data);
  1178.         }
  1179.  
  1180.         $key $table->getKeyName();
  1181.  
  1182.         if (array_key_exists($key(array) $data))
  1183.         {
  1184.             $aData = (array) $data;
  1185.             $oid $aData[$key];
  1186.             $table->load($oid);
  1187.         }
  1188.  
  1189.         if ($data instanceof FOFTable)
  1190.         {
  1191.             $allData $data->getData();
  1192.         }
  1193.         elseif (is_object($data))
  1194.         {
  1195.             $allData = (array) $data;
  1196.         }
  1197.         else
  1198.         {
  1199.             $allData $data;
  1200.         }
  1201.  
  1202.         // Get the form if there is any
  1203.         $form $this->getForm($allDatafalse);
  1204.  
  1205.         if ($form instanceof FOFForm)
  1206.         {
  1207.             // Make sure that $allData has for any field a key
  1208.             $fieldset $form->getFieldset();
  1209.  
  1210.             foreach ($fieldset as $nfield => $fldset)
  1211.             {
  1212.                 if (!array_key_exists($nfield$allData))
  1213.                 {
  1214.                     $field $form->getField($fldset->fieldname$fldset->group);
  1215.                     $type  strtolower($field->type);
  1216.  
  1217.                     switch ($type)
  1218.                     {
  1219.                         case 'checkbox':
  1220.                             $allData[$nfield0;
  1221.                             break;
  1222.  
  1223.                         default:
  1224.                             $allData[$nfield'';
  1225.                             break;
  1226.                     }
  1227.                 }
  1228.             }
  1229.  
  1230.             $serverside_validate strtolower($form->getAttribute('serverside_validate'));
  1231.  
  1232.             $validateResult true;
  1233.             if (in_array($serverside_validatearray('true''yes''1''on')))
  1234.             {
  1235.                 $validateResult $this->validateForm($form$allData);
  1236.             }
  1237.  
  1238.             if ($validateResult === false)
  1239.             {
  1240.                 return false;
  1241.             }
  1242.         }
  1243.  
  1244.         if (!$this->onBeforeSave($allData$table))
  1245.         {
  1246.             return false;
  1247.         }
  1248.         else
  1249.         {
  1250.             // If onBeforeSave successful, refetch the possibly modified data
  1251.             if ($data instanceof FOFTable)
  1252.             {
  1253.                 $data->bind($allData);
  1254.             }
  1255.             elseif (is_object($data))
  1256.             {
  1257.                 $data = (object) $allData;
  1258.             }
  1259.             else
  1260.             {
  1261.                 $data $allData;
  1262.             }
  1263.         }
  1264.  
  1265.         if (!$table->save($data))
  1266.         {
  1267.             foreach ($table->getErrors(as $error)
  1268.             {
  1269.                 if (!empty($error))
  1270.                 {
  1271.                     $this->setError($error);
  1272.                     $session JFactory::getSession();
  1273.                     $tableprops $table->getProperties(true);
  1274.                     unset($tableprops['input']);
  1275.                     unset($tableprops['config']['input']);
  1276.                     unset($tableprops['config']['db']);
  1277.                     unset($tableprops['config']['dbo']);
  1278.                     $hash $this->getHash('savedata';
  1279.                     $session->set($hashserialize($tableprops));
  1280.                 }
  1281.             }
  1282.  
  1283.             return false;
  1284.         }
  1285.         else
  1286.         {
  1287.             $this->id = $table->$key;
  1288.  
  1289.             // Remove the session data
  1290.             JFactory::getSession()->set($this->getHash('savedata'null);
  1291.         }
  1292.  
  1293.         $this->onAfterSave($table);
  1294.  
  1295.         $this->otable = $table;
  1296.  
  1297.         return true;
  1298.     }
  1299.  
  1300.     /**
  1301.      * Copy one or more records
  1302.      *
  1303.      * @return  boolean  True on success
  1304.      */
  1305.     public function copy()
  1306.     {
  1307.         if (is_array($this->id_list&& !empty($this->id_list))
  1308.         {
  1309.             $table $this->getTable($this->table);
  1310.  
  1311.             if (!$this->onBeforeCopy($table))
  1312.             {
  1313.                 return false;
  1314.             }
  1315.  
  1316.             if (!$table->copy($this->id_list))
  1317.             {
  1318.                 $this->setError($table->getError());
  1319.  
  1320.                 return false;
  1321.             }
  1322.             else
  1323.             {
  1324.                 // Call our internal event
  1325.                 $this->onAfterCopy($table);
  1326.  
  1327.                 // @todo Should we fire the content plugin?
  1328.             }
  1329.         }
  1330.  
  1331.         return true;
  1332.     }
  1333.  
  1334.     /**
  1335.      * Returns the table object after the last save() operation
  1336.      *
  1337.      * @return  FOFTable 
  1338.      */
  1339.     public function getSavedTable()
  1340.     {
  1341.         return $this->otable;
  1342.     }
  1343.  
  1344.     /**
  1345.      * Deletes one or several items
  1346.      *
  1347.      * @return  boolean True on success
  1348.      */
  1349.     public function delete()
  1350.     {
  1351.         if (is_array($this->id_list&& !empty($this->id_list))
  1352.         {
  1353.             $table $this->getTable($this->table);
  1354.  
  1355.             foreach ($this->id_list as $id)
  1356.             {
  1357.                 if (!$this->onBeforeDelete($id$table))
  1358.                 {
  1359.                     continue;
  1360.                 }
  1361.  
  1362.                 if (!$table->delete($id))
  1363.                 {
  1364.                     $this->setError($table->getError());
  1365.  
  1366.                     return false;
  1367.                 }
  1368.                 else
  1369.                 {
  1370.                     $this->onAfterDelete($id);
  1371.                 }
  1372.             }
  1373.         }
  1374.  
  1375.         return true;
  1376.     }
  1377.  
  1378.     /**
  1379.      * Toggles the published state of one or several items
  1380.      *
  1381.      * @param   integer  $publish  The publishing state to set (e.g. 0 is unpublished)
  1382.      * @param   integer  $user     The user ID performing this action
  1383.      *
  1384.      * @return  boolean True on success
  1385.      */
  1386.     public function publish($publish 1$user null)
  1387.     {
  1388.         if (is_array($this->id_list&& !empty($this->id_list))
  1389.         {
  1390.             if (empty($user))
  1391.             {
  1392.                 $oUser FOFPlatform::getInstance()->getUser();
  1393.                 $user $oUser->id;
  1394.             }
  1395.  
  1396.             $table $this->getTable($this->table);
  1397.  
  1398.             if (!$this->onBeforePublish($table))
  1399.             {
  1400.                 return false;
  1401.             }
  1402.  
  1403.             if (!$table->publish($this->id_list$publish$user))
  1404.             {
  1405.                 $this->setError($table->getError());
  1406.  
  1407.                 return false;
  1408.             }
  1409.             else
  1410.             {
  1411.                 // Call our itnernal event
  1412.                 $this->onAfterPublish($table);
  1413.  
  1414.                 // Call the plugin events
  1415.                 FOFPlatform::getInstance()->importPlugin('content');
  1416.                 $name $this->input->getCmd('view''cpanel');
  1417.                 $context $this->option . '.' $name;
  1418.                 $result FOFPlatform::getInstance()->runPlugins($this->event_change_statearray($context$this->id_list$publish));
  1419.             }
  1420.         }
  1421.  
  1422.         return true;
  1423.     }
  1424.  
  1425.     /**
  1426.      * Checks out the current item
  1427.      *
  1428.      * @return  boolean 
  1429.      */
  1430.     public function checkout()
  1431.     {
  1432.         $table $this->getTable($this->table);
  1433.         $status $table->checkout(FOFPlatform::getInstance()->getUser()->id$this->id);
  1434.  
  1435.         if (!$status)
  1436.         {
  1437.             $this->setError($table->getError());
  1438.         }
  1439.  
  1440.         return $status;
  1441.     }
  1442.  
  1443.     /**
  1444.      * Checks in the current item
  1445.      *
  1446.      * @return  boolean 
  1447.      */
  1448.     public function checkin()
  1449.     {
  1450.         $table $this->getTable($this->table);
  1451.         $status $table->checkin($this->id);
  1452.  
  1453.         if (!$status)
  1454.         {
  1455.             $this->setError($table->getError());
  1456.         }
  1457.  
  1458.         return $status;
  1459.     }
  1460.  
  1461.     /**
  1462.      * Tells you if the current item is checked out or not
  1463.      *
  1464.      * @return  boolean 
  1465.      */
  1466.     public function isCheckedOut()
  1467.     {
  1468.         $table $this->getTable($this->table);
  1469.         $status $table->isCheckedOut($this->id);
  1470.  
  1471.         if (!$status)
  1472.         {
  1473.             $this->setError($table->getError());
  1474.         }
  1475.  
  1476.         return $status;
  1477.     }
  1478.  
  1479.     /**
  1480.      * Increments the hit counter
  1481.      *
  1482.      * @return  boolean 
  1483.      */
  1484.     public function hit()
  1485.     {
  1486.         $table $this->getTable($this->table);
  1487.  
  1488.         if (!$this->onBeforeHit($table))
  1489.         {
  1490.             return false;
  1491.         }
  1492.  
  1493.         $status $table->hit($this->id);
  1494.  
  1495.         if (!$status)
  1496.         {
  1497.             $this->setError($table->getError());
  1498.         }
  1499.         else
  1500.         {
  1501.             $this->onAfterHit($table);
  1502.         }
  1503.  
  1504.         return $status;
  1505.     }
  1506.  
  1507.     /**
  1508.      * Moves the current item up or down in the ordering list
  1509.      *
  1510.      * @param   string  $dirn  The direction and magnitude to use (2 means move up by 2 positions, -3 means move down three positions)
  1511.      *
  1512.      * @return  boolean  True on success
  1513.      */
  1514.     public function move($dirn)
  1515.     {
  1516.         $table $this->getTable($this->table);
  1517.  
  1518.         $id $this->getId();
  1519.         $status $table->load($id);
  1520.  
  1521.         if (!$status)
  1522.         {
  1523.             $this->setError($table->getError());
  1524.         }
  1525.  
  1526.         if (!$status)
  1527.         {
  1528.             return false;
  1529.         }
  1530.  
  1531.         if (!$this->onBeforeMove($table))
  1532.         {
  1533.             return false;
  1534.         }
  1535.  
  1536.         $status $table->move($dirn);
  1537.  
  1538.         if (!$status)
  1539.         {
  1540.             $this->setError($table->getError());
  1541.         }
  1542.         else
  1543.         {
  1544.             $this->onAfterMove($table);
  1545.         }
  1546.  
  1547.         return $status;
  1548.     }
  1549.  
  1550.     /**
  1551.      * Reorders all items in the table
  1552.      *
  1553.      * @return  boolean 
  1554.      */
  1555.     public function reorder()
  1556.     {
  1557.         $table $this->getTable($this->table);
  1558.  
  1559.         if (!$this->onBeforeReorder($table))
  1560.         {
  1561.             return false;
  1562.         }
  1563.  
  1564.         $status $table->reorder($this->getReorderWhere());
  1565.  
  1566.         if (!$status)
  1567.         {
  1568.             $this->setError($table->getError());
  1569.         }
  1570.         else
  1571.         {
  1572.             if (!$this->onAfterReorder($table))
  1573.             {
  1574.                 return false;
  1575.             }
  1576.         }
  1577.  
  1578.         return $status;
  1579.     }
  1580.  
  1581.     /**
  1582.      * Get a pagination object
  1583.      *
  1584.      * @return  JPagination 
  1585.      */
  1586.     public function getPagination()
  1587.     {
  1588.         if (empty($this->pagination))
  1589.         {
  1590.             // Import the pagination library
  1591.             JLoader::import('joomla.html.pagination');
  1592.  
  1593.             // Prepare pagination values
  1594.             $total $this->getTotal();
  1595.             $limitstart $this->getState('limitstart');
  1596.             $limit $this->getState('limit');
  1597.  
  1598.             // Create the pagination object
  1599.             $this->pagination = new JPagination($total$limitstart$limit);
  1600.         }
  1601.  
  1602.         return $this->pagination;
  1603.     }
  1604.  
  1605.     /**
  1606.      * Get the number of all items
  1607.      *
  1608.      * @return  integer 
  1609.      */
  1610.     public function getTotal()
  1611.     {
  1612.         if (is_null($this->total))
  1613.         {
  1614.             $query $this->buildCountQuery();
  1615.  
  1616.             if ($query === false)
  1617.             {
  1618.                 $subquery $this->buildQuery(false);
  1619.                 $subquery->clear('order');
  1620.                 $query $this->_db->getQuery(true)
  1621.                     ->select('COUNT(*)')
  1622.                     ->from("(" . (string) $subquery ") AS a");
  1623.             }
  1624.  
  1625.             $this->_db->setQuery((string) $query);
  1626.  
  1627.             $this->total = $this->_db->loadResult();
  1628.         }
  1629.  
  1630.         return $this->total;
  1631.     }
  1632.  
  1633.     /**
  1634.      * Returns a record count for the query
  1635.      *
  1636.      * @param   string  $query  The query.
  1637.      *
  1638.      * @return  integer  Number of rows for query
  1639.      *
  1640.      * @since   12.2
  1641.      */
  1642.     protected function _getListCount($query)
  1643.     {
  1644.         return $this->getTotal();
  1645.     }
  1646.  
  1647.     /**
  1648.      * Get a filtered state variable
  1649.      *
  1650.      * @param   string  $key          The name of the state variable
  1651.      * @param   mixed   $default      The default value to use
  1652.      * @param   string  $filter_type  Filter type
  1653.      *
  1654.      * @return  mixed  The variable's value
  1655.      */
  1656.     public function getState($key null$default null$filter_type 'raw')
  1657.     {
  1658.         if (empty($key))
  1659.         {
  1660.             return $this->_real_getState();
  1661.         }
  1662.  
  1663.         // Get the savestate status
  1664.         $value $this->_real_getState($key);
  1665.  
  1666.         if (is_null($value))
  1667.         {
  1668.             $value $this->getUserStateFromRequest($this->getHash($key$key$value'none'$this->_savestate);
  1669.  
  1670.             if (is_null($value))
  1671.             {
  1672.                 return $default;
  1673.             }
  1674.         }
  1675.  
  1676.         if (strtoupper($filter_type== 'RAW')
  1677.         {
  1678.             return $value;
  1679.         }
  1680.         else
  1681.         {
  1682.             JLoader::import('joomla.filter.filterinput');
  1683.             $filter new JFilterInput;
  1684.  
  1685.             return $filter->clean($value$filter_type);
  1686.         }
  1687.     }
  1688.  
  1689.     /**
  1690.      * Method to get model state variables
  1691.      *
  1692.      * @param   string  $property  Optional parameter name
  1693.      * @param   mixed   $default   Optional default value
  1694.      *
  1695.      * @return  object  The property where specified, the state object where omitted
  1696.      *
  1697.      * @since   12.2
  1698.      */
  1699.     protected function _real_getState($property null$default null)
  1700.     {
  1701.         if (!$this->__state_set)
  1702.         {
  1703.             // Protected method to auto-populate the model state.
  1704.             $this->populateState();
  1705.  
  1706.             // Set the model state set flag to true.
  1707.             $this->__state_set = true;
  1708.         }
  1709.  
  1710.         return $property === null $this->state : $this->state->get($property$default);
  1711.     }
  1712.  
  1713.     /**
  1714.      * Returns a hash for this component and view, e.g. "foobar.items.", used
  1715.      * for determining the keys of the variables which will be placed in the
  1716.      * session storage.
  1717.      *
  1718.      * @return  string  The hash
  1719.      */
  1720.     public function getHash()
  1721.     {
  1722.         $option $this->input->getCmd('option''com_foobar');
  1723.         $view FOFInflector::pluralize($this->input->getCmd('view''cpanel'));
  1724.  
  1725.         return "$option.$view.";
  1726.     }
  1727.  
  1728.     /**
  1729.      * Gets the value of a user state variable.
  1730.      *
  1731.      * @param   string   $key           The key of the user state variable.
  1732.      * @param   string   $request       The name of the variable passed in a request.
  1733.      * @param   string   $default       The default value for the variable if not found. Optional.
  1734.      * @param   string   $type          Filter for the variable, for valid values see {@link JFilterInput::clean()}. Optional.
  1735.      * @param   boolean  $setUserState  Should I save the variable in the user state? Default: true. Optional.
  1736.      *
  1737.      * @return  The request user state.
  1738.      */
  1739.     protected function getUserStateFromRequest($key$request$default null$type 'none'$setUserState true)
  1740.     {
  1741.         return FOFPlatform::getInstance()->getUserStateFromRequest($key$request$this->input$default$type$setUserState);
  1742.     }
  1743.  
  1744.     /**
  1745.      * Returns an object list
  1746.      *
  1747.      * @param   string   $query       The query
  1748.      * @param   integer  $limitstart  Offset from start
  1749.      * @param   integer  $limit       The number of records
  1750.      * @param   string   $group       The group by clause
  1751.      *
  1752.      * @return  array  Array of objects
  1753.      */
  1754.     protected function &_getList($query$limitstart 0$limit 0$group '')
  1755.     {
  1756.         $this->_db->setQuery($query$limitstart$limit);
  1757.         $result $this->_db->loadObjectList($group);
  1758.  
  1759.         $this->onProcessList($result);
  1760.  
  1761.         return $result;
  1762.     }
  1763.  
  1764.     /**
  1765.      * Method to get a table object, load it if necessary.
  1766.      *
  1767.      * @param   string  $name     The table name. Optional.
  1768.      * @param   string  $prefix   The class prefix. Optional.
  1769.      * @param   array   $options  Configuration array for model. Optional.
  1770.      *
  1771.      * @return  FOFTable  A FOFTable object
  1772.      */
  1773.     public function getTable($name ''$prefix null$options array())
  1774.     {
  1775.         if (empty($name))
  1776.         {
  1777.             $name $this->table;
  1778.  
  1779.             if (empty($name))
  1780.             {
  1781.                 $name FOFInflector::singularize($this->getName());
  1782.             }
  1783.         }
  1784.  
  1785.         if (empty($prefix))
  1786.         {
  1787.             $prefix ucfirst($this->getName()) 'Table';
  1788.         }
  1789.  
  1790.         if (empty($options))
  1791.         {
  1792.             $options array('input' => $this->input);
  1793.         }
  1794.  
  1795.         if ($table $this->_createTable($name$prefix$options))
  1796.         {
  1797.             return $table;
  1798.         }
  1799.  
  1800.         if (FOFPlatform::getInstance()->checkVersion(JVERSION'3.0''ge'))
  1801.         {
  1802.             throw new Exception(JText::sprintf('JLIB_APPLICATION_ERROR_TABLE_NAME_NOT_SUPPORTED'$name)0);
  1803.         }
  1804.         else
  1805.         {
  1806.             JError::raiseError(0JText::sprintf('JLIB_APPLICATION_ERROR_TABLE_NAME_NOT_SUPPORTED'$name));
  1807.         }
  1808.  
  1809.         return null;
  1810.     }
  1811.  
  1812.     /**
  1813.      * Method to load and return a model object.
  1814.      *
  1815.      * @param   string  $name    The name of the view
  1816.      * @param   string  $prefix  The class prefix. Optional.
  1817.      * @param   array   $config  The configuration array to pass to the table
  1818.      *
  1819.      * @return  FOFTable  Table object or boolean false if failed
  1820.      */
  1821.     protected function &_createTable($name$prefix 'Table'$config array())
  1822.     {
  1823.         // Make sure $config is an array
  1824.         if (is_object($config))
  1825.         {
  1826.             $config = (array) $config;
  1827.         }
  1828.         elseif (!is_array($config))
  1829.         {
  1830.             $config array();
  1831.         }
  1832.  
  1833.         $result null;
  1834.  
  1835.         // Clean the model name
  1836.         $name preg_replace('/[^A-Z0-9_]/i'''$name);
  1837.         $prefix preg_replace('/[^A-Z0-9_]/i'''$prefix);
  1838.  
  1839.         // Make sure we are returning a DBO object
  1840.  
  1841.         if (!array_key_exists('dbo'$config))
  1842.         {
  1843.             $config['dbo'$this->getDBO();
  1844.         }
  1845.  
  1846.         $instance FOFTable::getAnInstance($name$prefix$config);
  1847.  
  1848.         return $instance;
  1849.     }
  1850.  
  1851.     /**
  1852.      * Creates the WHERE part of the reorder query
  1853.      *
  1854.      * @return  string 
  1855.      */
  1856.     public function getReorderWhere()
  1857.     {
  1858.         return '';
  1859.     }
  1860.  
  1861.     /**
  1862.      * Builds the SELECT query
  1863.      *
  1864.      * @param   boolean  $overrideLimits  Are we requested to override the set limits?
  1865.      *
  1866.      * @return  JDatabaseQuery 
  1867.      */
  1868.     public function buildQuery($overrideLimits false)
  1869.     {
  1870.         $table $this->getTable();
  1871.         $tableName $table->getTableName();
  1872.         $tableKey $table->getKeyName();
  1873.         $db $this->getDbo();
  1874.  
  1875.         $query $db->getQuery(true);
  1876.  
  1877.         // Call the behaviors
  1878.         $this->modelDispatcher->trigger('onBeforeBuildQuery'array(&$this&$query));
  1879.  
  1880.         $alias $this->getTableAlias();
  1881.  
  1882.         if ($alias)
  1883.         {
  1884.             $alias ' AS ' $db->qn($alias);
  1885.         }
  1886.         else
  1887.         {
  1888.             $alias '';
  1889.         }
  1890.  
  1891.         $select $this->getTableAlias($db->qn($this->getTableAlias()) '.*' $db->qn($tableName'.*';
  1892.  
  1893.         $query->select($select)->from($db->qn($tableName$alias);
  1894.  
  1895.         if (!$overrideLimits)
  1896.         {
  1897.             $order $this->getState('filter_order'null'cmd');
  1898.  
  1899.             if (!in_array($orderarray_keys($table->getData())))
  1900.             {
  1901.                 $order $tableKey;
  1902.             }
  1903.  
  1904.             $order $db->qn($order);
  1905.  
  1906.             if ($alias)
  1907.             {
  1908.                 $order $db->qn($this->getTableAlias()) '.' $order;
  1909.             }
  1910.  
  1911.             $dir $this->getState('filter_order_Dir''ASC''cmd');
  1912.             $query->order($order ' ' $dir);
  1913.         }
  1914.  
  1915.         // Call the behaviors
  1916.         $this->modelDispatcher->trigger('onAfterBuildQuery'array(&$this&$query));
  1917.  
  1918.         return $query;
  1919.     }
  1920.  
  1921.     /**
  1922.      * Returns a list of the fields of the table associated with this model
  1923.      *
  1924.      * @return  array 
  1925.      */
  1926.     public function getTableFields()
  1927.     {
  1928.         $tableName $this->getTable()->getTableName();
  1929.  
  1930.         if (FOFPlatform::getInstance()->checkVersion(JVERSION'3.0''ge'))
  1931.         {
  1932.             $fields $this->getDbo()->getTableColumns($tableNametrue);
  1933.         }
  1934.         else
  1935.         {
  1936.             $fieldsArray $this->getDbo()->getTableFields($tableNametrue);
  1937.             $fields array_shift($fieldsArray);
  1938.         }
  1939.  
  1940.         return $fields;
  1941.     }
  1942.  
  1943.     /**
  1944.      * Get the alias set for this model's table
  1945.      *
  1946.      * @return  string     The table alias
  1947.      */
  1948.     public function getTableAlias()
  1949.     {
  1950.         return $this->getTable($this->table)->getTableAlias();
  1951.     }
  1952.  
  1953.     /**
  1954.      * Builds the count query used in getTotal()
  1955.      *
  1956.      * @return  boolean 
  1957.      */
  1958.     public function buildCountQuery()
  1959.     {
  1960.         return false;
  1961.     }
  1962.  
  1963.     /**
  1964.      * Clones the model object and returns the clone
  1965.      *
  1966.      * @return  FOFModel 
  1967.      */
  1968.     public function &getClone()
  1969.     {
  1970.         $clone clone($this);
  1971.  
  1972.         return $clone;
  1973.     }
  1974.  
  1975.     /**
  1976.      * Magic getter; allows to use the name of model state keys as properties
  1977.      *
  1978.      * @param   string  $name  The name of the variable to get
  1979.      *
  1980.      * @return  mixed  The value of the variable
  1981.      */
  1982.     public function __get($name)
  1983.     {
  1984.         return $this->getState($name);
  1985.     }
  1986.  
  1987.     /**
  1988.      * Magic setter; allows to use the name of model state keys as properties
  1989.      *
  1990.      * @param   string  $name   The name of the variable
  1991.      * @param   mixed   $value  The value to set the variable to
  1992.      *
  1993.      * @return  void 
  1994.      */
  1995.     public function __set($name$value)
  1996.     {
  1997.         return $this->setState($name$value);
  1998.     }
  1999.  
  2000.     /**
  2001.      * Magic caller; allows to use the name of model state keys as methods to
  2002.      * set their values.
  2003.      *
  2004.      * @param   string  $name       The name of the state variable to set
  2005.      * @param   mixed   $arguments  The value to set the state variable to
  2006.      *
  2007.      * @return  FOFModel  Reference to self
  2008.      */
  2009.     public function __call($name$arguments)
  2010.     {
  2011.         $arg1 array_shift($arguments);
  2012.         $this->setState($name$arg1);
  2013.  
  2014.         return $this;
  2015.     }
  2016.  
  2017.     /**
  2018.      * Sets the model state auto-save status. By default the model is set up to
  2019.      * save its state to the session.
  2020.      *
  2021.      * @param   boolean  $newState  True to save the state, false to not save it.
  2022.      *
  2023.      * @return  FOFModel  Reference to self
  2024.      */
  2025.     public function &savestate($newState)
  2026.     {
  2027.         $this->_savestate = $newState true false;
  2028.  
  2029.         return $this;
  2030.     }
  2031.  
  2032.     /**
  2033.      * Initialises the _savestate variable
  2034.      *
  2035.      * @param   integer  $defaultSaveState  The default value for the savestate
  2036.      *
  2037.      * @return  void 
  2038.      */
  2039.     public function populateSavestate($defaultSaveState = -999)
  2040.     {
  2041.         if (is_null($this->_savestate))
  2042.         {
  2043.             $savestate $this->input->getInt('savestate'$defaultSaveState);
  2044.  
  2045.             if ($savestate == -999)
  2046.             {
  2047.                 $savestate true;
  2048.             }
  2049.  
  2050.             $this->savestate($savestate);
  2051.         }
  2052.     }
  2053.  
  2054.     /**
  2055.      * Method to auto-populate the model state.
  2056.      *
  2057.      * This method should only be called once per instantiation and is designed
  2058.      * to be called on the first call to the getState() method unless the model
  2059.      * configuration flag to ignore the request is set.
  2060.      *
  2061.      * @return  void 
  2062.      *
  2063.      * @note    Calling getState in this method will result in recursion.
  2064.      * @since   12.2
  2065.      */
  2066.     protected function populateState()
  2067.     {
  2068.     }
  2069.  
  2070.     /**
  2071.      * Applies view access level filtering for the specified user. Useful to
  2072.      * filter a front-end items listing.
  2073.      *
  2074.      * @param   integer  $userID  The user ID to use. Skip it to use the currently logged in user.
  2075.      *
  2076.      * @return  FOFModel  Reference to self
  2077.      */
  2078.     public function applyAccessFiltering($userID null)
  2079.     {
  2080.         $user FOFPlatform::getInstance()->getUser($userID);
  2081.  
  2082.         $table $this->getTable();
  2083.         $accessField $table->getColumnAlias('access');
  2084.  
  2085.         $this->setState($accessField$user->getAuthorisedViewLevels());
  2086.  
  2087.         return $this;
  2088.     }
  2089.  
  2090.     /**
  2091.      * A method for getting the form from the model.
  2092.      *
  2093.      * @param   array    $data      Data for the form.
  2094.      * @param   boolean  $loadData  True if the form is to load its own data (default case), false if not.
  2095.      * @param   boolean  $source    The name of the form. If not set we'll try the form_name state variable or fall back to default.
  2096.      *
  2097.      * @return  mixed  A FOFForm object on success, false on failure
  2098.      *
  2099.      * @since   2.0
  2100.      */
  2101.     public function getForm($data array()$loadData true$source null)
  2102.     {
  2103.         $this->_formData = $data;
  2104.  
  2105.         $name $this->input->getCmd('option''com_foobar''.'
  2106.             . $this->input->getCmd('view''cpanels');
  2107.  
  2108.         if (empty($source))
  2109.         {
  2110.             $source $this->getState('form_name'null);
  2111.         }
  2112.  
  2113.         if (empty($source))
  2114.         {
  2115.             $source 'form.' $this->input->getCmd('view''cpanels');
  2116.         }
  2117.  
  2118.         $options array(
  2119.             'control'     => false,
  2120.             'load_data'     => $loadData,
  2121.         );
  2122.  
  2123.         $this->onBeforeLoadForm($name$source$options);
  2124.  
  2125.         $form $this->loadForm($name$source$options);
  2126.  
  2127.         if ($form instanceof FOFForm)
  2128.         {
  2129.             $this->onAfterLoadForm($form$name$source$options);
  2130.         }
  2131.  
  2132.         return $form;
  2133.     }
  2134.  
  2135.     /**
  2136.      * Method to get a form object.
  2137.      *
  2138.      * @param   string   $name     The name of the form.
  2139.      * @param   string   $source   The form source. Can be XML string if file flag is set to false.
  2140.      * @param   array    $options  Optional array of options for the form creation.
  2141.      * @param   boolean  $clear    Optional argument to force load a new form.
  2142.      * @param   string   $xpath    An optional xpath to search for the fields.
  2143.      *
  2144.      * @return  mixed  FOFForm object on success, False on error.
  2145.      *
  2146.      * @see     FOFForm
  2147.      * @since   2.0
  2148.      */
  2149.     protected function loadForm($name$source null$options array()$clear false$xpath false)
  2150.     {
  2151.         // Handle the optional arguments.
  2152.         $options['control'JArrayHelper::getValue($options'control'false);
  2153.  
  2154.         // Create a signature hash.
  2155.         $hash md5($source serialize($options));
  2156.  
  2157.         // Check if we can use a previously loaded form.
  2158.  
  2159.         if (isset($this->_forms[$hash]&& !$clear)
  2160.         {
  2161.             return $this->_forms[$hash];
  2162.         }
  2163.  
  2164.         // Try to find the name and path of the form to load
  2165.         $formFilename $this->findFormFilename($source);
  2166.  
  2167.         // No form found? Quit!
  2168.  
  2169.         if ($formFilename === false)
  2170.         {
  2171.             return false;
  2172.         }
  2173.  
  2174.         // Set up the form name and path
  2175.         $source basename($formFilename'.xml');
  2176.         FOFForm::addFormPath(dirname($formFilename));
  2177.  
  2178.         // Set up field paths
  2179.  
  2180.         $option $this->input->getCmd('option''com_foobar');
  2181.         $componentPaths FOFPlatform::getInstance()->getComponentBaseDirs($option);
  2182.         $view $this->input->getCmd('view''cpanels');
  2183.         $file_root $componentPaths['main'];
  2184.         $alt_file_root $componentPaths['alt'];
  2185.  
  2186.         FOFForm::addFieldPath($file_root '/fields');
  2187.         FOFForm::addFieldPath($file_root '/models/fields');
  2188.         FOFForm::addFieldPath($alt_file_root '/fields');
  2189.         FOFForm::addFieldPath($alt_file_root '/models/fields');
  2190.  
  2191.         FOFForm::addHeaderPath($file_root '/fields/header');
  2192.         FOFForm::addHeaderPath($file_root '/models/fields/header');
  2193.         FOFForm::addHeaderPath($alt_file_root '/fields/header');
  2194.         FOFForm::addHeaderPath($alt_file_root '/models/fields/header');
  2195.  
  2196.         // Get the form.
  2197.         try
  2198.         {
  2199.             $form FOFForm::getInstance($name$source$optionsfalse$xpath);
  2200.  
  2201.             if (isset($options['load_data']&& $options['load_data'])
  2202.             {
  2203.                 // Get the data for the form.
  2204.                 $data $this->loadFormData();
  2205.             }
  2206.             else
  2207.             {
  2208.                 $data array();
  2209.             }
  2210.  
  2211.             // Allows data and form manipulation before preprocessing the form
  2212.             $this->onBeforePreprocessForm($form$data);
  2213.  
  2214.             // Allow for additional modification of the form, and events to be triggered.
  2215.             // We pass the data because plugins may require it.
  2216.             $this->preprocessForm($form$data);
  2217.  
  2218.             // Allows data and form manipulation After preprocessing the form
  2219.             $this->onAfterPreprocessForm($form$data);
  2220.  
  2221.             // Load the data into the form after the plugins have operated.
  2222.             $form->bind($data);
  2223.         }
  2224.         catch (Exception $e)
  2225.         {
  2226.             $this->setError($e->getMessage());
  2227.  
  2228.             return false;
  2229.         }
  2230.  
  2231.         // Store the form for later.
  2232.         $this->_forms[$hash$form;
  2233.  
  2234.         return $form;
  2235.     }
  2236.  
  2237.     /**
  2238.      * Guesses the best candidate for the path to use for a particular form.
  2239.      *
  2240.      * @param   string  $source  The name of the form file to load, without the .xml extension.
  2241.      * @param   array   $paths   The paths to look into. You can declare this to override the default FOF paths.
  2242.      *
  2243.      * @return  mixed  A string if the path and filename of the form to load is found, false otherwise.
  2244.      *
  2245.      * @since   2.0
  2246.      */
  2247.     public function findFormFilename($source$paths array())
  2248.     {
  2249.         $option $this->input->getCmd('option''com_foobar');
  2250.         $view     $this->input->getCmd('view''cpanels');
  2251.  
  2252.         $componentPaths FOFPlatform::getInstance()->getComponentBaseDirs($option);
  2253.         $file_root $componentPaths['main'];
  2254.         $alt_file_root $componentPaths['alt'];
  2255.         $template_root FOFPlatform::getInstance()->getTemplateOverridePath($option);
  2256.  
  2257.         if (empty($paths))
  2258.         {
  2259.             // Set up the paths to look into
  2260.             $paths array(
  2261.                 // In the template override
  2262.                 $template_root '/' $view,
  2263.                 $template_root '/' FOFInflector::singularize($view),
  2264.                 $template_root '/' FOFInflector::pluralize($view),
  2265.                 // In this side of the component
  2266.                 $file_root '/views/' $view '/tmpl',
  2267.                 $file_root '/views/' FOFInflector::singularize($view'/tmpl',
  2268.                 $file_root '/views/' FOFInflector::pluralize($view'/tmpl',
  2269.                 // In the other side of the component
  2270.                 $alt_file_root '/views/' $view '/tmpl',
  2271.                 $alt_file_root '/views/' FOFInflector::singularize($view'/tmpl',
  2272.                 $alt_file_root '/views/' FOFInflector::pluralize($view'/tmpl',
  2273.                 // In the models/forms of this side
  2274.                 $file_root '/models/forms',
  2275.                 // In the models/forms of the other side
  2276.                 $alt_file_root '/models/forms',
  2277.             );
  2278.         }
  2279.  
  2280.         // Set up the suffixes to look into
  2281.         $suffixes array();
  2282.         $temp_suffixes FOFPlatform::getInstance()->getTemplateSuffixes();
  2283.  
  2284.         if (!empty($temp_suffixes))
  2285.         {
  2286.             foreach ($temp_suffixes as $suffix)
  2287.             {
  2288.                 $suffixes[$suffix '.xml';
  2289.             }
  2290.         }
  2291.  
  2292.         $suffixes['.xml';
  2293.  
  2294.         // Look for all suffixes in all paths
  2295.         JLoader::import('joomla.filesystem.file');
  2296.         $result false;
  2297.  
  2298.         foreach ($paths as $path)
  2299.         {
  2300.             foreach ($suffixes as $suffix)
  2301.             {
  2302.                 $filename $path '/' $source $suffix;
  2303.  
  2304.                 if (JFile::exists($filename))
  2305.                 {
  2306.                     $result $filename;
  2307.                     break;
  2308.                 }
  2309.             }
  2310.  
  2311.             if ($result)
  2312.             {
  2313.                 break;
  2314.             }
  2315.         }
  2316.  
  2317.         return $result;
  2318.     }
  2319.  
  2320.     /**
  2321.      * Method to get the data that should be injected in the form.
  2322.      *
  2323.      * @return  array    The default data is an empty array.
  2324.      *
  2325.      * @since   2.0
  2326.      */
  2327.     protected function loadFormData()
  2328.     {
  2329.         if (empty($this->_formData))
  2330.         {
  2331.             return array();
  2332.         }
  2333.         else
  2334.         {
  2335.             return $this->_formData;
  2336.         }
  2337.     }
  2338.  
  2339.     /**
  2340.      * Method to allow derived classes to preprocess the form.
  2341.      *
  2342.      * @param   FOFForm  $form   A FOFForm object.
  2343.      * @param   mixed    &$data  The data expected for the form.
  2344.      * @param   string   $group  The name of the plugin group to import (defaults to "content").
  2345.      *
  2346.      * @return  void 
  2347.      *
  2348.      * @see     FOFFormField
  2349.      * @since   2.0
  2350.      * @throws  Exception if there is an error in the form event.
  2351.      */
  2352.     protected function preprocessForm(FOFForm $form&$data$group 'content')
  2353.     {
  2354.         // Import the appropriate plugin group.
  2355.         JLoader::import('joomla.plugin.helper');
  2356.         FOFPlatform::getInstance()->importPlugin($group);
  2357.  
  2358.         // Trigger the form preparation event.
  2359.         $results FOFPlatform::getInstance()->runPlugins('onContentPrepareForm'array($form$data));
  2360.  
  2361.         // Check for errors encountered while preparing the form.
  2362.         if (count($results&& in_array(false$resultstrue))
  2363.         {
  2364.             // Get the last error.
  2365.             $dispatcher JDispatcher::getInstance();
  2366.             $error $dispatcher->getError();
  2367.  
  2368.             if (!($error instanceof Exception))
  2369.             {
  2370.                 throw new Exception($error);
  2371.             }
  2372.         }
  2373.     }
  2374.  
  2375.     /**
  2376.      * Method to validate the form data.
  2377.      *
  2378.      * @param   FOFForm  $form   The form to validate against.
  2379.      * @param   array    $data   The data to validate.
  2380.      * @param   string   $group  The name of the field group to validate.
  2381.      *
  2382.      * @return  mixed   Array of filtered data if valid, false otherwise.
  2383.      *
  2384.      * @see     JFormRule
  2385.      * @see     JFilterInput
  2386.      * @since   2.0
  2387.      */
  2388.     public function validateForm($form$data$group null)
  2389.     {
  2390.         // Filter and validate the form data.
  2391.         $data $form->filter($data);
  2392.         $return $form->validate($data$group);
  2393.  
  2394.         // Check for an error.
  2395.         if ($return instanceof Exception)
  2396.         {
  2397.             $this->setError($return->getMessage());
  2398.  
  2399.             return false;
  2400.         }
  2401.  
  2402.         // Check the validation results.
  2403.         if ($return === false)
  2404.         {
  2405.             // Get the validation messages from the form.
  2406.             foreach ($form->getErrors(as $message)
  2407.             {
  2408.                 if ($message instanceof Exception)
  2409.                 {
  2410.                     $this->setError($message->getMessage());
  2411.                 }
  2412.                 else
  2413.                 {
  2414.                     $this->setError($message);
  2415.                 }
  2416.             }
  2417.  
  2418.             return false;
  2419.         }
  2420.  
  2421.         return $data;
  2422.     }
  2423.  
  2424.     /**
  2425.      * Allows the manipulation before the form is loaded
  2426.      *
  2427.      * @param   string  &$name     The name of the form.
  2428.      * @param   string  &$source   The form source. Can be XML string if file flag is set to false.
  2429.      * @param   array   &$options  Optional array of options for the form creation.
  2430.      *
  2431.      * @return  viod 
  2432.      */
  2433.     public function onBeforeLoadForm(&$name&$source&$options)
  2434.     {
  2435.     }
  2436.  
  2437.     /**
  2438.      * Allows the manipulation after the form is loaded
  2439.      *
  2440.      * @param   FOFForm  $form      A FOFForm object.
  2441.      * @param   string   &$name     The name of the form.
  2442.      * @param   string   &$source   The form source. Can be XML string if file flag is set to false.
  2443.      * @param   array    &$options  Optional array of options for the form creation.
  2444.      *
  2445.      * @return  viod 
  2446.      */
  2447.     public function onAfterLoadForm(FOFForm $form&$name&$source&$options)
  2448.     {
  2449.     }
  2450.  
  2451.     /**
  2452.      * Allows data and form manipulation before preprocessing the form
  2453.      *
  2454.      * @param   FOFForm  $form    A FOFForm object.
  2455.      * @param   array    &$data   The data expected for the form.
  2456.      *
  2457.      * @return  viod 
  2458.      */
  2459.     public function onBeforePreprocessForm(FOFForm $form&$data)
  2460.     {
  2461.     }
  2462.  
  2463.     /**
  2464.      * Allows data and form manipulation after preprocessing the form
  2465.      *
  2466.      * @param   FOFForm  $form    A FOFForm object.
  2467.      * @param   array    &$data   The data expected for the form.
  2468.      *
  2469.      * @return  viod 
  2470.      */
  2471.     public function onAfterPreprocessForm(FOFForm $form&$data)
  2472.     {
  2473.     }
  2474.  
  2475.     /**
  2476.      * This method can be overriden to automatically do something with the
  2477.      * list results array. You are supposed to modify the list which was passed
  2478.      * in the parameters; DO NOT return a new array!
  2479.      *
  2480.      * @param   array  &$resultArray  An array of objects, each row representing a record
  2481.      *
  2482.      * @return  void 
  2483.      */
  2484.     protected function onProcessList(&$resultArray)
  2485.     {
  2486.     }
  2487.  
  2488.     /**
  2489.      * This method runs after an item has been gotten from the database in a read
  2490.      * operation. You can modify it before it's returned to the MVC triad for
  2491.      * further processing.
  2492.      *
  2493.      * @param   FOFTable  &$record  The table instance we fetched
  2494.      *
  2495.      * @return  void 
  2496.      */
  2497.     protected function onAfterGetItem(&$record)
  2498.     {
  2499.         try
  2500.         {
  2501.             // Call the behaviors
  2502.             $result $this->modelDispatcher->trigger('onAfterGetItem'array(&$this&$record));
  2503.         }
  2504.         catch (Exception $e)
  2505.         {
  2506.             // Oops, an exception occured!
  2507.             $this->setError($e->getMessage());
  2508.         }
  2509.     }
  2510.  
  2511.     /**
  2512.      * This method runs before the $data is saved to the $table. Return false to
  2513.      * stop saving.
  2514.      *
  2515.      * @param   array     &$data   The data to save
  2516.      * @param   FOFTable  &$table  The table to save the data to
  2517.      *
  2518.      * @return  boolean  Return false to prevent saving, true to allow it
  2519.      */
  2520.     protected function onBeforeSave(&$data&$table)
  2521.     {
  2522.         // Let's import the plugin only if we're not in CLI (content plugin needs a user)
  2523.         FOFPlatform::getInstance()->importPlugin('content');
  2524.  
  2525.         try
  2526.         {
  2527.             // Do I have a new record?
  2528.             $key $table->getKeyName();
  2529.  
  2530.             $pk (!empty($data[$key])) $data[$key0;
  2531.  
  2532.             $this->_isNewRecord $pk <= 0;
  2533.  
  2534.             // Bind the data
  2535.             $table->bind($data);
  2536.  
  2537.             // Call the behaviors
  2538.             $result $this->modelDispatcher->trigger('onBeforeSave'array(&$this&$data));
  2539.  
  2540.             if (in_array(false$resulttrue))
  2541.             {
  2542.                 // Behavior failed, return false
  2543.                 return false;
  2544.             }
  2545.  
  2546.             // Call the plugin
  2547.             $name $this->name;
  2548.             $result FOFPlatform::getInstance()->runPlugins($this->event_before_savearray($this->option . '.' $name&$table$this->_isNewRecord));
  2549.  
  2550.             if (in_array(false$resulttrue))
  2551.             {
  2552.                 // Plugin failed, return false
  2553.                 $this->setError($table->getError());
  2554.  
  2555.                 return false;
  2556.             }
  2557.         }
  2558.         catch (Exception $e)
  2559.         {
  2560.             // Oops, an exception occured!
  2561.             $this->setError($e->getMessage());
  2562.  
  2563.             return false;
  2564.         }
  2565.  
  2566.         return true;
  2567.     }
  2568.  
  2569.     /**
  2570.      * This method runs after the data is saved to the $table.
  2571.      *
  2572.      * @param   FOFTable  &$table  The table which was saved
  2573.      *
  2574.      * @return  boolean 
  2575.      */
  2576.     protected function onAfterSave(&$table)
  2577.     {
  2578.         // Let's import the plugin only if we're not in CLI (content plugin needs a user)
  2579.  
  2580.         FOFPlatform::getInstance()->importPlugin('content');
  2581.  
  2582.         try
  2583.         {
  2584.             // Call the behaviors
  2585.             $result $this->modelDispatcher->trigger('onAfterSave'array(&$this));
  2586.  
  2587.             if (in_array(false$resulttrue))
  2588.             {
  2589.                 // Behavior failed, return false
  2590.                 return false;
  2591.             }
  2592.  
  2593.             $name $this->name;
  2594.             FOFPlatform::getInstance()->runPlugins($this->event_after_savearray($this->option . '.' $name&$table$this->_isNewRecord));
  2595.         }
  2596.         catch (Exception $e)
  2597.         {
  2598.             // Oops, an exception occured!
  2599.             $this->setError($e->getMessage());
  2600.  
  2601.             return false;
  2602.         }
  2603.     }
  2604.  
  2605.     /**
  2606.      * This method runs before the record with key value of $id is deleted from $table
  2607.      *
  2608.      * @param   integer   &$id     The ID of the record being deleted
  2609.      * @param   FOFTable  &$table  The table instance used to delete the record
  2610.      *
  2611.      * @return  boolean 
  2612.      */
  2613.     protected function onBeforeDelete(&$id&$table)
  2614.     {
  2615.         // Let's import the plugin only if we're not in CLI (content plugin needs a user)
  2616.  
  2617.         FOFPlatform::getInstance()->importPlugin('content');
  2618.  
  2619.         try
  2620.         {
  2621.             $table->load($id);
  2622.  
  2623.             // Call the behaviors
  2624.             $result $this->modelDispatcher->trigger('onBeforeDelete'array(&$this));
  2625.  
  2626.             if (in_array(false$resulttrue))
  2627.             {
  2628.                 // Behavior failed, return false
  2629.                 return false;
  2630.             }
  2631.  
  2632.             $name $this->input->getCmd('view''cpanel');
  2633.             $context $this->option . '.' $name;
  2634.             $result FOFPlatform::getInstance()->runPlugins($this->event_before_deletearray($context$table));
  2635.  
  2636.             if (in_array(false$resulttrue))
  2637.             {
  2638.                 // Plugin failed, return false
  2639.                 $this->setError($table->getError());
  2640.  
  2641.                 return false;
  2642.             }
  2643.  
  2644.             $this->_recordForDeletion clone $table;
  2645.         }
  2646.         catch (Exception $e)
  2647.         {
  2648.             // Oops, an exception occured!
  2649.             $this->setError($e->getMessage());
  2650.  
  2651.             return false;
  2652.         }
  2653.         return true;
  2654.     }
  2655.  
  2656.     /**
  2657.      * This method runs after a record with key value $id is deleted
  2658.      *
  2659.      * @param   integer  $id  The id of the record which was deleted
  2660.      *
  2661.      * @return  boolean  Return false to raise an error, true otherwise
  2662.      */
  2663.     protected function onAfterDelete($id)
  2664.     {
  2665.         FOFPlatform::getInstance()->importPlugin('content');
  2666.  
  2667.         // Call the behaviors
  2668.         $result $this->modelDispatcher->trigger('onAfterDelete'array(&$this));
  2669.  
  2670.         if (in_array(false$resulttrue))
  2671.         {
  2672.             // Behavior failed, return false
  2673.             return false;
  2674.         }
  2675.  
  2676.         $dispatcher JDispatcher::getInstance();
  2677.  
  2678.         try
  2679.         {
  2680.             $name $this->input->getCmd('view''cpanel');
  2681.             $context $this->option . '.' $name;
  2682.             $result FOFPlatform::getInstance()->runPlugins($this->event_after_deletearray($context$this->_recordForDeletion));
  2683.             unset($this->_recordForDeletion);
  2684.         }
  2685.         catch (Exception $e)
  2686.         {
  2687.             // Oops, an exception occured!
  2688.             $this->setError($e->getMessage());
  2689.  
  2690.             return false;
  2691.         }
  2692.     }
  2693.  
  2694.     /**
  2695.      * This method runs before a record is copied
  2696.      *
  2697.      * @param   FOFTable  &$table  The table instance of the record being copied
  2698.      *
  2699.      * @return  boolean  True to allow the copy
  2700.      */
  2701.     protected function onBeforeCopy(&$table)
  2702.     {
  2703.         // Call the behaviors
  2704.         $result $this->modelDispatcher->trigger('onBeforeCopy'array(&$this));
  2705.  
  2706.         if (in_array(false$resulttrue))
  2707.         {
  2708.             // Behavior failed, return false
  2709.             return false;
  2710.         }
  2711.  
  2712.         return true;
  2713.     }
  2714.  
  2715.     /**
  2716.      * This method runs after a record has been copied
  2717.      *
  2718.      * @param   FOFTable  &$table  The table instance of the record which was copied
  2719.      *
  2720.      * @return  boolean  True to allow the copy
  2721.      */
  2722.     protected function onAfterCopy(&$table)
  2723.     {
  2724.         // Call the behaviors
  2725.         $result $this->modelDispatcher->trigger('onAfterCopy'array(&$this));
  2726.  
  2727.         if (in_array(false$resulttrue))
  2728.         {
  2729.             // Behavior failed, return false
  2730.             return false;
  2731.         }
  2732.  
  2733.         return true;
  2734.     }
  2735.  
  2736.     /**
  2737.      * This method runs before a record is published
  2738.      *
  2739.      * @param   FOFTable  &$table  The table instance of the record being published
  2740.      *
  2741.      * @return  boolean  True to allow the operation
  2742.      */
  2743.     protected function onBeforePublish(&$table)
  2744.     {
  2745.         // Call the behaviors
  2746.         $result $this->modelDispatcher->trigger('onBeforePublish'array(&$this));
  2747.  
  2748.         if (in_array(false$resulttrue))
  2749.         {
  2750.             // Behavior failed, return false
  2751.             return false;
  2752.         }
  2753.  
  2754.         return true;
  2755.     }
  2756.  
  2757.     /**
  2758.      * This method runs after a record has been published
  2759.      *
  2760.      * @param   FOFTable  &$table  The table instance of the record which was published
  2761.      *
  2762.      * @return  boolean  True to allow the operation
  2763.      */
  2764.     protected function onAfterPublish(&$table)
  2765.     {
  2766.         // Call the behaviors
  2767.         $result $this->modelDispatcher->trigger('onAfterPublish'array(&$this));
  2768.  
  2769.         if (in_array(false$resulttrue))
  2770.         {
  2771.             // Behavior failed, return false
  2772.             return false;
  2773.         }
  2774.  
  2775.         return true;
  2776.     }
  2777.  
  2778.     /**
  2779.      * This method runs before a record is hit
  2780.      *
  2781.      * @param   FOFTable  &$table  The table instance of the record being hit
  2782.      *
  2783.      * @return  boolean  True to allow the operation
  2784.      */
  2785.     protected function onBeforeHit(&$table)
  2786.     {
  2787.         // Call the behaviors
  2788.         $result $this->modelDispatcher->trigger('onBeforeHit'array(&$this));
  2789.  
  2790.         if (in_array(false$resulttrue))
  2791.         {
  2792.             // Behavior failed, return false
  2793.             return false;
  2794.         }
  2795.  
  2796.         return true;
  2797.     }
  2798.  
  2799.     /**
  2800.      * This method runs after a record has been hit
  2801.      *
  2802.      * @param   FOFTable  &$table  The table instance of the record which was hit
  2803.      *
  2804.      * @return  boolean  True to allow the operation
  2805.      */
  2806.     protected function onAfterHit(&$table)
  2807.     {
  2808.         // Call the behaviors
  2809.         $result $this->modelDispatcher->trigger('onAfterHit'array(&$this));
  2810.  
  2811.         if (in_array(false$resulttrue))
  2812.         {
  2813.             // Behavior failed, return false
  2814.             return false;
  2815.         }
  2816.  
  2817.         return true;
  2818.     }
  2819.  
  2820.     /**
  2821.      * This method runs before a record is moved
  2822.      *
  2823.      * @param   FOFTable  &$table  The table instance of the record being moved
  2824.      *
  2825.      * @return  boolean  True to allow the operation
  2826.      */
  2827.     protected function onBeforeMove(&$table)
  2828.     {
  2829.         // Call the behaviors
  2830.         $result $this->modelDispatcher->trigger('onBeforeMove'array(&$this));
  2831.  
  2832.         if (in_array(false$resulttrue))
  2833.         {
  2834.             // Behavior failed, return false
  2835.             return false;
  2836.         }
  2837.  
  2838.         return true;
  2839.     }
  2840.  
  2841.     /**
  2842.      * This method runs after a record has been moved
  2843.      *
  2844.      * @param   FOFTable  &$table  The table instance of the record which was moved
  2845.      *
  2846.      * @return  boolean  True to allow the operation
  2847.      */
  2848.     protected function onAfterMove(&$table)
  2849.     {
  2850.         // Call the behaviors
  2851.         $result $this->modelDispatcher->trigger('onAfterMove'array(&$this));
  2852.  
  2853.         if (in_array(false$resulttrue))
  2854.         {
  2855.             // Behavior failed, return false
  2856.             return false;
  2857.         }
  2858.  
  2859.         return true;
  2860.     }
  2861.  
  2862.     /**
  2863.      * This method runs before a table is reordered
  2864.      *
  2865.      * @param   FOFTable  &$table  The table instance being reordered
  2866.      *
  2867.      * @return  boolean  True to allow the operation
  2868.      */
  2869.     protected function onBeforeReorder(&$table)
  2870.     {
  2871.         // Call the behaviors
  2872.         $result $this->modelDispatcher->trigger('onBeforeReorder'array(&$this));
  2873.  
  2874.         if (in_array(false$resulttrue))
  2875.         {
  2876.             // Behavior failed, return false
  2877.             return false;
  2878.         }
  2879.  
  2880.         return true;
  2881.     }
  2882.  
  2883.     /**
  2884.      * This method runs after a table is reordered
  2885.      *
  2886.      * @param   FOFTable  &$table  The table instance which was reordered
  2887.      *
  2888.      * @return  boolean  True to allow the operation
  2889.      */
  2890.     protected function onAfterReorder(&$table)
  2891.     {
  2892.         // Call the behaviors
  2893.         $result $this->modelDispatcher->trigger('onAfterReorder'array(&$this));
  2894.  
  2895.         if (in_array(false$resulttrue))
  2896.         {
  2897.             // Behavior failed, return false
  2898.             return false;
  2899.         }
  2900.  
  2901.         return true;
  2902.     }
  2903.  
  2904.     /**
  2905.      * Method to get the database driver object
  2906.      *
  2907.      * @return  JDatabaseDriver 
  2908.      */
  2909.     public function getDbo()
  2910.     {
  2911.         return $this->_db;
  2912.     }
  2913.  
  2914.     /**
  2915.      * Method to get the model name
  2916.      *
  2917.      * The model name. By default parsed using the classname or it can be set
  2918.      * by passing a $config['name'] in the class constructor
  2919.      *
  2920.      * @return  string  The name of the model
  2921.      *
  2922.      * @throws  Exception
  2923.      */
  2924.     public function getName()
  2925.     {
  2926.         if (empty($this->name))
  2927.         {
  2928.             $r null;
  2929.  
  2930.             if (!preg_match('/Model(.*)/i'get_class($this)$r))
  2931.             {
  2932.                 throw new Exception(JText::_('JLIB_APPLICATION_ERROR_MODEL_GET_NAME')500);
  2933.             }
  2934.  
  2935.             $this->name = strtolower($r[1]);
  2936.         }
  2937.  
  2938.         return $this->name;
  2939.     }
  2940.  
  2941.     /**
  2942.      * Method to set the database driver object
  2943.      *
  2944.      * @param   JDatabaseDriver  $db  A JDatabaseDriver based object
  2945.      *
  2946.      * @return  void 
  2947.      */
  2948.     public function setDbo($db)
  2949.     {
  2950.         $this->_db = $db;
  2951.     }
  2952.  
  2953.     /**
  2954.      * Method to set model state variables
  2955.      *
  2956.      * @param   string  $property  The name of the property.
  2957.      * @param   mixed   $value     The value of the property to set or null.
  2958.      *
  2959.      * @return  mixed  The previous value of the property or null if not set.
  2960.      */
  2961.     public function setState($property$value null)
  2962.     {
  2963.         return $this->state->set($property$value);
  2964.     }
  2965.  
  2966.     /**
  2967.      * Clean the cache
  2968.      *
  2969.      * @param   string   $group      The cache group
  2970.      * @param   integer  $client_id  The ID of the client
  2971.      *
  2972.      * @return  void 
  2973.      */
  2974.     protected function cleanCache($group null$client_id 0)
  2975.     {
  2976.         $conf JFactory::getConfig();
  2977.  
  2978.         $options array(
  2979.             'defaultgroup' => ($group$group (isset($this->option$this->option : JFactory::getApplication()->input->get('option')),
  2980.             'cachebase' => ($client_idJPATH_ADMINISTRATOR '/cache' $conf->get('cache_path'JPATH_SITE '/cache'));
  2981.  
  2982.         $cache JCache::getInstance('callback'$options);
  2983.         $cache->clean();
  2984.  
  2985.         // Trigger the onContentCleanCache event.
  2986.         FOFPlatform::getInstance()->runPlugins($this->event_clean_cache$options);
  2987.     }
  2988. }

Documentation generated on Tue, 19 Nov 2013 15:08:34 +0100 by phpDocumentor 1.4.3