Autodoc
  • Namespace
  • Class
  • Tree

Namespaces

  • BlueTihi
    • Context
  • Brickrouge
    • Element
      • Nodes
    • Renderer
    • Widget
  • ICanBoogie
    • ActiveRecord
    • AutoConfig
    • CLDR
    • Composer
    • Core
    • Event
    • Exception
    • HTTP
      • Dispatcher
      • Request
    • I18n
      • Translator
    • Mailer
    • Modules
      • Taxonomy
        • Support
      • Thumbnailer
        • Versions
    • Object
    • Operation
      • Dispatcher
    • Prototype
    • Routes
    • Routing
      • Dispatcher
    • Session
  • Icybee
    • ActiveRecord
      • Model
    • ConfigOperation
    • Document
    • EditBlock
    • Element
      • ActionbarContextual
      • ActionbarSearch
      • ActionbarToolbar
    • FormBlock
    • Installer
    • ManageBlock
    • Modules
      • Articles
      • Cache
        • Collection
        • ManageBlock
      • Comments
        • ManageBlock
      • Contents
        • ManageBlock
      • Dashboard
      • Editor
        • Collection
      • Files
        • File
        • ManageBlock
      • Forms
        • Form
        • ManageBlock
      • I18n
      • Images
        • ManageBlock
      • Members
      • Modules
        • ManageBlock
      • Nodes
        • ManageBlock
        • Module
      • Pages
        • BreadcrumbElement
        • LanguagesElement
        • ManageBlock
        • NavigationBranchElement
        • NavigationElement
        • Page
        • PageController
      • Registry
      • Search
      • Seo
      • Sites
        • ManageBlock
      • Taxonomy
        • Terms
          • ManageBlock
        • Vocabulary
          • ManageBlock
      • Users
        • ManageBlock
        • NonceLogin
        • Roles
      • Views
        • ActiveRecordProvider
        • Collection
        • View
    • Operation
      • ActiveRecord
      • Constructor
      • Module
      • Widget
    • Rendering
  • None
  • Patron
  • PHP

Classes

  • BeforeControlEvent
  • BeforeProcessEvent
  • BeforeValidateEvent
  • ControlEvent
  • ControlEventBase
  • Dispatcher
  • FailureEvent
  • GetFormEvent
  • ProcessEvent
  • RescueEvent
  • Response
  • ValidateEvent
  • ValidateEventBase

Exceptions

  • Failure
  • FormHasExpired

