1<?php
2/**
3 * OO AJAX Implementation for PHP, contains HTML_AJAX_Action
4 *
5 * SVN Rev: $Id: Action.php 626 2008-06-16 17:31:39Z jeichorn $
6 *
7 * @category  HTML
8 * @package   AJAX
9 * @author    Elizabeth Smith <auroraeosrose@gmail.com>
10 * @copyright 2005-2008 Elizabeth Smith
11 * @license   http://www.opensource.org/licenses/lgpl-license.php  LGPL
12 * @version   Release: 0.5.8
13 * @link      http://htmlajax.org/HTML_AJAX/Using%20haSerializer
14 */
15
16/**
17 * Require the response class and json serializer
18 */
19require_once 'HTML/AJAX/Response.php';
20require_once 'HTML/AJAX/Serializer/JSON.php';
21
22/**
23 * Helper class to eliminate the need to write javascript functions to deal with data
24 *
25 * This class creates information that can be properly serialized and used by
26 * the haaction serializer which eliminates the need for php users to write
27 * javascript for dealing with the information returned by an ajax method -
28 * instead the javascript is basically created for them
29 *
30 * @category  HTML
31 * @package   AJAX
32 * @author    Elizabeth Smith <auroraeosrose@gmail.com>
33 * @copyright 2005-2008 Elizabeth Smith
34 * @license   http://www.opensource.org/licenses/lgpl-license.php  LGPL
35 * @version   Release: 0.5.8
36 * @link      http://htmlajax.org/HTML_AJAX/Using%20haSerializer
37 */
38class HTML_AJAX_Action extends HTML_AJAX_Response
39{
40
41    /**
42     * Content type for the HAA response
43     *
44     * goofy but unique content type to tell the javascript which deserializer to use
45     * overrides HTML_AJAX_Response
46     *
47     * @var string
48     * @access public
49     */
50    var $contentType = 'application/html_ajax_action';
51
52    /**
53     * An array holding all the actions for the class
54     *
55     * these have numeric keys and each new action is added on the end, remember
56     * these are executed in the order added
57     *
58     * @var array
59     * @access private
60     */
61    var $_actions = array();
62
63    /**
64     * Prepends data to the attribute identified by id
65     *
66     * The data will be added to the beginning of the attribute identified by the id
67     * sent, id must be unique
68     *
69     * $response->prependAttr('myid', 'class', 'red');
70     * $response->prependAttr('myid', array('class' => 'red', 'innerHTML' => 'this is an error'));
71     *
72     * @param string       $id        id for a specific item on the page <div id="myid"></div>
73     * @param string|array $attribute either an array of attribute/data pairs or a string attribute name
74     * @param mixed        $data      should be NULL if attribute is an array, otherwise data you wish to set the attribute to
75     *
76     * @return void
77     * @access public
78     */
79    function prependAttr($id, $attribute, $data = null)
80    {
81        if (!is_null($data)) {
82            $attribute = array($attribute => $data);
83        }
84        $this->_actions[] = array(
85            'action' => 'prepend',
86            'id' => $id,
87            'attributes' => $attribute,
88            'data' => $data,
89        );
90        return;
91    }
92
93    /**
94     * Appends data to the attribute identified by id
95     *
96     * The data will be added to the end of the attribute identified by the id
97     * sent, id must be unique
98     *
99     * $response->appendAttr('myid', 'class', 'red');
100     * $response->appendAttr('myid', array('class' => 'red', 'innerHTML' => 'this is an error'));
101     *
102     * @param string       $id        id for a specific item on the page <div id="myid"></div>
103     * @param string|array $attribute either an array of attribute/data pairs or a string attribute name
104     * @param mixed        $data      should be NULL if attribute is an array, otherwise data you wish to set the attribute to
105     *
106     * @return void
107     * @access public
108     */
109    function appendAttr($id, $attribute, $data = null)
110    {
111        if (!is_null($data)) {
112            $attribute = array($attribute => $data);
113        }
114        $this->_actions[] = array(
115            'action' => 'append',
116            'id' => $id,
117            'attributes' => $attribute,
118        );
119        return;
120    }
121
122    /**
123     * Assigns data to the attribute identified by id overwriting any previous values
124     *
125     * The data will be assigned to the attribute identified by the id
126     * sent, id must be unique
127     *
128     * $response->assignAttr('myid', 'class', 'red');
129     * $response->assignAttr('myid', array('class' => 'red', 'innerHTML' => 'this is an error'));
130     *
131     * @param string       $id        id for a specific item on the page <div id="myid"></div>
132     * @param string|array $attribute either an array of attribute/data pairs or a string attribute name
133     * @param mixed        $data      should be NULL if attribute is an array, otherwise data you wish to set the attribute to
134     *
135     * @return void
136     * @access public
137     */
138    function assignAttr($id, $attribute, $data = null)
139    {
140        if (!is_null($data)) {
141            $attribute = array($attribute => $data);
142        }
143        $this->_actions[] = array(
144            'action' => 'assign',
145            'id' => $id,
146            'attributes' => $attribute,
147        );
148        return;
149    }
150
151    /**
152     * Deletes or assigns a value of an empty string to an attribute
153     *
154     * You may send either a single attribute or an array of attributes to clear
155     *
156     * $response->clearAttr('myid', 'class');
157     * $response->clearAttr('myid', array('class', 'innerHTML'));
158     *
159     * @param string       $id        id for a specific item on the page <div id="myid"></div>
160     * @param string|array $attribute either an array of attribute/data pairs or a string attribute name
161     *
162     * @return void
163     * @access public
164     */
165    function clearAttr($id, $attribute)
166    {
167        if (!is_array($attribute)) {
168            $attribute = array($attribute);
169        }
170        $this->_actions[] = array(
171            'action' => 'clear',
172            'id' => $id,
173            'attributes' => $attribute,
174        );
175        return;
176    }
177
178    /**
179     * create a dom node via javascript
180     *
181     * higher level dom manipulation - creates a new node to insert into the dom
182     * You can control where the new node is inserted with two things, the insertion
183     * type and the id/  The type should be append, prepend, insertBefore, or insertAfter
184     *
185     * The id is a sibling node - like a div in the same div you want to add more to
186     * If you choose to append or prepend a node it will be placed at the beginning
187     * or end of the node with the id you send. If you choose insertBefore or
188     * InsertAfter it will be put right before or right after the node you specified.
189     * You can send an array of attributes to apply to the new node as well,
190     * so you don't have to create it and then assign Attributes.
191     *
192     * <code>
193     * $response->createNode('myid', 'div');
194     * $response->createNode('submit', 'input',
195     *   array('id' => 'key',
196     *         'name' => 'key',
197     *         'type' => 'hidden',
198     *         'value' => $id),
199     *   'insertBefore');
200     * <code>
201     *
202     * @param string $id         id for a specific item on the page <div id="myid"></div>
203     * @param string $tag        html node to create
204     * @param array  $attributes array of attribute -> data to fill the node with
205     * @param string $type       append|prepend|insertBefore|insertAfter default is append
206     *
207     * @return void
208     * @access public
209     */
210    function createNode($id, $tag, $attributes, $type = 'append')
211    {
212        $types = array('append', 'prepend', 'insertBefore', 'insertAfter');
213        if (!in_array($type, $types)) {
214            $type = 'append';
215        }
216        settype($attributes, 'array');
217        $this->_actions[] = array(
218            'action' => 'create',
219            'id' => $id,
220            'tag' => $tag,
221            'attributes' => $attributes,
222            'type' => $type,
223        );
224        return;
225    }
226
227    /**
228     * Replace a dom node via javascript
229     *
230     * higher level dom manipulation - replaces one node with another
231     * This can be used to replace a div with a form for inline editing
232     * use innerHtml attribute to change inside text
233     *
234     * $response->replaceNode('myid', 'div', array('innerHTML' => 'loading complete'));
235     * $response->replaceNode('mydiv', 'form', array('innerHTML' => $form));
236     *
237     * @param string $id         id for a specific item on the page <div id="myid"></div>
238     * @param string $tag        html node to create
239     * @param array  $attributes array of attribute -> data to fill the node with
240     *
241     * @return void
242     * @access public
243     */
244    function replaceNode($id, $tag, $attributes)
245    {
246        settype($attributes, 'array');
247        $this->_actions[] = array(
248            'action' => 'replace',
249            'id' => $id,
250            'tag' => $tag,
251            'attributes' => $attributes,
252        );
253        return;
254    }
255
256    /**
257     * Delete a dom node via javascript
258     *
259     * $response->removeNode('myid');
260     * $response->removeNode(array('mydiv', 'myform'));
261     *
262     * @param string $id id for a specific item on the page <div id="myid"></div>
263     *
264     * @return void
265     * @access public
266     */
267    function removeNode($id)
268    {
269        $this->_actions[] = array(
270            'action' => 'remove',
271            'id' => $id,
272        );
273        return;
274    }
275
276    /**
277     * Send a string to a javascript eval
278     *
279     * This will send the data right to the eval javascript function, it will NOT
280     * allow you to dynamically add a javascript function for use later on because
281     * it is constrined by the eval function
282     *
283     * @param string $data string to pass to the alert javascript function
284     *
285     * @return void
286     * @access public
287     */
288    function insertScript($data)
289    {
290        $this->_actions[] = array(
291            'action' => 'script',
292            'data' => $data,
293        );
294        return;
295    }
296
297    /**
298     * Send a string to a javascript alert
299     *
300     * This will send the data right to the alert javascript function
301     *
302     * @param string $data string to pass to the alert javascript function
303     *
304     * @return void
305     * @access public
306     */
307    function insertAlert($data)
308    {
309        $this->_actions[] = array(
310            'action' => 'alert',
311            'data' => $data,
312        );
313        return;
314    }
315
316    /**
317     * Returns the serialized content of the response class
318     *
319     * we actually use the json serializer underneath, so we send the actions array
320     * to the json serializer and return the data
321     *
322     * @return string serialized response content
323     * @access public
324     */
325    function getPayload()
326    {
327        $serializer = new HTML_AJAX_Serializer_JSON();
328        return $serializer->serialize($this->_actions);
329    }
330
331    /**
332     * Adds all the actions from one response object to another, feature request
333     * #6635 at pear.php.net
334     *
335     * @param object &$instance referenced HTML_AJAX_Action object
336     *
337     * @return array
338     * @access public
339     */
340    function combineActions(&$instance)
341    {
342        $this->_actions = array_merge($this->_actions, $instance->retrieveActions());
343    }
344
345    /**
346     * to follow proper property access we need a way to retrieve the private
347     * actions array
348     *
349     * @return  array
350     * @access public
351     */
352    function retrieveActions()
353    {
354        return $this->_actions;
355    }
356}
357?>
358