FRED™  3.0
FRED™: Framework for Rapid and Easy Development
Thing.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Rsi;
4 
5 /**
6  * Basic object.
7  *
8  * By making use of the magic getter and setter it is not necessary to define a specific getter and setter for every property
9  * upfront. All properties can be used as normal properties (that is: without using getXxx() and setXxx() functions). A
10  * property which first was public can be made private/protected, after which it is possible to use a specific getter and/or
11  * setter. Private properties can also be published, which makes it unnecessary to create a specic getter and/or setter.
12  */
13 class Thing{
14 
15  const HIDDEN = 0; //!< Property is hidden.
16  const READABLE = 1; //!< Property is readable.
17  const WRITEABLE = 2; //!< Property is writeable.
18  const READWRITE = 3; //!< Property is readable and writeable.
19 
20  protected $_published = []; //!< Published properties (key = name of property, value = visibility).
21  protected $_aliases = []; //!< Alias properties (key = alias, value = [object,property]).
22 
23  /**
24  * Publish a property (or hide it again).
25  * @param string|array $property Name of the property, or an array with name-visibility pairs.
26  * @param int $visibility Visibility for the property (when a name is given). See the constants for possibilities.
27  */
28  protected function publish($property,$visibility = self::READABLE){
29  if(!is_array($properties = $property)) $properties = [$property => $visibility];
30  elseif(!Record::assoc($properties)) $properties = array_fill_keys($properties,$visibility);
31  $this->_published = array_merge($this->_published,$properties);
32  }
33  /**
34  * Define an alias for a property (of another object).
35  * @param string $alias Name for the property on this object.
36  * @param string $property Real name of the property.
37  * @param Object $object Object for the property (empty = this object).
38  */
39  protected function alias($alias,$property,$object = null){
40  $this->_aliases[$alias] = [$object,$property];
41  }
42  /**
43  * Check if a property exists (public or published).
44  * @param string $property Name of the property.
45  * @return bool True if the property exists.
46  */
47  public function propertyExists($property){
48  return property_exists($this,$property) || array_key_exists($property,$this->_published);
49  }
50  /**
51  * Configure the object.
52  * This will also alter protected and read-only properties. If a specific setter exists it will be used.
53  * @param array $config Array with the configuration (key-value pairs).
54  */
55  protected function configure($config){
56  if($config) foreach($config as $key => $value)
57  if(property_exists($this,$key)) $this->$key = $value;
58  elseif(method_exists($this,$func_name = 'set' . ucfirst($key))) call_user_func([$this,$func_name],$value);
59  elseif(property_exists($this,$property = '_' . $key) && !method_exists($this,'get' . ucfirst($key))) $this->$property = $value;
60  }
61  /**
62  * Return all constants.
63  * @param string $prefix Only constants starting with this prefix.
64  * @return array Key = constant name (without prefix), value = constant value.
65  */
66  public function constants($prefix = null){
67  $reflect = new \ReflectionClass($this);
68  $length = $prefix ? strlen($prefix) : null;
69  $constants = [];
70  foreach($reflect->getConstants() as $name => $value) if(!$prefix || substr($name,0,$length) == $prefix)
71  $constants[$prefix ? substr($name,$length) : $name] = $value;
72  return $constants;
73  }
74  /**
75  * Default getter if no specific setter is defined, and the property is also not published (readable).
76  * @param string $key Name of the property.
77  * @return mixed Value.
78  */
79  protected function _get($key){
80  throw new \OutOfRangeException("Can't get property '$key'");
81  }
82  /**
83  * Default setter if no specific setter is defined, and the property is also not published (writeable).
84  * @param string $key Name of the property.
85  * @param mixed $value Value for the property.
86  */
87  protected function _set($key,$value){
88  throw new \OutOfRangeException("Can't set property '$key'");
89  }
90  /**
91  * Get one or more properties.
92  * Evaluation order:
93  * - public property.
94  * - specific setter.
95  * - published property.
96  * - default _get() function.
97  * @see _get()
98  * @param string|array $key Name of the property, or an array with keys.
99  * @return mixed Value(s).
100  */
101  public function get($key){
102  if(is_array($key)){
103  $result = [];
104  foreach($key as $sub) $result[$sub] = $this->get($sub);
105  return $result;
106  }
107  if(property_exists($this,$key) && (new \ReflectionClass($this))->getProperty($key)->isPublic()) return $this->$key;
108  if(method_exists($this,$func_name = 'get' . ucfirst($key))) return call_user_func([$this,$func_name]);
109  if(array_key_exists($key,$this->_published) && ($this->_published[$key] & self::READABLE)){
110  $property = '_' . $key;
111  if(($this->$property === null) && (method_exists($this,$func_name = 'init' . ucfirst($key)))) $this->$property = call_user_func([$this,$func_name]);
112  return $this->$property;
113  }
114  if(array_key_exists($key,$this->_aliases)){
115  list($object,$property) = $this->_aliases[$key];
116  return ($object ?: $this)->$property;
117  }
118  return $this->_get($key);
119  }
120  /**
121  * Set one or more properties.
122  * Evaluation order:
123  * - public property.
124  * - specific setter.
125  * - published property.
126  * - default _set() function.
127  * @see _set()
128  * @param string|array $key Name of the property, or an assoc.array with key-value pairs.
129  * @param mixed $value Value(s).
130  */
131  public function set($key,$value = null){
132  if(is_array($key)) foreach($key as $sub => $value) $this->set($sub,$value);
133  elseif(property_exists($this,$key) && (new \ReflectionClass($this))->getProperty($key)->isPublic()) $this->$key = $value;
134  elseif(method_exists($this,$func_name = 'set' . ucfirst($key))) call_user_func([$this,$func_name],$value);
135  elseif(array_key_exists($key,$this->_published) && ($this->_published[$key] & self::WRITEABLE)){
136  $property = '_' . $key;
137  $this->$property = $value;
138  }
139  elseif(array_key_exists($key,$this->_aliases)){
140  list($object,$property) = $this->_aliases[$key];
141  if(!$object) $object = $this;
142  $object->$property = $value;
143  }
144  else $this->_set($key,$value);
145  }
146 
147  public function __get($key){
148  return $this->get($key);
149  }
150 
151  public function __set($key,$value){
152  $this->set($key,$value);
153  }
154 
155 }
Rsi\Thing
Basic object.
Definition: Thing.php:13
Rsi
Rsi\Thing\constants
constants($prefix=null)
Return all constants.
Definition: Thing.php:66
Rsi\Thing\configure
configure($config)
Configure the object.
Definition: Thing.php:55
Rsi\Thing\alias
alias($alias, $property, $object=null)
Define an alias for a property (of another object).
Definition: Thing.php:39
Rsi\Thing\_get
_get($key)
Default getter if no specific setter is defined, and the property is also not published (readable).
Definition: Thing.php:79
Rsi\Thing\publish
publish($property, $visibility=self::READABLE)
Publish a property (or hide it again).
Definition: Thing.php:28
Rsi\Thing\__get
__get($key)
Definition: Thing.php:147
Rsi\Thing\_set
_set($key, $value)
Default setter if no specific setter is defined, and the property is also not published (writeable).
Definition: Thing.php:87
Rsi\Thing\propertyExists
propertyExists($property)
Check if a property exists (public or published).
Definition: Thing.php:47
Rsi\Thing\__set
__set($key, $value)
Definition: Thing.php:151