Development

/branches/1.0/lib/view/sfView.class.php

You must first sign up to be able to contribute.

root/branches/1.0/lib/view/sfView.class.php

Revision 7791, 16.6 kB (checked in by fabien, 6 years ago)

updated Sean Kerr email address

  • Property svn:mime-type set to text/x-php
  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Rev Date
Line 
1 <?php
2
3 /*
4  * This file is part of the symfony package.
5  * (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
6  * (c) 2004-2006 Sean Kerr <sean@code-box.org>
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11
12 /**
13  *
14  * A view represents the presentation layer of an action. Output can be
15  * customized by supplying attributes, which a template can manipulate and
16  * display.
17  *
18  * @package    symfony
19  * @subpackage view
20  * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
21  * @author     Sean Kerr <sean@code-box.org>
22  * @version    SVN: $Id$
23  */
24 abstract class sfView
25 {
26   /**
27    * Show an alert view.
28    */
29   const ALERT = 'Alert';
30
31   /**
32    * Show an error view.
33    */
34   const ERROR = 'Error';
35
36   /**
37    * Show a form input view.
38    */
39   const INPUT = 'Input';
40
41   /**
42    * Skip view execution.
43    */
44   const NONE = 'None';
45
46   /**
47    * Show a success view.
48    */
49   const SUCCESS = 'Success';
50
51   /**
52     * Skip view rendering but output http headers
53     */
54   const HEADER_ONLY = 'Headers';
55
56   /**
57    * Render the presentation to the client.
58    */
59   const RENDER_CLIENT = 2;
60
61   /**
62    * Do not render the presentation.
63    */
64   const RENDER_NONE = 1;
65
66   /**
67    * Render the presentation to a variable.
68    */
69   const RENDER_VAR = 4;
70
71   protected
72     $context            = null,
73     $decorator          = false,
74     $decoratorDirectory = null,
75     $decoratorTemplate  = null,
76     $directory          = null,
77     $componentSlots     = array(),
78     $template           = null,
79     $escaping           = null,
80     $escapingMethod     = null,
81     $attributeHolder    = null,
82     $parameterHolder    = null,
83     $moduleName         = '',
84     $actionName         = '',
85     $viewName           = '',
86     $extension          = '.php';
87
88   /**
89    * Executes any presentation logic and set template attributes.
90    */
91   abstract function execute();
92
93   /**
94    * Configures template.
95    */
96   abstract function configure();
97
98   /**
99    * Retrieves the current application context.
100    *
101    * @return sfContext The current sfContext instance
102    */
103   public final function getContext()
104   {
105     return $this->context;
106   }
107
108   /**
109    * Retrieves this views decorator template directory.
110    *
111    * @return string An absolute filesystem path to this views decorator template directory
112    */
113   public function getDecoratorDirectory()
114   {
115     return $this->decoratorDirectory;
116   }
117
118   /**
119    * Retrieves this views decorator template.
120    *
121    * @return string A template filename, if a template has been set, otherwise null
122    */
123   public function getDecoratorTemplate()
124   {
125     return $this->decoratorTemplate;
126   }
127
128   /**
129    * Retrieves this view template directory.
130    *
131    * @return string An absolute filesystem path to this views template directory
132    */
133   public function getDirectory()
134   {
135     return $this->directory;
136   }
137
138   /**
139    * Retrieves the template engine associated with this view.
140    *
141    * Note: This will return null for PHPView instances.
142    *
143    * @return mixed A template engine instance
144    */
145   abstract function getEngine();
146
147   /**
148    * Retrieves this views template.
149    *
150    * @return string A template filename, if a template has been set, otherwise null
151    */
152   public function getTemplate()
153   {
154     return $this->template;
155   }
156
157   /**
158    * Gets the default escaping strategy associated with this view.
159    *
160    * The escaping strategy specifies how the variables get passed to the view.
161    *
162    * @return string the escaping strategy
163    */
164   public function getEscaping()
165   {
166     return null === $this->escaping ? sfConfig::get('sf_escaping_strategy') : $this->escaping;
167   }
168
169   /**
170    * Returns the name of the function that is to be used as the escaping method.
171    *
172    * If the escaping method is empty, then that is returned. The default value
173    * specified by the sub-class will be used. If the method does not exist (in
174    * the sense there is no define associated with the method) and exception is
175    * thrown.
176    *
177    * @return string The escaping method as the name of the function to use
178    *
179    * @throws <b>sfException</b> If the method does not exist
180    */
181   public function getEscapingMethod()
182   {
183     $method = null === $this->escapingMethod ? sfConfig::get('sf_escaping_method') : $this->escapingMethod;
184
185     if (empty($method))
186     {
187       return $method;
188     }
189
190     if (!defined($method))
191     {
192       throw new sfException(sprintf('Escaping method "%s" is not available; perhaps another helper needs to be loaded in?', $method));
193     }
194
195     return constant($method);
196   }
197
198   /**
199    * Imports parameter values and error messages from the request directly as view attributes.
200    *
201    * @param array An indexed array of file/parameter names
202    * @param boolean  Is this a list of files?
203    * @param boolean  Import error messages too?
204    * @param boolean  Run strip_tags() on attribute value?
205    * @param boolean  Run htmlspecialchars() on attribute value?
206    */
207   public function importAttributes($names, $files = false, $errors = true, $stripTags = true, $specialChars = true)
208   {
209     // alias $request to keep the code clean
210     $request = $this->context->getRequest();
211
212     // get our array
213     if ($files)
214     {
215       // file names
216       $array =& $request->getFiles();
217     }
218     else
219     {
220       // parameter names
221       $array =& $request->getParameterHolder()->getAll();
222     }
223
224     // loop through our parameter names and import them
225     foreach ($names as &$name)
226     {
227         if (preg_match('/^([a-z0-9\-_]+)\{([a-z0-9\s\-_]+)\}$/i', $name, $match))
228         {
229           // we have a parent
230           $parent  = $match[1];
231           $subname = $match[2];
232
233           // load the file/parameter value for this attribute if one exists
234           if (isset($array[$parent]) && isset($array[$parent][$subname]))
235           {
236             $value = $array[$parent][$subname];
237
238             if ($stripTags)
239               $value = strip_tags($value);
240
241             if ($specialChars)
242               $value = htmlspecialchars($value);
243
244             $this->setAttribute($name, $value);
245           }
246           else
247           {
248             // set an empty value
249             $this->setAttribute($name, '');
250           }
251         }
252         else
253         {
254           // load the file/parameter value for this attribute if one exists
255           if (isset($array[$name]))
256           {
257             $value = $array[$name];
258
259             if ($stripTags)
260               $value = strip_tags($value);
261
262             if ($specialChars)
263               $value = htmlspecialchars($value);
264
265             $this->setAttribute($name, $value);
266           }
267           else
268           {
269             // set an empty value
270             $this->setAttribute($name, '');
271           }
272         }
273
274         if ($errors)
275         {
276           if ($request->hasError($name))
277           {
278             $this->setAttribute($name.'_error', $request->getError($name));
279           }
280           else
281           {
282             // set empty error
283             $this->setAttribute($name.'_error', '');
284           }
285         }
286     }
287   }
288
289   /**
290    * Initializes this view.
291    *
292    * @param sfContext The current application context
293    * @param string The module name for this view
294    * @param string The action name for this view
295    * @param string The view name
296    *
297    * @return boolean true, if initialization completes successfully, otherwise false
298    */
299   public function initialize($context, $moduleName, $actionName, $viewName)
300   {
301     if (sfConfig::get('sf_logging_enabled'))
302     {
303       $context->getLogger()->info(sprintf('{sfView} initialize view for "%s/%s"', $moduleName, $actionName));
304     }
305
306     $this->moduleName = $moduleName;
307     $this->actionName = $actionName;
308     $this->viewName   = $viewName;
309
310     $this->context = $context;
311     $this->attributeHolder = new sfParameterHolder();
312     $this->parameterHolder = new sfParameterHolder();
313
314     $this->parameterHolder->add(sfConfig::get('mod_'.strtolower($moduleName).'_view_param', array()));
315
316     $this->decoratorDirectory = sfConfig::get('sf_app_template_dir');
317
318     // include view configuration
319     $this->configure();
320
321     return true;
322   }
323
324   /**
325    * Retrieves attributes for the current view.
326    *
327    * @return sfParameterHolder The attribute parameter holder
328    */
329   public function getAttributeHolder()
330   {
331     return $this->attributeHolder;
332   }
333
334   /**
335    * Retrieves an attribute for the current view.
336    *
337    * @param string Name of the attribute
338    * @param string Value of the attribute
339    * @param string The current namespace
340    *
341    * @return mixed Attribute
342    */
343   public function getAttribute($name, $default = null, $ns = null)
344   {
345     return $this->attributeHolder->get($name, $default, $ns);
346   }
347
348   /**
349    * Returns true if the view have attributes.
350    *
351    * @param string Name of the attribute
352    * @param string Namespace for the current view
353    *
354    * @return mixed Attribute of the view
355    */
356   public function hasAttribute($name, $ns = null)
357   {
358     return $this->attributeHolder->has($name, $ns);
359   }
360
361   /**
362    * Sets an attribute of the view.
363    *
364    * @param string Attribute name
365    * @param string Value for the attribute
366    * @param string Namespace for the current
367    */
368   public function setAttribute($name, $value, $ns = null)
369   {
370     $this->attributeHolder->set($name, $value, $ns);
371   }
372
373   /**
374    * Retrieves the parameters for the current view.
375    *
376    * @return sfParameterHolder The parameter holder
377    */
378   public function getParameterHolder()
379   {
380     return $this->parameterHolder;
381   }
382
383   /**
384    * Retrieves a parameter from the current view.
385    *
386    * @param string Parameter name
387    * @param string Default parameter value
388    * @param string Namespace for the current view
389    *
390    * @return mixed A parameter value
391    */
392   public function getParameter($name, $default = null, $ns = null)
393   {
394     return $this->parameterHolder->get($name, $default, $ns);
395   }
396
397   /**
398    * Indicates whether or not a parameter exist for the current view.
399    *
400    * @param string Name of the paramater
401    * @param string Namespace for the current view
402    *
403    * @return boolean true, if the parameter exists otherwise false
404    */
405   public function hasParameter($name, $ns = null)
406   {
407     return $this->parameterHolder->has($name, $ns);
408   }
409
410   /**
411    * Sets a parameter for the view.
412    *
413    * @param string Name of the parameter
414    * @param string The parameter value
415    * @param string Namespace for the current view
416    */
417   public function setParameter($name, $value, $ns = null)
418   {
419     $this->parameterHolder->set($name, $value, $ns);
420   }
421
422   /**
423    * Indicates that this view is a decorating view.
424    *
425    * @return boolean true, if this view is a decorating view, otherwise false
426    */
427   public function isDecorator()
428   {
429     return $this->decorator;
430   }
431
432   /**
433    * Sets the decorating mode for the current view.
434    *
435    * @param boolean Set the decorating mode for the view
436    */
437   public function setDecorator($boolean)
438   {
439     $this->decorator = (boolean) $boolean;
440   }
441
442   /**
443    * Executes a basic pre-render check to verify all required variables exist
444    * and that the template is readable.
445    *
446    * @throws <b>sfRenderException</b> If the pre-render check fails
447    */
448   protected function preRenderCheck()
449   {
450     if ($this->template == null)
451     {
452       // a template has not been set
453       $error = 'A template has not been set';
454
455       throw new sfRenderException($error);
456     }
457
458     $template = $this->directory.'/'.$this->template;
459
460     if (!is_readable($template))
461     {
462       // the template isn't readable
463       throw new sfRenderException(sprintf('The template "%s" does not exist in: %s', $template, $this->directory));
464     }
465
466     // check to see if this is a decorator template
467     if ($this->decorator)
468     {
469       $template = $this->decoratorDirectory.'/'.$this->decoratorTemplate;
470
471       if (!is_readable($template))
472       {
473         // the decorator template isn't readable
474         $error = 'The decorator template "%s" does not exist or is unreadable';
475         $error = sprintf($error, $template);
476
477         throw new sfRenderException($error);
478       }
479     }
480   }
481
482   /**
483    * Renders the presentation.
484    *
485    * When the controller render mode is sfView::RENDER_CLIENT, this method will
486    * render the presentation directly to the client and null will be returned.
487    *
488    * @param  array  An array with variables that will be extracted for the template
489    *                If empty, the current actions var holder will be extracted
490    * @return string A string representing the rendered presentation, if
491    *                the controller render mode is sfView::RENDER_VAR, otherwise null
492    */
493   abstract function render($templateVars = null);
494
495   /**
496    * Sets the decorator template directory for this view.
497    *
498    * @param string An absolute filesystem path to a template directory
499    */
500   public function setDecoratorDirectory($directory)
501   {
502     $this->decoratorDirectory = $directory;
503   }
504
505   /**
506    * Sets the escape caracter mode.
507    *
508    * @param string Escape code
509    */
510   public function setEscaping($escaping)
511   {
512     $this->escaping = $escaping;
513   }
514
515   /**
516    * Sets the escaping method for the current view.
517    *
518    * @param string Method for escaping
519    */
520   public function setEscapingMethod($method)
521   {
522     $this->escapingMethod = $method;
523   }
524
525   /**
526    * Sets the decorator template for this view.
527    *
528    * If the template path is relative, it will be based on the currently
529    * executing module's template sub-directory.
530    *
531    * @param string An absolute or relative filesystem path to a template
532    */
533   public function setDecoratorTemplate($template)
534   {
535     if (sfToolkit::isPathAbsolute($template))
536     {
537       $this->decoratorDirectory = dirname($template);
538       $this->decoratorTemplate  = basename($template);
539     }
540     else
541     {
542       $this->decoratorTemplate = $template;
543     }
544
545     if (!strpos($this->decoratorTemplate, '.'))
546     {
547       $this->decoratorTemplate .= $this->getExtension();
548     }
549
550     // set decorator status
551     $this->decorator = true;
552   }
553
554   /**
555    * Sets the template directory for this view.
556    *
557    * @param string An absolute filesystem path to a template directory
558    */
559   public function setDirectory($directory)
560   {
561     $this->directory = $directory;
562   }
563
564   /**
565    * Sets the module and action to be executed in place of a particular template attribute.
566    *
567    * @param string A template attribute name
568    * @param string A module name
569    * @param string A component name
570    */
571   public function setComponentSlot($attributeName, $moduleName, $componentName)
572   {
573     $this->componentSlots[$attributeName]                   = array();
574     $this->componentSlots[$attributeName]['module_name']    = $moduleName;
575     $this->componentSlots[$attributeName]['component_name'] = $componentName;
576   }
577
578   /**
579    * Indicates whether or not a component slot exists.
580    *
581    * @param  string The component slot name
582    *
583    * @return boolean true, if the component slot exists, otherwise false
584    */
585   public function hasComponentSlot($name)
586   {
587     return isset($this->componentSlots[$name]);
588   }
589
590   /**
591    * Gets a component slot
592    *
593    * @param  string The component slot name
594    *
595    * @return array The component slot
596    */
597   public function getComponentSlot($name)
598   {
599     if (isset($this->componentSlots[$name]) && $this->componentSlots[$name]['module_name'] && $this->componentSlots[$name]['component_name'])
600     {
601       return array($this->componentSlots[$name]['module_name'], $this->componentSlots[$name]['component_name']);
602     }
603
604     return null;
605   }
606
607   /**
608    * Sets the template for this view.
609    *
610    * If the template path is relative, it will be based on the currently
611    * executing module's template sub-directory.
612    *
613    * @param string An absolute or relative filesystem path to a template
614    */
615   public function setTemplate($template)
616   {
617     if (sfToolkit::isPathAbsolute($template))
618     {
619       $this->directory = dirname($template);
620       $this->template  = basename($template);
621     }
622     else
623     {
624       $this->template = $template;
625     }
626   }
627
628   /**
629    * Retrieves the current view extension.
630    *
631    * @return string The extension for current view.
632    */
633   public function getExtension()
634   {
635     return $this->extension;
636   }
637
638   /**
639    * Sets an extension for the current view.
640    *
641    * @param string The extension name.
642    */
643   public function setExtension($ext)
644   {
645     $this->extension = $ext;
646   }
647
648   /**
649    * Overloads a given method
650    *
651    * @param string Method name
652    * @param string Method arguments
653    *
654    * @return mixed User function callback
655    *
656    * @throws <b>sfException</b> If the call fails
657    */
658   public function __call($method, $arguments)
659   {
660     if (!$callable = sfMixer::getCallable('sfView:'.$method))
661     {
662       throw new sfException(sprintf('Call to undefined method sfView::%s', $method));
663     }
664
665     array_unshift($arguments, $this);
666
667     return call_user_func_array($callable, $arguments);
668   }
669 }
670
Note: See TracBrowser for help on using the browser.