Subversion Repositories PHPX

Rev

Rev 70 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 70 Rev 71
1
<?php
1
<?php
2
2
3
namespace PointedEars\PHPX;
3
namespace PointedEars\PHPX;
4
4
5
/**
5
/**
6
 * A general view handled by a controller according to the MVC pattern
6
 * A general view handled by a controller according to the MVC pattern
7
 *
7
 *
8
 * @author Thomas 'PointedEars' Lahn &lt;php@PointedEars.de>
8
 * @author Thomas 'PointedEars' Lahn &lt;php@PointedEars.de>
9
 */
9
 */
10
class View
10
class View
11
{
11
{
12
  /**
12
  /**
13
   * Default template resource path
13
   * Default template resource path
14
   *
14
   *
15
   * @var string
15
   * @var string
16
   */
16
   */
17
  protected $_template = '';
17
  protected $_template = '';
18
18
19
  /**
19
  /**
20
   * Content that can be inserted in the template
20
   * Content that can be inserted in the template
21
   *
21
   *
22
   * @var string
22
   * @var string
23
   */
23
   */
24
  protected $_content = '';
24
  protected $_content = '';
25
25
26
  /**
26
  /**
27
   * Template variables.  The variable name serves as item key, the item's value
27
   * Template variables.  The variable name serves as item key, the item's value
28
   * is the variable value.
28
   * is the variable value.
29
   *
29
   *
30
   * @var array
30
   * @var array
31
   */
31
   */
32
  protected $_template_vars = array();
32
  protected $_template_vars = array();
33
33
34
  /**
34
  /**
35
   * Stylesheets to be inserted into the <code>head</code> element
35
   * Stylesheets to be inserted into the <code>head</code> element
36
   *
36
   *
37
   * @var array
37
   * @var array
38
   */
38
   */
39
  protected $_stylesheets = array();
39
  protected $_stylesheets = array();
40
40
41
  /**
41
  /**
42
   * Scripts to be inserted into the <code>head</code> or
42
   * Scripts to be inserted into the <code>head</code> or
43
   * <code>body</code> element
43
   * <code>body</code> element
44
   *
44
   *
45
   * @var array
45
   * @var array
46
   */
46
   */
47
  protected $_scripts = array();
47
  protected $_scripts = array();
48
48
49
  /**
49
  /**
50
   * Creates a new view
50
   * Creates a new view
51
   *
51
   *
52
   * @param string $template
52
   * @param string $template
53
   *   Template resource path
53
   *   Template resource path
54
   */
54
   */
55
  public function __construct ($template)
55
  public function __construct ($template)
56
  {
56
  {
57
    $this->_template = $template;
57
    $this->_template = $template;
58
  }
58
  }
59
59
60
  /**
60
  /**
61
   * Magic setter method used for defining template variables
61
   * Magic setter method used for defining template variables
62
   *
62
   *
63
   * @param string $name
63
   * @param string $name
64
   *   Variable name
64
   *   Variable name
65
   * @param mixed $value
65
   * @param mixed $value
66
   *   Variable value
66
   *   Variable value
67
   */
67
   */
68
  public function __set ($name, $value)
68
  public function __set ($name, $value)
69
  {
69
  {
70
    $this->_template_vars[$name] = $value;
70
    $this->_template_vars[$name] = $value;
71
  }
71
  }
72
72
73
  /**
73
  /**
74
   * Magic getter method used for retrieving values of template variables
74
   * Magic getter method used for retrieving values of template variables
75
   *
75
   *
76
   * @param string $name
76
   * @param string $name
77
   *   Variable name
77
   *   Variable name
78
   */
78
   */
79
  public function __get ($name)
79
  public function __get ($name)
80
  {
80
  {
81
    return $this->_template_vars[$name];
81
    return $this->_template_vars[$name];
82
  }
82
  }
83
83
84
  /**
84
  /**
85
   * Returns <var>$v</var> with occurences of '&' (ampersand), '"' (double quote),
85
   * Returns <var>$v</var> with occurences of '&' (ampersand), '"' (double quote),
86
   * "'" (single quote), '<' (less than), and '>' (greater than) replaced by their
86
   * "'" (single quote), '<' (less than), and '>' (greater than) replaced by their
87
   * HTML character entity references, if any, or their numeric HTML character
87
   * HTML character entity references, if any, or their numeric HTML character
88
   * reference (as required primarily in HTML for attribute values and element
88
   * reference (as required primarily in HTML for attribute values and element
89
   * content).
89
   * content).
90
   *
90
   *
91
   * @param mixed $value
91
   * @param mixed $value
92
   */
92
   */
93
  public function escape ($value)
93
  public function escape ($value)
94
  {
94
  {
95
    if (is_array($value))
95
    if (is_array($value))
96
    {
96
    {
97
      return array_map(array('self', 'escape'), $value);
97
      return array_map(array('self', 'escape'), $value);
98
    }
98
    }
99
    else if (is_object($value))
99
    else if (is_object($value))
100
    {
100
    {
101
      if ($value instanceof AbstractModel)
101
      if ($value instanceof AbstractModel)
102
      {
102
      {
103
        foreach ($value->getPropertyVars() as $varName)
103
        foreach ($value->getPropertyVars() as $varName)
104
        {
104
        {
105
          $value->$varName = self::escape($value->$varName);
105
          $value->$varName = self::escape($value->$varName);
106
        }
106
        }
107
      }
107
      }
108
108
109
      return $value;
109
      return $value;
110
    }
110
    }
111
    else
111
    else
112
    {
112
    {
113
      if (is_string($value))
113
      if (is_string($value))
114
      {
114
      {
115
        $encoding = mb_detect_encoding($value);
115
        $encoding = mb_detect_encoding($value);
116
        if ($encoding === 'ASCII')
116
        if ($encoding === 'ASCII')
117
        {
117
        {
118
          $encoding = 'ISO-8859-1';
118
          $encoding = 'ISO-8859-1';
119
        }
119
        }
120
        return htmlspecialchars($value, ENT_QUOTES, $encoding);
120
        return htmlspecialchars($value, ENT_QUOTES, $encoding);
121
      }
121
      }
122
122
123
      return $value;
123
      return $value;
124
    }
124
    }
125
  }
125
  }
126
126
127
  /**
127
  /**
128
   * Assigns a value to a template variable
128
   * Assigns a value to a template variable
129
   *
129
   *
130
   * @param string $name
130
   * @param string $name
131
   *   Variable name
131
   *   Variable name
132
   * @param mixed $value
132
   * @param mixed $value
133
   *   Variable value
133
   *   Variable value
134
   * @param bool $escape
134
   * @param bool $escape
135
   *   If <code>true</code>, replace all potentially conflicting characters
135
   *   If <code>true</code>, replace all potentially conflicting characters
136
   *   in <var>$value</var> with their HTML entity references.  The default is
136
   *   in <var>$value</var> with their HTML entity references.  The default is
137
   *   <code>false</code>.
137
   *   <code>false</code>.
138
   * @return mixed The assigned value (after possible HTML encoding)
138
   * @return mixed The assigned value (after possible HTML encoding)
139
   * @see View::escape()
139
   * @see View::escape()
140
   */
140
   */
141
  public function assign ($name, $value, $escape = false)
141
  public function assign ($name, $value, $escape = false)
142
  {
142
  {
143
    if ($escape)
143
    if ($escape)
144
    {
144
    {
145
      $value = $this->escape($value);
145
      $value = $this->escape($value);
146
    }
146
    }
147
147
148
    $this->$name = $value;
148
    $this->$name = $value;
149
    return $value;
149
    return $value;
150
  }
150
  }
151
151
152
  /**
152
  /**
153
   * Adds a CSS resource (stylesheet) to the list of external
153
   * Adds an CSS resource (stylesheet)
154
   * stylesheets
154
   * to the list of external stylesheets
155
   *
155
   *
156
   * @param string $uri
156
   * @param string $uri
157
   *   Stylesheet URI
157
   *   Stylesheet URI
158
   * @param mixed $key (optional)
158
   * @param mixed $key (optional)
159
   *   Array key for the script.  May be used later to exclude
159
   *   Array key for the script.  May be used later to exclude
160
   *   or include the code for a specific stylesheet.
160
   *   or include the code for a specific stylesheet.
-
 
161
   * @return array
-
 
162
   *   The list of stylesheets
161
   */
163
   */
162
  public function addStylesheet ($uri, $key = null)
164
  public function addStylesheet ($uri, $key = null)
163
  {
165
  {
164
    $stylesheets =& $this->_stylesheets;
166
    $stylesheets =& $this->_stylesheets;
165
167
166
    if ($key !== null)
168
    if ($key !== null)
167
    {
169
    {
168
      $stylesheets[$key] = $uri;
170
      $stylesheets[$key] = $uri;
169
    }
171
    }
170
    else
172
    else
171
    {
173
    {
172
      $stylesheets[] = $uri;
174
      $stylesheets[] = $uri;
173
    }
175
    }
-
 
176
-
 
177
    return $stylesheets;
-
 
178
  }
-
 
179
-
 
180
  /**
-
 
181
   * Adds several CSS resources (stylesheets)
-
 
182
   * to the list of external stylesheets
-
 
183
   *
-
 
184
   * @param array $uris
-
 
185
   *   Stylesheet URIs
-
 
186
   * @return array
-
 
187
   *   The list of stylesheets
-
 
188
   */
-
 
189
  public function addStylesheets (array $uris)
-
 
190
  {
-
 
191
    $stylesheets = $this->_stylesheets;
-
 
192
-
 
193
    foreach ($uris as $uri)
-
 
194
    {
-
 
195
      $stylesheets = $this->addStylesheet($uri);
-
 
196
    }
-
 
197
-
 
198
    return $stylesheets;
174
  }
199
  }
175
200
176
  /**
201
  /**
177
   * Adds an ECMAScript resource (script) to the list of external
202
   * Adds an ECMAScript resource (script)
178
   * scripts
203
   * to the list of external scripts
179
   *
204
   *
180
   * @param string $uri
205
   * @param string $uri
181
   *   Script URI
206
   *   Script URI
182
   * @param mixed $key (optional)
207
   * @param mixed $key (optional)
183
   *   Array key for the script.  May be used later to exclude
208
   *   Array key for the script.  May be used later to exclude
184
   *   or include the code for a specific script.
209
   *   or include the code for a specific script.
185
   */
210
   */
186
  public function addScript ($uri, $key = null)
211
  public function addScript ($uri, $key = null)
187
  {
212
  {
188
    $scripts =& $this->_scripts;
213
    $scripts =& $this->_scripts;
189
214
190
    if ($key !== null)
215
    if ($key !== null)
191
    {
216
    {
192
      $scripts[$key] = $uri;
217
      $scripts[$key] = $uri;
193
    }
218
    }
194
    else
219
    else
195
    {
220
    {
196
      $scripts[] = $uri;
221
      $scripts[] = $uri;
197
    }
222
    }
-
 
223
-
 
224
    return $scripts;
-
 
225
  }
-
 
226
-
 
227
  /**
-
 
228
   * Adds several ECMAScript resources (scripts)
-
 
229
   * to the list of external scripts
-
 
230
   *
-
 
231
   * @param array $uris
-
 
232
   *   Script URIs
-
 
233
   * @return array
-
 
234
   *   The list of scripts
-
 
235
   */
-
 
236
  public function addScripts (array $uris)
-
 
237
  {
-
 
238
    $scripts = $this->_scripts;
-
 
239
-
 
240
    foreach ($uris as $uri)
-
 
241
    {
-
 
242
      $scripts = $this->addScript($uri);
-
 
243
    }
-
 
244
-
 
245
    return $scripts;
198
  }
246
  }
199
247
200
  /**
248
  /**
201
   * Renders the view by including a template
249
   * Renders the view by including a template
202
   *
250
   *
203
   * @param string $template
251
   * @param string $template
204
   *   Optional alternative template resource path.
252
   *   Optional alternative template resource path.
205
   *   If not provided, the default template ($template property) will be used.
253
   *   If not provided, the default template ($template property) will be used.
206
   * @throws Exception if no template has been defined before
254
   * @throws Exception if no template has been defined before
207
   */
255
   */
208
  public function render ($template = null, $content = null)
256
  public function render ($template = null, $content = null)
209
  {
257
  {
210
        if (!is_null($content))
258
        if (!is_null($content))
211
    {
259
    {
212
      ob_start();
260
      ob_start();
213
        require_once $content;
261
        require_once $content;
214
        $this->_content = ob_get_contents();
262
        $this->_content = ob_get_contents();
215
      ob_end_clean();
263
      ob_end_clean();
216
    }
264
    }
217
265
218
        if (!is_null($template))
266
        if (!is_null($template))
219
        {
267
        {
220
                require $template;
268
                require $template;
221
        }
269
        }
222
    elseif ($this->_template)
270
    elseif ($this->_template)
223
    {
271
    {
224
      require $this->_template;
272
      require $this->_template;
225
    }
273
    }
226
    else
274
    else
227
    {
275
    {
228
      throw new \Exception('No template defined');
276
      throw new \Exception('No template defined');
229
    }
277
    }
230
  }
278
  }
231
279
232
  /**
280
  /**
233
   * Returns the code for including all stylesheets,
281
   * Returns the code for including all stylesheets,
234
   * with exclusions.
282
   * with exclusions.
235
   *
283
   *
236
   * @param array $exclusions (optional, future)
284
   * @param array $exclusions (optional, future)
237
   *   The keys of the stylesheets that should be excluded
285
   *   The keys of the stylesheets that should be excluded
238
   * @return string
286
   * @return string
239
   */
287
   */
240
  public function getStylesheets ($exclusions = array())
288
  public function getStylesheets ($exclusions = array())
241
  {
289
  {
242
    return (
290
    return (
243
      implode(PHP_EOL, array_map(function ($uri) {
291
      implode(PHP_EOL, array_map(function ($uri) {
244
        return '<link rel="stylesheet" href="' . $this->escape($uri) . '">';
292
        return '<link rel="stylesheet" href="' . $this->escape($uri) . '">';
245
      }, array_diff_key($this->_stylesheets, array_flip($exclusions))))
293
      }, array_diff_key($this->_stylesheets, array_flip($exclusions))))
246
      . PHP_EOL);
294
      . PHP_EOL);
247
  }
295
  }
248
296
249
  /**
297
  /**
250
   * Returns the code for including a specific stylesheet
298
   * Returns the code for including a specific stylesheet
251
   *
299
   *
252
   * @param mixed $key
300
   * @param mixed $key
253
   * @return string
301
   * @return string
254
   */
302
   */
255
  public function getStylesheet ($key)
303
  public function getStylesheet ($key)
256
  {
304
  {
257
    return '<link rel="stylesheet" href="'
305
    return '<link rel="stylesheet" href="'
258
      . $this->escape($this->_stylesheets[$key])
306
      . $this->escape($this->_stylesheets[$key])
259
      . '">' . PHP_EOL;
307
      . '">' . PHP_EOL;
260
  }
308
  }
261
309
262
  /**
310
  /**
263
   * Returns the code for including all stylesheets,
311
   * Returns the code for including all stylesheets,
264
   * with exclusions.
312
   * with exclusions.
265
   *
313
   *
266
   * @param array $exclusions (optional, future)
314
   * @param array $exclusions (optional, future)
267
   *   The keys of the scripts that should be excluded.
315
   *   The keys of the scripts that should be excluded.
268
   *   Usually you would specify those scripts that you
316
   *   Usually you would specify those scripts that you
269
   *   want to include with {@link #getScript()}.
317
   *   want to include with {@link #getScript()}.
270
   * @return string
318
   * @return string
271
   */
319
   */
272
  public function getScripts ($exclusions = array())
320
  public function getScripts ($exclusions = array())
273
  {
321
  {
274
    return (
322
    return (
275
     implode(PHP_EOL, array_map(function ($uri) {
323
     implode(PHP_EOL, array_map(function ($uri) {
276
        return '<script type="text/javascript" src="'
324
        return '<script type="text/javascript" src="'
277
          . $this->escape($uri)
325
          . $this->escape($uri)
278
          . '"></script>';
326
          . '"></script>';
279
      }, array_diff_key($this->_scripts, array_flip($exclusions))))
327
      }, array_diff_key($this->_scripts, array_flip($exclusions))))
280
      . PHP_EOL);
328
      . PHP_EOL);
281
  }
329
  }
282
330
283
  public function getScript ($key)
331
  public function getScript ($key)
284
  {
332
  {
285
    return '<link rel="stylesheet" href="'
333
    return '<link rel="stylesheet" href="'
286
      . $this->escape($this->_scripts[$key])
334
      . $this->escape($this->_scripts[$key])
287
      . '">' . PHP_EOL;
335
      . '">' . PHP_EOL;
288
  }
336
  }
289
337
290
  /**
338
  /**
291
   * Returns the content for insertion into the template
339
   * Returns the content for insertion into the template
292
   */
340
   */
293
  public function getContent ()
341
  public function getContent ()
294
  {
342
  {
295
    return $this->_content;
343
    return $this->_content;
296
  }
344
  }
297
345
298
  /**
346
  /**
299
   * @param string[optional] $controller
347
   * @param string[optional] $controller
300
   * @param string[optional] $action
348
   * @param string[optional] $action
301
   * @param int[optional] $id
349
   * @param int[optional] $id
302
   * @see Application::getURL()
350
   * @see Application::getURL()
303
   */
351
   */
304
  public function getURL ($controller = null, $action = null, $id = null)
352
  public function getURL ($controller = null, $action = null, $id = null)
305
  {
353
  {
306
    return Application::getInstance()->getURL($controller, $action, $id);
354
    return Application::getInstance()->getURL($controller, $action, $id);
307
  }
355
  }
308
}
356
}
309
357
310
?>
358
?>