| [ Index ] |
PHP Cross Reference of Joomla 1.5.26 DE |
[Summary view] [Print] [Text view]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Wed Mar 28 15:54:07 2012 | Cross-referenced by PHPXref 0.7.1 |