Development

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

You must first sign up to be able to contribute.

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

Revision 9047, 14.4 kB (checked in by FabianLange, 6 years ago)

1.1: fixed @param phpdoc to fit specs in view and escaper (refs #2991)

  • 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  * A view represents the presentation layer of an action. Output can be
14  * customized by supplying attributes, which a template can manipulate and
15  * display.
16  *
17  * @package    symfony
18  * @subpackage view
19  * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
20  * @author     Sean Kerr <sean@code-box.org>
21  * @version    SVN: $Id$
22  */
23 abstract class sfView
24 {
25   /**
26    * Show an alert view.
27    */
28   const ALERT = 'Alert';
29
30   /**
31    * Show an error view.
32    */
33   const ERROR = 'Error';
34
35   /**
36    * Show a form input view.
37    */
38   const INPUT = 'Input';
39
40   /**
41    * Skip view execution.
42    */
43   const NONE = 'None';
44
45   /**
46    * Show a success view.
47    */
48   const SUCCESS = 'Success';
49
50   /**
51    * Do not render the presentation.
52    */
53   const RENDER_NONE = 1;
54
55   /**
56    * Render the presentation to the client.
57    */
58   const RENDER_CLIENT = 2;
59
60   /**
61    * Render the presentation to a variable.
62    */
63   const RENDER_VAR = 4;
64
65   /**
66    * Skip view rendering but output http headers
67    */
68   const HEADER_ONLY = 8;
69
70   protected
71     $context            = null,
72     $dispatcher         = null,
73     $decorator          = false,
74     $decoratorDirectory = null,
75     $decoratorTemplate  = null,
76     $directory          = null,
77     $componentSlots     = array(),
78     $template           = null,
79     $attributeHolder    = null,
80     $parameterHolder    = null,
81     $moduleName         = '',
82     $actionName         = '',
83     $viewName           = '',
84     $extension          = '.php';
85
86   /**
87    * Class constructor.
88    *
89    * @see initialize()
90    */
91   public function __construct($context, $moduleName, $actionName, $viewName)
92   {
93     $this->initialize($context, $moduleName, $actionName, $viewName);
94   }
95
96   /**
97    * Initializes this view.
98    *
99    * @param  sfContext $context     The current application context
100    * @param  string    $moduleName  The module name for this view
101    * @param  string    $actionName  The action name for this view
102    * @param  string    $viewName    The view name
103    *
104    * @return bool  true, if initialization completes successfully, otherwise false
105    */
106   public function initialize($context, $moduleName, $actionName, $viewName)
107   {
108     $this->moduleName = $moduleName;
109     $this->actionName = $actionName;
110     $this->viewName   = $viewName;
111
112     $this->context    = $context;
113     $this->dispatcher = $context->getEventDispatcher();
114
115     if (sfConfig::get('sf_logging_enabled'))
116     {
117       $this->dispatcher->notify(new sfEvent($this, 'application.log', array(sprintf('Initialize view for "%s/%s"', $moduleName, $actionName))));
118     }
119
120     sfOutputEscaper::markClassAsSafe('sfForm');
121
122     $this->attributeHolder = $this->initializeAttributeHolder();
123
124     $this->parameterHolder = new sfParameterHolder();
125     $this->parameterHolder->add(sfConfig::get('mod_'.strtolower($moduleName).'_view_param', array()));
126
127     $request = $context->getRequest();
128     if (!is_null($format = $request->getRequestFormat()))
129     {
130       if ('html' != $format)
131       {
132         $this->setExtension('.'.$format.$this->getExtension());
133       }
134
135       if ($mimeType = $request->getMimeType($format))
136       {
137         $this->context->getResponse()->setContentType($mimeType);
138         $this->setDecorator(false);
139       }
140
141       $this->dispatcher->notify(new sfEvent($this, 'view.configure_format', array('format' => $format, 'response' => $context->getResponse(), 'request' => $context->getRequest())));
142     }
143
144     // include view configuration
145     $this->configure();
146
147     return true;
148   }
149
150   protected function initializeAttributeHolder($attributes = array())
151   {
152     if ('both' === sfConfig::get('sf_escaping_strategy'))
153     {
154       $this->dispatcher->notify(new sfEvent($this, 'application.log', array('Escaping strategy "both" is deprecated, please use "on".', 'priority' => sfLogger::ERR)));
155       sfConfig::set('sf_escaping_strategy', 'on');
156     }
157     else if ('bc' === sfConfig::get('sf_escaping_strategy'))
158     {
159       $this->dispatcher->notify(new sfEvent($this, 'application.log', array('Escaping strategy "bc" is deprecated, please use "off".', 'priority' => sfLogger::ERR)));
160       sfConfig::set('sf_escaping_strategy', 'off');
161     }
162
163     $attributeHolder = new sfViewParameterHolder($this->dispatcher, $attributes, array(
164       'escaping_method'   => sfConfig::get('sf_escaping_method'),
165       'escaping_strategy' => sfConfig::get('sf_escaping_strategy'),
166     ));
167
168     return $attributeHolder;
169   }
170
171   /**
172    * Executes any presentation logic and set template attributes.
173    */
174   abstract function execute();
175
176   /**
177    * Configures template.
178    */
179   abstract function configure();
180
181   /**
182    * Retrieves this views decorator template directory.
183    *
184    * @return string An absolute filesystem path to this views decorator template directory
185    */
186   public function getDecoratorDirectory()
187   {
188     return $this->decoratorDirectory;
189   }
190
191   /**
192    * Retrieves this views decorator template.
193    *
194    * @return string A template filename, if a template has been set, otherwise null
195    */
196   public function getDecoratorTemplate()
197   {
198     return $this->decoratorTemplate;
199   }
200
201   /**
202    * Retrieves this view template directory.
203    *
204    * @return string An absolute filesystem path to this views template directory
205    */
206   public function getDirectory()
207   {
208     return $this->directory;
209   }
210
211   /**
212    * Retrieves the template engine associated with this view.
213    *
214    * Note: This will return null for PHPView instances.
215    *
216    * @return mixed A template engine instance
217    */
218   abstract function getEngine();
219
220   /**
221    * Retrieves this views template.
222    *
223    * @return string A template filename, if a template has been set, otherwise null
224    */
225   public function getTemplate()
226   {
227     return $this->template;
228   }
229
230   /**
231    * Retrieves attributes for the current view.
232    *
233    * @return sfParameterHolder The attribute parameter holder
234    */
235   public function getAttributeHolder()
236   {
237     return $this->attributeHolder;
238   }
239
240   /**
241    * Retrieves an attribute for the current view.
242    *
243    * @param  string $name     Name of the attribute
244    * @param  string $default  Value of the attribute
245    *
246    * @return mixed Attribute
247    */
248   public function getAttribute($name, $default = null)
249   {
250     return $this->attributeHolder->get($name, $default);
251   }
252
253   /**
254    * Returns true if the view have attributes.
255    *
256    * @param  string $name  Name of the attribute
257    *
258    * @return mixed Attribute of the view
259    */
260   public function hasAttribute($name)
261   {
262     return $this->attributeHolder->has($name);
263   }
264
265   /**
266    * Sets an attribute of the view.
267    *
268    * @param string $name   Attribute name
269    * @param string $value  Value for the attribute
270    */
271   public function setAttribute($name, $value)
272   {
273     $this->attributeHolder->set($name, $value);
274   }
275
276   /**
277    * Retrieves the parameters for the current view.
278    *
279    * @return sfParameterHolder The parameter holder
280    */
281   public function getParameterHolder()
282   {
283     return $this->parameterHolder;
284   }
285
286   /**
287    * Retrieves a parameter from the current view.
288    *
289    * @param  string $name     Parameter name
290    * @param  string $default  Default parameter value
291    *
292    * @return mixed A parameter value
293    */
294   public function getParameter($name, $default = null)
295   {
296     return $this->parameterHolder->get($name, $default);
297   }
298
299   /**
300    * Indicates whether or not a parameter exist for the current view.
301    *
302    * @param  string $name  Name of the paramater
303    *
304    * @return bool true, if the parameter exists otherwise false
305    */
306   public function hasParameter($name)
307   {
308     return $this->parameterHolder->has($name);
309   }
310
311   /**
312    * Sets a parameter for the view.
313    *
314    * @param string $name   Name of the parameter
315    * @param string $value  The parameter value
316    */
317   public function setParameter($name, $value)
318   {
319     $this->parameterHolder->set($name, $value);
320   }
321
322   /**
323    * Indicates that this view is a decorating view.
324    *
325    * @return bool true, if this view is a decorating view, otherwise false
326    */
327   public function isDecorator()
328   {
329     return $this->decorator;
330   }
331
332   /**
333    * Sets the decorating mode for the current view.
334    *
335    * @param bool $boolean  Set the decorating mode for the view
336    */
337   public function setDecorator($boolean)
338   {
339     $this->decorator = (boolean) $boolean;
340
341     if (false === $boolean)
342     {
343       $this->decoratorTemplate = false;
344     }
345   }
346
347   /**
348    * Executes a basic pre-render check to verify all required variables exist
349    * and that the template is readable.
350    *
351    * @throws sfRenderException If the pre-render check fails
352    */
353   protected function preRenderCheck()
354   {
355     if (is_null($this->template))
356     {
357       // a template has not been set
358       throw new sfRenderException('A template has not been set.');
359     }
360
361     if (!is_readable($this->directory.'/'.$this->template))
362     {
363       throw new sfRenderException(sprintf('The template "%s" does not exist or is unreadable in "%s".', $this->template, $this->directory));
364     }
365
366     // check to see if this is a decorator template
367     if ($this->decorator && !is_readable($this->decoratorDirectory.'/'.$this->decoratorTemplate))
368     {
369       throw new sfRenderException(sprintf('The decorator template "%s" does not exist or is unreadable in "%s".', $this->decoratorTemplate, $this->decoratorDirectory));
370     }
371   }
372
373   /**
374    * Renders the presentation.
375    *
376    * @return string A string representing the rendered presentation
377    */
378   abstract function render();
379
380   /**
381    * Sets the decorator template directory for this view.
382    *
383    * @param string $directory  An absolute filesystem path to a template directory
384    */
385   public function setDecoratorDirectory($directory)
386   {
387     $this->decoratorDirectory = $directory;
388   }
389
390   /**
391    * Sets the decorator template for this view.
392    *
393    * If the template path is relative, it will be based on the currently
394    * executing module's template sub-directory.
395    *
396    * @param string $template  An absolute or relative filesystem path to a template
397    */
398   public function setDecoratorTemplate($template)
399   {
400     if (false === $template)
401     {
402       $this->setDecorator(false);
403
404       return;
405     }
406     else if (is_null($template))
407     {
408       return;
409     }
410
411     if (!strpos($template, '.'))
412     {
413       $template .= $this->getExtension();
414     }
415
416     if (sfToolkit::isPathAbsolute($template))
417     {
418       $this->decoratorDirectory = dirname($template);
419       $this->decoratorTemplate  = basename($template);
420     }
421     else
422     {
423       $this->decoratorDirectory = $this->context->getConfiguration()->getDecoratorDir($template);
424       $this->decoratorTemplate = $template;
425     }
426
427     // set decorator status
428     $this->decorator = true;
429   }
430
431   /**
432    * Sets the template directory for this view.
433    *
434    * @param string $directory  An absolute filesystem path to a template directory
435    */
436   public function setDirectory($directory)
437   {
438     $this->directory = $directory;
439   }
440
441   /**
442    * Sets the module and action to be executed in place of a particular template attribute.
443    *
444    * @param string $attributeName  A template attribute name
445    * @param string $moduleName     A module name
446    * @param string $componentName  A component name
447    */
448   public function setComponentSlot($attributeName, $moduleName, $componentName)
449   {
450     $this->componentSlots[$attributeName]                   = array();
451     $this->componentSlots[$attributeName]['module_name']    = $moduleName;
452     $this->componentSlots[$attributeName]['component_name'] = $componentName;
453   }
454
455   /**
456    * Indicates whether or not a component slot exists.
457    *
458    * @param  string $name  The component slot name
459    *
460    * @return bool true, if the component slot exists, otherwise false
461    */
462   public function hasComponentSlot($name)
463   {
464     return isset($this->componentSlots[$name]);
465   }
466
467   /**
468    * Gets a component slot
469    *
470    * @param  string $name  The component slot name
471    *
472    * @return array The component slot
473    */
474   public function getComponentSlot($name)
475   {
476     if (isset($this->componentSlots[$name]) && $this->componentSlots[$name]['module_name'] && $this->componentSlots[$name]['component_name'])
477     {
478       return array($this->componentSlots[$name]['module_name'], $this->componentSlots[$name]['component_name']);
479     }
480
481     return null;
482   }
483
484   /**
485    * Sets the template for this view.
486    *
487    * If the template path is relative, it will be based on the currently
488    * executing module's template sub-directory.
489    *
490    * @param string $template  An absolute or relative filesystem path to a template
491    */
492   public function setTemplate($template)
493   {
494     if (sfToolkit::isPathAbsolute($template))
495     {
496       $this->directory = dirname($template);
497       $this->template  = basename($template);
498     }
499     else
500     {
501       $this->directory = $this->context->getConfiguration()->getTemplateDir($this->moduleName, $template);
502       $this->template = $template;
503     }
504   }
505
506   /**
507    * Retrieves the current view extension.
508    *
509    * @return string The extension for current view.
510    */
511   public function getExtension()
512   {
513     return $this->extension;
514   }
515
516   /**
517    * Sets an extension for the current view.
518    *
519    * @param string $extension  The extension name.
520    */
521   public function setExtension($extension)
522   {
523     $this->extension = $extension;
524   }
525
526   /**
527    * Gets the module name associated with this view.
528    *
529    * @return string A module name
530    */
531   public function getModuleName()
532   {
533     return $this->moduleName;
534   }
535
536   /**
537    * Gets the action name associated with this view.
538    *
539    * @return string An action name
540    */
541   public function getActionName()
542   {
543     return $this->actionName;
544   }
545
546   /**
547    * Gets the view name associated with this view.
548    *
549    * @return string An action name
550    */
551   public function getViewName()
552   {
553     return $this->viewName;
554   }
555
556   /**
557    * Calls methods defined via sfEventDispatcher.
558    *
559    * @param  string $method     The method name
560    * @param  array  $arguments  The method arguments
561    *
562    * @return mixed The returned value of the called method
563    *
564    * @throws sfException< If the calls fails
565    */
566   public function __call($method, $arguments)
567   {
568     $event = $this->dispatcher->notifyUntil(new sfEvent($this, 'view.method_not_found', array('method' => $method, 'arguments' => $arguments)));
569     if (!$event->isProcessed())
570     {
571       throw new sfException(sprintf('Call to undefined method %s::%s.', get_class($this), $method));
572     }
573
574     return $event->getReturnValue();
575   }
576 }
577
Note: See TracBrowser for help on using the browser.