PageRenderTime 26ms CodeModel.GetById 10ms app.highlight 12ms RepoModel.GetById 1ms app.codeStats 0ms

/library/QFrame/View.php

https://github.com/humansky/qframe
PHP | 341 lines | 142 code | 32 blank | 167 comment | 25 complexity | a5af266bf29a30d891189aed08db9475 MD5 | raw file
  1<?php
  2/**
  3 * This file is part of the CSI QFrame.
  4 *
  5 * The CSI QFrame is free software; you can redistribute it and/or modify
  6 * it under the terms of the GNU General Public License as published by
  7 * the Free Software Foundation; either version 3 of the License, or
  8 * (at your option) any later version.
  9 *
 10 * The CSI QFrame is distributed in the hope that it will be useful,
 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 13 * GNU General Public License for more details.
 14 *
 15 * You should have received a copy of the GNU General Public License
 16 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 17 *
 18 * @category   QFrame
 19 * @package    QFrame
 20 * @copyright  Copyright (c) 2007 Collaborative Software Initiative (CSI)
 21 * @license    http://www.gnu.org/licenses/   GNU General Public License v3
 22 */
 23
 24/**
 25 * Haml_Engine
 26 */
 27require_once 'Haml/Engine.php';
 28
 29
 30/**
 31 * @category   QFrame
 32 * @package    QFrame
 33 * @copyright  Copyright (c) 2007 Collaborative Software Initiative (CSI)
 34 * @license    http://www.gnu.org/licenses/   GNU General Public License v3
 35 */
 36class QFrame_View implements Zend_View_Interface {
 37  
 38  /**
 39   * Haml_Engine object used to do the actual work
 40   * @var Haml_Engine
 41   */
 42  private $_haml;
 43
 44  /**
 45   * Current list of helper paths
 46   * @var array
 47   */
 48  private $_helpers = array();
 49
 50  /**
 51   * Determines whether a layout will be rendered
 52   * @var bool
 53   */
 54  private $_renderLayout = true;
 55
 56  /**
 57   * Class constructor
 58   *  
 59   * @param string template path
 60   */
 61  public function __construct($templatePath = '') {
 62    $this->_haml = new Haml_Engine($templatePath);
 63    $this->_haml->setUndefined($this);
 64  }
 65  
 66  /**
 67   * Return the template engine object
 68   *
 69   * @return Haml_Engine
 70   */
 71  public function getEngine() {
 72    return $this->_haml;
 73  }
 74  
 75  /**
 76   * Set the path to the templates
 77   *
 78   * @param string $path Directory to set as the path
 79   */
 80  public function setScriptPath($path) {
 81    if(is_readable($path)) $this->_haml->setBase($path);
 82    else throw new Exception('Invalid path provided');
 83    
 84    return;
 85  }
 86  
 87  /**
 88   * Retrieves the current template directory
 89   *
 90   * @return string
 91   */
 92  public function getScriptPaths() {
 93    return array($this->_haml->getBase());
 94  }
 95  
 96  /**
 97   * Alias for setScriptPath
 98   *
 99   * @param string $path
100   * @param string $prefix Unused
101   */
102  public function setBasePath($path, $prefix = 'Zend_View') {
103    return $this->setScriptPath($path);
104  }
105  
106  /**
107   * Alias for setScriptPath
108   *
109   * @param string $path
110   * @param string $prefix Unused
111   */
112  public function addBasePath($path, $prefix = 'Zend_View') {
113    return $this->setScriptPath($path);
114  }
115  
116  /**
117   * Sets the helper path to a single path or list of paths
118   *
119   * @param string|array path(s) to set
120   * @param string       (optional) prefix to use for path(s)
121   */
122  public function setHelperPath($path, $prefix = 'QFrame_View_Helper') {
123    array_splice($this->_helpers, 0);
124    if(is_array($path)) {
125      foreach($path as $p) $this->addHelperPath($p, $prefix);
126    }
127    else {
128      $this->addHelperPath($path, $prefix);
129    }
130  }
131  
132  /**
133   * Adds a single path to the list of helpers
134   *
135   * @param string path to add
136   * @param string (optional) prefix to assign to this path
137   */
138  public function addHelperPath($path, $prefix = 'QFrame_View_Helper') {
139    $this->_helpers[$path] = $prefix;
140  }
141  
142  /**
143   * Turn on/off view rendering
144   *
145   * @param bool should layout rendering be on
146   */
147  public function setRenderLayout($r) {
148    $this->_renderLayout = $r;
149  }
150  
151  /**
152   * Sets an assigned variable
153   *
154   * @param string variable name
155   * @param string variable value
156   */
157  public function __set($key, $val) {
158    $this->_haml->assign($key, $val);
159  }
160  
161  /**
162   * Gets an assigned variable
163   *
164   * @param  string variable name
165   * @return mixed
166   */
167  public function __get($key) {
168    return $this->_haml->getAssign($key);
169  }
170  
171  /**
172   * Unsets an assigned variable
173   *
174   * @param string variable name
175   */
176  public function __unset($key) {
177    $this->_haml->unassign($key);
178  }
179  
180  /**
181   * Checks whether or not an assigned variable has been set
182   *
183   * @param string variable name
184   */
185  public function __isset($key) {
186    return $this->_haml->is_assigned($key);
187  }
188  
189  /**
190   * Assigns one or more variables to the template
191   *
192   * @param string|array either a variable name or array of variable => value pairs
193   * @param mixed        if first param is a string, the value of this variable
194   */
195  public function assign($spec, $value = null) {
196    if(is_array($spec)) {
197      foreach($spec as $key => $val) $this->__set($key, $val);
198    }
199    elseif(!is_null($value)) {
200      $this->__set($spec, $value);
201    }
202    else throw new Exception("You must specify either an array or a variable *and* value");
203    
204    return;
205  }
206  
207  /**
208   * Clear all assigned variables
209   */
210  public function clearVars() {
211    $this->_haml->clear_assigns();
212    return;
213  }
214  
215  /**
216   * Renders a specified template
217   *
218   * @param  string template name
219   * @param  Array  (optional) array of local variables to assign before rendering
220   * @return string
221   */
222  public function render($name, $locals = array()) {
223    ob_start();
224    $this->_haml->render($name, $this->_renderLayout, $locals);
225    $html = ob_get_clean();
226    /*if(function_exists('tidy_repair_string')) {
227      $tidy_config = array(
228        'indent'        => true,
229        'wrap'          => 120,
230        'hide-comments' => true
231      );
232      $html = tidy_repair_string($html, $tidy_config);
233    }*/
234    return $html;
235  }
236  
237  /**
238   * Renders a partial template
239   *
240   * @param  string      template name (will be prepended with '_' to make filename)
241   * @param  mixed|Array object or array of objects to provide to the partial
242   * @param  boolean     (optional) treat object argument as a collection
243   * @param  boolean     (optional) render application wide partial
244   * @param  Array       array of local variables to set before rendering
245   * @return string 
246   */
247  public function renderPartial($name, $object, $arr = false, $appl = false, $locals = array()) {
248    if($arr) {
249      $content = '';
250      foreach($object as $individual)
251        $content .= $this->renderPartial($name, $individual, false, $appl, $locals);
252      return $content;
253    }
254    
255    // Figure out the relative filename of the partial template to render (based on
256    // whether or not the user requested an application global)
257    if($appl) {
258      $filename = implode(DIRECTORY_SEPARATOR, array('scripts', 'application', "_{$name}.haml"));
259    }
260    else {
261      $filename = implode(DIRECTORY_SEPARATOR, array(
262        'scripts',
263        Zend_Controller_Front::getInstance()->getRequest()->getControllerName(),
264        "_{$name}.haml"
265      ));
266    }
267    
268    ob_start();
269    if($this->_haml->is_assigned($name)) $originalValue = $this->_haml->getAssign($name);
270    $this->_haml->assign($name, $object);
271    $this->_haml->render($filename, false, $locals);
272    $html = ob_get_clean();
273    if(isset($originalValue)) $this->_haml->assign($name, $originalValue);
274    return $html;
275  }
276  
277  /**
278   * Escapes special HTML characters in strings (required for some ZF helpers)
279   *
280   * @param  string string to escape
281   * @return string
282   */
283  public function escape($str) {
284    return htmlspecialchars($str);
285  }
286  
287  /**
288   * Handle calls to undefined methods
289   *
290   * @param string method name
291   * @param array  arguments
292   */
293  public function __call($method, $args) {
294    // First, check to see if there is a standard style Zend helper (class and method)
295    // named the same as the helper
296    foreach($this->_helpers as $path => $prefix) {
297      if(substr($prefix, -1, 1) != '_') $prefix .= '_';
298      $helperFile = $path . DIRECTORY_SEPARATOR . ucfirst($method) . '.php';
299      if(file_exists($helperFile)) {
300        require_once($helperFile);
301        $class = new ReflectionClass($prefix . ucfirst($method));
302        $object = $class->newInstance();
303        if(method_exists($object, 'setView')) $object->setView($this);
304        return call_user_func_array(array(&$object, $method), $args);
305      }
306    }
307    
308    // Second, check to see if there is a class named something of the form "ControllerHelpers"
309    // that has a method with the same name as what has been called
310    $controllerName = Zend_Controller_Front::getInstance()->getRequest()->getControllerName();
311    foreach($this->_helpers as $path => $prefix) {
312      if(substr($prefix, -1, 1) != '_') $prefix .= '_';
313      $globalHelperFile = $path . DIRECTORY_SEPARATOR . ucfirst($controllerName) . 'Helpers.php';
314      if(file_exists($globalHelperFile)) {
315        require_once($globalHelperFile);
316        $class = new ReflectionClass($prefix . ucfirst($controllerName) . 'Helpers');
317        $object = $class->newInstance();
318        if(method_exists($object, 'setView')) $object->setView($this);
319        if(method_exists($object, $method))
320          return call_user_func_array(array(&$object, $method), $args);
321      }
322    }
323    
324    // Lastly, check to see if there is a class named ApplicationHelpers with a method named the
325    // same thing as the helper that was called.
326    foreach($this->_helpers as $path => $prefix) {
327      if(substr($prefix, -1, 1) != '_') $prefix .= '_';
328      $applicationHelperFile = $path . DIRECTORY_SEPARATOR . 'ApplicationHelpers.php';
329      if(file_exists($applicationHelperFile)) {
330        require_once($applicationHelperFile);
331        $class = new ReflectionClass($prefix . 'ApplicationHelpers');
332        $object = $class->newInstance();
333        if(method_exists($object, 'setView')) $object->setView($this);
334        if(method_exists($object, $method))
335          return call_user_func_array(array(&$object, $method), $args);
336      }
337    }
338    
339    throw new Exception('Helper method ' . $method . ' is not defined');
340  }
341}