PageRenderTime 27ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 1ms

/libraries/legacy/view/legacy.php

https://bitbucket.org/pastor399/newcastleunifc
PHP | 796 lines | 333 code | 87 blank | 376 comment | 52 complexity | 14fb166012e3bd9e5d0dc5855a67fde4 MD5 | raw file
  1. <?php
  2. /**
  3. * @package Joomla.Legacy
  4. * @subpackage View
  5. *
  6. * @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
  7. * @license GNU General Public License version 2 or later; see LICENSE
  8. */
  9. defined('JPATH_PLATFORM') or die;
  10. /**
  11. * Base class for a Joomla View
  12. *
  13. * Class holding methods for displaying presentation data.
  14. *
  15. * @package Joomla.Legacy
  16. * @subpackage View
  17. * @since 12.2
  18. */
  19. class JViewLegacy extends JObject
  20. {
  21. /**
  22. * The name of the view
  23. *
  24. * @var array
  25. */
  26. protected $_name = null;
  27. /**
  28. * Registered models
  29. *
  30. * @var array
  31. */
  32. protected $_models = array();
  33. /**
  34. * The base path of the view
  35. *
  36. * @var string
  37. */
  38. protected $_basePath = null;
  39. /**
  40. * The default model
  41. *
  42. * @var string
  43. */
  44. protected $_defaultModel = null;
  45. /**
  46. * Layout name
  47. *
  48. * @var string
  49. */
  50. protected $_layout = 'default';
  51. /**
  52. * Layout extension
  53. *
  54. * @var string
  55. */
  56. protected $_layoutExt = 'php';
  57. /**
  58. * Layout template
  59. *
  60. * @var string
  61. */
  62. protected $_layoutTemplate = '_';
  63. /**
  64. * The set of search directories for resources (templates)
  65. *
  66. * @var array
  67. */
  68. protected $_path = array('template' => array(), 'helper' => array());
  69. /**
  70. * The name of the default template source file.
  71. *
  72. * @var string
  73. */
  74. protected $_template = null;
  75. /**
  76. * The output of the template script.
  77. *
  78. * @var string
  79. */
  80. protected $_output = null;
  81. /**
  82. * Callback for escaping.
  83. *
  84. * @var string
  85. * @deprecated 13.3
  86. */
  87. protected $_escape = 'htmlspecialchars';
  88. /**
  89. * Charset to use in escaping mechanisms; defaults to urf8 (UTF-8)
  90. *
  91. * @var string
  92. */
  93. protected $_charset = 'UTF-8';
  94. /**
  95. * Constructor
  96. *
  97. * @param array $config A named configuration array for object construction.<br/>
  98. * name: the name (optional) of the view (defaults to the view class name suffix).<br/>
  99. * charset: the character set to use for display<br/>
  100. * escape: the name (optional) of the function to use for escaping strings<br/>
  101. * base_path: the parent path (optional) of the views directory (defaults to the component folder)<br/>
  102. * template_plath: the path (optional) of the layout directory (defaults to base_path + /views/ + view name<br/>
  103. * helper_path: the path (optional) of the helper files (defaults to base_path + /helpers/)<br/>
  104. * layout: the layout (optional) to use to display the view<br/>
  105. *
  106. * @since 12.2
  107. */
  108. public function __construct($config = array())
  109. {
  110. // Set the view name
  111. if (empty($this->_name))
  112. {
  113. if (array_key_exists('name', $config))
  114. {
  115. $this->_name = $config['name'];
  116. }
  117. else
  118. {
  119. $this->_name = $this->getName();
  120. }
  121. }
  122. // Set the charset (used by the variable escaping functions)
  123. if (array_key_exists('charset', $config))
  124. {
  125. JLog::add('Setting a custom charset for escaping is deprecated. Override JViewLegacy::escape() instead.', JLog::WARNING, 'deprecated');
  126. $this->_charset = $config['charset'];
  127. }
  128. // User-defined escaping callback
  129. if (array_key_exists('escape', $config))
  130. {
  131. $this->setEscape($config['escape']);
  132. }
  133. // Set a base path for use by the view
  134. if (array_key_exists('base_path', $config))
  135. {
  136. $this->_basePath = $config['base_path'];
  137. }
  138. else
  139. {
  140. $this->_basePath = JPATH_COMPONENT;
  141. }
  142. // Set the default template search path
  143. if (array_key_exists('template_path', $config))
  144. {
  145. // User-defined dirs
  146. $this->_setPath('template', $config['template_path']);
  147. }
  148. else
  149. {
  150. $this->_setPath('template', $this->_basePath . '/views/' . $this->getName() . '/tmpl');
  151. }
  152. // Set the default helper search path
  153. if (array_key_exists('helper_path', $config))
  154. {
  155. // User-defined dirs
  156. $this->_setPath('helper', $config['helper_path']);
  157. }
  158. else
  159. {
  160. $this->_setPath('helper', $this->_basePath . '/helpers');
  161. }
  162. // Set the layout
  163. if (array_key_exists('layout', $config))
  164. {
  165. $this->setLayout($config['layout']);
  166. }
  167. else
  168. {
  169. $this->setLayout('default');
  170. }
  171. $this->baseurl = JURI::base(true);
  172. }
  173. /**
  174. * Execute and display a template script.
  175. *
  176. * @param string $tpl The name of the template file to parse; automatically searches through the template paths.
  177. *
  178. * @return mixed A string if successful, otherwise a Error object.
  179. *
  180. * @see fetch()
  181. * @since 12.2
  182. */
  183. public function display($tpl = null)
  184. {
  185. $result = $this->loadTemplate($tpl);
  186. if ($result instanceof Exception)
  187. {
  188. return $result;
  189. }
  190. echo $result;
  191. }
  192. /**
  193. * Assigns variables to the view script via differing strategies.
  194. *
  195. * This method is overloaded; you can assign all the properties of
  196. * an object, an associative array, or a single value by name.
  197. *
  198. * You are not allowed to set variables that begin with an underscore;
  199. * these are either private properties for JView or private variables
  200. * within the template script itself.
  201. *
  202. * <code>
  203. * $view = new JView;
  204. *
  205. * // Assign directly
  206. * $view->var1 = 'something';
  207. * $view->var2 = 'else';
  208. *
  209. * // Assign by name and value
  210. * $view->assign('var1', 'something');
  211. * $view->assign('var2', 'else');
  212. *
  213. * // Assign by assoc-array
  214. * $ary = array('var1' => 'something', 'var2' => 'else');
  215. * $view->assign($obj);
  216. *
  217. * // Assign by object
  218. * $obj = new stdClass;
  219. * $obj->var1 = 'something';
  220. * $obj->var2 = 'else';
  221. * $view->assign($obj);
  222. *
  223. * </code>
  224. *
  225. * @return boolean True on success, false on failure.
  226. *
  227. * @deprecated 13.3 Use native PHP syntax.
  228. */
  229. public function assign()
  230. {
  231. JLog::add(__METHOD__ . ' is deprecated. Use native PHP syntax.', JLog::WARNING, 'deprecated');
  232. // Get the arguments; there may be 1 or 2.
  233. $arg0 = @func_get_arg(0);
  234. $arg1 = @func_get_arg(1);
  235. // Assign by object
  236. if (is_object($arg0))
  237. {
  238. // Assign public properties
  239. foreach (get_object_vars($arg0) as $key => $val)
  240. {
  241. if (substr($key, 0, 1) != '_')
  242. {
  243. $this->$key = $val;
  244. }
  245. }
  246. return true;
  247. }
  248. // Assign by associative array
  249. if (is_array($arg0))
  250. {
  251. foreach ($arg0 as $key => $val)
  252. {
  253. if (substr($key, 0, 1) != '_')
  254. {
  255. $this->$key = $val;
  256. }
  257. }
  258. return true;
  259. }
  260. // Assign by string name and mixed value.
  261. // We use array_key_exists() instead of isset() because isset()
  262. // fails if the value is set to null.
  263. if (is_string($arg0) && substr($arg0, 0, 1) != '_' && func_num_args() > 1)
  264. {
  265. $this->$arg0 = $arg1;
  266. return true;
  267. }
  268. // $arg0 was not object, array, or string.
  269. return false;
  270. }
  271. /**
  272. * Assign variable for the view (by reference).
  273. *
  274. * You are not allowed to set variables that begin with an underscore;
  275. * these are either private properties for JView or private variables
  276. * within the template script itself.
  277. *
  278. * <code>
  279. * $view = new JView;
  280. *
  281. * // Assign by name and value
  282. * $view->assignRef('var1', $ref);
  283. *
  284. * // Assign directly
  285. * $view->ref = &$var1;
  286. * </code>
  287. *
  288. * @param string $key The name for the reference in the view.
  289. * @param mixed &$val The referenced variable.
  290. *
  291. * @return boolean True on success, false on failure.
  292. *
  293. * @since 12.2
  294. * @deprecated 13.3 Use native PHP syntax.
  295. */
  296. public function assignRef($key, &$val)
  297. {
  298. JLog::add(__METHOD__ . ' is deprecated. Use native PHP syntax.', JLog::WARNING, 'deprecated');
  299. if (is_string($key) && substr($key, 0, 1) != '_')
  300. {
  301. $this->$key = &$val;
  302. return true;
  303. }
  304. return false;
  305. }
  306. /**
  307. * Escapes a value for output in a view script.
  308. *
  309. * If escaping mechanism is either htmlspecialchars or htmlentities, uses
  310. * {@link $_encoding} setting.
  311. *
  312. * @param mixed $var The output to escape.
  313. *
  314. * @return mixed The escaped value.
  315. *
  316. * @since 12.2
  317. */
  318. public function escape($var)
  319. {
  320. if (in_array($this->_escape, array('htmlspecialchars', 'htmlentities')))
  321. {
  322. return call_user_func($this->_escape, $var, ENT_COMPAT, $this->_charset);
  323. }
  324. return call_user_func($this->_escape, $var);
  325. }
  326. /**
  327. * Method to get data from a registered model or a property of the view
  328. *
  329. * @param string $property The name of the method to call on the model or the property to get
  330. * @param string $default The name of the model to reference or the default value [optional]
  331. *
  332. * @return mixed The return value of the method
  333. *
  334. * @since 12.2
  335. */
  336. public function get($property, $default = null)
  337. {
  338. // If $model is null we use the default model
  339. if (is_null($default))
  340. {
  341. $model = $this->_defaultModel;
  342. }
  343. else
  344. {
  345. $model = strtolower($default);
  346. }
  347. // First check to make sure the model requested exists
  348. if (isset($this->_models[$model]))
  349. {
  350. // Model exists, let's build the method name
  351. $method = 'get' . ucfirst($property);
  352. // Does the method exist?
  353. if (method_exists($this->_models[$model], $method))
  354. {
  355. // The method exists, let's call it and return what we get
  356. $result = $this->_models[$model]->$method();
  357. return $result;
  358. }
  359. }
  360. // Degrade to JObject::get
  361. $result = parent::get($property, $default);
  362. return $result;
  363. }
  364. /**
  365. * Method to get the model object
  366. *
  367. * @param string $name The name of the model (optional)
  368. *
  369. * @return mixed JModelLegacy object
  370. *
  371. * @since 12.2
  372. */
  373. public function getModel($name = null)
  374. {
  375. if ($name === null)
  376. {
  377. $name = $this->_defaultModel;
  378. }
  379. return $this->_models[strtolower($name)];
  380. }
  381. /**
  382. * Get the layout.
  383. *
  384. * @return string The layout name
  385. */
  386. public function getLayout()
  387. {
  388. return $this->_layout;
  389. }
  390. /**
  391. * Get the layout template.
  392. *
  393. * @return string The layout template name
  394. */
  395. public function getLayoutTemplate()
  396. {
  397. return $this->_layoutTemplate;
  398. }
  399. /**
  400. * Method to get the view name
  401. *
  402. * The model name by default parsed using the classname, or it can be set
  403. * by passing a $config['name'] in the class constructor
  404. *
  405. * @return string The name of the model
  406. *
  407. * @since 12.2
  408. * @throws Exception
  409. */
  410. public function getName()
  411. {
  412. if (empty($this->_name))
  413. {
  414. $classname = get_class($this);
  415. $viewpos = strpos($classname, 'View');
  416. if ($viewpos === false)
  417. {
  418. throw new Exception(JText::_('JLIB_APPLICATION_ERROR_VIEW_GET_NAME'), 500);
  419. }
  420. $this->_name = strtolower(substr($classname, $viewpos + 4));
  421. }
  422. return $this->_name;
  423. }
  424. /**
  425. * Method to add a model to the view. We support a multiple model single
  426. * view system by which models are referenced by classname. A caveat to the
  427. * classname referencing is that any classname prepended by JModel will be
  428. * referenced by the name without JModel, eg. JModelCategory is just
  429. * Category.
  430. *
  431. * @param JModelLegacy $model The model to add to the view.
  432. * @param boolean $default Is this the default model?
  433. *
  434. * @return object The added model.
  435. *
  436. * @since 12.2
  437. */
  438. public function setModel($model, $default = false)
  439. {
  440. $name = strtolower($model->getName());
  441. $this->_models[$name] = $model;
  442. if ($default)
  443. {
  444. $this->_defaultModel = $name;
  445. }
  446. return $model;
  447. }
  448. /**
  449. * Sets the layout name to use
  450. *
  451. * @param string $layout The layout name or a string in format <template>:<layout file>
  452. *
  453. * @return string Previous value.
  454. *
  455. * @since 12.2
  456. */
  457. public function setLayout($layout)
  458. {
  459. $previous = $this->_layout;
  460. if (strpos($layout, ':') === false)
  461. {
  462. $this->_layout = $layout;
  463. }
  464. else
  465. {
  466. // Convert parameter to array based on :
  467. $temp = explode(':', $layout);
  468. $this->_layout = $temp[1];
  469. // Set layout template
  470. $this->_layoutTemplate = $temp[0];
  471. }
  472. return $previous;
  473. }
  474. /**
  475. * Allows a different extension for the layout files to be used
  476. *
  477. * @param string $value The extension.
  478. *
  479. * @return string Previous value
  480. *
  481. * @since 12.2
  482. */
  483. public function setLayoutExt($value)
  484. {
  485. $previous = $this->_layoutExt;
  486. if ($value = preg_replace('#[^A-Za-z0-9]#', '', trim($value)))
  487. {
  488. $this->_layoutExt = $value;
  489. }
  490. return $previous;
  491. }
  492. /**
  493. * Sets the _escape() callback.
  494. *
  495. * @param mixed $spec The callback for _escape() to use.
  496. *
  497. * @return void
  498. *
  499. * @since 12.2
  500. * @deprecated 13.3 Override JViewLegacy::escape() instead.
  501. */
  502. public function setEscape($spec)
  503. {
  504. JLog::add(__METHOD__ . ' is deprecated. Override JViewLegacy::escape() instead.', JLog::WARNING, 'deprecated');
  505. $this->_escape = $spec;
  506. }
  507. /**
  508. * Adds to the stack of view script paths in LIFO order.
  509. *
  510. * @param mixed $path A directory path or an array of paths.
  511. *
  512. * @return void
  513. *
  514. * @since 12.2
  515. */
  516. public function addTemplatePath($path)
  517. {
  518. $this->_addPath('template', $path);
  519. }
  520. /**
  521. * Adds to the stack of helper script paths in LIFO order.
  522. *
  523. * @param mixed $path A directory path or an array of paths.
  524. *
  525. * @return void
  526. *
  527. * @since 12.2
  528. */
  529. public function addHelperPath($path)
  530. {
  531. $this->_addPath('helper', $path);
  532. }
  533. /**
  534. * Load a template file -- first look in the templates folder for an override
  535. *
  536. * @param string $tpl The name of the template source file; automatically searches the template paths and compiles as needed.
  537. *
  538. * @return string The output of the the template script.
  539. *
  540. * @since 12.2
  541. * @throws Exception
  542. */
  543. public function loadTemplate($tpl = null)
  544. {
  545. // Clear prior output
  546. $this->_output = null;
  547. $template = JFactory::getApplication()->getTemplate();
  548. $layout = $this->getLayout();
  549. $layoutTemplate = $this->getLayoutTemplate();
  550. // Create the template file name based on the layout
  551. $file = isset($tpl) ? $layout . '_' . $tpl : $layout;
  552. // Clean the file name
  553. $file = preg_replace('/[^A-Z0-9_\.-]/i', '', $file);
  554. $tpl = isset($tpl) ? preg_replace('/[^A-Z0-9_\.-]/i', '', $tpl) : $tpl;
  555. // Load the language file for the template
  556. $lang = JFactory::getLanguage();
  557. $lang->load('tpl_' . $template, JPATH_BASE, null, false, false)
  558. || $lang->load('tpl_' . $template, JPATH_THEMES . "/$template", null, false, false)
  559. || $lang->load('tpl_' . $template, JPATH_BASE, $lang->getDefault(), false, false)
  560. || $lang->load('tpl_' . $template, JPATH_THEMES . "/$template", $lang->getDefault(), false, false);
  561. // Change the template folder if alternative layout is in different template
  562. if (isset($layoutTemplate) && $layoutTemplate != '_' && $layoutTemplate != $template)
  563. {
  564. $this->_path['template'] = str_replace($template, $layoutTemplate, $this->_path['template']);
  565. }
  566. // Load the template script
  567. jimport('joomla.filesystem.path');
  568. $filetofind = $this->_createFileName('template', array('name' => $file));
  569. $this->_template = JPath::find($this->_path['template'], $filetofind);
  570. // If alternate layout can't be found, fall back to default layout
  571. if ($this->_template == false)
  572. {
  573. $filetofind = $this->_createFileName('', array('name' => 'default' . (isset($tpl) ? '_' . $tpl : $tpl)));
  574. $this->_template = JPath::find($this->_path['template'], $filetofind);
  575. }
  576. if ($this->_template != false)
  577. {
  578. // Unset so as not to introduce into template scope
  579. unset($tpl);
  580. unset($file);
  581. // Never allow a 'this' property
  582. if (isset($this->this))
  583. {
  584. unset($this->this);
  585. }
  586. // Start capturing output into a buffer
  587. ob_start();
  588. // Include the requested template filename in the local scope
  589. // (this will execute the view logic).
  590. include $this->_template;
  591. // Done with the requested template; get the buffer and
  592. // clear it.
  593. $this->_output = ob_get_contents();
  594. ob_end_clean();
  595. return $this->_output;
  596. }
  597. else
  598. {
  599. throw new Exception(JText::sprintf('JLIB_APPLICATION_ERROR_LAYOUTFILE_NOT_FOUND', $file), 500);
  600. }
  601. }
  602. /**
  603. * Load a helper file
  604. *
  605. * @param string $hlp The name of the helper source file automatically searches the helper paths and compiles as needed.
  606. *
  607. * @return void
  608. *
  609. * @since 12.2
  610. */
  611. public function loadHelper($hlp = null)
  612. {
  613. // Clean the file name
  614. $file = preg_replace('/[^A-Z0-9_\.-]/i', '', $hlp);
  615. // Load the template script
  616. jimport('joomla.filesystem.path');
  617. $helper = JPath::find($this->_path['helper'], $this->_createFileName('helper', array('name' => $file)));
  618. if ($helper != false)
  619. {
  620. // Include the requested template filename in the local scope
  621. include_once $helper;
  622. }
  623. }
  624. /**
  625. * Sets an entire array of search paths for templates or resources.
  626. *
  627. * @param string $type The type of path to set, typically 'template'.
  628. * @param mixed $path The new search path, or an array of search paths. If null or false, resets to the current directory only.
  629. *
  630. * @return void
  631. *
  632. * @since 12.2
  633. */
  634. protected function _setPath($type, $path)
  635. {
  636. $component = JApplicationHelper::getComponentName();
  637. $app = JFactory::getApplication();
  638. // Clear out the prior search dirs
  639. $this->_path[$type] = array();
  640. // Actually add the user-specified directories
  641. $this->_addPath($type, $path);
  642. // Always add the fallback directories as last resort
  643. switch (strtolower($type))
  644. {
  645. case 'template':
  646. // Set the alternative template search dir
  647. if (isset($app))
  648. {
  649. $component = preg_replace('/[^A-Z0-9_\.-]/i', '', $component);
  650. $fallback = JPATH_THEMES . '/' . $app->getTemplate() . '/html/' . $component . '/' . $this->getName();
  651. $this->_addPath('template', $fallback);
  652. }
  653. break;
  654. }
  655. }
  656. /**
  657. * Adds to the search path for templates and resources.
  658. *
  659. * @param string $type The type of path to add.
  660. * @param mixed $path The directory or stream, or an array of either, to search.
  661. *
  662. * @return void
  663. *
  664. * @since 12.2
  665. */
  666. protected function _addPath($type, $path)
  667. {
  668. // Just force to array
  669. settype($path, 'array');
  670. // Loop through the path directories
  671. foreach ($path as $dir)
  672. {
  673. // No surrounding spaces allowed!
  674. $dir = trim($dir);
  675. // Add trailing separators as needed
  676. if (substr($dir, -1) != DIRECTORY_SEPARATOR)
  677. {
  678. // Directory
  679. $dir .= DIRECTORY_SEPARATOR;
  680. }
  681. // Add to the top of the search dirs
  682. array_unshift($this->_path[$type], $dir);
  683. }
  684. }
  685. /**
  686. * Create the filename for a resource
  687. *
  688. * @param string $type The resource type to create the filename for
  689. * @param array $parts An associative array of filename information
  690. *
  691. * @return string The filename
  692. *
  693. * @since 12.2
  694. */
  695. protected function _createFileName($type, $parts = array())
  696. {
  697. $filename = '';
  698. switch ($type)
  699. {
  700. case 'template':
  701. $filename = strtolower($parts['name']) . '.' . $this->_layoutExt;
  702. break;
  703. default:
  704. $filename = strtolower($parts['name']) . '.php';
  705. break;
  706. }
  707. return $filename;
  708. }
  709. }