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