Autodoc
  • Namespace
  • Function
  • 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

  • PropertyEvent

Functions

  • get_public_object_vars
  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;
 13 
 14 /**
 15  * Together with the {@link Prototype} class the {@link Object} class provides means to
 16  * define getters and setters, as well as define getters, setters, and method at runtime.
 17  *
 18  * The class also provides a method to create instances in the same fashion PDO creates instances
 19  * with the `FETCH_CLASS` mode, that is the properties of the instance are set *before* its
 20  * constructor is invoked.
 21  *
 22  * @property-read Prototype $prototype The prototype associated with the class.
 23  */
 24 class Object implements ToArrayRecursive
 25 {
 26     use ToArrayRecursiveTrait;
 27     use PrototypeTrait;
 28 
 29     /**
 30      * Creates a new instance of the class using the supplied properties.
 31      *
 32      * The instance is created in the same fashion [PDO](http://www.php.net/manual/en/book.pdo.php)
 33      * creates instances when fetching objects using the `FETCH_CLASS` mode, that is the properties
 34      * of the instance are set *before* its constructor is invoked.
 35      *
 36      * Note: Because the method uses the [`unserialize`](http://www.php.net/manual/en/function.unserialize.php)
 37      * function to create the instance, the `__wakeup()` magic method will be called if it is
 38      * defined by the class, and it will be called *before* the constructor.
 39      *
 40      * Note: The {@link __wakeup()} method of the {@link Object} class removes `null` properties
 41      * for which a getter is defined.
 42      *
 43      * @param array $properties Properties to be set before the constructor is invoked.
 44      * @param array $construct_args Arguments passed to the constructor.
 45      * @param string|null $class_name The name of the instance class. If empty the name of the
 46      * called class is used.
 47      *
 48      * @return mixed The new instance.
 49      */
 50     static public function from($properties=null, array $construct_args=[], $class_name=null)
 51     {
 52         if (!$class_name)
 53         {
 54             $class_name = get_called_class();
 55         }
 56 
 57         $properties_count = 0;
 58         $serialized = '';
 59 
 60         if ($properties)
 61         {
 62             $class_reflection = new \ReflectionClass($class_name);
 63             $class_properties = $class_reflection->getProperties();
 64             $defaults = $class_reflection->getDefaultProperties();
 65 
 66             $done = [];
 67 
 68             foreach ($class_properties as $property)
 69             {
 70                 if ($property->isStatic())
 71                 {
 72                     continue;
 73                 }
 74 
 75                 $properties_count++;
 76 
 77                 $identifier = $property->name;
 78                 $done[] = $identifier;
 79                 $value = null;
 80 
 81                 if (array_key_exists($identifier, $properties))
 82                 {
 83                     $value = $properties[$identifier];
 84                 }
 85                 else if (isset($defaults[$identifier]))
 86                 {
 87                     $value = $defaults[$identifier];
 88                 }
 89 
 90                 if ($property->isProtected())
 91                 {
 92                     $identifier = "\x00*\x00" . $identifier;
 93                 }
 94                 else if ($property->isPrivate())
 95                 {
 96                     $identifier = "\x00" . $property->class . "\x00" . $identifier;
 97                 }
 98 
 99                 $serialized .= serialize($identifier) . serialize($value);
100             }
101 
102             $extra = array_diff(array_keys($properties), $done);
103 
104             foreach ($extra as $name)
105             {
106                 $properties_count++;
107 
108                 $serialized .= serialize($name) . serialize($properties[$name]);
109             }
110         }
111 
112         $serialized = 'O:' . strlen($class_name) . ':"' . $class_name . '":' . $properties_count . ':{' . $serialized . '}';
113 
114         $instance = unserialize($serialized);
115 
116         #
117         # for some reason is_callable() sometimes returns true event if the `__construct` method is not defined.
118         #
119 
120         if (method_exists($instance, '__construct') && is_callable([ $instance, '__construct' ]))
121         {
122             call_user_func_array([ $instance, '__construct' ], $construct_args);
123         }
124 
125         return $instance;
126     }
127 
128     /**
129      * Returns the private properties defined by the reference, this includes the private
130      * properties defined by the whole class inheritance.
131      *
132      * @param string|object $reference Class name or instance.
133      *
134      * @return array
135      */
136     static public function resolve_private_properties($reference)
137     {
138         if (is_object($reference))
139         {
140             $reference = get_class($reference);
141         }
142 
143         if (isset(self::$resolve_private_properties_cache[$reference]))
144         {
145             return self::$resolve_private_properties_cache[$reference];
146         }
147 
148         $private_properties = [];
149         $class_reflection = new \ReflectionClass($reference);
150 
151         while ($class_reflection)
152         {
153             $private_properties = array_merge($private_properties, $class_reflection->getProperties(\ReflectionProperty::IS_PRIVATE));
154 
155             $class_reflection = $class_reflection->getParentClass();
156         }
157 
158         return self::$resolve_private_properties_cache[$reference] = $private_properties;
159     }
160 
161     static private $resolve_private_properties_cache = [];
162 
163     /**
164      * Returns the façade properties implemented by the specified reference.
165      *
166      * A façade property is a combination of a private property with the corresponding volatile
167      * getter and setter.
168      *
169      * @param string|object $reference Class name of instance.
170      *
171      * @return array[string]\ReflectionProperty
172      */
173     static public function resolve_facade_properties($reference)
174     {
175         if (is_object($reference))
176         {
177             $reference = get_class($reference);
178         }
179 
180         if (isset(self::$resolve_facade_properties_cache[$reference]))
181         {
182             return self::$resolve_facade_properties_cache[$reference];
183         }
184 
185         $facade_properties = [];
186 
187         foreach (self::resolve_private_properties($reference) as $property)
188         {
189             $name = $property->name;
190 
191             if (!method_exists($reference, "get_{$name}") || !method_exists($reference, "set_{$name}"))
192             {
193                 continue;
194             }
195 
196             $facade_properties[$name] = $property;
197         }
198 
199         return self::$resolve_facade_properties_cache[$reference] = $facade_properties;
200     }
201 
202     static private $resolve_facade_properties_cache = [];
203 
204     /**
205      * Converts the object into an array.
206      *
207      * Only public properties and façade properties are included.
208      *
209      * @return array
210      */
211     public function to_array()
212     {
213         $array = Object\get_public_object_vars($this);
214 
215         foreach (array_keys(self::resolve_facade_properties($this)) as $name)
216         {
217             $array[$name] = $this->$name;
218         }
219 
220         return $array;
221     }
222 
223     /**
224      * Converts the object into a JSON string.
225      *
226      * @return string
227      */
228     public function to_json()
229     {
230         return json_encode($this->to_array_recursive());
231     }
232 }
233 
234 namespace ICanBoogie\Object;
235 
236 function get_public_object_vars($object)
237 {
238     return get_object_vars($object);
239 }
Autodoc API documentation generated by ApiGen 2.8.0