root/trunk/patForms/Renderer/patTemplate.php

Revision 326, 11.5 kB (checked in by schst, 3 years ago)

Fixed bug #194: Pass element type to the template

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 <?php
2 /**
3  * patForms Renderer for patTemplate
4  *
5  * $Id$
6  *
7  * @package       patForms
8  * @subpackage    Renderer
9  */
10  
11 /**
12  * Error: patTemplate is not available
13  */   
14 define('PATFORMS_RENDERER_PATTEMPLATE_ERROR_NO_CLASS', 'Renderer:patTemplate:001');
15
16 /**
17  * Error:
18  */   
19 define('PATFORMS_RENDERER_PATTEMPLATE_ERROR_NO_TEMPLATE', 'Renderer:patTemplate:002');
20
21 /**
22  * patForms Renderer for patTemplate
23  *
24  * This needs patTemplate 3.0.0 or higher to work.
25  *
26  * @package       patForms
27  * @subpackage    Renderer
28  * @author        Stephan Schmidt <schst@php-tools.net>
29  * @license       LGPL, see license.txt for details
30  * @link          http://www.php-tools.net
31  */
32 class patForms_Renderer_patTemplate extends patForms_Renderer
33 {
34    /**
35     * Stores the template object
36     *
37     * @access    private
38     * @var       object patTemplate
39     */
40     var $_tmpl = null;
41
42    /**
43     * Stores the name of the placeholders to use to insert
44     * the elements and element attributes.
45     *
46     * @access    private
47     * @var       string
48     */
49     var $_placeholder = 'PATFORMS_ELEMENT_%s';
50     
51    /**
52     * Stores the name of the place holder attribute
53     *
54     * @access    private
55     * @var       string
56     */
57     var $_placeholderAttribute = 'id';
58
59    /**
60     * Stores the name of the placeholder to use for the
61     * opening form tag.
62     *
63     * @access    private
64     * @var       string
65     */
66     var $_placeholderFormStart = 'PATFORMS_FORM_%s_START';
67     
68    /**
69     * Stores the name of the placeholder to use for the
70     * closing form tag.
71     *
72     * @access    private
73     * @var       string
74     */
75     var $_placeholderFormEnd = 'PATFORMS_FORM_%s_END';
76
77    /**
78     * Stores the name of the element attributes that will
79     * be replaced in the template.
80     *
81     * @access    private
82     * @var       array
83     */
84     var $_attributes = array(
85         'label',
86         'title',
87     );
88
89    /**
90     * checks whether errors have been rendered or not
91     * @access    private
92     */
93     var $errorsRendered = array();
94     
95    /**
96     * Sets the patTemplate object, that will be used to render
97     * the page.
98     *
99     * @access    public
100     * @param    object patTemplate
101     */
102     function setTemplate(&$tmpl)
103     {
104         $this->_tmpl = &$tmpl;
105     }
106     
107    /**
108     * Sets a list of attributes to replace in the template
109     * in addition of the default attributes list.
110     *
111     * @access   public
112     * @param    array   The list of attributes
113     * @see      $_attributes
114     */
115     function setAttributes($attributes)
116     {
117         $this->_attributes = array_merge( $this->_attributes, $attributes );
118     }
119     
120    /**
121     * Sets the placeholder to use for the elements and the
122     * element attributes.
123     *
124     * Note: make sure this has a %s where you want the element
125     * ID to be inserted so the replacement will work.
126     *
127     * @access   public
128     * @param    string        The placeholder to use
129     * @param    string        Name of the attribute that will be inserted in the placeholder
130     */
131     function setPlaceholder($placeholder, $attribute = 'id')
132     {
133         $this->_placeholder          = $placeholder;
134         $this->_placeholderAttribute = $attribute;
135     }
136     
137    /**
138     * Sets the placeholders to use for the opening and closing
139     * form tags.
140     *
141     * Note: make sure this has a %s where you want the form
142     * name to be inserted so the replacement will work.
143     *
144     * @access   public
145     * @param    string    The placeholder for the opening form tag
146     * @param    string    The placeholder for the closing form tag
147     */
148     function setFormPlaceholders($placeholderStart, $placeholderEnd)
149     {
150         $this->_placeholderFormStart = $placeholderStart;
151         $this->_placeholderFormEnd   = $placeholderEnd;
152     }
153     
154    /**
155     * Serializes the form elements and renders them using a patTemplate
156     * object.
157     *
158     * The renderer will create a new instance of patTemplate
159     *
160     * Arguments that can be passed:
161     * - tmplName = name of the template to use
162     * - basedir  = directory in which templates are stored
163     * - tmplFile = load a template file before rendering the form
164     *
165     * @access   public
166     * @param    object        Reference to the patForms object
167     * @param    array         optional arguments for the renderer
168     * @return   object patTemplate
169     */
170     function &render(&$patForms, $args = array())
171     {
172         // create a new template instance
173         if ($this->_tmpl === null) {
174             if (!class_exists('patTemplate')) {
175                 return patErrorManager::raiseError(PATFORMS_RENDERER_PATTEMPLATE_ERROR_NO_CLASS, 'No instance of patTemplate has been passed, nor has the class been loaded.');
176             }
177             $this->_tmpl = &new patTemplate();
178         }
179
180         // set the base directory
181         if (isset($args['tmplDir'])) {
182             $this->_tmpl->setRoot($args['tmplDir']);
183         }
184         
185         // load the template
186         if (isset($args['tmplFile'])) {
187             $result = $this->_tmpl->readTemplatesFromInput($args['tmplFile']);
188             if (patErrorManager::isError($result)) {
189                 return $result;
190             }
191         }
192         
193         if (isset($args['tmplName']) && !$this->_tmpl->exists($args['tmplName'])) {
194             return patErrorManager::raiseError(PATFORMS_RENDERER_PATTEMPLATE_ERROR_NO_TEMPLATE, 'The template has not been defined.');
195         }
196
197         $this->_renderFormTags($patForms, $args);
198         
199         if (isset($args['elementTemplate'])) {
200             $result = $this->_renderElementsRepeating($patForms, $args);
201         } else {
202             $result = $this->_renderElementsStatic($patForms, $args);
203         }
204         
205         if (patErrorManager::isError($result)) {
206             return $result;
207         }
208
209         if (!isset($args['errorTemplate'])) {
210             return $this->_tmpl;
211         }
212         
213         $this->_renderErrors($patForms, $args);
214         return $this->_tmpl;
215     }
216
217    /**
218     * render the elements by repeating an element
219     *
220     * @access   private
221     * @param    object patForms   Reference to the patForms object
222     * @param    array             optional arguments for the renderer
223     * @return   boolean
224     */
225     function _renderElementsRepeating(&$patForms, $args = array())
226     {
227         $elements = $patForms->getElements();
228
229         // go through the elements list and replace each element's
230         // placeholders and attribute placeholders.
231         $cnt = count( $elements );
232         for ($i = 0; $i < $cnt; $i++) {
233             $el  = $elements[$i]->serialize();
234             $this->_tmpl->addVar($args['elementTemplate'], $this->_placeholder, $el);
235             $varName = $this->_placeholder.'_ELEMENTTYPE';
236             $this->_tmpl->addVar($args['elementTemplate'], $varName, $elements[$i]->getElementName());
237             foreach ($this->_attributes as $attribute) {
238                $varName = $this->_placeholder.'_'.$attribute;
239                $this->_tmpl->addVar($args['elementTemplate'], $varName, $elements[$i]->getAttribute($attribute));
240             }
241             $this->_tmpl->parseTemplate($args['elementTemplate'], 'a');
242         }
243         return true;
244     }
245
246    /**
247     * render the elements by adding them to different variables in
248     * the same template.
249     *
250     * This gives you more power over the layout.
251     *
252     * @access   private
253     * @param    object patForms   Reference to the patForms object
254     * @param    array             optional arguments for the renderer
255     * @return   boolean
256     */
257     function _renderElementsStatic(&$patForms, $args = array())
258     {
259         $elements = $patForms->getElements();
260
261         // go through the elements list and replace each element's
262         // placeholders and attribute placeholders.
263         $cnt = count( $elements );
264         for ($i = 0; $i < $cnt; $i++) {
265             $el  = $elements[$i]->serialize();
266             $var = sprintf($this->_placeholder, $elements[$i]->getAttribute($this->_placeholderAttribute));
267             if (isset($args['tmplName'])) {
268                 $this->_tmpl->addVar($args['tmplName'], $var, $el);
269                 $varName = $this->_placeholder.'_ELEMENTTYPE';
270                 $this->_tmpl->addVar($args['tmplName'], $varName, $elements[$i]->getElementName());
271                 foreach ($this->_attributes as $attribute) {
272                     $varName = $var.'_'.$attribute;
273                     $this->_tmpl->addVar($args['tmplName'], $varName, $elements[$i]->getAttribute($attribute));
274                 }
275             } else {
276                 $this->_tmpl->addGlobalVar($var, $el);
277                 $varName = $this->_placeholder.'_ELEMENTTYPE';
278                 $this->_tmpl->addGlobalVar($varName, $elements[$i]->getElementName());
279                 foreach ($this->_attributes as $attribute) {
280                     $varName = $var.'_'.$attribute;
281                     $this->_tmpl->addGlobalVar($varName, $elements[$i]->getAttribute($attribute));
282                 }
283             }
284         }
285         
286         return true;
287     }
288     
289    /**
290     * render the opening and closing form tag
291     *
292     * @access   private
293     * @param    object patForms   Reference to the patForms object
294     * @param    array             optional arguments for the renderer
295     * @return   boolean
296     */
297     function _renderFormTags(&$patForms, $args = array())
298     {
299         $name = $patForms->getName();
300
301         // replace the form's opening tag
302         $varName = sprintf($this->_placeholderFormStart, $name);
303         if (isset($args['tmplName'])) {
304             $this->_tmpl->addVar($args['tmplName'], $varName, $patForms->serializeStart());
305         } else {
306             $this->_tmpl->addGlobalVar($varName, $patForms->serializeStart());
307         }
308
309         // replace the form's closing tag
310         $varName = sprintf($this->_placeholderFormEnd, $name);
311         if (isset($args['tmplName'])) {
312             $this->_tmpl->addVar($args['tmplName'], $varName, $patForms->serializeEnd());
313         } else {
314             $this->_tmpl->addGlobalVar($varName, $patForms->serializeEnd());
315         }
316         return true;
317     }
318
319    /**
320     * render the errors
321     *
322     * @access    private
323     * @param    object patForms   Reference to the patForms object
324     * @param    array             optional arguments for the renderer
325     * @return   boolean
326     */
327     function _renderErrors(&$patForms, $args = null)
328     {
329         // already rendered
330         if (isset($this->errorsRendered[$patForms->getName()])) {
331             return true;
332         }
333         
334         // not submitted
335         if (!$patForms->isSubmitted()) {
336             return true;
337         }
338         
339         // no errors
340         if ($patForms->validateForm()) {
341             return true;
342         }
343             
344         if (isset($args['errorTemplateContainer'])) {
345             $this->_tmpl->setAttribute( $args['errorTemplateContainer'], 'visibility', 'visible' );
346         }
347         $validationErrors = $patForms->getValidationErrors();
348
349         foreach($validationErrors as $fieldName => $errors) {
350             if (empty($errors)) {
351                 continue;
352             }
353             $field =& $patForms->getElement($fieldName);
354
355             $atts = $field->getAttributes();
356             foreach ($atts as $key => $value) {
357                 if (!is_scalar($value)) {
358                     unset($atts[$key]);
359                 }
360             }
361
362             if ($fieldName === '__form') {
363                 $this->_tmpl->addVar($args['errorTemplate'], 'ERROR_TYPE', 'form');
364             } else {
365                 $this->_tmpl->addVar($args['errorTemplate'], 'ERROR_TYPE', 'field');
366             }
367
368             $this->_tmpl->addVars($args['errorTemplate'], $atts, 'FIELD_');
369             
370             foreach ($errors as $error) {
371                 $error['field'] = $fieldName;
372                 $this->_tmpl->addVars( $args['errorTemplate'], $error, 'ERROR_' );
373                 $this->_tmpl->parseTemplate($args['errorTemplate'], 'a');
374             }
375         }
376
377         $this->errorsRendered[$patForms->getName()] = true;
378         return    true;
379     }
380 }
381 ?>
Note: See TracBrowser for help on using the browser.