root/trunk/trax/vendor/trax/action_view/helpers.php

Revision 311, 12.2 KB (checked in by john, 3 years ago)

updates and bug fixes

  • Property svn:keywords set to Id
Line 
1<?php
2/**
3 *  File containing the Helpers class and associated functions
4 *
5 *  (PHP 5)
6 *
7 *  @package PHPonTrax
8 *  @version $Id$
9 *  @copyright (c) 2005 John Peterson
10 *
11 *  Permission is hereby granted, free of charge, to any person obtaining
12 *  a copy of this software and associated documentation files (the
13 *  "Software"), to deal in the Software without restriction, including
14 *  without limitation the rights to use, copy, modify, merge, publish,
15 *  distribute, sublicense, and/or sell copies of the Software, and to
16 *  permit persons to whom the Software is furnished to do so, subject to
17 *  the following conditions:
18 *
19 *  The above copyright notice and this permission notice shall be
20 *  included in all copies or substantial portions of the Software.
21 *
22 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 */
30
31/**
32 *  Basic helper functions
33 *
34 *  A collection of methods used to generate basic HTML/XML.
35 */
36class Helpers {
37
38    /**
39     *  @todo Document this variable
40     *  @var boolean
41     */
42    public $auto_index;
43
44    /**
45     *  @todo Document this variable
46     *  Name of a PHP class(?)
47     *  @var string
48     */
49    public $object_name;
50
51    /**
52     *  @todo Document this variable
53     */
54    public $attribute_name;
55
56    /**
57     *  Current controller object
58     *
59     *  Local copy of Trax::$current_controller_object<br />
60     *  <b>NB:</b> {@link object()} faults if this does not contain a
61     *  valid instance of ActionController.
62     *  @var ActionController
63     */
64    public $controller_object;
65
66    /**
67     *  Current controller name
68     *
69     *  Local copy of Trax::$current_controller_name
70     *  @var string
71     */
72    public $controller_name;
73
74    /**
75     *  Current controller path
76     *
77     *  Local copy of Trax::$current_controller_path
78     *  @var string
79     */
80    public $controller_path;
81
82
83    /**
84     *  Construct a Helpers object
85     *
86     *  @param string Name of ActiveRecord subclass
87     *  @param string Attribute of ActiveRecord subclass
88     *  @uses auto_index
89     *  @uses object_name
90     *  @uses attribute_name
91     *  @uses controller_name
92     *  @uses controller_path
93     *  @uses controller_object
94     */
95    function __construct($object_name = null, $attribute_name = null) {
96        if(substr($object_name, -2) == "[]") {
97            $auto_index = true;
98        } else {
99            $auto_index = false;
100        }
101        $this->auto_index = false;
102        $this->object_name = str_replace("[]", "", $object_name);     
103        $this->attribute_name = $attribute_name;       
104
105        //  Copy controller information from $GLOBALS
106        $this->controller_name =
107            !is_null(Trax::$current_controller_name)           
108            ? Trax::$current_controller_name : null;
109        $this->controller_path =
110            !is_null(Trax::$current_controller_path)
111            ? Trax::$current_controller_path : null;
112        $this->controller_object =
113            (!is_null(Trax::$current_controller_object) 
114            && is_object(Trax::$current_controller_object))
115            ? Trax::$current_controller_object : null;
116        if($auto_index) {
117            $object = $this->object();
118            if(is_object($object)) {
119                $index = $object->index_on; # should be primary key (usually id field)
120                $this->auto_index = $object->$index;   
121            } 
122        }         
123    }
124
125    /**
126     *  Get value of current attribute in the current ActiveRecord object
127     *
128     *  If there is a value in $_REQUEST[][], return it.
129     *  Otherwise fetch the value from the database.
130     *  @uses attribute_name
131     *  @uses object()
132     *  @uses object_name
133     *  @uses ActiveRecord::send()
134     */
135    protected function value() {
136        if (array_key_exists($this->object_name, (array)$_REQUEST)
137            && array_key_exists($this->attribute_name,
138                                 (array)$_REQUEST[$this->object_name])) {
139            $value = $_REQUEST[$this->object_name][$this->attribute_name];
140        } else {
141            //  Attribute value not found in $_REQUEST.  Find the
142            //  ActiveRecord subclass instance and query it.
143            $object = $this->object();
144            if(is_object($object) && $this->attribute_name) {
145                //$value = $object->send($this->attribute_name);
146                $value = $object->{$this->attribute_name};
147            }
148        }
149        return stripslashes($value);
150    }
151
152    /**
153     *  Given the name of an ActiveRecord subclass, find an instance
154     *
155     *  Finds the AR instance from the ActionController instance.
156     *  Assumes that if a $object_name is defined either as the
157     *  argument or an instance variable, then there must be
158     *  a controller object instance which points to a single instance
159     *  of the ActiveRecord.
160     *  <b>FIXME:</b> Handle errors better.
161     *  @param string Name of an ActiveRecord subclass or null
162     *  @return mixed Instance of the subclass, or null if
163     *                object not available.
164     *  @uses controller_object
165     *  @uses object_name
166     */
167    protected function object($object_name = null) {
168        $object_name = $object_name ? $object_name : $this->object_name;
169        if($object_name
170           && isset($this->controller_object)
171           && isset($this->controller_object->$object_name)) {
172            return $this->controller_object->$object_name;
173        }
174        return null;
175    }   
176   
177    /**
178     *  Convert array of tag attribute names and values to string
179     *
180     *  @param string[] $options
181     *  @return string
182     */
183    protected function tag_options($options) {
184        if(count($options)) {
185            $html = array();
186            foreach($options as $key => $value) {
187                $html[] = "$key=\"".@htmlspecialchars($value, ENT_COMPAT)."\"";
188            }
189            sort($html);
190            $html = implode(" ", $html);
191            return $html;
192        } else {
193            return '';
194        }
195    }
196
197    /**
198     *  Convert selected attributes to proper XML boolean form
199     *
200     *  @uses boolean_attribute()
201     *  @param string[] $options
202     *  @return string[] Input argument with selected attributes converted
203     *                   to proper XML boolean form
204     */
205    protected function convert_options($options = array()) {
206        foreach(array('disabled', 'readonly', 'multiple') as $a) {
207            $this->boolean_attribute($options, $a);
208        }
209        return $options;
210    }
211
212    /**
213     *  Convert an attribute to proper XML boolean form
214     *
215     *  @param string[] $options
216     *  @param string $attribute
217     *  @return void Contents of $options have been converted
218     */
219    protected function boolean_attribute(&$options, $attribute) {
220        if(array_key_exists($attribute,$options)
221           && $options[$attribute]) {
222            $options[$attribute] = $attribute;
223        } else {
224            unset($options[$attribute]);
225        }
226    }
227   
228    /**
229     *  Wrap CDATA begin and end tags around argument
230     *
231     *  Returns a CDATA section for the given content.  CDATA sections
232     *  are used to escape blocks of text containing characters which would
233     *  otherwise be recognized as markup. CDATA sections begin with the string
234     *  <samp><![CDATA[</samp> and end with (and may not contain) the string
235     *  <samp>]]></samp>.
236     *  @param string $content  Content to wrap
237     *  @return string          Wrapped argument
238     */
239    function cdata_section($content) {
240        return "<![CDATA[".$content."]]>";
241    }   
242
243    /**
244     *  Generate an HTML or XML tag with optional attributes and self-ending
245     *
246     *  <ul>
247     *   <li>Example: <samp>tag("br");</samp><br>
248     *       Returns: <samp><br  />\n</samp></li>
249     *   <li> Example: <samp>tag("div", array("class" => "warning"), true);</samp><br>
250     *       Returns: <samp><div class="warning">\n</samp></li>
251     *  </ul>
252     *  @param string $name      Tag name
253     *  @param string[] $options Tag attributes to apply, specified as
254     *                  array('attr1' => 'value1'[, 'attr2' => 'value2']...)
255     *  @param boolean $open
256     *  <ul>
257     *    <li>true =>  make opening tag (end with '>')</li>
258     *    <li>false => make self-terminating tag (end with ' \>')</li>
259     *  </ul>
260     *  @return string The generated tag, followed by "\n"
261     *  @uses tag_options()
262     */
263    function tag($name, $options = array(), $open = false) {
264        $html = "<$name ";
265        $html .= $this->tag_options($options);
266        $html .= $open ? ">" : " />";
267        return $html."\n";
268    }
269
270    /**
271     *  Generate an open/close pair of tags with optional attributes and content between
272     *
273     *  <ul>
274     *   <li>Example: <samp>content_tag("p", "Hello world!");</samp><br />
275     *       Returns: <samp><p>Hello world!</p>\n</samp><li>
276     *   <li>Example:
277     *     <samp>content_tag("div",
278     *                       content_tag("p", "Hello world!"),
279     *                       array("class" => "strong"));</samp><br />
280     *     Returns:
281     *     <samp><div class="strong"><p>Hello world!</p></div>\n</samp></li>
282     *  </ul>
283     *  @uses tag_options()
284     *  @param string $name    Tag to wrap around $content
285     *  @param string $content Text to put between tags
286     *  @param string[] $options Tag attributes to apply, specified as
287     *                  array('attr1' => 'value1'[, 'attr2' => 'value2']...)
288     *  @return string Text wrapped with tag and attributes,
289     *                 followed by "\n"
290     */
291    function content_tag($name, $content, $options = array()) {
292        $html = "<$name ";
293        $html .= $this->tag_options($options);
294        if(isset($options['strip_slashes'])) {
295            $content = stripslashes($content);   
296        }
297        $html .= ">$content</$name>";
298        return $html."\n";
299    }
300   
301    /**
302     *
303     *  @uses content_tag()
304     *  @uses value()
305     */   
306    function to_content_tag($tag_name, $options = array()) {
307        return $this->content_tag($tag_name, $this->value(), $options);
308    } 
309   
310    /**
311     *  If this tag has an error, wrap it with a visual indicator
312     *
313     *  @param string HTML to be wrapped
314     *  @param boolean  true=>error, false=>no error
315     *  @return string
316     */
317    function error_wrapping($html_tag, $has_error) {
318        return ($has_error ? '<span class="fieldWithErrors">' . eregi_replace("[\n\r]", '', $html_tag) . '</span>' : $html_tag);
319    }         
320
321}
322
323/**
324 *  Create a Helpers object and call its content_tag() method
325 *
326 *  @see Helpers::content_tag()
327 *  @param string $name    Tag to wrap around $content
328 *  @param string $content Text to put between tags
329 *  @param string[] $options Tag attributes to apply
330 *  @return string Text wrapped with tag and attributes,
331 *                 followed by "\n"
332 */
333function content_tag() {
334    $helper = new Helpers();
335    $args = func_get_args();
336    return call_user_func_array(array($helper, 'content_tag'), $args);
337}
338
339/**
340 *  Create a Helpers object and call its tag() method
341 *
342 *  @see Helpers::tag()
343 *  @param string $name    Tag name
344 *  @param string[] $options Tag attributes to apply
345 *  @param boolean $open
346 *  <ul>
347 *    <li>true =>  make opening tag (end with '>')</li>
348 *    <li>false => make self-terminating tag (end with ' \>')</li>
349 *  </ul>
350 *  @return string The tag, followed by "\n"
351 */
352function tag() {
353    $helper = new Helpers();
354    $args = func_get_args();
355    return call_user_func_array(array($helper, 'tag'), $args);
356}
357
358/**
359 *  Create a Helpers object and call its cdata_section() method
360 */
361function cdata_section() {
362    $helper = new Helpers();
363    $args = func_get_args();
364    return call_user_func_array(array($helper, 'cdata_section'), $args);
365}
366
367// -- set Emacs parameters --
368// Local variables:
369// tab-width: 4
370// c-basic-offset: 4
371// c-hanging-comment-ender-p: nil
372// indent-tabs-mode: nil
373// End:
374?>
Note: See TracBrowser for help on using the browser.