view.php

Go to the documentation of this file.
00001 <?php
00002 /* SVN FILE: $Id: view_8php-source.html 675 2008-12-26 00:27:14Z gwoo $ */
00003 /**
00004  * Methods for displaying presentation data in the view.
00005  *
00006  * PHP versions 4 and 5
00007  *
00008  * CakePHP(tm) :  Rapid Development Framework <http://www.cakephp.org/>
00009  * Copyright 2005-2008, Cake Software Foundation, Inc.
00010  *                              1785 E. Sahara Avenue, Suite 490-204
00011  *                              Las Vegas, Nevada 89104
00012  *
00013  * Licensed under The MIT License
00014  * Redistributions of files must retain the above copyright notice.
00015  *
00016  * @filesource
00017  * @copyright       Copyright 2005-2008, Cake Software Foundation, Inc.
00018  * @link                http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
00019  * @package         cake
00020  * @subpackage      cake.cake.libs.view
00021  * @since           CakePHP(tm) v 0.10.0.1076
00022  * @version         $Revision: 675 $
00023  * @modifiedby      $LastChangedBy: gwoo $
00024  * @lastmodified    $Date: 2008-12-25 16:27:14 -0800 (Thu, 25 Dec 2008) $
00025  * @license         http://www.opensource.org/licenses/mit-license.php The MIT License
00026  */
00027 /**
00028  * Included libraries.
00029  */
00030 uses ('view' . DS . 'helper', 'class_registry');
00031 /**
00032  * View, the V in the MVC triad.
00033  *
00034  * Class holding methods for displaying presentation data.
00035  *
00036  * @package         cake
00037  * @subpackage      cake.cake.libs.view
00038  */
00039 class View extends Object{
00040 /**
00041  * Name of the controller.
00042  *
00043  * @var string Name of controller
00044  * @access public
00045  */
00046     var $name = null;
00047 /**
00048  * Stores the current URL (for links etc.)
00049  *
00050  * @var string Current URL
00051  * @access public
00052  */
00053     var $here = null;
00054 /**
00055  * Action to be performed.
00056  *
00057  * @var string Name of action
00058  * @access public
00059  */
00060     var $action = null;
00061 /**
00062  * An array of names of built-in helpers to include.
00063  *
00064  * @var mixed A single name as a string or a list of names as an array.
00065  * @access public
00066  */
00067     var $helpers = array('Html');
00068 /**
00069  * Path to View.
00070  *
00071  * @var string Path to View
00072  * @access public
00073  */
00074     var $viewPath;
00075 /**
00076  * Replaced with public var viewVars
00077  * @access protected
00078  * @deprecated
00079  */
00080     var $_viewVars = array();
00081 /**
00082  * Variables for the view
00083  *
00084  * @var array
00085  * @access public
00086  */
00087     var $viewVars = array();
00088 /**
00089  * Title HTML element of this View.
00090  *
00091  * @var boolean
00092  * @access public
00093  */
00094     var $pageTitle = false;
00095 /**
00096  * Path parts for creating links in views.
00097  *
00098  * @var string Base URL
00099  * @access public
00100  */
00101     var $base = null;
00102 /**
00103  * Name of layout to use with this View.
00104  *
00105  * @var string
00106  * @access public
00107  */
00108     var $layout = 'default';
00109 /**
00110  * Turns on or off Cake's conventional mode of rendering views. On by default.
00111  *
00112  * @var boolean
00113  * @access public
00114  */
00115     var $autoRender = true;
00116 /**
00117  * Turns on or off Cake's conventional mode of finding layout files. On by default.
00118  *
00119  * @var boolean
00120  * @access public
00121  */
00122     var $autoLayout = true;
00123 /**
00124  * Array of parameter data
00125  *
00126  * @var array Parameter data
00127  * @access public
00128  */
00129     var $params;
00130 /**
00131  * True when the view has been rendered.
00132  *
00133  * @var boolean
00134  * @access protected
00135  */
00136     var $_hasRendered = null;
00137 /**
00138  * @deprecated will not be avialable after 1.1.x.x
00139  */
00140     var $controller = null;
00141 /**
00142  * Array of loaded view helpers.
00143  *
00144  * @var array
00145  * @access public
00146  */
00147     var $loaded = array();
00148 /**
00149  * File extension. Defaults to Cake's conventional ".thtml".
00150  *
00151  * @var array
00152  * @access public
00153  */
00154     var $ext = '.thtml';
00155 /**
00156  * Sub-directory for this view file.
00157  *
00158  * @var string
00159  * @access public
00160  */
00161     var $subDir = null;
00162 /**
00163  * The directory where theme web accessible content is stored
00164  *
00165  * @var array
00166  * @access public
00167  */
00168     var $themeWeb = null;
00169 /**
00170  * Plugin name. A Plugin is a sub-application.
00171  * This is used to set the correct paths for views
00172  *
00173  * @var string
00174  * @access public
00175  */
00176     var $plugin = null;
00177 /**
00178  * Creates system path to plugin: plugins . DS . plugin_name . DS
00179  *
00180  * @var string
00181  */
00182     var $pluginPath = null;
00183 /**
00184  * Holds an array of plugin paths.
00185  * VIEWS . $this->pluginPath
00186  * APP . $this->pluginPath . views . DS
00187  *
00188  * @var array
00189  */
00190     var $pluginPaths = array();
00191 /**
00192  * List of variables to collect from the associated controller
00193  *
00194  * @var array
00195  * @access protected
00196  */
00197     var $_passedVars = array('viewVars', 'action', 'autoLayout', 'autoRender', 'ext', 'base', 'webroot', 'helpers', 'here', 'layout', 'modelNames', 'name', 'pageTitle', 'viewPath', 'params', 'data', 'webservices', 'plugin');
00198 /**
00199  * Constructor
00200  *
00201  * Instance is created in Controller::render() and is never called directly
00202  *
00203  * @var object instance of the calling controller
00204  */
00205     function __construct(&$controller) {
00206         if (is_object($controller)) {
00207             $this->controller =& $controller;
00208             $c = count($this->_passedVars);
00209 
00210             for ($j = 0; $j < $c; $j++) {
00211                 $var = $this->_passedVars[$j];
00212                 $this->{$var} = $controller->{$var};
00213             }
00214             $this->_viewVars =& $this->viewVars;
00215         }
00216         if (!is_null($this->plugin)) {
00217             $this->pluginPath = 'plugins'. DS . $this->plugin . DS;
00218             $this->pluginPaths = array(
00219                                     VIEWS . $this->pluginPath,
00220                                     APP . $this->pluginPath . 'views' . DS,
00221                                 );
00222 
00223         }
00224         parent::__construct();
00225         ClassRegistry::addObject('view', $this);
00226     }
00227 /**
00228  * Renders view for given action and layout. If $file is given, that is used
00229  * for a view filename (e.g. customFunkyView.thtml).
00230  *
00231  * @param string $action Name of action to render for
00232  * @param string $layout Layout to use
00233  * @param string $file Custom filename for view
00234  * @return mixed returns an error if View::render() fails to find a related template.
00235  *                  boolean on successful render
00236  * @access public
00237  */
00238     function render($action = null, $layout = null, $file = null) {
00239 
00240         if (isset($this->_hasRendered) && $this->_hasRendered) {
00241             return true;
00242         } else {
00243             $this->_hasRendered = false;
00244         }
00245 
00246         if (!$action) {
00247             $action = $this->action;
00248         }
00249         $tempLayout = $this->layout;
00250 
00251         if ($layout) {
00252             $this->setLayout($layout);
00253         }
00254 
00255         if ($file) {
00256             $viewFileName = $file;
00257         } else {
00258             $viewFileName = $this->_getViewFileName($action);
00259         }
00260 
00261         if (!is_null($this->plugin) && is_null($file)) {
00262             return $this->pluginView($action, $layout);
00263         }
00264 
00265         if (!is_file($viewFileName) && !fileExistsInPath($viewFileName) || $viewFileName === '/' || $viewFileName === '\\') {
00266             if (strpos($action, 'missingAction') !== false) {
00267                 $errorAction = 'missingAction';
00268             } else {
00269                 $errorAction = 'missingView';
00270             }
00271 
00272             foreach (array($this->name, 'errors') as $viewDir) {
00273                 $errorAction = Inflector::underscore($errorAction);
00274 
00275                 if (file_exists(VIEWS . $viewDir . DS . $errorAction . $this->ext)) {
00276                     $missingViewFileName = VIEWS . $viewDir . DS . $errorAction . $this->ext;
00277                 } elseif ($missingViewFileName = fileExistsInPath(LIBS . 'view' . DS . 'templates' . DS . $viewDir . DS . $errorAction . '.thtml')) {
00278                 } else {
00279                     $missingViewFileName = false;
00280                 }
00281 
00282                 $missingViewExists = is_file($missingViewFileName);
00283 
00284                 if ($missingViewExists) {
00285                     break;
00286                 }
00287             }
00288 
00289             if (strpos($action, 'missingView') === false) {
00290                 return $this->cakeError('missingView', array(array('className' => $this->controller->name,
00291                                                                                     'action' => $action,
00292                                                                                     'file' => $viewFileName,
00293                                                                                     'base' => $this->base)));
00294 
00295                 $isFatal = isset($this->isFatal) ? $this->isFatal : false;
00296 
00297                 if (!$isFatal) {
00298                     $viewFileName = $missingViewFileName;
00299                 }
00300             } else {
00301                 $missingViewExists = false;
00302             }
00303 
00304             if (!$missingViewExists || $isFatal) {
00305                 if (Configure::read() > 0) {
00306                     trigger_error(sprintf("No template file for view %s (expected %s), create it first'", $action, $viewFileName), E_USER_ERROR);
00307                 } else {
00308                     $this->error('404', 'Not found', sprintf("The requested address %s was not found on this server.", '', "missing view \"{$action}\""));
00309                 }
00310                 die();
00311             }
00312         }
00313 
00314         if ($viewFileName && !$this->_hasRendered) {
00315             if (substr($viewFileName, -5) === 'thtml') {
00316                 $out = View::_render($viewFileName, $this->viewVars);
00317             } else {
00318                 $out = $this->_render($viewFileName, $this->viewVars);
00319             }
00320 
00321             if ($out !== false) {
00322                 if ($this->layout && $this->autoLayout) {
00323                     $out = $this->renderLayout($out);
00324                     if (isset($this->loaded['cache']) && ((isset($this->controller) && $this->controller->cacheAction != false)) && (defined('CACHE_CHECK') && CACHE_CHECK === true)) {
00325                         $replace = array('<cake:nocache>', '</cake:nocache>');
00326                         $out = str_replace($replace, '', $out);
00327                     }
00328                 }
00329 
00330                 print $out;
00331                 $this->setLayout($tempLayout);
00332                 $this->_hasRendered = true;
00333             } else {
00334                 $out = $this->_render($viewFileName, $this->viewVars);
00335                 trigger_error(sprintf("Error in view %s, got: <blockquote>%s</blockquote>", $viewFileName, $out), E_USER_ERROR);
00336             }
00337             return true;
00338         }
00339     }
00340 /**
00341  * Renders a piece of PHP with provided parameters and returns HTML, XML, or any other string.
00342  *
00343  * This realizes the concept of Elements, (or "partial layouts")
00344  * and the $params array is used to send data to be used in the Element.
00345  *
00346  * @param string $name Name of template file in the/app/views/elements/ folder
00347  * @param array $params Array of data to be made available to the for rendered view (i.e. the Element)
00348  * @return string Rendered output
00349  * @access public
00350  */
00351     function renderElement($name, $params = array()) {
00352         if (isset($params['plugin'])) {
00353             $this->plugin = $params['plugin'];
00354             $this->pluginPath = 'plugins' . DS . $this->plugin . DS;
00355             $this->pluginPaths = array(
00356                                     VIEWS . $this->pluginPath,
00357                                     APP . $this->pluginPath . 'views' . DS,
00358                                 );
00359         }
00360 
00361         $paths = Configure::getInstance();
00362         $viewPaths = am($this->pluginPaths, $paths->viewPaths);
00363 
00364         $file = null;
00365         foreach ($viewPaths as $path) {
00366             if (file_exists($path . 'elements' . DS . $name . $this->ext)) {
00367                 $file = $path . 'elements' . DS . $name . $this->ext;
00368                 break;
00369             } elseif (file_exists($path . 'elements' . DS . $name . '.ctp')) {
00370                 $file = $path . 'elements' . DS . $name . '.ctp';
00371                 break;
00372             }
00373         }
00374 
00375         if (!is_null($file)) {
00376             $params = array_merge_recursive($params, $this->loaded);
00377             return $this->_render($file, array_merge($this->viewVars, $params), false);
00378         }
00379 
00380         if (!is_null($this->pluginPath)) {
00381             $file = APP . $this->pluginPath . 'views' . DS . 'elements' . DS . $name . $this->ext;
00382         } else {
00383             $file = VIEWS . 'elements' . DS . $name . $this->ext;
00384         }
00385 
00386         if (Configure::read() > 0) {
00387             return "Element Not Found: " . $file;
00388         }
00389     }
00390 /**
00391  * Wrapper for View::renderElement();
00392  *
00393  * @param string $name Name of template file in the/app/views/elements/ folder
00394  * @param array $params Array of data to be made available to the for rendered view (i.e. the Element)
00395  * @return string View::renderElement()
00396  * @access public
00397  */
00398     function element($name, $params = array()) {
00399         return $this->renderElement($name, $params);
00400     }
00401 /**
00402  * Renders a layout. Returns output from _render(). Returns false on error.
00403  *
00404  * @param string $contentForLayout Content to render in a view, wrapped by the surrounding layout.
00405  * @return mixed Rendered output, or false on error
00406  * @access public
00407  */
00408     function renderLayout($contentForLayout) {
00409         $layoutFilename = $this->_getLayoutFileName();
00410 
00411         if (Configure::read() > 2 && $this->controller != null) {
00412             $debug = View::_render(LIBS . 'view' . DS . 'templates' . DS . 'elements' . DS . 'dump.thtml', array('controller' => $this->controller), false);
00413         } else {
00414             $debug = '';
00415         }
00416 
00417         if ($this->pageTitle !== false) {
00418             $pageTitle = $this->pageTitle;
00419         } else {
00420             $pageTitle = Inflector::humanize($this->viewPath);
00421         }
00422 
00423         $dataForLayout = array_merge($this->viewVars, array('title_for_layout'   => $pageTitle,
00424                                                                                 'content_for_layout' => $contentForLayout,
00425                                                                                 'cakeDebug'          => $debug));
00426 
00427         if (is_file($layoutFilename)) {
00428             if (empty($this->loaded) && !empty($this->helpers)) {
00429                 $loadHelpers = true;
00430             } else {
00431                 $loadHelpers = false;
00432                 $dataForLayout = array_merge($dataForLayout, $this->loaded);
00433             }
00434 
00435             if (substr($layoutFilename, -5) === 'thtml') {
00436                 $out = View::_render($layoutFilename, $dataForLayout, $loadHelpers, true);
00437             } else {
00438                 $out = $this->_render($layoutFilename, $dataForLayout, $loadHelpers);
00439             }
00440 
00441             if ($out === false) {
00442                 $out = $this->_render($layoutFilename, $dataForLayout);
00443                 trigger_error(sprintf("Error in layout %s, got: <blockquote>%s</blockquote>", $layoutFilename, $out), E_USER_ERROR);
00444                 return false;
00445             } else {
00446                 return $out;
00447             }
00448         } else {
00449             return $this->cakeError('missingLayout', array(array('layout' => $this->layout,
00450                                                                                     'file' => $layoutFilename,
00451                                                                                     'base' => $this->base)));
00452         }
00453     }
00454 /**
00455  * Sets layout to be used when rendering.
00456  *
00457  * @param string $layout Name of layout.
00458  * @return void
00459  * @access public
00460  * @deprecated in 1.2.x.x
00461  */
00462     function setLayout($layout) {
00463         $this->layout = $layout;
00464     }
00465 /**
00466  * Displays an error page to the user. Uses layouts/error.html to render the page.
00467  *
00468  * @param int $code HTTP Error code (for instance: 404)
00469  * @param string $name Name of the error (for instance: Not Found)
00470  * @param string $message Error message as a web page
00471  * @return rendered error message
00472  * @access public
00473  *
00474  */
00475     function error($code, $name, $message) {
00476         header ("HTTP/1.0 {$code} {$name}");
00477         print ($this->_render(VIEWS . 'layouts/error.thtml', array('code'    => $code,
00478                                                                                         'name'    => $name,
00479                                                                                         'message' => $message)));
00480     }
00481 /**
00482  * 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.
00483  *
00484  * @param string $action Controller action to find template filename for
00485  * @return string Template filename
00486  * @access protected
00487  */
00488     function _getViewFileName($action) {
00489         $action = Inflector::underscore($action);
00490 
00491         if (!is_null($this->webservices)) {
00492             $type = strtolower($this->webservices) . DS;
00493         } else {
00494             $type = null;
00495         }
00496 
00497         $position = strpos($action, '..');
00498         if ($position !== false) {
00499             $action = explode('/', $action);
00500             $i = array_search('..', $action);
00501             unset($action[$i - 1]);
00502             unset($action[$i]);
00503             $action = '..' . DS . implode(DS, $action);
00504         }
00505 
00506         $paths = Configure::getInstance();
00507         $viewPaths = am($this->pluginPaths, $paths->viewPaths);
00508 
00509         $name = $this->viewPath . DS . $this->subDir . $type . $action;
00510         foreach ($viewPaths as $path) {
00511             if (file_exists($path . $name . $this->ext)) {
00512                 return $path . $name . $this->ext;
00513             } elseif (file_exists($path . $name . '.ctp')) {
00514                 return $path . $name . '.ctp';
00515             }
00516         }
00517 
00518         if ($viewFileName = fileExistsInPath(LIBS . 'view' . DS . 'templates' . DS . 'errors' . DS . $type . $action . '.thtml')) {
00519             return $viewFileName;
00520         } elseif ($viewFileName = fileExistsInPath(LIBS . 'view' . DS . 'templates' . DS . $this->viewPath . DS . $type . $action . '.thtml')) {
00521             return $viewFileName;
00522         } else {
00523             if (!is_null($this->pluginPath)) {
00524                 $viewFileName = APP . $this->pluginPath . 'views' . DS . $name . $this->ext;
00525             } else {
00526                 $viewFileName = VIEWS . $name . $this->ext;
00527             }
00528         }
00529         return $viewFileName;
00530     }
00531 /**
00532  * Returns layout filename for this template as a string.
00533  *
00534  * @return string Filename for layout file (.thtml).
00535  * @access protected
00536  */
00537     function _getLayoutFileName() {
00538         if (isset($this->webservices) && !is_null($this->webservices)) {
00539             $type = strtolower($this->webservices) . DS;
00540         } else {
00541             $type = null;
00542         }
00543 
00544         $paths = Configure::getInstance();
00545         $viewPaths = am($this->pluginPaths, $paths->viewPaths);
00546 
00547         $name = $this->subDir . $type . $this->layout;
00548         foreach ($viewPaths as $path) {
00549             if (file_exists($path . 'layouts' . DS . $name . $this->ext)) {
00550                 return $path . 'layouts' . DS . $name . $this->ext;
00551             } elseif (file_exists($path . 'layouts' . DS . $name . '.ctp')) {
00552                 return $path . 'layouts' . DS . $name . '.ctp';
00553             }
00554         }
00555 
00556         if (!is_null($this->pluginPath)) {
00557             $layoutFileName = APP . $this->pluginPath . 'views' . DS . 'layouts' . DS . $name . $this->ext;
00558         } else {
00559             $layoutFileName = VIEWS . 'layouts' . DS . $name . $this->ext;
00560         }
00561 
00562         $layoutFileName = fileExistsInPath(LIBS . 'view' . DS . 'templates' . DS . 'layouts' . DS . $type . $this->layout . '.thtml');
00563         if (empty($layoutFileName) && !empty($type)) {
00564             $layoutFileName = fileExistsInPath(LIBS . 'view' . DS . 'templates' . DS . 'layouts' . DS . $type . 'default.thtml');
00565         }
00566         return $layoutFileName;
00567     }
00568 
00569 /**
00570  * Renders and returns output for given view filename with its array of data.
00571  *
00572  * @param string $___viewFn Filename of the view
00573  * @param array $___dataForView Data to include in rendered view
00574  * @return string Rendered output
00575  * @access protected
00576  */
00577     function _render($___viewFn, $___dataForView, $loadHelpers = true, $cached = false) {
00578         if ($this->helpers != false && $loadHelpers === true) {
00579             $loadedHelpers = array();
00580             $loadedHelpers = $this->_loadHelpers($loadedHelpers, $this->helpers);
00581 
00582             foreach (array_keys($loadedHelpers) as $helper) {
00583                 $replace = strtolower(substr($helper, 0, 1));
00584                 $camelBackedHelper = preg_replace('/\\w/', $replace, $helper, 1);
00585 
00586                 ${$camelBackedHelper} =& $loadedHelpers[$helper];
00587 
00588                 if (isset(${$camelBackedHelper}->helpers) && is_array(${$camelBackedHelper}->helpers)) {
00589                     foreach (${$camelBackedHelper}->helpers as $subHelper) {
00590                         ${$camelBackedHelper}->{$subHelper} =& $loadedHelpers[$subHelper];
00591                     }
00592                 }
00593                 $this->loaded[$camelBackedHelper] =& ${$camelBackedHelper};
00594             }
00595         }
00596         extract($___dataForView, EXTR_SKIP);
00597         $BASE = $this->base;
00598         $params =& $this->params;
00599 
00600         ob_start();
00601 
00602         if (Configure::read() > 0) {
00603             include ($___viewFn);
00604         } else {
00605             @include ($___viewFn);
00606         }
00607 
00608         if ($this->helpers != false && $loadHelpers === true) {
00609             foreach ($loadedHelpers as $helper) {
00610                 if (is_object($helper)) {
00611                     if (is_subclass_of($helper, 'Helper') || is_subclass_of($helper, 'helper')) {
00612                         $helper->afterRender();
00613                     }
00614                 }
00615             }
00616         }
00617         $out = ob_get_clean();
00618 
00619         if (isset($this->loaded['cache']) && ((isset($this->controller) && $this->controller->cacheAction != false)) && (defined('CACHE_CHECK') && CACHE_CHECK === true)) {
00620             if (is_a($this->loaded['cache'], 'CacheHelper')) {
00621                 $cache =& $this->loaded['cache'];
00622 
00623                 if ($cached === true) {
00624                     $cache->view = &$this;
00625                 }
00626 
00627                 $cache->base            = $this->base;
00628                 $cache->here            = $this->here;
00629                 $cache->action          = $this->action;
00630                 $cache->controllerName  = $this->params['controller'];
00631                 $cache->cacheAction     = $this->controller->cacheAction;
00632                 $cache->cache($___viewFn, $out, $cached);
00633             }
00634         }
00635         return $out;
00636     }
00637 /**
00638  * Loads helpers, with their dependencies.
00639  *
00640  * @param array $loaded List of helpers that are already loaded.
00641  * @param array $helpers List of helpers to load.
00642  * @return array
00643  * @access protected
00644  */
00645     function &_loadHelpers(&$loaded, $helpers) {
00646         static $tags;
00647         $helpers[] = 'Session';
00648         if (empty($tags)) {
00649             $helperTags = new Helper();
00650             $tags = $helperTags->loadConfig();
00651         }
00652 
00653         foreach ($helpers as $helper) {
00654             $parts = preg_split('/\/|\./', $helper);
00655 
00656             if (count($parts) === 1) {
00657                 $plugin = $this->plugin;
00658             } else {
00659                 $plugin = Inflector::underscore($parts['0']);
00660                 $helper = $parts[count($parts) - 1];
00661             }
00662             $helperCn = $helper . 'Helper';
00663 
00664             if (in_array($helper, array_keys($loaded)) !== true) {
00665                 if (!class_exists($helperCn)) {
00666                     if (is_null($plugin) || !loadPluginHelper($plugin, $helper)) {
00667                         if (!loadHelper($helper)) {
00668                             $this->cakeError('missingHelperFile', array(array(
00669                                                     'helper' => $helper,
00670                                                     'file' => Inflector::underscore($helper) . '.php',
00671                                                     'base' => $this->base)));
00672                             exit();
00673                         }
00674                     }
00675                     if (!class_exists($helperCn)) {
00676                         $this->cakeError('missingHelperClass', array(array(
00677                                                 'helper' => $helper,
00678                                                 'file' => Inflector::underscore($helper) . '.php',
00679                                                 'base' => $this->base)));
00680                         exit();
00681                     }
00682                 }
00683 
00684                 $camelBackedHelper = Inflector::variable($helper);
00685 
00686                 ${$camelBackedHelper} =& new $helperCn;
00687                 ${$camelBackedHelper}->view =& $this;
00688                 ${$camelBackedHelper}->tags = $tags;
00689 
00690                 $vars = array('base', 'webroot', 'here', 'params', 'action', 'data', 'themeWeb', 'plugin');
00691                 $c = count($vars);
00692                 for ($j = 0; $j < $c; $j++) {
00693                     ${$camelBackedHelper}->{$vars[$j]} = $this->{$vars[$j]};
00694                 }
00695 
00696                 if (!empty($this->validationErrors)) {
00697                     ${$camelBackedHelper}->validationErrors = $this->validationErrors;
00698                 }
00699 
00700                 $loaded[$helper] =& ${$camelBackedHelper};
00701 
00702                 if (isset(${$camelBackedHelper}->helpers) && is_array(${$camelBackedHelper}->helpers)) {
00703                     $loaded = &$this->_loadHelpers($loaded, ${$camelBackedHelper}->helpers);
00704                 }
00705             }
00706         }
00707         return $loaded;
00708     }
00709 /**
00710  * Returns a plugin view
00711  *
00712  * @param string $action Name of action to render for
00713  * @param string $layout Layout to use
00714  * @return mixed View::render() if template is found, error if template is missing
00715  * @access public
00716  */
00717     function pluginView($action, $layout) {
00718         $viewFileName = APP . 'plugins' . DS . $this->plugin . DS . 'views' . DS . $this->viewPath . DS . $action . $this->ext;
00719 
00720         if (file_exists($viewFileName)) {
00721             $this->render($action, $layout, $viewFileName);
00722         } else {
00723             return $this->cakeError('missingView', array(array(
00724                                             'className' => $this->controller->name,
00725                                             'action' => $action,
00726                                             'file' => $viewFileName,
00727                                             'base' => $this->base)));
00728         }
00729     }
00730 /**
00731  * Renders a cached view if timestamp in file is less or equal to current time.
00732  *
00733  * If $layout is xml content type will be set before rendering the cache
00734  *
00735  * @param string $filename
00736  * @param int $timeStart
00737  * @return mixed outputs view, or returns void if timestamp has expired
00738  * @access public
00739  */
00740     function renderCache($filename, $timeStart) {
00741         ob_start();
00742         include ($filename);
00743 
00744         if (Configure::read() > 0 && $this->layout != 'xml') {
00745             echo "<!-- Cached Render Time: " . round(getMicrotime() - $timeStart, 4) . "s -->";
00746         }
00747         $out = ob_get_clean();
00748 
00749         if (preg_match('/^<!--cachetime:(\\d+)-->/', $out, $match)) {
00750             if (time() >= $match['1']) {
00751                 @unlink($filename);
00752                 unset ($out);
00753                 return;
00754             } else {
00755                 if ($this->layout === 'xml') {
00756                     header('Content-type: text/xml');
00757                 }
00758                 $out = str_replace('<!--cachetime:'.$match['1'].'-->', '', $out);
00759                 e($out);
00760                 die();
00761             }
00762         }
00763     }
00764 }
00765 ?>