[ Index ]

PHP Cross Reference of Joomla 1.5.26 DE

title

Body

[close]

/libraries/joomla/application/component/ -> controller.php (source)

   1  <?php
   2  /**
   3  * @version        $Id: controller.php 14401 2010-01-26 14:10:00Z louis $
   4  * @package        Joomla.Framework
   5  * @subpackage    Application
   6  * @copyright    Copyright (C) 2005 - 2010 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_methods( get_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( $method, 0, 1 ) != '_' ) {
 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|false The 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::raiseError( 404, JText::_('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::raiseError( 403, JText::_('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($model, true);
 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|array The 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                      500, JText::_( '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|array The 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_array( strtolower( $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                          500, JText::_( '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[$type] = array();
 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|array The 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, -1 ) != 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  }


Generated: Wed Mar 28 15:54:07 2012 Cross-referenced by PHPXref 0.7.1