Support Joomla!

Joomla! 1.5 Documentation

Packages

Package: Joomla-Framework

Developer Network License

The Joomla! Developer Network content is © copyright 2006 by the individual contributors and can be used in accordance with the Creative Commons License, Attribution- NonCommercial- ShareAlike 2.5
Source code for file /joomla/application/component/controller.php

Documentation is available at controller.php

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

Documentation generated on Mon, 05 Mar 2007 20:55:43 +0000 by phpDocumentor 1.3.1