Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 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: sfView.class.php 28713 2010-03-23 15:08:22Z fabien $
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
}