,
* Bertrand Mansion
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * The names of the authors may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @category HTML
* @package HTML_QuickForm2
* @author Alexey Borzov
* @author Bertrand Mansion
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @link http://pear.php.net/package/HTML_QuickForm2
*/
/**
* Class with static methods for loading classes and files
*/
require_once 'HTML/QuickForm2/Loader.php';
/**
* Abstract base class for QuickForm2 renderers
*
* This class serves two main purposes:
*
* - Defines the API all renderers should implement (render*() methods);
* - Provides static methods for registering renderers and their plugins
* and {@link factory()} method for creating renderer instances.
*
*
* Note that renderers should always be instantiated through factory(), in the
* other case it will not be possible to add plugins.
*
* @category HTML
* @package HTML_QuickForm2
* @author Alexey Borzov
* @author Bertrand Mansion
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 2.0.2
* @link http://pear.php.net/package/HTML_QuickForm2
*/
abstract class HTML_QuickForm2_Renderer
{
/**
* List of registered renderer types
* @var array
*/
private static $_types = array(
'callback' => array('HTML_QuickForm2_Renderer_Callback', null),
'default' => array('HTML_QuickForm2_Renderer_Default', null),
'array' => array('HTML_QuickForm2_Renderer_Array', null),
'stub' => array('HTML_QuickForm2_Renderer_Stub', null)
);
/**
* List of registered renderer plugins
* @var array
*/
private static $_pluginClasses = array(
'callback' => array(),
'default' => array(),
'array' => array(),
'stub' => array()
);
/**
* Renderer options
* @var array
* @see setOption()
*/
protected $options = array(
'group_hiddens' => true,
'required_note' => '* denotes required fields.',
'errors_prefix' => 'Invalid information entered:',
'errors_suffix' => 'Please correct these fields.',
'group_errors' => false
);
/**
* Javascript builder object
* @var HTML_QuickForm2_JavascriptBuilder
*/
protected $jsBuilder;
/**
* Creates a new renderer instance of the given type
*
* A renderer is always wrapped by a Proxy, which handles calling its
* "published" methods and methods of its plugins. Registered plugins are
* added automagically to the existing renderer instances so that
*
* $foo = HTML_QuickForm2_Renderer::factory('foo');
* // Plugin implementing bar() method
* HTML_QuickForm2_Renderer::registerPlugin('foo', 'Plugin_Foo_Bar');
* $foo->bar();
*
* will work.
*
* @param string $type Type name (treated case-insensitively)
*
* @return HTML_QuickForm2_Renderer_Proxy A renderer instance of the given
* type wrapped by a Proxy
* @throws HTML_QuickForm2_InvalidArgumentException If type name is unknown
* @throws HTML_QuickForm2_NotFoundException If class for the renderer can
* not be found and/or loaded from file
*/
final public static function factory($type)
{
$type = strtolower($type);
if (!isset(self::$_types[$type])) {
throw new HTML_QuickForm2_InvalidArgumentException(
"Renderer type '$type' is not known"
);
}
list ($className, $includeFile) = self::$_types[$type];
HTML_QuickForm2_Loader::loadClass($className, $includeFile);
HTML_QuickForm2_Loader::loadClass('HTML_QuickForm2_Renderer_Proxy');
return new HTML_QuickForm2_Renderer_Proxy(new $className, self::$_pluginClasses[$type]);
}
/**
* Registers a new renderer type
*
* @param string $type Type name (treated case-insensitively)
* @param string $className Class name
* @param string $includeFile File containing the class, leave empty
* if class already loaded
*
* @throws HTML_QuickForm2_InvalidArgumentException if type already registered
*/
final public static function register($type, $className, $includeFile = null)
{
$type = strtolower($type);
self::$_types[$type] = array($className, $includeFile);
if (empty(self::$_pluginClasses[$type])) {
self::$_pluginClasses[$type] = array();
}
}
/**
* Registers a plugin for a renderer type
*
* @param string $type Renderer type name (treated case-insensitively)
* @param string $className Plugin class name
* @param string $includeFile File containing the plugin class, leave empty if class already loaded
*
* @throws HTML_QuickForm2_InvalidArgumentException if plugin is already registered
*/
final public static function registerPlugin($type, $className, $includeFile = null)
{
$type = strtolower($type);
// We don't check self::$_types, since a plugin may be registered
// before renderer itself if it goes with some custom element
if (empty(self::$_pluginClasses[$type])) {
self::$_pluginClasses[$type] = array(array($className, $includeFile));
} else {
foreach (self::$_pluginClasses[$type] as $plugin) {
if (0 == strcasecmp($plugin[0], $className)) {
throw new HTML_QuickForm2_InvalidArgumentException(
"Plugin '$className' for renderer type '$type' is already registered"
);
}
}
self::$_pluginClasses[$type][] = array($className, $includeFile);
}
}
/**
* Constructor
*
* Renderer instances should not be created directly, use {@link factory()}
*/
protected function __construct()
{
}
/**
* Returns an array of "published" method names that should be callable through proxy
*
* Methods defined in HTML_QuickForm2_Renderer are proxied automatically,
* only additional methods should be returned.
*
* @return array
*/
protected function exportMethods()
{
return array();
}
/**
* Checks whether a method is available in this object
*
* @param string $name Method name
*
* @return bool
*/
public function methodExists($name)
{
try {
$method = new ReflectionMethod($this, $name);
return $method->isPublic();
} catch (ReflectionException $e) {
return false;
}
}
/**
* Sets the option(s) affecting renderer behaviour
*
* The following options are available:
*
* - 'group_hiddens' - whether to group hidden elements together or
* render them where they were added (boolean)
* - 'group_errors' - whether to group error messages or render them
* alongside elements they apply to (boolean)
* - 'errors_prefix' - leading message for grouped errors (string)
* - 'errors_suffix' - trailing message for grouped errors (string)
* - 'required_note' - note displayed if the form contains required
* elements (string)
*
*
* @param string|array $nameOrOptions option name or array ('option name' => 'option value')
* @param mixed $value parameter value if $nameOrConfig is not an array
*
* @return $this
* @throws HTML_QuickForm2_NotFoundException in case of unknown option
*/
public function setOption($nameOrOptions, $value = null)
{
if (is_array($nameOrOptions)) {
foreach ($nameOrOptions as $name => $value) {
$this->setOption($name, $value);
}
} else {
if (!array_key_exists($nameOrOptions, $this->options)) {
throw new HTML_QuickForm2_NotFoundException(
"Unknown option '{$nameOrOptions}'"
);
}
$this->options[$nameOrOptions] = $value;
}
return $this;
}
/**
* Returns the value(s) of the renderer option(s)
*
* @param string $name parameter name
*
* @return mixed value of $name parameter, array of all configuration
* parameters if $name is not given
* @throws HTML_QuickForm2_NotFoundException in case of unknown option
*/
public function getOption($name = null)
{
if (null === $name) {
return $this->options;
} elseif (!array_key_exists($name, $this->options)) {
throw new HTML_QuickForm2_NotFoundException(
"Unknown option '{$name}'"
);
}
return $this->options[$name];
}
/**
* Returns the javascript builder object
*
* @return HTML_QuickForm2_JavascriptBuilder
*/
public function getJavascriptBuilder()
{
if (empty($this->jsBuilder)) {
HTML_QuickForm2_Loader::loadClass('HTML_QuickForm2_JavascriptBuilder');
$this->jsBuilder = new HTML_QuickForm2_JavascriptBuilder();
}
return $this->jsBuilder;
}
/**
* Sets the javascript builder object
*
* You may want to reuse the same builder object if outputting several
* forms on one page.
*
* @param HTML_QuickForm2_JavascriptBuilder $builder
*
* @return $this
*/
public function setJavascriptBuilder(HTML_QuickForm2_JavascriptBuilder $builder = null)
{
$this->jsBuilder = $builder;
return $this;
}
/**
* Resets the accumulated data
*
* This method is called automatically by startForm() method, but should
* be called manually before calling other rendering methods separately.
*
* @return $this
*/
abstract public function reset();
/**
* Renders a generic element
*
* @param HTML_QuickForm2_Node $element Element being rendered
*/
abstract public function renderElement(HTML_QuickForm2_Node $element);
/**
* Renders a hidden element
*
* @param HTML_QuickForm2_Node $element Hidden element being rendered
*/
abstract public function renderHidden(HTML_QuickForm2_Node $element);
/**
* Starts rendering a form, called before processing contained elements
*
* @param HTML_QuickForm2_Node $form Form being rendered
*/
abstract public function startForm(HTML_QuickForm2_Node $form);
/**
* Finishes rendering a form, called after processing contained elements
*
* @param HTML_QuickForm2_Node $form Form being rendered
*/
abstract public function finishForm(HTML_QuickForm2_Node $form);
/**
* Starts rendering a generic container, called before processing contained elements
*
* @param HTML_QuickForm2_Node $container Container being rendered
*/
abstract public function startContainer(HTML_QuickForm2_Node $container);
/**
* Finishes rendering a generic container, called after processing contained elements
*
* @param HTML_QuickForm2_Node $container Container being rendered
*/
abstract public function finishContainer(HTML_QuickForm2_Node $container);
/**
* Starts rendering a group, called before processing grouped elements
*
* @param HTML_QuickForm2_Node $group Group being rendered
*/
abstract public function startGroup(HTML_QuickForm2_Node $group);
/**
* Finishes rendering a group, called after processing grouped elements
*
* @param HTML_QuickForm2_Node $group Group being rendered
*/
abstract public function finishGroup(HTML_QuickForm2_Node $group);
}
?>