Verzeichnisstruktur phpBB-3.3.15
- Veröffentlicht
- 28.08.2024
So funktioniert es
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
Configurable.php
001 <?php
002
003 /**
004 * @package s9e\TextFormatter
005 * @copyright Copyright (c) 2010-2022 The s9e authors
006 * @license http://www.opensource.org/licenses/mit-license.php The MIT License
007 */
008 namespace s9e\TextFormatter\Configurator\Traits;
009
010 use InvalidArgumentException;
011 use RuntimeException;
012 use s9e\TextFormatter\Configurator\Collections\Collection;
013 use s9e\TextFormatter\Configurator\Collections\NormalizedCollection;
014 use Traversable;
015
016 /**
017 * Provides magic __get, __set, __isset and __unset implementations
018 */
019 trait Configurable
020 {
021 /**
022 * Magic getter
023 *
024 * Will return $this->foo if it exists, then $this->getFoo() or will throw an exception if
025 * neither exists
026 *
027 * @param string $propName
028 * @return mixed
029 */
030 public function __get($propName)
031 {
032 $methodName = 'get' . ucfirst($propName);
033
034 // Look for a getter, e.g. getDefaultTemplate()
035 if (method_exists($this, $methodName))
036 {
037 return $this->$methodName();
038 }
039
040 if (!property_exists($this, $propName))
041 {
042 throw new RuntimeException("Property '" . $propName . "' does not exist");
043 }
044
045 return $this->$propName;
046 }
047
048 /**
049 * Magic setter
050 *
051 * Will call $this->setFoo($propValue) if it exists, otherwise it will set $this->foo.
052 * If $this->foo is a NormalizedCollection, we do not replace it, instead we clear() it then
053 * fill it back up. It will not overwrite an object with a different incompatible object (of a
054 * different, non-extending class) and it will throw an exception if the PHP type cannot match
055 * without incurring data loss.
056 *
057 * @param string $propName
058 * @param mixed $propValue
059 * @return void
060 */
061 public function __set($propName, $propValue)
062 {
063 $methodName = 'set' . ucfirst($propName);
064
065 // Look for a setter, e.g. setDefaultChildRule()
066 if (method_exists($this, $methodName))
067 {
068 $this->$methodName($propValue);
069
070 return;
071 }
072
073 // If the property isn't already set, we just create/set it
074 if (!isset($this->$propName))
075 {
076 $this->$propName = $propValue;
077
078 return;
079 }
080
081 // If we're trying to replace a NormalizedCollection, instead we clear it then
082 // iteratively set new values
083 if ($this->$propName instanceof NormalizedCollection)
084 {
085 if (!is_array($propValue) && !($propValue instanceof Traversable))
086 {
087 throw new InvalidArgumentException("Property '" . $propName . "' expects an array or a traversable object to be passed");
088 }
089
090 $this->$propName->clear();
091 foreach ($propValue as $k => $v)
092 {
093 $this->$propName->set($k, $v);
094 }
095
096 return;
097 }
098
099 // If this property is an object, test whether they are compatible. Otherwise, test if PHP
100 // types are compatible
101 if (is_object($this->$propName))
102 {
103 if (!($propValue instanceof $this->$propName))
104 {
105 throw new InvalidArgumentException("Cannot replace property '" . $propName . "' of class '" . get_class($this->$propName) . "' with instance of '" . get_class($propValue) . "'");
106 }
107 }
108 else
109 {
110 // Test whether the PHP types are compatible
111 $oldType = gettype($this->$propName);
112 $newType = gettype($propValue);
113
114 // If the property is a boolean, we'll accept "true" and "false" as strings
115 if ($oldType === 'boolean' && preg_match('(^(?:fals|tru)e$)', $propValue))
116 {
117 $newType = 'boolean';
118 $propValue = ($propValue === 'true');
119 }
120
121 if ($oldType !== $newType)
122 {
123 // Test whether the PHP type roundtrip is lossless
124 $tmp = $propValue;
125 settype($tmp, $oldType);
126 settype($tmp, $newType);
127
128 if ($tmp !== $propValue)
129 {
130 throw new InvalidArgumentException("Cannot replace property '" . $propName . "' of type " . $oldType . ' with value of type ' . $newType);
131 }
132
133 // Finally, set the new value to the correct type
134 settype($propValue, $oldType);
135 }
136 }
137
138 $this->$propName = $propValue;
139 }
140
141 /**
142 * Test whether a property is set
143 *
144 * @param string $propName
145 * @return bool
146 */
147 public function __isset($propName)
148 {
149 $methodName = 'isset' . ucfirst($propName);
150 if (method_exists($this, $methodName))
151 {
152 return $this->$methodName();
153 }
154
155 return isset($this->$propName);
156 }
157
158 /**
159 * Unset a property, if the class supports it
160 *
161 * @param string $propName
162 * @return void
163 */
164 public function __unset($propName)
165 {
166 $methodName = 'unset' . ucfirst($propName);
167 if (method_exists($this, $methodName))
168 {
169 $this->$methodName();
170 }
171 elseif (isset($this->$propName))
172 {
173 if ($this->$propName instanceof Collection)
174 {
175 $this->$propName->clear();
176 }
177 else
178 {
179 throw new RuntimeException("Property '" . $propName . "' cannot be unset");
180 }
181 }
182 }
183 }