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
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
 
11
/**
12
 * sfViewConfigHandler allows you to configure views.
13
 *
14
 * @package    symfony
15
 * @subpackage config
16
 * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
17
 * @version    SVN: $Id: sfViewConfigHandler.class.php 23810 2009-11-12 11:07:44Z Kris.Wallsmith $
18
 */
19
class sfViewConfigHandler extends sfYamlConfigHandler
20
{
21
  /**
22
   * Executes this configuration handler.
23
   *
24
   * @param array $configFiles An array of absolute filesystem path to a configuration file
25
   *
26
   * @return string Data to be written to a cache file
27
   *
28
   * @throws <b>sfConfigurationException</b> If a requested configuration file does not exist or is not readable
29
   * @throws <b>sfParseException</b> If a requested configuration file is improperly formatted
30
   * @throws <b>sfInitializationException</b> If a view.yml key check fails
31
   */
32
  public function execute($configFiles)
33
  {
34
    // parse the yaml
35
    $this->yamlConfig = self::getConfiguration($configFiles);
36
 
37
    // init our data array
38
    $data = array();
39
 
40
    $data[] = "\$response = \$this->context->getResponse();\n\n";
41
 
42
    // first pass: iterate through all view names to determine the real view name
43
    $first = true;
44
    foreach ($this->yamlConfig as $viewName => $values)
45
    {
46
      if ($viewName == 'all')
47
      {
48
        continue;
49
      }
50
 
51
      $data[] = ($first ? '' : 'else ')."if (\$this->actionName.\$this->viewName == '$viewName')\n".
52
                "{\n";
53
      $data[] = $this->addTemplate($viewName);
54
      $data[] = "}\n";
55
 
56
      $first = false;
57
    }
58
 
59
    // general view configuration
60
    $data[] = ($first ? '' : "else\n{")."\n";
61
    $data[] = $this->addTemplate($viewName);
62
    $data[] = ($first ? '' : "}")."\n\n";
63
 
64
    // second pass: iterate through all real view names
65
    $first = true;
66
    foreach ($this->yamlConfig as $viewName => $values)
67
    {
68
      if ($viewName == 'all')
69
      {
70
        continue;
71
      }
72
 
73
      $data[] = ($first ? '' : 'else ')."if (\$templateName.\$this->viewName == '$viewName')\n".
74
                "{\n";
75
 
76
      $data[] = $this->addLayout($viewName);
77
      $data[] = $this->addComponentSlots($viewName);
78
      $data[] = $this->addHtmlHead($viewName);
79
      $data[] = $this->addEscaping($viewName);
80
 
81
      $data[] = $this->addHtmlAsset($viewName);
82
 
83
      $data[] = "}\n";
84
 
85
      $first = false;
86
    }
87
 
88
    // general view configuration
89
    $data[] = ($first ? '' : "else\n{")."\n";
90
 
91
    $data[] = $this->addLayout();
92
    $data[] = $this->addComponentSlots();
93
    $data[] = $this->addHtmlHead();
94
    $data[] = $this->addEscaping();
95
 
96
    $data[] = $this->addHtmlAsset();
97
    $data[] = ($first ? '' : "}")."\n";
98
 
99
    // compile data
100
    $retval = sprintf("<?php\n".
101
                      "// auto-generated by sfViewConfigHandler\n".
102
                      "// date: %s\n%s\n",
103
                      date('Y/m/d H:i:s'), implode('', $data));
104
 
105
    return $retval;
106
  }
107
 
108
  /**
109
   * Adds a component slot statement to the data.
110
   *
111
   * @param string $viewName The view name
112
   *
113
   * @return string The PHP statement
114
   */
115
  protected function addComponentSlots($viewName = '')
116
  {
117
    $data = '';
118
 
119
    $components = $this->mergeConfigValue('components', $viewName);
120
    foreach ($components as $name => $component)
121
    {
122
      if (!is_array($component) || count($component) < 1)
123
      {
124
        $component = array(null, null);
125
      }
126
 
127
      $data .= "  \$this->setComponentSlot('$name', '{$component[0]}', '{$component[1]}');\n";
128
      $data .= "  if (sfConfig::get('sf_logging_enabled')) \$this->context->getEventDispatcher()->notify(new sfEvent(\$this, 'application.log', array(sprintf('Set component \"%s\" (%s/%s)', '$name', '{$component[0]}', '{$component[1]}'))));\n";
129
    }
130
 
131
    return $data;
132
  }
133
 
134
  /**
135
   * Adds a template setting statement to the data.
136
   *
137
   * @param string $viewName The view name
138
   *
139
   * @return string The PHP statement
140
   */
141
  protected function addTemplate($viewName = '')
142
  {
143
    $data = '';
144
 
145
    $templateName = $this->getConfigValue('template', $viewName);
146
    $defaultTemplateName = $templateName ? "'$templateName'" : '$this->actionName';
147
 
148
    $data .= "  \$templateName = sfConfig::get('symfony.view.'.\$this->moduleName.'_'.\$this->actionName.'_template', $defaultTemplateName);\n";
149
    $data .= "  \$this->setTemplate(\$templateName.\$this->viewName.\$this->getExtension());\n";
150
 
151
    return $data;
152
  }
153
 
154
  /**
155
   * Adds a layout statement statement to the data.
156
   *
157
   * @param string $viewName The view name
158
   *
159
   * @return string The PHP statement
160
   */
161
  protected function addLayout($viewName = '')
162
  {
163
    // true if the user set 'has_layout' to true or set a 'layout' name for this specific action
164
    $hasLocalLayout = isset($this->yamlConfig[$viewName]['layout']) || (isset($this->yamlConfig[$viewName]) && array_key_exists('has_layout', $this->yamlConfig[$viewName]));
165
 
166
    // the layout value
167
    $layout = $this->getConfigValue('has_layout', $viewName) ? $this->getConfigValue('layout', $viewName) : false;
168
 
169
    // the user set a decorator in the action
170
    $data = <<<EOF
171
  if (null !== \$layout = sfConfig::get('symfony.view.'.\$this->moduleName.'_'.\$this->actionName.'_layout'))
172
  {
173
    \$this->setDecoratorTemplate(false === \$layout ? false : \$layout.\$this->getExtension());
174
  }
175
EOF;
176
 
177
    if ($hasLocalLayout)
178
    {
179
      // the user set a decorator in view.yml for this action
180
      $data .= <<<EOF
181
 
182
  else
183
  {
184
    \$this->setDecoratorTemplate('' == '$layout' ? false : '$layout'.\$this->getExtension());
185
  }
186
 
187
EOF;
188
    }
189
    else
190
    {
191
      // no specific configuration
192
      // set the layout to the 'all' view.yml value except if:
193
      //   * the decorator template has already been set by "someone" (via view.configure_format for example)
194
      //   * the request is an XMLHttpRequest request
195
      $data .= <<<EOF
196
 
197
  else if (null === \$this->getDecoratorTemplate() && !\$this->context->getRequest()->isXmlHttpRequest())
198
  {
199
    \$this->setDecoratorTemplate('' == '$layout' ? false : '$layout'.\$this->getExtension());
200
  }
201
 
202
EOF;
203
    }
204
 
205
    return $data;
206
  }
207
 
208
  /**
209
   * Adds http metas and metas statements to the data.
210
   *
211
   * @param string $viewName The view name
212
   *
213
   * @return string The PHP statement
214
   */
215
  protected function addHtmlHead($viewName = '')
216
  {
217
    $data = array();
218
 
219
    foreach ($this->mergeConfigValue('http_metas', $viewName) as $httpequiv => $content)
220
    {
221
      $data[] = sprintf("  \$response->addHttpMeta('%s', '%s', false);", $httpequiv, str_replace('\'', '\\\'', $content));
222
    }
223
 
224
    foreach ($this->mergeConfigValue('metas', $viewName) as $name => $content)
225
    {
226
      $data[] = sprintf("  \$response->addMeta('%s', '%s', false, false);", $name, str_replace('\'', '\\\'', preg_replace('/&amp;(?=\w+;)/', '&', htmlspecialchars($content, ENT_QUOTES, sfConfig::get('sf_charset')))));
227
    }
228
 
229
    return implode("\n", $data)."\n";
230
  }
231
 
232
  /**
233
   * Adds stylesheets and javascripts statements to the data.
234
   *
235
   * @param string $viewName The view name
236
   *
237
   * @return string The PHP statement
238
   */
239
  protected function addHtmlAsset($viewName = '')
240
  {
241
    // Merge the current view's stylesheets with the app's default stylesheets
242
    $stylesheets = $this->mergeConfigValue('stylesheets', $viewName);
243
    $css = $this->addAssets('Stylesheet', $stylesheets);
244
 
245
    // Merge the current view's javascripts with the app's default javascripts
246
    $javascripts = $this->mergeConfigValue('javascripts', $viewName);
247
    $js = $this->addAssets('Javascript', $javascripts);
248
 
249
    return implode("\n", array_merge($css, $js))."\n";
250
  }
251
 
252
  /**
253
   * Creates a list of add$Type PHP statements for the given type and config.
254
   *
255
   * @param string $type of asset. Requires an sfWebResponse->add$Type(string, string, array) method
256
   *
257
   * @return array ist of add$Type PHP statements
258
   */
259
  private function addAssets($type, $assets){
260
    $tmp = array();
261
    foreach ((array) $assets as $asset)
262
    {
263
      $position = '';
264
      if (is_array($asset))
265
      {
266
        $key = key($asset);
267
        $options = $asset[$key];
268
        if (isset($options['position']))
269
        {
270
          $position = $options['position'];
271
          unset($options['position']);
272
        }
273
      }
274
      else
275
      {
276
        $key = $asset;
277
        $options = array();
278
      }
279
 
280
      if ('-*' == $key)
281
      {
282
        $tmp = array();
283
      }
284
      else if ('-' == $key[0])
285
      {
286
        unset($tmp[substr($key, 1)]);
287
      }
288
      else
289
      {
290
        $tmp[$key] = sprintf("  \$response->add%s('%s', '%s', %s);", $type, $key, $position, str_replace("\n", '', var_export($options, true)));
291
      }
292
    }
293
    return array_values($tmp);
294
  }
295
 
296
  /**
297
   * Adds an escaping statement to the data.
298
   *
299
   * @param string $viewName The view name
300
   *
301
   * @return string The PHP statement
302
   */
303
  protected function addEscaping($viewName = '')
304
  {
305
    $data = array();
306
 
307
    $escaping = $this->getConfigValue('escaping', $viewName);
308
 
309
    if (isset($escaping['method']))
310
    {
311
      $data[] = sprintf("  \$this->getAttributeHolder()->setEscapingMethod(%s);", var_export($escaping['method'], true));
312
    }
313
 
314
    return implode("\n", $data)."\n";
315
  }
316
 
317
  /**
318
   * @see sfConfigHandler
319
   */
320
  static public function getConfiguration(array $configFiles)
321
  {
322
    return self::mergeConfig(self::parseYamls($configFiles));
323
  }
324
 
325
  static protected function mergeConfig($config)
326
  {
327
    // merge javascripts and stylesheets
328
    $config['all']['stylesheets'] = array_merge(isset($config['default']['stylesheets']) && is_array($config['default']['stylesheets']) ? $config['default']['stylesheets'] : array(), isset($config['all']['stylesheets']) && is_array($config['all']['stylesheets']) ? $config['all']['stylesheets'] : array());
329
    unset($config['default']['stylesheets']);
330
 
331
    $config['all']['javascripts'] = array_merge(isset($config['default']['javascripts']) && is_array($config['default']['javascripts']) ? $config['default']['javascripts'] : array(), isset($config['all']['javascripts']) && is_array($config['all']['javascripts']) ? $config['all']['javascripts'] : array());
332
    unset($config['default']['javascripts']);
333
 
334
    // merge default and all
335
    $config['all'] = sfToolkit::arrayDeepMerge(
336
      isset($config['default']) && is_array($config['default']) ? $config['default'] : array(),
337
      isset($config['all']) && is_array($config['all']) ? $config['all'] : array()
338
    );
339
 
340
    unset($config['default']);
341
 
342
    return self::replaceConstants($config);
343
  }
344
}