00001 <?php
00023 require_once 'Zend/Loader.php';
00024
00026 require_once 'Zend/Loader/PluginLoader.php';
00027
00029 require_once 'Zend/View/Interface.php';
00030
00039 abstract class Zend_View_Abstract implements Zend_View_Interface
00040 {
00046 private $_path = array(
00047 'script' => array(),
00048 'helper' => array(),
00049 'filter' => array(),
00050 );
00051
00057 private $_file = null;
00058
00064 private $_helper = array();
00065
00071 private $_helperLoaded = array();
00072
00077 private $_helperLoadedDir = array();
00078
00083 private $_filter = array();
00084
00089 private $_filterClass = array();
00090
00096 private $_filterLoaded = array();
00097
00102 private $_filterLoadedDir = array();
00103
00109 private $_escape = 'htmlspecialchars';
00110
00115 private $_encoding = 'UTF-8';
00116
00121 private $_lfiProtectionOn = true;
00122
00127 private $_loaders = array();
00128
00133 private $_loaderTypes = array('filter', 'helper');
00134
00140 private $_strictVars = false;
00141
00147 public function __construct($config = array())
00148 {
00149
00150 $this->setScriptPath(null);
00151
00152
00153 $this->setFilterPath(null);
00154
00155
00156 if (array_key_exists('escape', $config)) {
00157 $this->setEscape($config['escape']);
00158 }
00159
00160
00161 if (array_key_exists('encoding', $config)) {
00162 $this->setEncoding($config['encoding']);
00163 }
00164
00165
00166 if (array_key_exists('basePath', $config)) {
00167 $prefix = 'Zend_View';
00168 if (array_key_exists('basePathPrefix', $config)) {
00169 $prefix = $config['basePathPrefix'];
00170 }
00171 $this->setBasePath($config['basePath'], $prefix);
00172 }
00173
00174
00175 if (array_key_exists('scriptPath', $config)) {
00176 $this->addScriptPath($config['scriptPath']);
00177 }
00178
00179
00180 if (array_key_exists('helperPath', $config)) {
00181 if (is_array($config['helperPath'])) {
00182 foreach ($config['helperPath'] as $prefix => $path) {
00183 $this->addHelperPath($path, $prefix);
00184 }
00185 } else {
00186 $prefix = 'Zend_View_Helper';
00187 if (array_key_exists('helperPathPrefix', $config)) {
00188 $prefix = $config['helperPathPrefix'];
00189 }
00190 $this->addHelperPath($config['helperPath'], $prefix);
00191 }
00192 }
00193
00194
00195 if (array_key_exists('filterPath', $config)) {
00196 if (is_array($config['filterPath'])) {
00197 foreach ($config['filterPath'] as $prefix => $path) {
00198 $this->addFilterPath($path, $prefix);
00199 }
00200 } else {
00201 $prefix = 'Zend_View_Filter';
00202 if (array_key_exists('filterPathPrefix', $config)) {
00203 $prefix = $config['filterPathPrefix'];
00204 }
00205 $this->addFilterPath($config['filterPath'], $prefix);
00206 }
00207 }
00208
00209
00210 if (array_key_exists('filter', $config)) {
00211 $this->addFilter($config['filter']);
00212 }
00213
00214
00215 if (array_key_exists('strictVars', $config)) {
00216 $this->strictVars($config['strictVars']);
00217 }
00218
00219
00220 if (array_key_exists('lfiProtectionOn', $config)) {
00221 $this->setLfiProtection($config['lfiProtectionOn']);
00222 }
00223
00224 $this->init();
00225 }
00226
00234 public function getEngine()
00235 {
00236 return $this;
00237 }
00238
00247 public function init()
00248 {
00249 }
00250
00259 public function __get($key)
00260 {
00261 if ($this->_strictVars) {
00262 trigger_error('Key "' . $key . '" does not exist', E_USER_NOTICE);
00263 }
00264
00265 return null;
00266 }
00267
00275 public function __isset($key)
00276 {
00277 if ('_' != substr($key, 0, 1)) {
00278 return isset($this->$key);
00279 }
00280
00281 return false;
00282 }
00283
00297 public function __set($key, $val)
00298 {
00299 if ('_' != substr($key, 0, 1)) {
00300 $this->$key = $val;
00301 return;
00302 }
00303
00304 require_once 'Zend/View/Exception.php';
00305 throw new Zend_View_Exception('Setting private or protected class members is not allowed', $this);
00306 }
00307
00314 public function __unset($key)
00315 {
00316 if ('_' != substr($key, 0, 1) && isset($this->$key)) {
00317 unset($this->$key);
00318 }
00319 }
00320
00331 public function __call($name, $args)
00332 {
00333
00334 $helper = $this->getHelper($name);
00335
00336
00337 return call_user_func_array(
00338 array($helper, $name),
00339 $args
00340 );
00341 }
00342
00358 public function setBasePath($path, $classPrefix = 'Zend_View')
00359 {
00360 $path = rtrim($path, '/');
00361 $path = rtrim($path, '\\');
00362 $path .= DIRECTORY_SEPARATOR;
00363 $classPrefix = rtrim($classPrefix, '_') . '_';
00364 $this->setScriptPath($path . 'scripts');
00365 $this->setHelperPath($path . 'helpers', $classPrefix . 'Helper');
00366 $this->setFilterPath($path . 'filters', $classPrefix . 'Filter');
00367 return $this;
00368 }
00369
00385 public function addBasePath($path, $classPrefix = 'Zend_View')
00386 {
00387 $path = rtrim($path, '/');
00388 $path = rtrim($path, '\\');
00389 $path .= DIRECTORY_SEPARATOR;
00390 $classPrefix = rtrim($classPrefix, '_') . '_';
00391 $this->addScriptPath($path . 'scripts');
00392 $this->addHelperPath($path . 'helpers', $classPrefix . 'Helper');
00393 $this->addFilterPath($path . 'filters', $classPrefix . 'Filter');
00394 return $this;
00395 }
00396
00403 public function addScriptPath($path)
00404 {
00405 $this->_addPath('script', $path);
00406 return $this;
00407 }
00408
00417 public function setScriptPath($path)
00418 {
00419 $this->_path['script'] = array();
00420 $this->_addPath('script', $path);
00421 return $this;
00422 }
00423
00431 public function getScriptPath($name)
00432 {
00433 try {
00434 $path = $this->_script($name);
00435 return $path;
00436 } catch (Zend_View_Exception $e) {
00437 if (strstr($e->getMessage(), 'no view script directory set')) {
00438 throw $e;
00439 }
00440
00441 return false;
00442 }
00443 }
00444
00450 public function getScriptPaths()
00451 {
00452 return $this->_getPaths('script');
00453 }
00454
00462 public function setPluginLoader(Zend_Loader_PluginLoader $loader, $type)
00463 {
00464 $type = strtolower($type);
00465 if (!in_array($type, $this->_loaderTypes)) {
00466 require_once 'Zend/View/Exception.php';
00467 throw new Zend_View_Exception(sprintf('Invalid plugin loader type "%s"', $type));
00468 }
00469
00470 $this->_loaders[$type] = $loader;
00471 return $this;
00472 }
00473
00480 public function getPluginLoader($type)
00481 {
00482 $type = strtolower($type);
00483 if (!in_array($type, $this->_loaderTypes)) {
00484 require_once 'Zend/View/Exception.php';
00485 throw new Zend_View_Exception(sprintf('Invalid plugin loader type "%s"; cannot retrieve', $type));
00486 }
00487
00488 if (!array_key_exists($type, $this->_loaders)) {
00489 $prefix = 'Zend_View_';
00490 $pathPrefix = 'Zend/View/';
00491
00492 $pType = ucfirst($type);
00493 switch ($type) {
00494 case 'filter':
00495 case 'helper':
00496 default:
00497 $prefix .= $pType;
00498 $pathPrefix .= $pType;
00499 $loader = new Zend_Loader_PluginLoader(array(
00500 $prefix => $pathPrefix
00501 ));
00502 $this->_loaders[$type] = $loader;
00503 break;
00504 }
00505 }
00506 return $this->_loaders[$type];
00507 }
00508
00517 public function addHelperPath($path, $classPrefix = 'Zend_View_Helper_')
00518 {
00519 return $this->_addPluginPath('helper', $classPrefix, (array) $path);
00520 }
00521
00532 public function setHelperPath($path, $classPrefix = 'Zend_View_Helper_')
00533 {
00534 unset($this->_loaders['helper']);
00535 return $this->addHelperPath($path, $classPrefix);
00536 }
00537
00544 public function getHelperPath($name)
00545 {
00546 return $this->_getPluginPath('helper', $name);
00547 }
00548
00554 public function getHelperPaths()
00555 {
00556 return $this->getPluginLoader('helper')->getPaths();
00557 }
00558
00565 public function getHelper($name)
00566 {
00567 return $this->_getPlugin('helper', $name);
00568 }
00569
00577 public function getHelpers()
00578 {
00579 return $this->_helper;
00580 }
00581
00590 public function addFilterPath($path, $classPrefix = 'Zend_View_Filter_')
00591 {
00592 return $this->_addPluginPath('filter', $classPrefix, (array) $path);
00593 }
00594
00605 public function setFilterPath($path, $classPrefix = 'Zend_View_Filter_')
00606 {
00607 unset($this->_loaders['filter']);
00608 return $this->addFilterPath($path, $classPrefix);
00609 }
00610
00617 public function getFilterPath($name)
00618 {
00619 return $this->_getPluginPath('filter', $name);
00620 }
00621
00628 public function getFilter($name)
00629 {
00630 return $this->_getPlugin('filter', $name);
00631 }
00632
00640 public function getFilters()
00641 {
00642 return $this->_filter;
00643 }
00644
00650 public function getFilterPaths()
00651 {
00652 return $this->getPluginLoader('filter')->getPaths();
00653 }
00654
00660 public function getAllPaths()
00661 {
00662 $paths = $this->_path;
00663 $paths['helper'] = $this->getHelperPaths();
00664 $paths['filter'] = $this->getFilterPaths();
00665 return $paths;
00666 }
00667
00674 public function addFilter($name)
00675 {
00676 foreach ((array) $name as $val) {
00677 $this->_filter[] = $val;
00678 }
00679 return $this;
00680 }
00681
00690 public function setFilter($name)
00691 {
00692 $this->_filter = array();
00693 $this->addFilter($name);
00694 return $this;
00695 }
00696
00703 public function setEscape($spec)
00704 {
00705 $this->_escape = $spec;
00706 return $this;
00707 }
00708
00715 public function setLfiProtection($flag)
00716 {
00717 $this->_lfiProtectionOn = (bool) $flag;
00718 return $this;
00719 }
00720
00726 public function isLfiProtectionOn()
00727 {
00728 return $this->_lfiProtectionOn;
00729 }
00730
00748 public function assign($spec, $value = null)
00749 {
00750
00751 if (is_string($spec)) {
00752
00753 if ('_' == substr($spec, 0, 1)) {
00754 require_once 'Zend/View/Exception.php';
00755 throw new Zend_View_Exception('Setting private or protected class members is not allowed', $this);
00756 }
00757 $this->$spec = $value;
00758 } elseif (is_array($spec)) {
00759
00760 $error = false;
00761 foreach ($spec as $key => $val) {
00762 if ('_' == substr($key, 0, 1)) {
00763 $error = true;
00764 break;
00765 }
00766 $this->$key = $val;
00767 }
00768 if ($error) {
00769 require_once 'Zend/View/Exception.php';
00770 throw new Zend_View_Exception('Setting private or protected class members is not allowed', $this);
00771 }
00772 } else {
00773 require_once 'Zend/View/Exception.php';
00774 throw new Zend_View_Exception('assign() expects a string or array, received ' . gettype($spec), $this);
00775 }
00776
00777 return $this;
00778 }
00779
00788 public function getVars()
00789 {
00790 $vars = get_object_vars($this);
00791 foreach ($vars as $key => $value) {
00792 if ('_' == substr($key, 0, 1)) {
00793 unset($vars[$key]);
00794 }
00795 }
00796
00797 return $vars;
00798 }
00799
00808 public function clearVars()
00809 {
00810 $vars = get_object_vars($this);
00811 foreach ($vars as $key => $value) {
00812 if ('_' != substr($key, 0, 1)) {
00813 unset($this->$key);
00814 }
00815 }
00816 }
00817
00824 public function render($name)
00825 {
00826
00827 $this->_file = $this->_script($name);
00828 unset($name);
00829
00830 ob_start();
00831 $this->_run($this->_file);
00832
00833 return $this->_filter(ob_get_clean());
00834 }
00835
00845 public function escape($var)
00846 {
00847 if (in_array($this->_escape, array('htmlspecialchars', 'htmlentities'))) {
00848 return call_user_func($this->_escape, $var, ENT_COMPAT, $this->_encoding);
00849 }
00850
00851 return call_user_func($this->_escape, $var);
00852 }
00853
00860 public function setEncoding($encoding)
00861 {
00862 $this->_encoding = $encoding;
00863 return $this;
00864 }
00865
00871 public function getEncoding()
00872 {
00873 return $this->_encoding;
00874 }
00875
00888 public function strictVars($flag = true)
00889 {
00890 $this->_strictVars = ($flag) ? true : false;
00891
00892 return $this;
00893 }
00894
00901 protected function _script($name)
00902 {
00903 if ($this->isLfiProtectionOn() && preg_match('#\.\.[\\\/]#', $name)) {
00904 require_once 'Zend/View/Exception.php';
00905 throw new Zend_View_Exception('Requested scripts may not include parent directory traversal ("../", "..\\" notation)');
00906 }
00907
00908 if (0 == count($this->_path['script'])) {
00909 require_once 'Zend/View/Exception.php';
00910 throw new Zend_View_Exception('no view script directory set; unable to determine location for view script',
00911 $this);
00912 }
00913
00914 foreach ($this->_path['script'] as $dir) {
00915 if (is_readable($dir . $name)) {
00916 return $dir . $name;
00917 }
00918 }
00919
00920 require_once 'Zend/View/Exception.php';
00921 $message = "script '$name' not found in path ("
00922 . implode(PATH_SEPARATOR, $this->_path['script'])
00923 . ")";
00924 throw new Zend_View_Exception($message, $this);
00925 }
00926
00933 private function _filter($buffer)
00934 {
00935
00936 foreach ($this->_filter as $name) {
00937
00938 $filter = $this->getFilter($name);
00939 $buffer = call_user_func(array($filter, 'filter'), $buffer);
00940 }
00941
00942
00943 return $buffer;
00944 }
00945
00964 private function _addPath($type, $path, $prefix = null)
00965 {
00966 foreach ((array) $path as $dir) {
00967
00968
00969 $dir = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $dir);
00970 $dir = rtrim($dir, DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR)
00971 . DIRECTORY_SEPARATOR;
00972
00973 switch ($type) {
00974 case 'script':
00975
00976 array_unshift($this->_path[$type], $dir);
00977 break;
00978 case 'filter':
00979 case 'helper':
00980 default:
00981
00982 array_unshift($this->_path[$type], array('prefix' => $prefix, 'dir' => $dir));
00983 break;
00984 }
00985 }
00986 }
00987
00995 private function _setPath($type, $path, $classPrefix = null)
00996 {
00997 $dir = DIRECTORY_SEPARATOR . ucfirst($type) . DIRECTORY_SEPARATOR;
00998
00999 switch ($type) {
01000 case 'script':
01001 $this->_path[$type] = array(dirname(__FILE__) . $dir);
01002 $this->_addPath($type, $path);
01003 break;
01004 case 'filter':
01005 case 'helper':
01006 default:
01007 $this->_path[$type] = array(array(
01008 'prefix' => 'Zend_View_' . ucfirst($type) . '_',
01009 'dir' => dirname(__FILE__) . $dir
01010 ));
01011 $this->_addPath($type, $path, $classPrefix);
01012 break;
01013 }
01014 }
01015
01022 private function _getPaths($type)
01023 {
01024 return $this->_path[$type];
01025 }
01026
01035 private function _setHelperClass($name, $class, $file)
01036 {
01037 $this->_helperLoadedDir[$name] = $file;
01038 $this->_helperLoaded[$name] = $class;
01039 }
01040
01049 private function _setFilterClass($name, $class, $file)
01050 {
01051 $this->_filterLoadedDir[$name] = $file;
01052 $this->_filterLoaded[$name] = $class;
01053 }
01054
01063 private function _addPluginPath($type, $classPrefix, array $paths)
01064 {
01065 $loader = $this->getPluginLoader($type);
01066 foreach ($paths as $path) {
01067 $loader->addPrefixPath($classPrefix, $path);
01068 }
01069 return $this;
01070 }
01071
01079 private function _getPluginPath($type, $name)
01080 {
01081 $loader = $this->getPluginLoader($type);
01082 if ($loader->isLoaded($name)) {
01083 return $loader->getClassPath($name);
01084 }
01085
01086 try {
01087 $loader->load($name);
01088 return $loader->getClassPath($name);
01089 } catch (Zend_Loader_Exception $e) {
01090 return false;
01091 }
01092 }
01093
01101 private function _getPlugin($type, $name)
01102 {
01103 $name = ucfirst($name);
01104 switch ($type) {
01105 case 'filter':
01106 $storeVar = '_filterClass';
01107 $store = $this->_filterClass;
01108 break;
01109 case 'helper':
01110 $storeVar = '_helper';
01111 $store = $this->_helper;
01112 break;
01113 }
01114
01115 if (!isset($store[$name])) {
01116 $class = $this->getPluginLoader($type)->load($name);
01117 $store[$name] = new $class();
01118 if (method_exists($store[$name], 'setView')) {
01119 $store[$name]->setView($this);
01120 }
01121 }
01122
01123 $this->$storeVar = $store;
01124 return $store[$name];
01125 }
01126
01133 abstract protected function _run();
01134 }