JOOMLA中国
  • Joomla中国首页
  • 社区
  • 教程
  • 应用市场
  • B计划
Joomla! Framework TM
  • Namespace
  • Class
  • Tree
  • Deprecated

Namespaces

  • Composer
    • Autoload
  • Joomla
    • Application
      • Cli
        • Output
          • Processor
      • Web
    • Data
    • DI
      • Exception
    • Event
    • Filter
    • Input
    • Ldap
    • Registry
      • Format
    • Session
      • Storage
    • String
    • Uri
    • Utilities
  • None
  • PasswordCompat
    • binary
  • PHP
  • Psr
    • Log
  • Symfony
    • Component
      • Yaml
        • Exception
    • Polyfill
      • Util

Classes

  • DataObject
  • DataSet

Interfaces

  • DumpableInterface
  1 <?php
  2 /**
  3  * Part of the Joomla Framework Data Package
  4  *
  5  * @copyright  Copyright (C) 2005 - 2016 Open Source Matters, Inc. All rights reserved.
  6  * @license    GNU General Public License version 2 or later; see LICENSE
  7  */
  8 
  9 namespace Joomla\Data;
 10 
 11 use Joomla\Registry\Registry;
 12 
 13 /**
 14  * DataObject is a class that is used to store data but allowing you to access the data
 15  * by mimicking the way PHP handles class properties.
 16  *
 17  * @since  1.0
 18  */
 19 class DataObject implements DumpableInterface, \IteratorAggregate, \JsonSerializable, \Countable
 20 {
 21     /**
 22      * The data object properties.
 23      *
 24      * @var    array
 25      * @since  1.0
 26      */
 27     private $properties = array();
 28 
 29     /**
 30      * The class constructor.
 31      *
 32      * @param   mixed  $properties  Either an associative array or another object
 33      *                              by which to set the initial properties of the new object.
 34      *
 35      * @since   1.0
 36      * @throws  \InvalidArgumentException
 37      */
 38     public function __construct($properties = array())
 39     {
 40         // Check the properties input.
 41         if (!empty($properties))
 42         {
 43             // Bind the properties.
 44             $this->bind($properties);
 45         }
 46     }
 47 
 48     /**
 49      * The magic get method is used to get a data property.
 50      *
 51      * This method is a public proxy for the protected getProperty method.
 52      *
 53      * Note: Magic __get does not allow recursive calls. This can be tricky because the error generated by recursing into
 54      * __get is "Undefined property:  {CLASS}::{PROPERTY}" which is misleading. This is relevant for this class because
 55      * requesting a non-visible property can trigger a call to a sub-function. If that references the property directly in
 56      * the object, it will cause a recursion into __get.
 57      *
 58      * @param   string  $property  The name of the data property.
 59      *
 60      * @return  mixed  The value of the data property, or null if the data property does not exist.
 61      *
 62      * @see     DataObject::getProperty()
 63      * @since   1.0
 64      */
 65     public function __get($property)
 66     {
 67         return $this->getProperty($property);
 68     }
 69 
 70     /**
 71      * The magic isset method is used to check the state of an object property.
 72      *
 73      * @param   string  $property  The name of the data property.
 74      *
 75      * @return  boolean  True if set, otherwise false is returned.
 76      *
 77      * @since   1.0
 78      */
 79     public function __isset($property)
 80     {
 81         return isset($this->properties[$property]);
 82     }
 83 
 84     /**
 85      * The magic set method is used to set a data property.
 86      *
 87      * This is a public proxy for the protected setProperty method.
 88      *
 89      * @param   string  $property  The name of the data property.
 90      * @param   mixed   $value     The value to give the data property.
 91      *
 92      * @return  void
 93      *
 94      * @see     DataObject::setProperty()
 95      * @since   1.0
 96      */
 97     public function __set($property, $value)
 98     {
 99         $this->setProperty($property, $value);
100     }
101 
102     /**
103      * The magic unset method is used to unset a data property.
104      *
105      * @param   string  $property  The name of the data property.
106      *
107      * @return  void
108      *
109      * @since   1.0
110      */
111     public function __unset($property)
112     {
113         unset($this->properties[$property]);
114     }
115 
116     /**
117      * Binds an array or object to this object.
118      *
119      * @param   mixed    $properties   An associative array of properties or an object.
120      * @param   boolean  $updateNulls  True to bind null values, false to ignore null values.
121      *
122      * @return  DataObject  Returns itself to allow chaining.
123      *
124      * @since   1.0
125      * @throws  \InvalidArgumentException
126      */
127     public function bind($properties, $updateNulls = true)
128     {
129         // Check the properties data type.
130         if (!is_array($properties) && !is_object($properties))
131         {
132             throw new \InvalidArgumentException(sprintf('%s(%s)', __METHOD__, gettype($properties)));
133         }
134 
135         // Check if the object is traversable.
136         if ($properties instanceof \Traversable)
137         {
138             // Convert iterator to array.
139             $properties = iterator_to_array($properties);
140         }
141         elseif (is_object($properties))
142         // Check if the object needs to be converted to an array.
143         {
144             // Convert properties to an array.
145             $properties = (array) $properties;
146         }
147 
148         // Bind the properties.
149         foreach ($properties as $property => $value)
150         {
151             // Check if the value is null and should be bound.
152             if ($value === null && !$updateNulls)
153             {
154                 continue;
155             }
156 
157             // Set the property.
158             $this->setProperty($property, $value);
159         }
160 
161         return $this;
162     }
163 
164     /**
165      * Dumps the data properties into a stdClass object, recursively if appropriate.
166      *
167      * @param   integer            $depth   The maximum depth of recursion (default = 3).
168      *                                      For example, a depth of 0 will return a stdClass with all the properties in native
169      *                                      form. A depth of 1 will recurse into the first level of properties only.
170      * @param   \SplObjectStorage  $dumped  An array of already serialized objects that is used to avoid infinite loops.
171      *
172      * @return  \stdClass  The data properties as a simple PHP stdClass object.
173      *
174      * @since   1.0
175      */
176     public function dump($depth = 3, \SplObjectStorage $dumped = null)
177     {
178         // Check if we should initialise the recursion tracker.
179         if ($dumped === null)
180         {
181             $dumped = new \SplObjectStorage;
182         }
183 
184         // Add this object to the dumped stack.
185         $dumped->attach($this);
186 
187         // Setup a container.
188         $dump = new \stdClass;
189 
190         // Dump all object properties.
191         foreach (array_keys($this->properties) as $property)
192         {
193             // Get the property.
194             $dump->$property = $this->dumpProperty($property, $depth, $dumped);
195         }
196 
197         return $dump;
198     }
199 
200     /**
201      * Gets this object represented as an ArrayIterator.
202      *
203      * This allows the data properties to be access via a foreach statement.
204      *
205      * @return  \ArrayIterator  This object represented as an ArrayIterator.
206      *
207      * @see     IteratorAggregate::getIterator()
208      * @since   1.0
209      */
210     public function getIterator()
211     {
212         return new \ArrayIterator($this->dump(0));
213     }
214 
215     /**
216      * Gets the data properties in a form that can be serialised to JSON format.
217      *
218      * @return  string  An object that can be serialised by json_encode().
219      *
220      * @since   1.0
221      */
222     public function jsonSerialize()
223     {
224         return $this->dump();
225     }
226 
227     /**
228      * Dumps a data property.
229      *
230      * If recursion is set, this method will dump any object implementing Data\Dumpable (like Data\Object and Data\Set); it will
231      * convert a Date object to a string; and it will convert a Registry to an object.
232      *
233      * @param   string             $property  The name of the data property.
234      * @param   integer            $depth     The current depth of recursion (a value of 0 will ignore recursion).
235      * @param   \SplObjectStorage  $dumped    An array of already serialized objects that is used to avoid infinite loops.
236      *
237      * @return  mixed  The value of the dumped property.
238      *
239      * @since   1.0
240      */
241     protected function dumpProperty($property, $depth, \SplObjectStorage $dumped)
242     {
243         $value = $this->getProperty($property);
244 
245         if ($depth > 0)
246         {
247             // Check if the object is also an dumpable object.
248             if ($value instanceof DumpableInterface)
249             {
250                 // Do not dump the property if it has already been dumped.
251                 if (!$dumped->contains($value))
252                 {
253                     $value = $value->dump($depth - 1, $dumped);
254                 }
255             }
256 
257             // Check if the object is a date.
258             if ($value instanceof \DateTime)
259             {
260                 $value = $value->format('Y-m-d H:i:s');
261             }
262             elseif ($value instanceof Registry)
263             // Check if the object is a registry.
264             {
265                 $value = $value->toObject();
266             }
267         }
268 
269         return $value;
270     }
271 
272     /**
273      * Gets a data property.
274      *
275      * @param   string  $property  The name of the data property.
276      *
277      * @return  mixed  The value of the data property.
278      *
279      * @see     DataObject::__get()
280      * @since   1.0
281      */
282     protected function getProperty($property)
283     {
284         // Get the raw value.
285         $value = array_key_exists($property, $this->properties) ? $this->properties[$property] : null;
286 
287         return $value;
288     }
289 
290     /**
291      * Sets a data property.
292      *
293      * If the name of the property starts with a null byte, this method will return null.
294      *
295      * @param   string  $property  The name of the data property.
296      * @param   mixed   $value     The value to give the data property.
297      *
298      * @return  mixed  The value of the data property.
299      *
300      * @see     DataObject::__set()
301      * @since   1.0
302      */
303     protected function setProperty($property, $value)
304     {
305         /*
306          * Check if the property starts with a null byte. If so, discard it because a later attempt to try to access it
307          * can cause a fatal error. See http://us3.php.net/manual/en/language.types.array.php#language.types.array.casting
308          */
309         if (strpos($property, "\0") === 0)
310         {
311             return null;
312         }
313 
314         // Set the value.
315         $this->properties[$property] = $value;
316 
317         return $value;
318     }
319 
320     /**
321      * Count the number of data properties.
322      *
323      * @return  integer  The number of data properties.
324      *
325      * @since   1.0
326      */
327     public function count()
328     {
329         return count($this->properties);
330     }
331 }
332 
Joomla! Framework TM API documentation generated by ApiGen 2.8.0
Joomla!® and Joomla! Framework™ are trademarks of Open Source Matters, Inc. in the United States and other countries.