Support Joomla!

Packages

Package: Joomla-Framework

License

Content on this site is copyright © 2005 - 2008 Open Source Matters Inc and can be used in accordance with the Joomla! Electronic Documentation License. Some parts of this website may be subject to other licenses.
Source code for file /joomla/application/component/controller.php

Documentation is available at controller.php

  1. <?php
  2. /**
  3. @version        $Id: controller.php 10910 2008-09-05 19:41:09Z willebil $
  4. @package        Joomla.Framework
  5. @subpackage    Application
  6. @copyright    Copyright (C) 2005 - 2008 Open Source Matters. All rights reserved.
  7. @license        GNU/GPL, see LICENSE.php
  8. *  Joomla! is free software. This version may have been modified pursuant
  9. *  to the GNU General Public License, and as distributed it includes or
  10. *  is derivative of works licensed under the GNU General Public License or
  11. *  other free or open source software licenses.
  12. *  See COPYRIGHT.php for copyright notices and details.
  13. */
  14.  
  15. // Check to ensure this file is within the rest of the framework
  16. defined('JPATH_BASE'or die();
  17.  
  18. /**
  19.  * Base class for a Joomla Controller
  20.  *
  21.  * Controller (controllers are where you put all the actual code) Provides basic
  22.  * functionality, such as rendering views (aka displaying templates).
  23.  *
  24.  * @abstract
  25.  * @package        Joomla.Framework
  26.  * @subpackage    Application
  27.  * @since        1.5
  28.  */
  29. class JController extends JObject
  30. {
  31.     /**
  32.      * The base path of the controller
  33.      *
  34.      * @var        string 
  35.      * @access     protected
  36.      */
  37.     var $_basePath = null;
  38.  
  39.     /**
  40.      * The name of the controller
  41.      *
  42.      * @var        array 
  43.      * @access    protected
  44.      */
  45.     var $_name = null;
  46.  
  47.     /**
  48.      * Array of class methods
  49.      *
  50.      * @var    array 
  51.      * @access    protected
  52.      */
  53.     var $_methods     = null;
  54.  
  55.     /**
  56.      * Array of class methods to call for a given task.
  57.      *
  58.      * @var    array 
  59.      * @access    protected
  60.      */
  61.     var $_taskMap     = null;
  62.  
  63.     /**
  64.      * Current or most recent task to be performed.
  65.      *
  66.      * @var    string 
  67.      * @access    protected
  68.      */
  69.     var $_task         = null;
  70.  
  71.     /**
  72.      * The mapped task that was performed.
  73.      *
  74.      * @var    string 
  75.      * @access    protected
  76.      */
  77.     var $_doTask     = null;
  78.  
  79.     /**
  80.      * The set of search directories for resources (views).
  81.      *
  82.      * @var array 
  83.      * @access    protected
  84.      */
  85.     var $_path = array(
  86.         'view'    => array()
  87.     );
  88.  
  89.     /**
  90.      * URL for redirection.
  91.      *
  92.      * @var    string 
  93.      * @access    protected
  94.      */
  95.     var $_redirect     = null;
  96.  
  97.     /**
  98.      * Redirect message.
  99.      *
  100.      * @var    string 
  101.      * @access    protected
  102.      */
  103.     var $_message     = null;
  104.  
  105.     /**
  106.      * Redirect message type.
  107.      *
  108.      * @var    string 
  109.      * @access    protected
  110.      */
  111.     var $_messageType     = null;
  112.  
  113.     /**
  114.      * ACO Section for the controller.
  115.      *
  116.      * @var    string 
  117.      * @access    protected
  118.      */
  119.     var $_acoSection         = null;
  120.  
  121.     /**
  122.      * Default ACO Section value for the controller.
  123.      *
  124.      * @var    string 
  125.      * @access    protected
  126.      */
  127.     var $_acoSectionValue     = null;
  128.  
  129.     /**
  130.      * Constructor.
  131.      *
  132.      * @access    protected
  133.      * @param    array An optional associative array of configuration settings.
  134.      *  Recognized key values include 'name', 'default_task', 'model_path', and
  135.      *  'view_path' (this list is not meant to be comprehensive).
  136.      * @since    1.5
  137.      */
  138.     function __construct$config array() )
  139.     {
  140.         //Initialize private variables
  141.         $this->_redirect    = null;
  142.         $this->_message        = null;
  143.         $this->_messageType = 'message';
  144.         $this->_taskMap        = array();
  145.         $this->_methods        = array();
  146.         $this->_data        array();
  147.  
  148.         // Get the methods only for the final controller class
  149.         $thisMethods    get_class_methodsget_class$this ) );
  150.         $baseMethods    get_class_methods'JController' );
  151.         $methods        array_diff$thisMethods$baseMethods );
  152.  
  153.         // Add default display method
  154.         $methods['display';
  155.  
  156.         // Iterate through methods and map tasks
  157.         foreach $methods as $method )
  158.         {
  159.             if substr$method0!= '_' {
  160.                 $this->_methods[strtolower$method );
  161.                 // auto register public methods as tasks
  162.                 $this->_taskMap[strtolower$method )$method;
  163.             }
  164.         }
  165.  
  166.         //set the view name
  167.         if (empty$this->_name ))
  168.         {
  169.             if (array_key_exists('name'$config))  {
  170.                 $this->_name = $config['name'];
  171.             else {
  172.                 $this->_name = $this->getName();
  173.             }
  174.         }
  175.  
  176.         // Set a base path for use by the controller
  177.         if (array_key_exists('base_path'$config)) {
  178.             $this->_basePath    = $config['base_path'];
  179.         else {
  180.             $this->_basePath    = JPATH_COMPONENT;
  181.         }
  182.  
  183.         // If the default task is set, register it as such
  184.         if array_key_exists'default_task'$config ) ) {
  185.             $this->registerDefaultTask$config['default_task');
  186.         else {
  187.             $this->registerDefaultTask'display' );
  188.         }
  189.  
  190.         // set the default model search path
  191.         if array_key_exists'model_path'$config ) ) {
  192.             // user-defined dirs
  193.             $this->addModelPath($config['model_path']);
  194.         else {
  195.             $this->addModelPath($this->_basePath.DS.'models');
  196.         }
  197.  
  198.         // set the default view search path
  199.         if array_key_exists'view_path'$config ) ) {
  200.             // user-defined dirs
  201.             $this->_setPath'view'$config['view_path');
  202.         else {
  203.             $this->_setPath'view'$this->_basePath.DS.'views' );
  204.         }
  205.     }
  206.  
  207.     /**
  208.      * Execute a task by triggering a method in the derived class.
  209.      *
  210.      * @access    public
  211.      * @param    string The task to perform. If no matching task is found, the
  212.      *  '__default' task is executed, if defined.
  213.      * @return    mixed|falseThe value returned by the called method, false in
  214.      *  error case.
  215.      * @since    1.5
  216.      */
  217.     function execute$task )
  218.     {
  219.         $this->_task = $task;
  220.  
  221.         $task strtolower$task );
  222.         if (isset$this->_taskMap[$task)) {
  223.             $doTask $this->_taskMap[$task];
  224.         elseif (isset$this->_taskMap['__default')) {
  225.             $doTask $this->_taskMap['__default'];
  226.         else {
  227.             return JError::raiseError404JText::_('Task ['.$task.'] not found') );
  228.         }
  229.  
  230.         // Record the actual task being fired
  231.         $this->_doTask = $doTask;
  232.  
  233.         // Make sure we have access
  234.         if ($this->authorize$doTask ))
  235.         {
  236.             $retval $this->$doTask();
  237.             return $retval;
  238.         }
  239.         else
  240.         {
  241.             return JError::raiseError403JText::_('Access Forbidden') );
  242.         }
  243.  
  244.     }
  245.  
  246.     /**
  247.      * Authorization check
  248.      *
  249.      * @access    public
  250.      * @param    string    $task    The ACO Section Value to check access on
  251.      * @return    boolean    True if authorized
  252.      * @since    1.5
  253.      */
  254.     function authorize$task )
  255.     {
  256.         // Only do access check if the aco section is set
  257.         if ($this->_acoSection)
  258.         {
  259.             // If we have a section value set that trumps the passed task ???
  260.             if ($this->_acoSectionValue{
  261.                 // We have one, so set it and lets do the check
  262.                 $task $this->_acoSectionValue;
  263.             }
  264.             // Get the JUser object for the current user and return the authorization boolean
  265.             $user JFactory::getUser();
  266.             return $user->authorize$this->_acoSection$task );
  267.         }
  268.         else
  269.         {
  270.             // Nothing set, nothing to check... so obviously its ok :)
  271.             return true;
  272.         }
  273.     }
  274.  
  275.     /**
  276.      * Typical view method for MVC based architecture
  277.      *
  278.      * This function is provide as a default implementation, in most cases
  279.      * you will need to override it in your own controllers.
  280.      *
  281.      * @access    public
  282.      * @param    string    $cachable    If true, the view output will be cached
  283.      * @since    1.5
  284.      */
  285.     function display($cachable=false)
  286.     {
  287.         $document =JFactory::getDocument();
  288.  
  289.         $viewType    $document->getType();
  290.         $viewName    JRequest::getCmd'view'$this->getName() );
  291.         $viewLayout    JRequest::getCmd'layout''default' );
  292.  
  293.         $view $this->getView$viewName$viewType''array'base_path'=>$this->_basePath));
  294.  
  295.         // Get/Create the model
  296.         if ($model $this->getModel($viewName)) {
  297.             // Push the model into the view (as default)
  298.             $view->setModel($modeltrue);
  299.         }
  300.  
  301.         // Set the layout
  302.         $view->setLayout($viewLayout);
  303.  
  304.         // Display the view
  305.         if ($cachable && $viewType != 'feed'{
  306.             global $option;
  307.             $cache =JFactory::getCache($option'view');
  308.             $cache->get($view'display');
  309.         else {
  310.             $view->display();
  311.         }
  312.     }
  313.  
  314.     /**
  315.      * Redirects the browser or returns false if no redirect is set.
  316.      *
  317.      * @access    public
  318.      * @return    boolean    False if no redirect exists.
  319.      * @since    1.5
  320.      */
  321.     function redirect()
  322.     {
  323.         if ($this->_redirect{
  324.             global $mainframe;
  325.             $mainframe->redirect$this->_redirect$this->_message$this->_messageType );
  326.         }
  327.         return false;
  328.     }
  329.  
  330.     /**
  331.      * Method to get a model object, loading it if required.
  332.      *
  333.      * @access    public
  334.      * @param    string    The model name. Optional.
  335.      * @param    string    The class prefix. Optional.
  336.      * @param    array    Configuration array for model. Optional.
  337.      * @return    object    The model.
  338.      * @since    1.5
  339.      */
  340.     function &getModel$name ''$prefix ''$config array() )
  341.     {
  342.         if empty$name ) ) {
  343.             $name $this->getName();
  344.         }
  345.  
  346.         if empty$prefix ) ) {
  347.             $prefix $this->getName('Model';
  348.         }
  349.  
  350.         if $model $this->_createModel$name$prefix$config ) )
  351.         {
  352.             // task is a reserved state
  353.             $model->setState'task'$this->_task );
  354.  
  355.             // Lets get the application object and set menu information if its available
  356.             $app    &JFactory::getApplication();
  357.             $menu    &$app->getMenu();
  358.             if (is_object$menu ))
  359.             {
  360.                 if ($item $menu->getActive())
  361.                 {
  362.                     $params    =$menu->getParams($item->id);
  363.                     // Set Default State Data
  364.                     $model->setState'parameters.menu'$params );
  365.                 }
  366.             }
  367.         }
  368.         return $model;
  369.     }
  370.  
  371.     /**
  372.      * Adds to the stack of model paths in LIFO order.
  373.      *
  374.      * @static
  375.      * @param    string|arrayThe directory (string), or list of directories
  376.      *                        (array) to add.
  377.      * @return    void 
  378.      */
  379.     function addModelPath$path )
  380.     {
  381.         jimport('joomla.application.component.model');
  382.         JModel::addIncludePath($path);
  383.     }
  384.  
  385.     /**
  386.      * Gets the available tasks in the controller.
  387.      * @access    public
  388.      * @return    array Array[i] of task names.
  389.      * @since    1.5
  390.      */
  391.     function getTasks()
  392.     {
  393.         return $this->_methods;
  394.     }
  395.  
  396.     /**
  397.      * Get the last task that is or was to be performed.
  398.      *
  399.      * @access    public
  400.      * @return     string The task that was or is being performed.
  401.      * @since    1.5
  402.      */
  403.     function getTask()
  404.     {
  405.         return $this->_task;
  406.     }
  407.  
  408.     /**
  409.      * Method to get the controller name
  410.      *
  411.      * The dispatcher name by default parsed using the classname, or it can be set
  412.      * by passing a $config['name'] in the class constructor
  413.      *
  414.      * @access    public
  415.      * @return    string The name of the dispatcher
  416.      * @since    1.5
  417.      */
  418.     function getName()
  419.     {
  420.         $name $this->_name;
  421.  
  422.         if (empty$name ))
  423.         {
  424.             $r null;
  425.             if !preg_match'/(.*)Controller/i'get_class$this )$r ) ) {
  426.                 JError::raiseError(500"JController::getName() : Cannot get or parse class name.");
  427.             }
  428.             $name strtolower$r[1);
  429.         }
  430.  
  431.         return $name;
  432.     }
  433.  
  434.     /**
  435.      * Method to get a reference to the current view and load it if necessary.
  436.      *
  437.      * @access    public
  438.      * @param    string    The view name. Optional, defaults to the controller
  439.      *  name.
  440.      * @param    string    The view type. Optional.
  441.      * @param    string    The class prefix. Optional.
  442.      * @param    array    Configuration array for view. Optional.
  443.      * @return    object    Reference to the view or an error.
  444.      * @since    1.5
  445.      */
  446.     function &getView$name ''$type ''$prefix ''$config array() )
  447.     {
  448.         static $views;
  449.  
  450.         if !isset$views ) ) {
  451.             $views array();
  452.         }
  453.  
  454.         if empty$name ) ) {
  455.             $name $this->getName();
  456.         }
  457.  
  458.         if empty$prefix ) ) {
  459.             $prefix $this->getName('View';
  460.         }
  461.  
  462.         if empty$views[$name) )
  463.         {
  464.             if $view $this->_createView$name$prefix$type$config ) ) {
  465.                 $views[$name$view;
  466.             else {
  467.                 $result JError::raiseError(
  468.                     500JText::_'View not found [name, type, prefix]:' )
  469.                         . ' ' $name ',' $type ',' $prefix
  470.                 );
  471.                 return $result;
  472.             }
  473.         }
  474.  
  475.         return $views[$name];
  476.     }
  477.  
  478.     /**
  479.      * Add one or more view paths to the controller's stack, in LIFO order.
  480.      *
  481.      * @static
  482.      * @param    string|arrayThe directory (string), or list of directories
  483.      *  (array) to add.
  484.      * @return    void 
  485.      */
  486.     function addViewPath$path )
  487.     {
  488.         $this->_addPath'view'$path );
  489.     }
  490.  
  491.     /**
  492.      * Register (map) a task to a method in the class.
  493.      *
  494.      * @access    public
  495.      * @param    string    The task.
  496.      * @param    string    The name of the method in the derived class to perform
  497.      *                   for this task.
  498.      * @return    void 
  499.      * @since    1.5
  500.      */
  501.     function registerTask$task$method )
  502.     {
  503.         if in_arraystrtolower$method )$this->_methods ) ) {
  504.             $this->_taskMap[strtolower$task )$method;
  505.         }
  506.     }
  507.  
  508.     /**
  509.      * Register the default task to perform if a mapping is not found.
  510.      *
  511.      * @access    public
  512.      * @param    string The name of the method in the derived class to perform if
  513.      *  a named task is not found.
  514.      * @return    void 
  515.      * @since    1.5
  516.      */
  517.     function registerDefaultTask$method )
  518.     {
  519.         $this->registerTask'__default'$method );
  520.     }
  521.  
  522.     /**
  523.      * Sets the internal message that is passed with a redirect
  524.      *
  525.      * @access    public
  526.      * @param    string    The message
  527.      * @return    string    Previous message
  528.      * @since    1.5
  529.      */
  530.     function setMessage$text )
  531.     {
  532.         $previous        $this->_message;
  533.         $this->_message = $text;
  534.         return $previous;
  535.     }
  536.  
  537.     /**
  538.      * Set a URL for browser redirection.
  539.      *
  540.      * @access    public
  541.      * @param    string URL to redirect to.
  542.      * @param    string    Message to display on redirect. Optional, defaults to
  543.      *              value set internally by controller, if any.
  544.      * @param    string    Message type. Optional, defaults to 'message'.
  545.      * @return    void 
  546.      * @since    1.5
  547.      */
  548.     function setRedirect$url$msg null$type 'message' )
  549.     {
  550.         $this->_redirect = $url;
  551.         if ($msg !== null{
  552.             // controller may have set this directly
  553.             $this->_message    = $msg;
  554.         }
  555.         $this->_messageType    = $type;
  556.     }
  557.  
  558.     /**
  559.      * Sets the access control levels.
  560.      *
  561.      * @access    public
  562.      * @param    string The ACO section (eg, the component).
  563.      * @param    string The ACO section value (if using a constant value).
  564.      * @return    void 
  565.      * @since    1.5
  566.      */
  567.     function setAccessControl$section$value null )
  568.     {
  569.         $this->_acoSection = $section;
  570.         $this->_acoSectionValue = $value;
  571.     }
  572.  
  573.     /**
  574.      * Method to load and return a model object.
  575.      *
  576.      * @access    private
  577.      * @param    string  The name of the model.
  578.      * @param    string    Optional model prefix.
  579.      * @param    array    Configuration array for the model. Optional.
  580.      * @return    mixed    Model object on success; otherwise null
  581.      *  failure.
  582.      * @since    1.5
  583.      */
  584.     function &_createModel$name$prefix ''$config array())
  585.     {
  586.         $result null;
  587.  
  588.         // Clean the model name
  589.         $modelName     preg_replace'/[^A-Z0-9_]/i'''$name );
  590.         $classPrefix preg_replace'/[^A-Z0-9_]/i'''$prefix );
  591.  
  592.         $result =JModel::getInstance($modelName$classPrefix$config);
  593.         return $result;
  594.     }
  595.  
  596.     /**
  597.      * Method to load and return a view object. This method first looks in the
  598.      * current template directory for a match, and failing that uses a default
  599.      * set path to load the view class file.
  600.      *
  601.      * Note the "name, prefix, type" order of parameters, which differs from the
  602.      * "name, type, prefix" order used in related public methods.
  603.      *
  604.      * @access    private
  605.      * @param    string    The name of the view.
  606.      * @param    string    Optional prefix for the view class name.
  607.      * @param    string    The type of view.
  608.      * @param    array    Configuration array for the view. Optional.
  609.      * @return    mixed    View object on success; null or error result on failure.
  610.      * @since    1.5
  611.      */
  612.     function &_createView$name$prefix ''$type ''$config array() )
  613.     {
  614.         $result null;
  615.  
  616.         // Clean the view name
  617.         $viewName     preg_replace'/[^A-Z0-9_]/i'''$name );
  618.         $classPrefix preg_replace'/[^A-Z0-9_]/i'''$prefix );
  619.         $viewType     preg_replace'/[^A-Z0-9_]/i'''$type );
  620.  
  621.         // Build the view class name
  622.         $viewClass $classPrefix $viewName;
  623.  
  624.         if !class_exists$viewClass ) )
  625.         {
  626.             jimport'joomla.filesystem.path' );
  627.             $path JPath::find(
  628.                 $this->_path['view'],
  629.                 $this->_createFileName'view'array'name' => $viewName'type' => $viewType) )
  630.             );
  631.             if ($path{
  632.                 require_once $path;
  633.  
  634.                 if !class_exists$viewClass ) ) {
  635.                     $result JError::raiseError(
  636.                         500JText::_'View class not found [class, file]:' )
  637.                         . ' ' $viewClass ', ' $path );
  638.                     return $result;
  639.                 }
  640.             else {
  641.                 return $result;
  642.             }
  643.         }
  644.  
  645.         $result new $viewClass($config);
  646.         return $result;
  647.     }
  648.  
  649.     /**
  650.     * Sets an entire array of search paths for resources.
  651.     *
  652.     * @access    protected
  653.     * @param    string    The type of path to set, typically 'view' or 'model'.
  654.     * @param    string|array   The new set of search paths. If null or false,
  655.     *  resets to the current directory only.
  656.     */
  657.     function _setPath$type$path )
  658.     {
  659.         // clear out the prior search dirs
  660.         $this->_path[$typearray();
  661.  
  662.         // actually add the user-specified directories
  663.         $this->_addPath$type$path );
  664.     }
  665.  
  666.     /**
  667.     * Adds to the search path for templates and resources.
  668.     *
  669.     * @access    protected
  670.     * @param    string The path type (e.g. 'model', 'view'.
  671.     * @param    string|arrayThe directory or stream to search.
  672.     * @return    void 
  673.     */
  674.     function _addPath$type$path )
  675.     {
  676.         // just force path to array
  677.         settype$path'array' );
  678.  
  679.         // loop through the path directories
  680.         foreach $path as $dir )
  681.         {
  682.             // no surrounding spaces allowed!
  683.             $dir trim$dir );
  684.  
  685.             // add trailing separators as needed
  686.             if substr$dir-!= DIRECTORY_SEPARATOR {
  687.                 // directory
  688.                 $dir .= DIRECTORY_SEPARATOR;
  689.             }
  690.  
  691.             // add to the top of the search dirs
  692.             array_unshift$this->_path[$type]$dir );
  693.         }
  694.     }
  695.  
  696.     /**
  697.      * Create the filename for a resource.
  698.      *
  699.      * @access    private
  700.      * @param    string    The resource type to create the filename for.
  701.      * @param    array    An associative array of filename information. Optional.
  702.      * @return    string    The filename.
  703.      * @since    1.5
  704.      */
  705.     function _createFileName$type$parts array() )
  706.     {
  707.         $filename '';
  708.  
  709.         switch $type )
  710.         {
  711.             case 'view':
  712.                 if !empty$parts['type') ) {
  713.                     $parts['type''.'.$parts['type'];
  714.                 }
  715.  
  716.                 $filename strtolower($parts['name']).DS.'view'.$parts['type'].'.php';
  717.             break;
  718.         }
  719.         return $filename;
  720.     }
  721. }

Documentation generated on Sat, 14 Nov 2009 11:11:55 +0000 by phpDocumentor 1.3.1