[ Index ] |
|
Code source de CakePHP 1.1.13.4450 |
1 <?php 2 /* SVN FILE: $Id: view.php 4409 2007-02-02 13:20:59Z phpnut $ */ 3 /** 4 * Methods for displaying presentation data in the view. 5 * 6 * PHP versions 4 and 5 7 * 8 * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/> 9 * Copyright 2005-2007, Cake Software Foundation, Inc. 10 * 1785 E. Sahara Avenue, Suite 490-204 11 * Las Vegas, Nevada 89104 12 * 13 * Licensed under The MIT License 14 * Redistributions of files must retain the above copyright notice. 15 * 16 * @filesource 17 * @copyright Copyright 2005-2007, Cake Software Foundation, Inc. 18 * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project 19 * @package cake 20 * @subpackage cake.cake.libs.view 21 * @since CakePHP(tm) v 0.10.0.1076 22 * @version $Revision: 4409 $ 23 * @modifiedby $LastChangedBy: phpnut $ 24 * @lastmodified $Date: 2007-02-02 07:20:59 -0600 (Fri, 02 Feb 2007) $ 25 * @license http://www.opensource.org/licenses/mit-license.php The MIT License 26 */ 27 /** 28 * Included libraries. 29 */ 30 uses (DS . 'view' . DS . 'helper'); 31 /** 32 * View, the V in the MVC triad. 33 * 34 * Class holding methods for displaying presentation data. 35 * 36 * @package cake 37 * @subpackage cake.cake.libs.view 38 */ 39 class View extends Object{ 40 /** 41 * Name of the controller. 42 * 43 * @var string Name of controller 44 * @access public 45 */ 46 var $name = null; 47 /** 48 * Stores the current URL (for links etc.) 49 * 50 * @var string Current URL 51 * @access public 52 */ 53 var $here = null; 54 /** 55 * Action to be performed. 56 * 57 * @var string Name of action 58 * @access public 59 */ 60 var $action = null; 61 /** 62 * An array of names of built-in helpers to include. 63 * 64 * @var mixed A single name as a string or a list of names as an array. 65 * @access public 66 */ 67 var $helpers = array('Html'); 68 /** 69 * Path to View. 70 * 71 * @var string Path to View 72 * @access public 73 */ 74 var $viewPath; 75 /** 76 * Replaced with public var viewVars 77 * @access protected 78 * @deprecated 79 */ 80 var $_viewVars = array(); 81 /** 82 * Variables for the view 83 * 84 * @var array 85 * @access public 86 */ 87 var $viewVars = array(); 88 /** 89 * Title HTML element of this View. 90 * 91 * @var boolean 92 * @access public 93 */ 94 var $pageTitle = false; 95 /** 96 * Path parts for creating links in views. 97 * 98 * @var string Base URL 99 * @access public 100 */ 101 var $base = null; 102 /** 103 * Name of layout to use with this View. 104 * 105 * @var string 106 * @access public 107 */ 108 var $layout = 'default'; 109 /** 110 * Turns on or off Cake's conventional mode of rendering views. On by default. 111 * 112 * @var boolean 113 * @access public 114 */ 115 var $autoRender = true; 116 /** 117 * Turns on or off Cake's conventional mode of finding layout files. On by default. 118 * 119 * @var boolean 120 * @access public 121 */ 122 var $autoLayout = true; 123 /** 124 * Array of parameter data 125 * 126 * @var array Parameter data 127 * @access public 128 */ 129 var $params; 130 /** 131 * True when the view has been rendered. 132 * 133 * @var boolean 134 * @access protected 135 */ 136 var $_hasRendered = null; 137 /** 138 * @deprecated will not be avialable after 1.1.x.x 139 */ 140 var $controller = null; 141 /** 142 * Array of loaded view helpers. 143 * 144 * @var array 145 * @access public 146 */ 147 var $loaded = array(); 148 /** 149 * File extension. Defaults to Cake's conventional ".thtml". 150 * 151 * @var array 152 * @access public 153 */ 154 var $ext = '.thtml'; 155 /** 156 * Sub-directory for this view file. 157 * 158 * @var string 159 * @access public 160 */ 161 var $subDir = null; 162 /** 163 * The directory where theme web accessible content is stored 164 * 165 * @var array 166 * @access public 167 */ 168 var $themeWeb = null; 169 /** 170 * Plugin name. A Plugin is a sub-application. 171 * This is used to set the correct paths for views 172 * 173 * @var string 174 * @access public 175 */ 176 var $plugin = null; 177 /** 178 /** 179 * List of variables to collect from the associated controller 180 * 181 * @var array 182 * @access protected 183 */ 184 var $_passedVars = array('viewVars', 'action', 'autoLayout', 'autoRender', 'ext', 'base', 'webroot', 'helpers', 'here', 'layout', 'modelNames', 'name', 'pageTitle', 'viewPath', 'params', 'data', 'webservices', 'plugin'); 185 /** 186 * Constructor 187 * 188 * Instance is created in Controller::render() and is never called directly 189 * 190 * @var object instance of the calling controller 191 */ 192 function __construct(&$controller) { 193 if(is_object($controller)) { 194 $this->controller =& $controller; 195 $c = count($this->_passedVars); 196 197 for ($j = 0; $j < $c; $j++) { 198 $var = $this->_passedVars[$j]; 199 $this->{$var} = $controller->{$var}; 200 } 201 $this->_viewVars =& $this->viewVars; 202 } 203 parent::__construct(); 204 } 205 /** 206 * Renders view for given action and layout. If $file is given, that is used 207 * for a view filename (e.g. customFunkyView.thtml). 208 * 209 * @param string $action Name of action to render for 210 * @param string $layout Layout to use 211 * @param string $file Custom filename for view 212 * @return mixed returns an error if View::render() fails to find a related template. 213 * boolean on successful render 214 * @access public 215 */ 216 function render($action = null, $layout = null, $file = null) { 217 218 if (isset($this->_hasRendered) && $this->_hasRendered) { 219 return true; 220 } else { 221 $this->_hasRendered = false; 222 } 223 224 if (!$action) { 225 $action = $this->action; 226 } 227 228 if ($layout) { 229 $this->setLayout($layout); 230 } 231 232 if ($file) { 233 $viewFileName = $file; 234 } else { 235 $viewFileName = $this->_getViewFileName($action); 236 } 237 238 if (!is_null($this->plugin) && is_null($file)) { 239 return $this->pluginView($action, $layout); 240 } 241 242 if (!is_file($viewFileName) && !fileExistsInPath($viewFileName) || $viewFileName === '/' || $viewFileName === '\\') { 243 if (strpos($action, 'missingAction') !== false) { 244 $errorAction = 'missingAction'; 245 } else { 246 $errorAction = 'missingView'; 247 } 248 249 foreach(array($this->name, 'errors') as $viewDir) { 250 $errorAction = Inflector::underscore($errorAction); 251 252 if (file_exists(VIEWS . $viewDir . DS . $errorAction . $this->ext)) { 253 $missingViewFileName = VIEWS . $viewDir . DS . $errorAction . $this->ext; 254 } elseif($missingViewFileName = fileExistsInPath(LIBS . 'view' . DS . 'templates' . DS . $viewDir . DS . $errorAction . '.thtml')) { 255 } else { 256 $missingViewFileName = false; 257 } 258 259 $missingViewExists = is_file($missingViewFileName); 260 261 if ($missingViewExists) { 262 break; 263 } 264 } 265 266 if (strpos($action, 'missingView') === false) { 267 return $this->cakeError('missingView', array(array('className' => $this->controller->name, 268 'action' => $action, 269 'file' => $viewFileName, 270 'base' => $this->base))); 271 272 $isFatal = isset($this->isFatal) ? $this->isFatal : false; 273 274 if (!$isFatal) { 275 $viewFileName = $missingViewFileName; 276 } 277 } else { 278 $missingViewExists = false; 279 } 280 281 if (!$missingViewExists || $isFatal) { 282 if (Configure::read() > 0) { 283 trigger_error(sprintf("No template file for view %s (expected %s), create it first'", $action, $viewFileName), E_USER_ERROR); 284 } else { 285 $this->error('404', 'Not found', sprintf("The requested address %s was not found on this server.", '', "missing view \"{$action}\"")); 286 } 287 die(); 288 } 289 } 290 291 if ($viewFileName && !$this->_hasRendered) { 292 if (substr($viewFileName, -5) === 'thtml') { 293 $out = View::_render($viewFileName, $this->viewVars); 294 } else { 295 $out = $this->_render($viewFileName, $this->viewVars); 296 } 297 298 if ($out !== false) { 299 if ($this->layout && $this->autoLayout) { 300 $out = $this->renderLayout($out); 301 if (isset($this->loaded['cache']) && ((isset($this->controller) && $this->controller->cacheAction != false)) && (defined('CACHE_CHECK') && CACHE_CHECK === true)) { 302 $replace = array('<cake:nocache>', '</cake:nocache>'); 303 $out = str_replace($replace, '', $out); 304 } 305 } 306 307 print $out; 308 $this->_hasRendered = true; 309 } else { 310 $out = $this->_render($viewFileName, $this->viewVars); 311 trigger_error(sprintf("Error in view %s, got: <blockquote>%s</blockquote>", $viewFileName, $out), E_USER_ERROR); 312 } 313 return true; 314 } 315 } 316 /** 317 * Renders a piece of PHP with provided parameters and returns HTML, XML, or any other string. 318 * 319 * This realizes the concept of Elements, (or "partial layouts") 320 * and the $params array is used to send data to be used in the Element. 321 * 322 * @param string $name Name of template file in the/app/views/elements/ folder 323 * @param array $params Array of data to be made available to the for rendered view (i.e. the Element) 324 * @return string Rendered output 325 * @access public 326 */ 327 function renderElement($name, $params = array()) { 328 $params = array_merge_recursive($params, $this->loaded); 329 330 if(isset($params['plugin'])) { 331 $this->plugin = $params['plugin']; 332 } 333 334 if (!is_null($this->plugin)) { 335 if (file_exists(APP . 'plugins' . DS . $this->plugin . DS . 'views' . DS . 'elements' . DS . $name . $this->ext)) { 336 $elementFileName = APP . 'plugins' . DS . $this->plugin . DS . 'views' . DS . 'elements' . DS . $name . $this->ext; 337 return $this->_render($elementFileName, array_merge($this->viewVars, $params), false); 338 } 339 } 340 341 $paths = Configure::getInstance(); 342 foreach($paths->viewPaths as $path) { 343 if (file_exists($path . 'elements' . DS . $name . $this->ext)) { 344 $elementFileName = $path . 'elements' . DS . $name . $this->ext; 345 return $this->_render($elementFileName, array_merge($this->viewVars, $params), false); 346 } 347 } 348 return "(Error rendering Element: {$name})"; 349 } 350 /** 351 * Wrapper for View::renderElement(); 352 * 353 * @param string $name Name of template file in the/app/views/elements/ folder 354 * @param array $params Array of data to be made available to the for rendered view (i.e. the Element) 355 * @return string View::renderElement() 356 * @access public 357 */ 358 function element($name, $params = array()) { 359 return $this->renderElement($name, $params); 360 } 361 /** 362 * Renders a layout. Returns output from _render(). Returns false on error. 363 * 364 * @param string $contentForLayout Content to render in a view, wrapped by the surrounding layout. 365 * @return mixed Rendered output, or false on error 366 * @access public 367 */ 368 function renderLayout($contentForLayout) { 369 $layoutFilename = $this->_getLayoutFileName(); 370 371 if (Configure::read() > 2 && $this->controller != null) { 372 $debug = View::_render(LIBS . 'view' . DS . 'templates' . DS . 'elements' . DS . 'dump.thtml', array('controller' => $this->controller), false); 373 } else { 374 $debug = ''; 375 } 376 377 if ($this->pageTitle !== false) { 378 $pageTitle = $this->pageTitle; 379 } else { 380 $pageTitle = Inflector::humanize($this->viewPath); 381 } 382 383 $dataForLayout = array_merge($this->viewVars, array('title_for_layout' => $pageTitle, 384 'content_for_layout' => $contentForLayout, 385 'cakeDebug' => $debug)); 386 387 if (is_file($layoutFilename)) { 388 if (empty($this->loaded) && !empty($this->helpers)) { 389 $loadHelpers = true; 390 } else { 391 $loadHelpers = false; 392 $dataForLayout = array_merge($dataForLayout, $this->loaded); 393 } 394 395 if (substr($layoutFilename, -5) === 'thtml') { 396 $out = View::_render($layoutFilename, $dataForLayout, $loadHelpers, true); 397 } else { 398 $out = $this->_render($layoutFilename, $dataForLayout, $loadHelpers); 399 } 400 401 if ($out === false) { 402 $out = $this->_render($layoutFilename, $dataForLayout); 403 trigger_error(sprintf("Error in layout %s, got: <blockquote>%s</blockquote>", $layoutFilename, $out), E_USER_ERROR); 404 return false; 405 } else { 406 return $out; 407 } 408 } else { 409 return $this->cakeError('missingLayout', array(array('layout' => $this->layout, 410 'file' => $layoutFilename, 411 'base' => $this->base))); 412 } 413 } 414 /** 415 * Sets layout to be used when rendering. 416 * 417 * @param string $layout Name of layout. 418 * @return void 419 * @access public 420 * @deprecated in 1.2.x.x 421 */ 422 function setLayout($layout) { 423 $this->layout = $layout; 424 } 425 /** 426 * Displays an error page to the user. Uses layouts/error.html to render the page. 427 * 428 * @param int $code HTTP Error code (for instance: 404) 429 * @param string $name Name of the error (for instance: Not Found) 430 * @param string $message Error message as a web page 431 * @return rendered error message 432 * @access public 433 * 434 */ 435 function error($code, $name, $message) { 436 header ("HTTP/1.0 {$code} {$name}"); 437 print ($this->_render(VIEWS . 'layouts/error.thtml', array('code' => $code, 438 'name' => $name, 439 'message' => $message))); 440 } 441 /** 442 * Returns filename of given action's template file (.thtml) as a string. CamelCased action names will be under_scored! This means that you can have LongActionNames that refer to long_action_names.thtml views. 443 * 444 * @param string $action Controller action to find template filename for 445 * @return string Template filename 446 * @access protected 447 */ 448 function _getViewFileName($action) { 449 $action = Inflector::underscore($action); 450 $paths = Configure::getInstance(); 451 452 if (!is_null($this->webservices)) { 453 $type = strtolower($this->webservices) . DS; 454 } else { 455 $type = null; 456 } 457 458 $position = strpos($action, '..'); 459 460 if ($position === false) { 461 } else { 462 $action = explode('/', $action); 463 $i = array_search('..', $action); 464 unset($action[$i - 1]); 465 unset($action[$i]); 466 $action='..' . DS . implode(DS, $action); 467 } 468 469 foreach($paths->viewPaths as $path) { 470 if (file_exists($path . $this->viewPath . DS . $this->subDir . $type . $action . $this->ext)) { 471 $viewFileName = $path . $this->viewPath . DS . $this->subDir . $type . $action . $this->ext; 472 return $viewFileName; 473 } 474 } 475 476 if ($viewFileName = fileExistsInPath(LIBS . 'view' . DS . 'templates' . DS . 'errors' . DS . $type . $action . '.thtml')) { 477 } elseif($viewFileName = fileExistsInPath(LIBS . 'view' . DS . 'templates' . DS . $this->viewPath . DS . $type . $action . '.thtml')) { 478 } else { 479 $viewFileName = VIEWS . $this->viewPath . DS . $this->subDir . $type . $action . $this->ext; 480 } 481 482 return $viewFileName; 483 } 484 /** 485 * Returns layout filename for this template as a string. 486 * 487 * @return string Filename for layout file (.thtml). 488 * @access protected 489 */ 490 function _getLayoutFileName() { 491 if (isset($this->webservices) && !is_null($this->webservices)) { 492 $type = strtolower($this->webservices) . DS; 493 } else { 494 $type = null; 495 } 496 497 if (isset($this->plugin) && !is_null($this->plugin)) { 498 if (file_exists(APP . 'plugins' . DS . $this->plugin . DS . 'views' . DS . 'layouts' . DS . $this->layout . $this->ext)) { 499 $layoutFileName = APP . 'plugins' . DS . $this->plugin . DS . 'views' . DS . 'layouts' . DS . $this->layout . $this->ext; 500 return $layoutFileName; 501 } 502 } 503 $paths = Configure::getInstance(); 504 505 foreach($paths->viewPaths as $path) { 506 if (file_exists($path . 'layouts' . DS . $this->subDir . $type . $this->layout . $this->ext)) { 507 $layoutFileName = $path . 'layouts' . DS . $this->subDir . $type . $this->layout . $this->ext; 508 return $layoutFileName; 509 } 510 } 511 512 if($layoutFileName = fileExistsInPath(LIBS . 'view' . DS . 'templates' . DS . 'layouts' . DS . $type . $this->layout . '.thtml')) { 513 } else { 514 $layoutFileName = LAYOUTS . $type . $this->layout.$this->ext; 515 } 516 return $layoutFileName; 517 } 518 519 /** 520 * Renders and returns output for given view filename with its array of data. 521 * 522 * @param string $___viewFn Filename of the view 523 * @param array $___dataForView Data to include in rendered view 524 * @return string Rendered output 525 * @access protected 526 */ 527 function _render($___viewFn, $___dataForView, $loadHelpers = true, $cached = false) { 528 if ($this->helpers != false && $loadHelpers === true) { 529 $loadedHelpers = array(); 530 $loadedHelpers = $this->_loadHelpers($loadedHelpers, $this->helpers); 531 532 foreach(array_keys($loadedHelpers) as $helper) { 533 $replace = strtolower(substr($helper, 0, 1)); 534 $camelBackedHelper = preg_replace('/\\w/', $replace, $helper, 1); 535 536 ${$camelBackedHelper} =& $loadedHelpers[$helper]; 537 538 if (isset(${$camelBackedHelper}->helpers) && is_array(${$camelBackedHelper}->helpers)) { 539 foreach(${$camelBackedHelper}->helpers as $subHelper) { 540 ${$camelBackedHelper}->{$subHelper} =& $loadedHelpers[$subHelper]; 541 } 542 } 543 $this->loaded[$camelBackedHelper] = (${$camelBackedHelper}); 544 } 545 } 546 extract($___dataForView, EXTR_SKIP); 547 $BASE = $this->base; 548 $params =& $this->params; 549 $page_title = $this->pageTitle; 550 551 ob_start(); 552 553 if (Configure::read() > 0) { 554 include ($___viewFn); 555 } else { 556 @include ($___viewFn); 557 } 558 559 if ($this->helpers != false && $loadHelpers === true) { 560 foreach ($loadedHelpers as $helper) { 561 if (is_object($helper)) { 562 if (is_subclass_of($helper, 'Helper') || is_subclass_of($helper, 'helper')) { 563 $helper->afterRender(); 564 } 565 } 566 } 567 } 568 $out = ob_get_clean(); 569 570 if (isset($this->loaded['cache']) && ((isset($this->controller) && $this->controller->cacheAction != false)) && (defined('CACHE_CHECK') && CACHE_CHECK === true)) { 571 if (is_a($this->loaded['cache'], 'CacheHelper')) { 572 $cache =& $this->loaded['cache']; 573 574 if ($cached === true) { 575 $cache->view = &$this; 576 } 577 578 $cache->base = $this->base; 579 $cache->here = $this->here; 580 $cache->action = $this->action; 581 $cache->controllerName = $this->params['controller']; 582 $cache->cacheAction = $this->controller->cacheAction; 583 $cache->cache($___viewFn, $out, $cached); 584 } 585 } 586 return $out; 587 } 588 /** 589 * Loads helpers, with their dependencies. 590 * 591 * @param array $loaded List of helpers that are already loaded. 592 * @param array $helpers List of helpers to load. 593 * @return array 594 * @access protected 595 */ 596 function &_loadHelpers(&$loaded, $helpers) { 597 static $tags; 598 $helpers[] = 'Session'; 599 if (empty($tags)) { 600 $helperTags = new Helper(); 601 $tags = $helperTags->loadConfig(); 602 } 603 604 foreach($helpers as $helper) { 605 $pos = strpos($helper, '/'); 606 if ($pos === false) { 607 $plugin = $this->plugin; 608 } else { 609 $parts = explode('/', $helper); 610 $plugin = Inflector::underscore($parts['0']); 611 $helper = $parts['1']; 612 } 613 $helperCn = $helper . 'Helper'; 614 615 if (in_array($helper, array_keys($loaded)) !== true) { 616 if (!class_exists($helperCn)) { 617 if (is_null($plugin) || !loadPluginHelper($plugin, $helper)) { 618 if (!loadHelper($helper)) { 619 $this->cakeError('missingHelperFile', array(array( 620 'helper' => $helper, 621 'file' => Inflector::underscore($helper) . '.php', 622 'base' => $this->base))); 623 exit(); 624 } 625 } 626 if (!class_exists($helperCn)) { 627 $this->cakeError('missingHelperClass', array(array( 628 'helper' => $helper, 629 'file' => Inflector::underscore($helper) . '.php', 630 'base' => $this->base))); 631 exit(); 632 } 633 } 634 635 $camelBackedHelper = Inflector::variable($helper); 636 637 ${$camelBackedHelper} =& new $helperCn; 638 ${$camelBackedHelper}->view =& $this; 639 ${$camelBackedHelper}->tags = $tags; 640 641 $vars = array('base', 'webroot', 'here', 'params', 'action', 'data', 'themeWeb', 'plugin'); 642 $c = count($vars); 643 for ($j = 0; $j < $c; $j++) { 644 ${$camelBackedHelper}->{$vars[$j]} = $this->{$vars[$j]}; 645 } 646 647 if (!empty($this->validationErrors)) { 648 ${$camelBackedHelper}->validationErrors = $this->validationErrors; 649 } 650 651 $loaded[$helper] =& ${$camelBackedHelper}; 652 653 if (isset(${$camelBackedHelper}->helpers) && is_array(${$camelBackedHelper}->helpers)) { 654 $loaded = &$this->_loadHelpers($loaded, ${$camelBackedHelper}->helpers); 655 } 656 } 657 } 658 return $loaded; 659 } 660 /** 661 * Returns a plugin view 662 * 663 * @param string $action Name of action to render for 664 * @param string $layout Layout to use 665 * @return mixed View::render() if template is found, error if template is missing 666 * @access public 667 */ 668 function pluginView($action, $layout) { 669 $viewFileName = APP . 'plugins' . DS . $this->plugin . DS . 'views' . DS . $this->viewPath . DS . $action . $this->ext; 670 671 if (file_exists($viewFileName)) { 672 $this->render($action, $layout, $viewFileName); 673 } else { 674 return $this->cakeError('missingView', array(array( 675 'className' => $this->controller->name, 676 'action' => $action, 677 'file' => $viewFileName, 678 'base' => $this->base))); 679 } 680 } 681 /** 682 * Renders a cached view if timestamp in file is less or equal to current time. 683 * 684 * If $layout is xml content type will be set before rendering the cache 685 * 686 * @param string $filename 687 * @param int $timeStart 688 * @return mixed outputs view, or returns void if timestamp has expired 689 * @access public 690 */ 691 function renderCache($filename, $timeStart) { 692 ob_start(); 693 include ($filename); 694 695 if (Configure::read() > 0 && $this->layout != 'xml') { 696 echo "<!-- Cached Render Time: " . round(getMicrotime() - $timeStart, 4) . "s -->"; 697 } 698 $out = ob_get_clean(); 699 700 if (preg_match('/^<!--cachetime:(\\d+)-->/', $out, $match)) { 701 if (time() >= $match['1']) { 702 @unlink($filename); 703 unset ($out); 704 return; 705 } else { 706 if($this->layout === 'xml'){ 707 header('Content-type: text/xml'); 708 } 709 $out = str_replace('<!--cachetime:'.$match['1'].'-->', '', $out); 710 e($out); 711 die(); 712 } 713 } 714 } 715 } 716 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Sun Feb 25 19:27:47 2007 | par Balluche grâce à PHPXref 0.7 |