--- /dev/null
+<?php
+/**
+ * @package Horde_View
+ */
+
+if ($this->books):
+?>
+
+<!-- A table of some books. -->
+<table>
+ <tr>
+ <th>Author</th>
+ <th>Title</th>
+ </tr>
+
+<?php foreach ($this->books as $key => $val): ?>
+ <tr>
+<td><?php echo $this->escape($val['author']) ?></td>
+<td><?php echo $this->escape($val['title']) ?></td>
+ </tr>
+<?php endforeach; ?>
+
+</table>
+
+<?php else: ?>
+ <p>There are no books to display.</p>
+<?php endif; ?>
--- /dev/null
+<?php
+/**
+ * @package Horde_View
+ */
+
+require 'Horde/Autoloader.php';
+
+// use a model to get the data for book authors and titles.
+$data = array(
+ array(
+ 'author' => 'Hernando de Soto',
+ 'title' => 'The Mystery of Capitalism'
+ ),
+ array(
+ 'author' => 'Henry Hazlitt',
+ 'title' => 'Economics in One Lesson'
+ ),
+ array(
+ 'author' => 'Milton Friedman',
+ 'title' => 'Free to Choose'
+ )
+ );
+
+$view = new Horde_View;
+$view->books = $data;
+
+// and render a template called "template.php"
+echo $view->render('template.php');
--- /dev/null
+<?php
+/**
+ * @category Horde
+ * @package Horde_View
+ */
+
+/**
+ * Concrete class for handling views.
+ *
+ * @category Horde
+ * @package Horde_View
+ */
+class Horde_View extends Horde_View_Base
+{
+ /**
+ * Includes the template in a scope with only public variables.
+ *
+ * @param string The template to execute. Not declared in the
+ * function signature so it stays out of the view's public scope.
+ */
+ protected function _run()
+ {
+ $oldShortOpenTag = ini_set('short_open_tag', 1);
+ include func_get_arg(0);
+ ini_set('short_open_tag', $oldShortOpenTag);
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * @category Horde
+ * @package Horde_View
+ */
+
+/**
+ * Abstract base class for Horde_View to get private constructs out of
+ * template scope.
+ *
+ * @category Horde
+ * @package Horde_View
+ */
+abstract class Horde_View_Base
+{
+ /**
+ * Path stack for templates.
+ *
+ * @var array
+ */
+ private $_templatePath = array('./');
+
+ /**
+ * Template to execute. Stored in a private variable to keep it
+ * out of the public view scope.
+ *
+ * @var string
+ */
+ private $_file = null;
+
+ /**
+ * Cache of helper objects.
+ *
+ * @var array
+ */
+ private $_helpers = array();
+
+ /**
+ * Callback for escaping.
+ *
+ * @var string
+ */
+ private $_escape = 'htmlspecialchars';
+
+ /**
+ * Encoding to use in escaping mechanisms; defaults to UTF-8.
+ * @var string
+ */
+ private $_encoding = 'UTF-8';
+
+ /**
+ * Constructor.
+ *
+ * @param array $config Configuration key-value pairs.
+ */
+ public function __construct($config = array())
+ {
+ // user-defined escaping callback
+ if (!empty($config['escape'])) {
+ $this->setEscape($config['escape']);
+ }
+
+ // encoding
+ if (!empty($config['encoding'])) {
+ $this->setEncoding($config['encoding']);
+ }
+
+ // user-defined template path
+ if (!empty($config['templatePath'])) {
+ $this->addTemplatePath($config['templatePath']);
+ }
+ }
+
+ /**
+ * Return a view variable
+ *
+ * @param string $name Variable name to retrieve
+ */
+ public function __get($name)
+ {
+ return isset($this->name) ? $this->name : '';
+ }
+
+ /**
+ * Assign a single view variable
+ *
+ * @param string $name Variable name to set
+ * @param mixed $value The value of $name
+ */
+ public function __set($name, $value)
+ {
+ $this->$name = $value;
+ }
+
+ /**
+ * Accesses a helper object from within a template.
+ *
+ * @param string $method The helper method.
+ * @param array $args The parameters for the helper.
+ *
+ * @return string The result of the helper method.
+ */
+ public function __call($method, $args)
+ {
+ if (isset($this->_helpers[$method])) {
+ return call_user_func_array(array($this->_helpers[$method], $method), $args);
+ }
+
+ throw new Horde_View_Exception('Helper for ' . $method . ' not found.');
+ }
+
+ /**
+ * Adds to the stack of template paths in LIFO order.
+ *
+ * @param string|array The directory (-ies) to add.
+ */
+ public function addTemplatePath($path)
+ {
+ foreach ((array)$path as $dir) {
+ // Attempt to strip any possible separator and append the
+ // system directory separator.
+ $dir = rtrim($dir, '\\/' . DIRECTORY_SEPARATOR)
+ . DIRECTORY_SEPARATOR;
+
+ // Add to the top of the stack.
+ array_unshift($this->_templatePath, $dir);
+ }
+ }
+
+ /**
+ * Resets the stack of template paths.
+ *
+ * To clear all paths, use Horde_View::setTemplatePath(null).
+ *
+ * @param string|array The directory (-ies) to set as the path.
+ */
+ public function setTemplatePath($path)
+ {
+ $this->_templatePath = array();
+ $this->addTemplatePath($path);
+ }
+
+ /**
+ * Adds to the stack of helpers in LIFO order.
+ *
+ * @param Horde_View_Helper $helper The helper instance to add.
+ */
+ public function addHelper($helper)
+ {
+ foreach (get_class_methods($helper) as $method) {
+ $this->_helpers[$method] = $helper;
+ }
+ }
+
+ /**
+ * Sets the escape() callback.
+ *
+ * @param mixed $spec The callback for escape() to use.
+ */
+ public function setEscape($spec)
+ {
+ $this->_escape = $spec;
+ }
+
+ /**
+ * Assigns multiple variables to the view.
+ *
+ * The array keys are used as names, each assigned their
+ * corresponding array value.
+ *
+ * @param array $array The array of key/value pairs to assign.
+ *
+ * @see __set()
+ */
+ public function assign($array)
+ {
+ foreach ($array as $key => $val) {
+ $this->$key = $val;
+ }
+ }
+
+ /**
+ * Processes a template and returns the output.
+ *
+ * @param string $name The template to process.
+ *
+ * @return string The template output.
+ */
+ public function render($name)
+ {
+ // Find the template file name.
+ $this->_file = $this->_template($name);
+
+ // remove $name from local scope
+ unset($name);
+
+ ob_start();
+ $this->_run($this->_file);
+ return ob_get_clean();
+ }
+
+ /**
+ * Escapes a value for output in a template.
+ *
+ * If escaping mechanism is one of htmlspecialchars or htmlentities, uses
+ * {@link $_encoding} setting.
+ *
+ * @param mixed $var The output to escape.
+ *
+ * @return mixed The escaped value.
+ */
+ public function escape($var)
+ {
+ if (in_array($this->_escape, array('htmlspecialchars', 'htmlentities'))) {
+ return call_user_func($this->_escape, $var, ENT_QUOTES, $this->_encoding);
+ }
+
+ return call_user_func($this->_escape, $var);
+ }
+
+ /**
+ * Set encoding to use with htmlentities() and htmlspecialchars()
+ *
+ * @param string $encoding
+ */
+ public function setEncoding($encoding)
+ {
+ $this->_encoding = $encoding;
+ }
+
+ /**
+ * Return current escape encoding
+ *
+ * @return string
+ */
+ public function getEncoding()
+ {
+ return $this->_encoding;
+ }
+
+ /**
+ * Finds a template from the available directories.
+ *
+ * @param $name string The base name of the template.
+ */
+ protected function _template($name)
+ {
+ if (!count($this->_templatePath)) {
+ throw new Horde_View_Exception('No template directory set; unable to locate ' . $name);
+ }
+
+ foreach ($this->_templatePath as $dir) {
+ if (is_readable($dir . $name)) {
+ return $dir . $name;
+ }
+ }
+
+ throw new Horde_View_Exception("\"$name\" not found in template path (\"" . implode(':', $this->_templatePath) . '")');
+ }
+
+ /**
+ * Use to include the template in a scope that only allows public
+ * members.
+ *
+ * @return mixed
+ */
+ abstract protected function _run();
+
+}
--- /dev/null
+<?php
+/**
+ * @category Horde
+ * @package Horde_View
+ */
+
+/**
+ * @category Horde
+ * @package Horde_View
+ */
+class Horde_View_Exception extends Exception
+{
+}
--- /dev/null
+<?php
+/**
+ * @category Horde
+ * @package Horde_View
+ */
+
+/**
+ * Abstract class for Horde_View_Helper objects.
+ *
+ * @category Horde
+ * @package Horde_View
+ */
+abstract class Horde_View_Helper
+{
+ /**
+ * The parent view invoking the helper
+ *
+ * @var Horde_View
+ */
+ protected $_view;
+
+ /**
+ * Create a helper for $view
+ *
+ * @param Horde_View $view The view to help.
+ */
+ public function __construct($view)
+ {
+ $this->_view = $view;
+ $view->addHelper($this);
+ }
+
+ /**
+ * Call chaining so other helpers can be called transparently.
+ *
+ * @param string $method The helper method.
+ * @param array $args The parameters for the helper.
+ *
+ * @return string The result of the helper method.
+ */
+ public function __call($method, $args)
+ {
+ return call_user_func_array(array($this->_view, $method), $args);
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * $Horde: framework/View/lib/Horde/View/Helper/Block.php,v 1.2 2008/10/09 02:43:53 chuck Exp $
+ *
+ * @category Horde
+ * @package Horde_View
+ * @subpackage Helpers
+ */
+
+/**
+ * View helper for displaying Horde_Block objects
+ *
+ * @category Horde
+ * @package Horde_View
+ * @subpackage Helpers
+ */
+class Horde_View_Helper_Block extends Horde_View_Helper
+{
+ /**
+ * Blocks that have already been fetched.
+ *
+ * @var array
+ */
+ protected $_blockCache = array();
+
+ /**
+ * Return the title of the specified block.
+ *
+ * @param string $app The application the block is from.
+ * @param string $block The name of the block to get the title for.
+ * @param mixed $arg1 (optional) The first argument to the Block constructor.
+ * @param mixed $arg2 (optional) The first argument to the Block constructor.
+ * @param mixed $arg3 (optional) The first argument to the Block constructor.
+ *
+ * ...
+ *
+ * @return string The requested Block's title.
+ *
+ * @throws Horde_View_Exception, InvalidArgumentException
+ */
+ public function blockTitle()
+ {
+ $args = func_get_args();
+ list($app, $block, $params) = $this->_args($args);
+
+ return $this->_block($app, $block, $params)->getTitle();
+ }
+
+ /**
+ * Return the content of the specified block.
+ *
+ * @param string $app The application the block is from.
+ * @param string $block The name of the block to get the content for.
+ * @param mixed $arg1 (optional) The first argument to the Block constructor.
+ * @param mixed $arg2 (optional) The first argument to the Block constructor.
+ * @param mixed $arg3 (optional) The first argument to the Block constructor.
+ *
+ * ...
+ *
+ * @return string The requested Block's content.
+ *
+ * @throws Horde_View_Exception, InvalidArgumentException
+ */
+ public function blockContent()
+ {
+ $args = func_get_args();
+ list($app, $block, $params) = $this->_args($args);
+
+ return $this->_block($app, $block, $params)->getContent();
+ }
+
+ /**
+ * Instantiate and cache Block objects
+ *
+ * @param string $app The application the block is from.
+ * @param string $block The name of the block to fetch.
+ * @param array $params (option) Any arguments to the Block constructor.
+ *
+ * ...
+ *
+ * @return Horde_Block The requested Block object
+ *
+ * @throws Horde_View_Exception, InvalidArgumentException
+ */
+ protected function _block($app, $block, $params)
+ {
+ $hash = sha1(serialize(array($app, $block, $params)));
+ if (!isset($this->_blockCache[$hash])) {
+ $block = Horde_Block_Collection::getBlock($app, $block, $params);
+ if (!$block instanceof Horde_Block) {
+ if (is_callable(array($block, 'getMessage'))) {
+ throw new Horde_View_Exception($block->getMessage());
+ } else {
+ throw new Horde_View_Exception('Unknown error instantiating Block object');
+ }
+ }
+
+ $this->_blockCache[$hash] = $block;
+ }
+
+ return $this->_blockCache[$hash];
+ }
+
+ /**
+ * Parse any argument style for the Block-fetching functions
+ *
+ * @param array $args
+ */
+ protected function _args($args)
+ {
+ $argc = count($args);
+
+ if ($argc == 1) {
+ if (is_array($args[0])) {
+ $args = $args[0];
+ $argc = count($args);
+ }
+ }
+
+ if ($argc < 2) {
+ throw new InvalidArgumentException('You must provide at least an application name and a block name.');
+ }
+ $app = array_shift($args);
+ $block = array_shift($args);
+
+ return array($app, $block, $args);
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * $Horde: framework/View/lib/Horde/View/Helper/Url.php,v 1.2 2008/10/09 02:43:53 chuck Exp $
+ *
+ * @category Horde
+ * @package Horde_View
+ * @subpackage Helpers
+ */
+
+/**
+ * View helper for URLs
+ *
+ * @category Horde
+ * @package Horde_View
+ * @subpackage Helpers
+ */
+class Horde_View_Helper_Url extends Horde_View_Helper
+{
+ /**
+ * Creates a link tag of the given +name+ using a URL created by the set
+ * of +options+. See the valid options in the documentation for
+ * url_for. It's also possible to pass a string instead
+ * of an options hash to get a link tag that uses the value of the string as the
+ * href for the link, or use +:back+ to link to the referrer - a JavaScript back
+ * link will be used in place of a referrer if none exists. If nil is passed as
+ * a name, the link itself will become the name.
+ *
+ * ==== Options
+ * * <tt>:confirm => 'question?'</tt> -- This will add a JavaScript confirm
+ * prompt with the question specified. If the user accepts, the link is
+ * processed normally, otherwise no action is taken.
+ * * <tt>:popup => true || array of window options</tt> -- This will force the
+ * link to open in a popup window. By passing true, a default browser window
+ * will be opened with the URL. You can also specify an array of options
+ * that are passed-thru to JavaScripts window.open method.
+ * * <tt>:method => symbol of HTTP verb</tt> -- This modifier will dynamically
+ * create an HTML form and immediately submit the form for processing using
+ * the HTTP verb specified. Useful for having links perform a POST operation
+ * in dangerous actions like deleting a record (which search bots can follow
+ * while spidering your site). Supported verbs are :post, :delete and :put.
+ * Note that if the user has JavaScript disabled, the request will fall back
+ * to using GET. If you are relying on the POST behavior, you should check
+ * for it in your controller's action by using the request object's methods
+ * for post?, delete? or put?.
+ * * The +html_options+ will accept a hash of html attributes for the link tag.
+ *
+ * Note that if the user has JavaScript disabled, the request will fall back
+ * to using GET. If :href=>'#' is used and the user has JavaScript disabled
+ * clicking the link will have no effect. If you are relying on the POST
+ * behavior, your should check for it in your controller's action by using the
+ * request object's methods for post?, delete? or put?.
+ */
+ public function linkTo($name, $url, $htmlOptions = array())
+ {
+ if ($htmlOptions) {
+ $href = isset($htmlOptions['href']) ? $htmlOptions['href'] : null;
+ // @todo convert_otpions_to_javascript!(html_options, url)
+ $tagOptions = $this->tagOptions($htmlOptions);
+ } else {
+ $tagOptions = null;
+ }
+
+ $hrefAttr = isset($href) ? null : 'href="' . $url . '"';
+ $nameOrUrl = isset($name) ? $name : $url;
+ return '<a ' . $hrefAttr . $tagOptions . '>' . $this->escape($nameOrUrl) . '</a>';
+ }
+
+ /**
+ * Creates a link tag of the given $name using $url unless the current
+ * request URI is the same as the links, in which case only the name is
+ * returned.
+ */
+ public function linkToUnlessCurrent($name, $url, $htmlOptions = array())
+ {
+ return $this->linkToUnless($this->isCurrentPage($url),
+ $name, $url, $htmlOptions);
+ }
+
+ /**
+ * Creates a link tag of the given +name+ using a URL created by the set of
+ * +options+ unless +condition+ is true, in which case only the name is
+ * returned. To specialize the default behavior (i.e., show a login link rather
+ * than just the plaintext link text), you can pass a block that
+ * accepts the name or the full argument list for link_to_unless.
+ */
+ public function linkToUnless($condition, $name, $url, $htmlOptions = array())
+ {
+ return $condition ? $name : $this->linkTo($name, $url, $htmlOptions);
+ }
+
+ /**
+ * Creates a link tag of the given +name+ using a URL created by the set of
+ * +options+ if +condition+ is true, in which case only the name is
+ * returned. To specialize the default behavior, you can pass a block that
+ * accepts the name or the full argument list for link_to_unless (see the examples
+ * in link_to_unless).
+ */
+ public function linkToIf($condition, $name, $url, $htmlOptions = array())
+ {
+ return $this->linkToUnless(!$condition, $name, $url, $htmlOptions);
+ }
+
+ /**
+ * True if the current request URI is the same as the current URL.
+ *
+ * @TODO Get REQUEST_URI from somewhere other than the global environment.
+ */
+ public function isCurrentPage($url)
+ {
+ return $url == $_SERVER['REQUEST_URI'];
+ }
+
+ // @TODO Move these methods to a generic HTML/Tag helper
+
+ /**
+ * HTML attributes that get converted from boolean to the attribute name:
+ * array('disabled' => true) becomes array('disabled' => 'disabled')
+ *
+ * @var array
+ */
+ private $_booleanAttributes = array('disabled', 'readonly', 'multiple', 'selected', 'checked');
+
+ /**
+ * Converts an associative array of $options into
+ * a string of HTML attributes
+ *
+ * @param array $options key/value pairs
+ * @param string key1="value1" key2="value2"
+ */
+ public function tagOptions($options)
+ {
+ foreach ($options as $k => &$v) {
+ if ($v === null || $v === false) {
+ unset($options[$k]);
+ } else {
+ if (in_array($k, $this->_booleanAttributes)) {
+ $v = $k;
+ }
+ }
+ }
+
+ if (!empty($options)) {
+ foreach ($options as $k => &$v) {
+ $v = $k . '="' . $this->escapeOnce($v) . '"';
+ }
+ sort($options);
+ return ' ' . implode(' ', $options);
+ } else {
+ return '';
+ }
+ }
+
+ /**
+ * Returns the escaped $html without affecting existing escaped entities.
+ *
+ * $this->escapeOnce("1 > 2 & 3")
+ * => "1 < 2 & 3"
+ *
+ * @param string $html HTML to be escaped
+ *
+ * @return string Escaped HTML without affecting existing escaped entities
+ */
+ public function escapeOnce($html)
+ {
+ return $this->_fixDoubleEscape(htmlspecialchars($html, ENT_QUOTES, $this->getEncoding()));
+ }
+
+ /**
+ * Fix double-escaped entities, such as &amp;
+ *
+ * @param string $escaped Double-escaped entities
+ * @return string Entities fixed
+ */
+ private function _fixDoubleEscape($escaped)
+ {
+ return preg_replace('/&([a-z]+|(#\d+));/i', '&\\1;', $escaped);
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * @category Horde
+ * @package Horde_View
+ */
+
+/**
+ * Horde_View_Interface is a reference for classes to be used as Horde
+ * Views. Implementing it is optional; type hinting is not used to
+ * enforce the interface.
+ *
+ * @category Horde
+ * @package Horde_View
+ */
+interface Horde_View_Interface
+{
+ /**
+ * Return a view variable
+ *
+ * @param string $name Variable name to retrieve
+ */
+ public function __get($name);
+
+ /**
+ * Assign a single view variable
+ *
+ * @param string $name Variable name to set
+ * @param mixed $value The value of $name
+ */
+ public function __set($name, $value);
+
+ /**
+ * Accesses a helper object from within a template.
+ *
+ * @param string $name The helper name.
+ * @param array $args The parameters for the helper.
+ *
+ * @return string The result of the helper output.
+ */
+ public function __call($name, $args);
+
+ /**
+ * Adds to the stack of template paths in LIFO order.
+ *
+ * @param string|array The directory (-ies) to add.
+ */
+ public function addTemplatePath($path);
+
+ /**
+ * Resets the stack of template paths.
+ *
+ * To clear all paths, use Horde_View::setTemplatePath(null).
+ *
+ * @param string|array The directory (-ies) to set as the path.
+ */
+ public function setTemplatePath($path);
+
+ /**
+ * Adds to the stack of helpers in LIFO order.
+ *
+ * @param Horde_View_Helper The helper instance to add.
+ */
+ public function addHelper($helper);
+
+ /**
+ * Sets the escape() callback.
+ *
+ * @param mixed $spec The callback for escape() to use.
+ */
+ public function setEscape($spec);
+
+ /**
+ * Assigns multiple variables to the view.
+ *
+ * The array keys are used as names, each assigned their
+ * corresponding array value.
+ *
+ * @param array $array The array of key/value pairs to assign.
+ *
+ * @see __set()
+ */
+ public function assign($array);
+
+ /**
+ * Processes a template and returns the output.
+ *
+ * @param string $name The template name to process.
+ *
+ * @return string The template output.
+ */
+ public function render($name);
+
+ /**
+ * Escapes a value for output in a template.
+ *
+ * If escaping mechanism is one of htmlspecialchars or htmlentities, uses
+ * {@link $_encoding} setting.
+ *
+ * @param mixed $var The output to escape.
+ *
+ * @return mixed The escaped value.
+ */
+ public function escape($var);
+
+ /**
+ * Set encoding to use with htmlentities() and htmlspecialchars()
+ *
+ * @param string $encoding
+ */
+ public function setEncoding($encoding);
+
+ /**
+ * Return current escape encoding
+ *
+ * @return string
+ */
+ public function getEncoding();
+
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<package packagerversion="1.4.9" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0
+http://pear.php.net/dtd/tasks-1.0.xsd
+http://pear.php.net/dtd/package-2.0
+http://pear.php.net/dtd/package-2.0.xsd">
+ <name>View</name>
+ <channel>pear.horde.org</channel>
+ <summary>Horde View API</summary>
+ <description>The Horde_View:: class provides a simple View pattern implementation.
+ </description>
+ <lead>
+ <name>Chuck Hagenbuch</name>
+ <user>chuck</user>
+ <email>chuck@horde.org</email>
+ <active>yes</active>
+ </lead>
+ <date>2008-02-12</date>
+ <time>17:00:00</time>
+ <version>
+ <release>0.2.1</release>
+ <api>0.2.0</api>
+ </version>
+ <stability>
+ <release>beta</release>
+ <api>beta</api>
+ </stability>
+ <license uri="http://www.gnu.org/copyleft/lesser.html">LGPL</license>
+ <notes>- Better Helper architecture, improved View/Helper registration
+ </notes>
+ <contents>
+ <dir name="/">
+ <dir name="lib">
+ <dir name="Horde">
+ <dir name="View">
+ <dir name="Helper">
+ <file name="Block.php" role="php" />
+ <file name="Url.php" role="php" />
+ </dir> <!-- /lib/Horde/View/Helper -->
+ <file name="Base.php" role="php" />
+ <file name="Exception.php" role="php" />
+ <file name="Helper.php" role="php" />
+ <file name="Interface.php" role="php" />
+ </dir> <!-- /lib/Horde/View -->
+ <file name="View.php" role="php" />
+ </dir> <!-- /lib/Horde -->
+ </dir> <!-- /lib -->
+ </dir> <!-- / -->
+ </contents>
+ <dependencies>
+ <required>
+ <php>
+ <min>5.2.0</min>
+ </php>
+ <pearinstaller>
+ <min>1.5.0</min>
+ </pearinstaller>
+ </required>
+ </dependencies>
+ <phprelease>
+ <filelist>
+ <install name="lib/Horde/View/Helper/Block.php" as="Horde/View/Helper/Block.php" />
+ <install name="lib/Horde/View/Helper/Url.php" as="Horde/View/Helper/Url.php" />
+ <install name="lib/Horde/View/Base.php" as="Horde/View/Base.php" />
+ <install name="lib/Horde/View/Exception.php" as="Horde/View/Exception.php" />
+ <install name="lib/Horde/View/Helper.php" as="Horde/View/Helper.php" />
+ <install name="lib/Horde/View/Interface.php" as="Horde/View/Interface.php" />
+ <install name="lib/Horde/View.php" as="Horde/View.php" />
+ </filelist>
+ </phprelease>
+</package>
--- /dev/null
+<?php
+/**
+ * @package Horde_View
+ * @subpackage UnitTests
+ */
+
+if (!defined('PHPUnit_MAIN_METHOD')) {
+ define('PHPUnit_MAIN_METHOD', 'Horde_View_AllTests::main');
+}
+
+require_once 'PHPUnit/Framework/TestSuite.php';
+require_once 'PHPUnit/TextUI/TestRunner.php';
+
+class Horde_View_AllTests {
+
+ public static function main()
+ {
+ PHPUnit_TextUI_TestRunner::run(self::suite());
+ }
+
+ public static function suite()
+ {
+ $suite = new PHPUnit_Framework_TestSuite('Horde Framework - Horde_View');
+
+ $basedir = dirname(__FILE__);
+ $baseregexp = preg_quote($basedir . DIRECTORY_SEPARATOR, '/');
+
+ foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($basedir)) as $file) {
+ if ($file->isFile() && preg_match('/Test.php$/', $file->getFilename())) {
+ $pathname = $file->getPathname();
+ require $pathname;
+
+ $class = str_replace(DIRECTORY_SEPARATOR, '_',
+ preg_replace("/^$baseregexp(.*)\.php/", '\\1', $pathname));
+ $suite->addTestSuite('Horde_View_' . $class);
+ }
+ }
+
+ return $suite;
+ }
+
+}
+
+if (PHPUnit_MAIN_METHOD == 'Horde_View_AllTests::main') {
+ Horde_View_AllTests::main();
+}
--- /dev/null
+<?php
+/**
+ * @category Horde
+ * @package Horde_View
+ * @subpackage UnitTests
+ */
+
+require_once dirname(__FILE__) . '/../../../lib/Horde/View/Interface.php';
+require_once dirname(__FILE__) . '/../../../lib/Horde/View/Base.php';
+require_once dirname(__FILE__) . '/../../../lib/Horde/View.php';
+
+class Horde_View_InterfaceTest extends PHPUnit_Framework_TestCase {
+
+ public function testViewInterface()
+ {
+ eval('class Test_View extends Horde_View implements Horde_View_Interface {};');
+ }
+
+}