Functions

  • array_to_xml
  1 <?php
  2 
  3 /*
  4  * This file is part of the ICanBoogie package.
  5  *
  6  * (c) Olivier Laviale <olivier.laviale@gmail.com>
  7  *
  8  * For the full copyright and license information, please view the LICENSE
  9  * file that was distributed with this source code.
 10  */
 11 
 12 namespace ICanBoogie\Operation;
 13 
 14 use ICanBoogie\Errors;
 15 
 16 /**
 17  * @property string $message The response message.
 18  * @property-read \ICanBoogie\Errors $errors
 19  */
 20 class Response extends \ICanBoogie\HTTP\Response implements \ArrayAccess
 21 {
 22     /**
 23      * Result of the response.
 24      *
 25      * @var mixed
 26      */
 27     public $rc;
 28 
 29     /**
 30      * Message associated with the response.
 31      *
 32      * @var string|array
 33      */
 34     private $message;
 35 
 36     /**
 37      * Sets the response message.
 38      *
 39      * @param string $message
 40      *
 41      * @throws \InvalidArgumentException if the message is an array or an object that do not implement `__toString()`.
 42      */
 43     protected function set_message($message)
 44     {
 45         if (is_array($message) || (is_object($message) && !method_exists($message, '__toString')))
 46         {
 47             throw new \InvalidArgumentException(\ICanBoogie\format
 48             (
 49                 'Invalid message type "{0}", shoud be a string or an object implementing "__toString()". Given: {1}', array
 50                 (
 51                     gettype($message), $message
 52                 )
 53             ));
 54         }
 55 
 56         $this->message = $message;
 57     }
 58 
 59     /**
 60      * Returns the response message.
 61      *
 62      * @return string
 63      */
 64     protected function get_message()
 65     {
 66         return $this->message;
 67     }
 68 
 69     /**
 70      * Errors occuring during the response.
 71      *
 72      * @var Errors
 73      */
 74     public $errors;
 75 
 76     protected $metas = array();
 77 
 78     /**
 79      * Initializes the {@link $errors} property.
 80      *
 81      * @see \ICanBoogie\HTTP\Response::__construct
 82      */
 83     public function __construct($body=null, $status=200, array $headers=array())
 84     {
 85         parent::__construct($body, $status, $headers);
 86 
 87         $this->errors = new Errors();
 88     }
 89 
 90     public function __invoke()
 91     {
 92         if ($this->body !== null)
 93         {
 94             return parent::__invoke();
 95         }
 96 
 97         $body_data = array();
 98 
 99         # rc
100 
101         $rc = null;
102 
103         if ($this->is_successful)
104         {
105             $rc = $this->rc;
106 
107             if (is_object($rc) && method_exists($rc, '__toString'))
108             {
109                 $rc = (string) $rc;
110             }
111 
112             $body_data['rc'] = $rc;
113         }
114 
115         # message
116 
117         $message = $this->message;
118 
119         if ($message !== null)
120         {
121             $body_data['message'] = (string) $message;
122         }
123 
124         # errors
125 
126         if (isset($this->errors) && count($this->errors))
127         {
128             $errors = array();
129 
130             foreach ($this->errors as $identifier => $error)
131             {
132                 if (!$identifier)
133                 {
134                     $identifier = '_base';
135                 }
136 
137                 if (isset($errors[$identifier]))
138                 {
139                     $errors[$identifier] .= '; ' . $error;
140                 }
141                 else
142                 {
143                     $errors[$identifier] = is_bool($error) ? $error : (string) $error;
144                 }
145             }
146 
147             $body_data['errors'] = $errors;
148         }
149 
150         # metas
151 
152         $body_data += $this->metas;
153 
154         /*
155          * If a location is set on the request it is remove and added to the result message.
156          * This is because if we use XHR to get the result we don't want that result to go
157          * avail because the operation usually change the location.
158          *
159          * TODO-20110924: for XHR instead of JSON/XML.
160          */
161         if ($this->location)
162         {
163             $body_data['location'] = $this->location;
164 
165             $this->location = null;
166         }
167 
168         // FIXME: $rc only if valid !!!
169 
170         if (is_array($rc) && !((string) $this->content_type)) // FIXME-20120107: must force 'application/json' for arrays... that might not be fair.
171         {
172             $this->content_type = 'application/json';
173         }
174 
175         $body = $rc;
176 
177         if ($this->content_type == 'application/json')
178         {
179             $body = json_encode($body_data);
180             $this->content_length = null;
181         }
182         else if ($this->content_type == 'application/xml')
183         {
184             $body = array_to_xml($body_data, 'response');
185             $this->content_length = null;
186         }
187 
188         if ($this->content_length === null && is_string($body))
189         {
190             $this->set_content_length(strlen($body));
191         }
192 
193         $this->body = $body;
194 
195         return parent::__invoke();
196     }
197 
198     /*
199      * TODO-20110923: we used to return *all* the fields of the response, we can't do this anymore
200      * because most of this stuff belongs to the response object. We need a mean to add
201      * additional properties, and maybe we could use the response as an array for this purpose:
202      *
203      * Example:
204      *
205      * $response->rc = true;
206      * $response['widget'] = (string) new Button('madonna');
207      *
208      * This might be better than $response->additional_results->widget = ...;
209      *
210      * Or we could let that behind us and force everything in the `rc`:
211      *
212      * rc: {
213      *
214      *     widget: '<div class="widget-pop-node">...</div>',
215      *     assets: {
216      *
217      *         css: [...],
218      *         js: [...]
219      *     }
220      * }
221      *
222      * We could also drop 'rc' because it was used to check if the operation was
223      * successful (before we handle HTTP status correctly), we might not need it anymore.
224      *
225      * If the operation returns anything but an array, it is converted into an array with the 'rc'
226      * key and the value, 'success' and 'errors' are added if needed. This only apply to XHR
227      * request !!
228      *
229      */
230 
231     /**
232      * Checks if a meta exists.
233      *
234      * @see ArrayAccess::offsetExists()
235      */
236     public function offsetExists($offset)
237     {
238         return isset($this->metas[$offset]);
239     }
240 
241     /**
242      * Returns a meta or null if it is not defined.
243      *
244      * @see ArrayAccess::offsetGet()
245      */
246     public function offsetGet($offset)
247     {
248         return $this->offsetExists($offset) ? $this->metas[$offset] : null;
249     }
250 
251     /**
252      * Sets a meta.
253      *
254      * @see ArrayAccess::offsetSet()
255      */
256     public function offsetSet($offset, $value)
257     {
258         $this->metas[$offset] = $value;
259     }
260 
261     /**
262      * Unsets a meta.
263      *
264      * @see ArrayAccess::offsetUnset()
265      */
266     public function offsetUnset($offset)
267     {
268         unset($this->metas[$offset]);
269     }
270 }
271 
272 function array_to_xml($array, $parent='root', $encoding='utf-8', $nest=1)
273 {
274     $rc = '';
275 
276     if ($nest == 1)
277     {
278         #
279         # first level, time to write the XML header and open the root markup
280         #
281 
282         $rc .= '<?xml version="1.0" encoding="' . $encoding . '"?>' . PHP_EOL;
283         $rc .= '<' . $parent . '>' . PHP_EOL;
284     }
285 
286     $tab = str_repeat("\t", $nest);
287 
288     if (substr($parent, -3, 3) == 'ies')
289     {
290         $collection = substr($parent, 0, -3) . 'y';
291     }
292     else if (substr($parent, -2, 2) == 'es')
293     {
294         $collection = substr($parent, 0, -2);
295     }
296     else if (substr($parent, -1, 1) == 's')
297     {
298         $collection = substr($parent, 0, -1);
299     }
300     else
301     {
302         $collection = 'entry';
303     }
304 
305     foreach ($array as $key => $value)
306     {
307         if (is_numeric($key))
308         {
309             $key = $collection;
310         }
311 
312         if (is_array($value) || is_object($value))
313         {
314             $rc .= $tab . '<' . $key . '>' . PHP_EOL;
315             $rc .= wd_array_to_xml((array) $value, $key, $encoding, $nest + 1);
316             $rc .= $tab . '</' . $key . '>' . PHP_EOL;
317 
318             continue;
319         }
320 
321         #
322         # if we find special chars, we put the value into a CDATA section
323         #
324 
325         if (strpos($value, '<') !== false || strpos($value, '>') !== false || strpos($value, '&') !== false)
326         {
327             $value = '<![CDATA[' . $value . ']]>';
328         }
329 
330         $rc .= $tab . '<' . $key . '>' . $value . '</' . $key . '>' . PHP_EOL;
331     }
332 
333     if ($nest == 1)
334     {
335         #
336         # first level, time to close the root markup
337         #
338 
339         $rc .= '</' . $parent . '>';
340     }
341 
342     return $rc;
343 }
Autodoc API documentation generated by ApiGen 2.8.0