Development

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

You must first sign up to be able to contribute.

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

Revision 28713, 14.0 kB (checked in by fabien, 5 years ago)

[1.3, 1.4] fixed layout.php is required even if you use decorate_with() to use another layout (closes #8441)

  • Property svn:mime-type set to text/x-php
  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
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     sfOutputEscaper::markClassesAsSafe(array('sfForm', 'sfFormField', 'sfFormFieldSchema', 'sfModelGeneratorHelper'));
116
117     $this->attributeHolder = $this->initializeAttributeHolder();
118
119     $this->parameterHolder = new sfParameterHolder();
120     $this->parameterHolder->add(sfConfig::get('mod_'.strtolower($moduleName).'_view_param', array()));
121
122     $request = $context->getRequest();
123
124     $format = $request->getRequestFormat();
125     if (null !== $format)
126     {
127       if ('html' != $format)
128       {
129         $this->setExtension('.'.$format.$this->getExtension());
130       }
131
132       if ($mimeType = $request->getMimeType($format))
133       {
134         $this->context->getResponse()->setContentType($mimeType);
135
136         if ('html' != $format)
137         {
138           $this->setDecorator(false);
139         }
140       }
141     }
142     $this->dispatcher->notify(new sfEvent($this, 'view.configure_format', array('format' => $format, 'response' => $context->getResponse(), 'request' => $context->getRequest())));
143
144     // include view configuration
145     $this->configure();
146
147     return true;
148   }
149
150   protected function initializeAttributeHolder($attributes = array())
151   {
152     $attributeHolder = new sfViewParameterHolder($this->dispatcher, $attributes, array(
153       'escaping_method'   => sfConfig::get('sf_escaping_method'),
154       'escaping_strategy' => sfConfig::get('sf_escaping_strategy'),
155     ));
156
157     return $attributeHolder;
158   }
159
160   /**
161    * Executes any presentation logic and set template attributes.
162    */
163   abstract function execute();
164
165   /**
166    * Configures template.
167    */
168   abstract function configure();
169
170   /**
171    * Retrieves this views decorator template directory.
172    *
173    * @return string An absolute filesystem path to this views decorator template directory
174    */
175   public function getDecoratorDirectory()
176   {
177     return $this->decoratorDirectory;
178   }
179
180   /**
181    * Retrieves this views decorator template.
182    *
183    * @return string A template filename, if a template has been set, otherwise null
184    */
185   public function getDecoratorTemplate()
186   {
187     return $this->decoratorTemplate;
188   }
189
190   /**
191    * Retrieves this view template directory.
192    *
193    * @return string An absolute filesystem path to this views template directory
194    */
195   public function getDirectory()
196   {
197     return $this->directory;
198   }
199
200   /**
201    * Retrieves the template engine associated with this view.
202    *
203    * Note: This will return null for PHPView instances.
204    *
205    * @return mixed A template engine instance
206    */
207   abstract function getEngine();
208
209   /**
210    * Retrieves this views template.
211    *
212    * @return string A template filename, if a template has been set, otherwise null
213    */
214   public function getTemplate()
215   {
216     return $this->template;
217   }
218
219   /**
220    * Retrieves attributes for the current view.
221    *
222    * @return sfParameterHolder The attribute parameter holder
223    */
224   public function getAttributeHolder()
225   {
226     return $this->attributeHolder;
227   }
228
229   /**
230    * Retrieves an attribute for the current view.
231    *
232    * @param  string $name     Name of the attribute
233    * @param  string $default  Value of the attribute
234    *
235    * @return mixed Attribute
236    */
237   public function getAttribute($name, $default = null)
238   {
239     return $this->attributeHolder->get($name, $default);
240   }
241
242   /**
243    * Returns true if the view have attributes.
244    *
245    * @param  string $name  Name of the attribute
246    *
247    * @return mixed Attribute of the view
248    */
249   public function hasAttribute($name)
250   {
251     return $this->attributeHolder->has($name);
252   }
253
254   /**
255    * Sets an attribute of the view.
256    *
257    * @param string $name   Attribute name
258    * @param string $value  Value for the attribute
259    */
260   public function setAttribute($name, $value)
261   {
262     $this->attributeHolder->set($name, $value);
263   }
264
265   /**
266    * Retrieves the parameters for the current view.
267    *
268    * @return sfParameterHolder The parameter holder
269    */
270   public function getParameterHolder()
271   {
272     return $this->parameterHolder;
273   }
274
275   /**
276    * Retrieves a parameter from the current view.
277    *
278    * @param  string $name     Parameter name
279    * @param  string $default  Default parameter value
280    *
281    * @return mixed A parameter value
282    */
283   public function getParameter($name, $default = null)
284   {
285     return $this->parameterHolder->get($name, $default);
286   }
287
288   /**
289    * Indicates whether or not a parameter exist for the current view.
290    *
291    * @param  string $name  Name of the parameter
292    *
293    * @return bool true, if the parameter exists otherwise false
294    */
295   public function hasParameter($name)
296   {
297     return $this->parameterHolder->has($name);
298   }
299
300   /**
301    * Sets a parameter for the view.
302    *
303    * @param string $name   Name of the parameter
304    * @param string $value  The parameter value
305    */
306   public function setParameter($name, $value)
307   {
308     $this->parameterHolder->set($name, $value);
309   }
310
311   /**
312    * Indicates that this view is a decorating view.
313    *
314    * @return bool true, if this view is a decorating view, otherwise false
315    */
316   public function isDecorator()
317   {
318     return $this->decorator;
319   }
320
321   /**
322    * Sets the decorating mode for the current view.
323    *
324    * @param bool $boolean  Set the decorating mode for the view
325    */
326   public function setDecorator($boolean)
327   {
328     $this->decorator = (boolean) $boolean;
329
330     if (false === $boolean)
331     {
332       $this->decoratorTemplate = false;
333     }
334   }
335
336   /**
337    * Executes a basic pre-render check to verify all required variables exist
338    * and that the template is readable.
339    *
340    * @throws sfRenderException If the pre-render check fails
341    */
342   protected function preRenderCheck()
343   {
344     if (null === $this->template)
345     {
346       // a template has not been set
347       throw new sfRenderException('A template has not been set.');
348     }
349
350     if (!is_readable($this->directory.'/'.$this->template))
351     {
352       // 404?
353       if ('404' == $this->context->getResponse()->getStatusCode())
354       {
355         // use default exception templates
356         $this->template = sfException::getTemplatePathForError($this->context->getRequest()->getRequestFormat(), false);
357         $this->directory = dirname($this->template);
358         $this->template = basename($this->template);
359         $this->setAttribute('code', '404');
360         $this->setAttribute('text', 'Not Found');
361       }
362       else
363       {
364         throw new sfRenderException(sprintf('The template "%s" does not exist or is unreadable in "%s".', $this->template, $this->directory));
365       }
366     }
367   }
368
369   /**
370    * Renders the presentation.
371    *
372    * @return string A string representing the rendered presentation
373    */
374   abstract function render();
375
376   /**
377    * Sets the decorator template directory for this view.
378    *
379    * @param string $directory  An absolute filesystem path to a template directory
380    */
381   public function setDecoratorDirectory($directory)
382   {
383     $this->decoratorDirectory = $directory;
384   }
385
386   /**
387    * Sets the decorator template for this view.
388    *
389    * If the template path is relative, it will be based on the currently
390    * executing module's template sub-directory.
391    *
392    * @param string $template  An absolute or relative filesystem path to a template
393    */
394   public function setDecoratorTemplate($template)
395   {
396     if (false === $template)
397     {
398       $this->setDecorator(false);
399
400       return;
401     }
402     else if (null === $template)
403     {
404       return;
405     }
406
407     if (!strpos($template, '.'))
408     {
409       $template .= $this->getExtension();
410     }
411
412     if (sfToolkit::isPathAbsolute($template))
413     {
414       $this->decoratorDirectory = dirname($template);
415       $this->decoratorTemplate  = basename($template);
416     }
417     else
418     {
419       $this->decoratorDirectory = $this->context->getConfiguration()->getDecoratorDir($template);
420       $this->decoratorTemplate = $template;
421     }
422
423     // set decorator status
424     $this->decorator = true;
425   }
426
427   /**
428    * Sets the template directory for this view.
429    *
430    * @param string $directory  An absolute filesystem path to a template directory
431    */
432   public function setDirectory($directory)
433   {
434     $this->directory = $directory;
435   }
436
437   /**
438    * Sets the module and action to be executed in place of a particular template attribute.
439    *
440    * @param string $attributeName  A template attribute name
441    * @param string $moduleName     A module name
442    * @param string $componentName  A component name
443    */
444   public function setComponentSlot($attributeName, $moduleName, $componentName)
445   {
446     $this->componentSlots[$attributeName]                   = array();
447     $this->componentSlots[$attributeName]['module_name']    = $moduleName;
448     $this->componentSlots[$attributeName]['component_name'] = $componentName;
449   }
450
451   /**
452    * Indicates whether or not a component slot exists.
453    *
454    * @param  string $name  The component slot name
455    *
456    * @return bool true, if the component slot exists, otherwise false
457    */
458   public function hasComponentSlot($name)
459   {
460     return isset($this->componentSlots[$name]);
461   }
462
463   /**
464    * Gets a component slot
465    *
466    * @param  string $name  The component slot name
467    *
468    * @return array The component slot
469    */
470   public function getComponentSlot($name)
471   {
472     if (isset($this->componentSlots[$name]) && $this->componentSlots[$name]['module_name'] && $this->componentSlots[$name]['component_name'])
473     {
474       return array($this->componentSlots[$name]['module_name'], $this->componentSlots[$name]['component_name']);
475     }
476
477     return null;
478   }
479
480   /**
481    * Sets the template for this view.
482    *
483    * If the template path is relative, it will be based on the currently
484    * executing module's template sub-directory.
485    *
486    * @param string $template  An absolute or relative filesystem path to a template
487    */
488   public function setTemplate($template)
489   {
490     if (sfToolkit::isPathAbsolute($template))
491     {
492       $this->directory = dirname($template);
493       $this->template  = basename($template);
494     }
495     else
496     {
497       $this->directory = $this->context->getConfiguration()->getTemplateDir($this->moduleName, $template);
498       $this->template = $template;
499     }
500   }
501
502   /**
503    * Retrieves the current view extension.
504    *
505    * @return string The extension for current view.
506    */
507   public function getExtension()
508   {
509     return $this->extension;
510   }
511
512   /**
513    * Sets an extension for the current view.
514    *
515    * @param string $extension  The extension name.
516    */
517   public function setExtension($extension)
518   {
519     $this->extension = $extension;
520   }
521
522   /**
523    * Gets the module name associated with this view.
524    *
525    * @return string A module name
526    */
527   public function getModuleName()
528   {
529     return $this->moduleName;
530   }
531
532   /**
533    * Gets the action name associated with this view.
534    *
535    * @return string An action name
536    */
537   public function getActionName()
538   {
539     return $this->actionName;
540   }
541
542   /**
543    * Gets the view name associated with this view.
544    *
545    * @return string An action name
546    */
547   public function getViewName()
548   {
549     return $this->viewName;
550   }
551
552   /**
553    * Calls methods defined via sfEventDispatcher.
554    *
555    * @param  string $method     The method name
556    * @param  array  $arguments  The method arguments
557    *
558    * @return mixed The returned value of the called method
559    *
560    * @throws sfException< If the calls fails
561    */
562   public function __call($method, $arguments)
563   {
564     $event = $this->dispatcher->notifyUntil(new sfEvent($this, 'view.method_not_found', array('method' => $method, 'arguments' => $arguments)));
565     if (!$event->isProcessed())
566     {
567       throw new sfException(sprintf('Call to undefined method %s::%s.', get_class($this), $method));
568     }
569
570     return $event->getReturnValue();
571   }
572 }
573
Note: See TracBrowser for help on using the browser.