home *** CD-ROM | disk | FTP | other *** search
/ Enter 2004 June / ENTER.ISO / files / xampp-win32-1.4.5-installer.exe / xampp / ArraySmarty.php < prev    next >
Encoding:
PHP Script  |  2004-03-24  |  13.5 KB  |  374 lines

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4: */
  3. // +----------------------------------------------------------------------+
  4. // | PHP version 4.0                                                      |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2003 The PHP Group                                |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.0 of the PHP license,       |
  9. // | that is bundled with this package in the file LICENSE, and is        |
  10. // | available at through the world-wide-web at                           |
  11. // | http://www.php.net/license/2_02.txt.                                 |
  12. // | If you did not receive a copy of the PHP license and are unable to   |
  13. // | obtain it through the world-wide-web, please send a note to          |
  14. // | license@php.net so we can mail you a copy immediately.               |
  15. // +----------------------------------------------------------------------+
  16. // | Authors: Alexey Borzov <borz_off@cs.msu.su>                          |
  17. // |          Bertrand Mansion <bmansion@mamasam.com>                     |
  18. // |          Thomas Schulz <ths@4bconsult.de>                            |
  19. // +----------------------------------------------------------------------+
  20. //
  21. // $Id: ArraySmarty.php,v 1.8 2004/02/14 11:01:51 ths Exp $
  22.  
  23. require_once 'HTML/QuickForm/Renderer/Array.php';
  24.  
  25. /**
  26.  * A static renderer for HTML_QuickForm, makes an array of form content
  27.  * useful for an Smarty template
  28.  *
  29.  * Based on old toArray() code and ITStatic renderer.
  30.  *
  31.  * The form array structure is the following:
  32.  * Array (
  33.  *  [frozen]       => whether the complete form is frozen'
  34.  *  [javascript]   => javascript for client-side validation
  35.  *  [attributes]   => attributes for <form> tag
  36.  *  [hidden]       => html of all hidden elements
  37.  *  [requirednote] => note about the required elements
  38.  *  [errors] => Array
  39.  *      (
  40.  *          [1st_element_name] => Error for the 1st element
  41.  *          ...
  42.  *          [nth_element_name] => Error for the nth element
  43.  *      )
  44.  *
  45.  *  [header] => Array
  46.  *      (
  47.  *          [1st_header_name] => Header text for the 1st header
  48.  *          ...
  49.  *          [nth_header_name] => Header text for the nth header
  50.  *      )
  51.  *
  52.  *  [1st_element_name] => Array for the 1st element
  53.  *  ...
  54.  *  [nth_element_name] => Array for the nth element
  55.  *
  56.  * // where an element array has the form:
  57.  *      (
  58.  *          [name]      => element name
  59.  *          [value]     => element value,
  60.  *          [type]      => type of the element
  61.  *          [frozen]    => whether element is frozen
  62.  *          [label]     => label for the element
  63.  *          [required]  => whether element is required
  64.  * // if element is not a group:
  65.  *          [html]      => HTML for the element
  66.  * // if element is a group:
  67.  *          [separator] => separator for group elements
  68.  *          [1st_gitem_name] => Array for the 1st element in group
  69.  *          ...
  70.  *          [nth_gitem_name] => Array for the nth element in group
  71.  *      )
  72.  * )
  73.  *
  74.  * @access public
  75.  */
  76. class HTML_QuickForm_Renderer_ArraySmarty extends HTML_QuickForm_Renderer_Array
  77. {
  78.    /**
  79.     * The Smarty template engine instance
  80.     * @var object
  81.     */
  82.     var $_tpl = null;
  83.  
  84.    /**
  85.     * Current element index
  86.     * @var integer
  87.     */
  88.     var $_elementIdx = 0;
  89.  
  90.     /**
  91.     * The current element index inside a group
  92.     * @var integer
  93.     */
  94.     var $_groupElementIdx = 0;
  95.  
  96.    /**
  97.     * How to handle the required tag for required fields
  98.     * @var string
  99.     * @see      setRequiredTemplate()
  100.     */
  101.     var $_required = '';
  102.  
  103.    /**
  104.     * How to handle error messages in form validation
  105.     * @var string
  106.     * @see      setErrorTemplate()
  107.     */
  108.     var $_error = '';
  109.  
  110.    /**
  111.     * Constructor
  112.     *
  113.     * @access public
  114.     */
  115.     function HTML_QuickForm_Renderer_ArraySmarty(&$tpl)
  116.     {
  117.         $this->HTML_QuickForm_Renderer_Array(true);
  118.         $this->_tpl =& $tpl;
  119.     } // end constructor
  120.  
  121.    /**
  122.     * Called when visiting a header element
  123.     *
  124.     * @param    object     An HTML_QuickForm_header element being visited
  125.     * @access   public
  126.     * @return   void
  127.     */
  128.     function renderHeader(&$header)
  129.     {
  130.         if ($name = $header->getName()) {
  131.             $this->_ary['header'][$name] = $header->toHtml();
  132.         } else {
  133.             $this->_ary['header'][$this->_sectionCount] = $header->toHtml();
  134.         }
  135.         $this->_currentSection = $this->_sectionCount++;
  136.     } // end func renderHeader
  137.  
  138.    /**
  139.     * Called when visiting a group, before processing any group elements
  140.     *
  141.     * @param    object     An HTML_QuickForm_group object being visited
  142.     * @param    bool       Whether a group is required
  143.     * @param    string     An error message associated with a group
  144.     * @access   public
  145.     * @return   void
  146.     */
  147.     function startGroup(&$group, $required, $error)
  148.     {
  149.         parent::startGroup($group, $required, $error);
  150.         $this->_groupElementIdx = 1;
  151.     } // end func startGroup
  152.  
  153.    /**
  154.     * Creates an array representing an element containing
  155.     * the key for storing this
  156.     *
  157.     * @access private
  158.     * @param  object    An HTML_QuickForm_element object
  159.     * @param  bool      Whether an element is required
  160.     * @param  string    Error associated with the element
  161.     * @return array
  162.     */
  163.     function _elementToArray(&$element, $required, $error)
  164.     {
  165.         $ret = parent::_elementToArray($element, $required, $error);
  166.  
  167.         if ('group' == $ret['type']) {
  168.             $ret['html'] = $element->toHtml();
  169.             // we don't need the elements, see the array structure
  170.             unset($ret['elements']);
  171.         }
  172.         if (!empty($this->_required)){
  173.             $this->_renderRequired($ret['label'], $ret['html'], $required, $error);
  174.         }
  175.         if (!empty($this->_error)) {
  176.             $this->_renderError($ret['label'], $ret['html'], $error);
  177.             $ret['error'] = $error;
  178.         }
  179.         // create keys for elements grouped by native group or name
  180.         if (strstr($ret['name'], '[') or $this->_currentGroup) {
  181.             preg_match('/([^]]*)\\[([^]]*)\\]/', $ret['name'], $matches);
  182.             if (isset($matches[1])) {
  183.                 $sKeysSub = substr_replace($ret['name'], '', 0, strlen($matches[1]));
  184.                 $sKeysSub = str_replace(
  185.                     array('['  ,   ']', '[\'\']'),
  186.                     array('[\'', '\']', '[]'    ),
  187.                     $sKeysSub
  188.                 );
  189.                 $sKeys = '[\'' . $matches[1]  . '\']' . $sKeysSub;
  190.             } else {
  191.                 $sKeys = '[\'' . $ret['name'] . '\']';
  192.             }
  193.             // special handling for elements in native groups
  194.             if ($this->_currentGroup) {
  195.                 // skip unnamed group items unless radios: no name -> no static access
  196.                 // identification: have the same key string as the parent group
  197.                 if ($this->_currentGroup['keys'] == $sKeys and 'radio' != $ret['type']) {
  198.                     return false;
  199.                 }
  200.                 // reduce string of keys by remove leading group keys
  201.                 if (0 === strpos($sKeys, $this->_currentGroup['keys'])) {
  202.                     $sKeys = substr_replace($sKeys, '', 0, strlen($this->_currentGroup['keys']));
  203.                 }
  204.             }
  205.         // element without a name
  206.         } elseif ($ret['name'] == '') {
  207.             $sKeys = '[\'element_' . $this->_elementIdx . '\']';
  208.         // other elements
  209.         } else {
  210.             $sKeys = '[\'' . $ret['name'] . '\']';
  211.         }
  212.         // for radios: add extra key from value
  213.         if ('radio' == $ret['type'] and substr($sKeys, -2) != '[]') {
  214.             $sKeys .= '[\'' . $ret['value'] . '\']';
  215.         }
  216.         $this->_elementIdx++;
  217.         $ret['keys'] = $sKeys;
  218.         return $ret;
  219.     } // end func _elementToArray
  220.  
  221.    /**
  222.     * Stores an array representation of an element in the form array
  223.     *
  224.     * @access private
  225.     * @param array  Array representation of an element
  226.     * @return void
  227.     */
  228.     function _storeArray($elAry)
  229.     {
  230.         if ($elAry) {
  231.             $sKeys = $elAry['keys'];
  232.             unset($elAry['keys']);
  233.             // where should we put this element...
  234.             if (is_array($this->_currentGroup) && ('group' != $elAry['type'])) {
  235.                 $toEval = '$this->_currentGroup' . $sKeys . ' = $elAry;';
  236.             } else {
  237.                 $toEval = '$this->_ary' . $sKeys . ' = $elAry;';
  238.             }
  239.             eval($toEval);
  240.         }
  241.         return;
  242.     }
  243.  
  244.    /**
  245.     * Called when an element is required
  246.     *
  247.     * This method will add the required tag to the element label and/or the element html
  248.     * such as defined with the method setRequiredTemplate.
  249.     *
  250.     * @param    string      The element label
  251.     * @param    string      The element html rendering
  252.     * @param    boolean     The element required
  253.     * @param    string      The element error
  254.     * @see      setRequiredTemplate()
  255.     * @access   private
  256.     * @return   void
  257.     */
  258.     function _renderRequired(&$label, &$html, &$required, &$error)
  259.     {
  260.         $this->_tpl->assign(array(
  261.             'label'    => $label,
  262.             'html'     => $html,
  263.             'required' => $required,
  264.             'error'    => $error
  265.         ));
  266.         if (!empty($label) && strpos($this->_required, $this->_tpl->left_delimiter . '$label') !== false) {
  267.             $label = $this->_tplFetch($this->_required);
  268.         }
  269.         if (!empty($html) && strpos($this->_required, $this->_tpl->left_delimiter . '$html') !== false) {
  270.             $html = $this->_tplFetch($this->_required);
  271.         }
  272.         $this->_tpl->clear_assign(array('label', 'html', 'required'));
  273.     } // end func _renderRequired
  274.  
  275.    /**
  276.     * Called when an element has a validation error
  277.     *
  278.     * This method will add the error message to the element label or the element html
  279.     * such as defined with the method setErrorTemplate. If the error placeholder is not found
  280.     * in the template, the error will be displayed in the form error block.
  281.     *
  282.     * @param    string      The element label
  283.     * @param    string      The element html rendering
  284.     * @param    string      The element error
  285.     * @see      setErrorTemplate()
  286.     * @access   private
  287.     * @return   void
  288.     */
  289.     function _renderError(&$label, &$html, &$error)
  290.     {
  291.         $this->_tpl->assign(array('label' => '', 'html' => '', 'error' => $error));
  292.         $error = $this->_tplFetch($this->_error);
  293.         $this->_tpl->assign(array('label' => $label, 'html'  => $html));
  294.  
  295.         if (!empty($label) && strpos($this->_error, $this->_tpl->left_delimiter . '$label') !== false) {
  296.             $label = $this->_tplFetch($this->_error);
  297.         } elseif (!empty($html) && strpos($this->_error, $this->_tpl->left_delimiter . '$html') !== false) {
  298.             $html = $this->_tplFetch($this->_error);
  299.         }
  300.         $this->_tpl->clear_assign(array('label', 'html', 'error'));
  301.     } // end func _renderError
  302.  
  303.    /**
  304.     * Process an template sourced in a string with Smarty
  305.     *
  306.     * Smarty has no core function to render    a template given as a string.
  307.     * So we use the smarty eval plugin function    to do this.
  308.     *
  309.     * @param    string      The template source
  310.     * @access   private
  311.     * @return   void
  312.     */
  313.     function _tplFetch($tplSource)
  314.     {
  315.         if (!function_exists('smarty_function_eval')) {
  316.             require SMARTY_DIR . '/plugins/function.eval.php';
  317.         }
  318.         return smarty_function_eval(array('var' => $tplSource), $this->_tpl);
  319.     }// end func _tplFetch
  320.  
  321.    /**
  322.     * Sets the way required elements are rendered
  323.     *
  324.     * You can use {$label} or {$html} placeholders to let the renderer know where
  325.     * where the element label or the element html are positionned according to the
  326.     * required tag. They will be replaced accordingly with the right value.    You
  327.     * can use the full smarty syntax here, especially a custom modifier for I18N.
  328.     * For example:
  329.     * {if $required}<span style="color: red;">*</span>{/if}{$label|translate}
  330.     * will put a red star in front of the label if the element is required and
  331.     * translate the label.
  332.     *
  333.     *
  334.     * @param    string      The required element template
  335.     * @access   public
  336.     * @return   void
  337.     */
  338.     function setRequiredTemplate($template)
  339.     {
  340.         $this->_required = $template;
  341.     } // end func setRequiredTemplate
  342.  
  343.    /**
  344.     * Sets the way elements with validation errors are rendered
  345.     *
  346.     * You can use {$label} or {$html} placeholders to let the renderer know where
  347.     * where the element label or the element html are positionned according to the
  348.     * error message. They will be replaced accordingly with the right value.
  349.     * The error message will replace the {$error} placeholder.
  350.     * For example:
  351.     * {if $error}<span style="color: red;">{$error}</span>{/if}<br />{$html}
  352.     * will put the error message in red on top of the element html.
  353.     *
  354.     * If you want all error messages to be output in the main error block, use
  355.     * the {$form.errors} part of the rendered array that collects all raw error
  356.     * messages.
  357.     *
  358.     * If you want to place all error messages manually, do not specify {$html}
  359.     * nor {$label}.
  360.     *
  361.     * Groups can have special layouts. With this kind of groups, you have to
  362.     * place the formated error message manually. In this case, use {$form.group.error}
  363.     * where you want the formated error message to appear in the form.
  364.     *
  365.     * @param    string      The element error template
  366.     * @access   public
  367.     * @return   void
  368.     */
  369.     function setErrorTemplate($template)
  370.     {
  371.         $this->_error = $template;
  372.     } // end func setErrorTemplate
  373. }
  374. ?>