1: <?php
2: /**
3: * Slim - a micro PHP 5 framework
4: *
5: * @author Josh Lockhart <info@slimframework.com>
6: * @copyright 2011 Josh Lockhart
7: * @link http://www.slimframework.com
8: * @license http://www.slimframework.com/license
9: * @version 2.2.0
10: * @package Slim
11: *
12: * MIT LICENSE
13: *
14: * Permission is hereby granted, free of charge, to any person obtaining
15: * a copy of this software and associated documentation files (the
16: * "Software"), to deal in the Software without restriction, including
17: * without limitation the rights to use, copy, modify, merge, publish,
18: * distribute, sublicense, and/or sell copies of the Software, and to
19: * permit persons to whom the Software is furnished to do so, subject to
20: * the following conditions:
21: *
22: * The above copyright notice and this permission notice shall be
23: * included in all copies or substantial portions of the Software.
24: *
25: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26: * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27: * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28: * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29: * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30: * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31: * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32: */
33: namespace Slim;
34:
35: /**
36: * View
37: *
38: * The view is responsible for rendering a template. The view
39: * should subclass \Slim\View and implement this interface:
40: *
41: * public render(string $template);
42: *
43: * This method should render the specified template and return
44: * the resultant string.
45: *
46: * @package Slim
47: * @author Josh Lockhart
48: * @since 1.0.0
49: */
50: class View
51: {
52: /**
53: * @var string Absolute or relative filesystem path to a specific template
54: *
55: * DEPRECATION WARNING!
56: * This variable will be removed in the near future
57: */
58: protected $templatePath = '';
59:
60: /**
61: * @var array Associative array of template variables
62: */
63: protected $data = array();
64:
65: /**
66: * @var string Absolute or relative path to the application's templates directory
67: */
68: protected $templatesDirectory;
69:
70: /**
71: * Constructor
72: *
73: * This is empty but may be implemented in a subclass
74: */
75: public function __construct()
76: {
77:
78: }
79:
80: /**
81: * Get data
82: * @param string|null $key
83: * @return mixed If key is null, array of template data;
84: * If key exists, value of datum with key;
85: * If key does not exist, null;
86: */
87: public function getData($key = null)
88: {
89: if (!is_null($key)) {
90: return isset($this->data[$key]) ? $this->data[$key] : null;
91: } else {
92: return $this->data;
93: }
94: }
95:
96: /**
97: * Set data
98: *
99: * If two arguments:
100: * A single datum with key is assigned value;
101: *
102: * $view->setData('color', 'red');
103: *
104: * If one argument:
105: * Replace all data with provided array keys and values;
106: *
107: * $view->setData(array('color' => 'red', 'number' => 1));
108: *
109: * @param mixed
110: * @param mixed
111: * @throws InvalidArgumentException If incorrect method signature
112: */
113: public function setData()
114: {
115: $args = func_get_args();
116: if (count($args) === 1 && is_array($args[0])) {
117: $this->data = $args[0];
118: } elseif (count($args) === 2) {
119: $this->data[(string) $args[0]] = $args[1];
120: } else {
121: throw new \InvalidArgumentException('Cannot set View data with provided arguments. Usage: `View::setData( $key, $value );` or `View::setData([ key => value, ... ]);`');
122: }
123: }
124:
125: /**
126: * Append new data to existing template data
127: * @param array
128: * @throws InvalidArgumentException If not given an array argument
129: */
130: public function appendData($data)
131: {
132: if (!is_array($data)) {
133: throw new \InvalidArgumentException('Cannot append view data. Expected array argument.');
134: }
135: $this->data = array_merge($this->data, $data);
136: }
137:
138: /**
139: * Get templates directory
140: * @return string|null Path to templates directory without trailing slash;
141: * Returns null if templates directory not set;
142: */
143: public function getTemplatesDirectory()
144: {
145: return $this->templatesDirectory;
146: }
147:
148: /**
149: * Set templates directory
150: * @param string $dir
151: */
152: public function setTemplatesDirectory($dir)
153: {
154: $this->templatesDirectory = rtrim($dir, '/');
155: }
156:
157: /**
158: * Set template
159: * @param string $template
160: * @throws RuntimeException If template file does not exist
161: *
162: * DEPRECATION WARNING!
163: * This method will be removed in the near future.
164: */
165: public function setTemplate($template)
166: {
167: $this->templatePath = $this->getTemplatesDirectory() . '/' . ltrim($template, '/');
168: if (!file_exists($this->templatePath)) {
169: throw new \RuntimeException('View cannot render template `' . $this->templatePath . '`. Template does not exist.');
170: }
171: }
172:
173: /**
174: * Display template
175: *
176: * This method echoes the rendered template to the current output buffer
177: *
178: * @param string $template Pathname of template file relative to templates directoy
179: */
180: public function display($template)
181: {
182: echo $this->fetch($template);
183: }
184:
185: /**
186: * Fetch rendered template
187: *
188: * This method returns the rendered template
189: *
190: * @param string $template Pathname of template file relative to templates directory
191: * @return string
192: */
193: public function fetch($template)
194: {
195: return $this->render($template);
196: }
197:
198: /**
199: * Render template
200: *
201: * @param string $template Pathname of template file relative to templates directory
202: * @return string
203: *
204: * DEPRECATION WARNING!
205: * Use `\Slim\View::fetch` to return a rendered template instead of `\Slim\View::render`.
206: */
207: public function render($template)
208: {
209: $this->setTemplate($template);
210: extract($this->data);
211: ob_start();
212: require $this->templatePath;
213:
214: return ob_get_clean();
215: }
216: }
217: