1717 * - access to undeclared members throws exceptions
1818 * - support for @property annotations
1919 * - support for calling event handlers stored in $onEvent via onEvent()
20- * - compatible with Nette\Object
2120 */
2221trait SmartObject
2322{
@@ -29,12 +28,8 @@ trait SmartObject
2928 public function __call ($ name , $ args )
3029 {
3130 $ class = get_class ($ this );
32- $ isProp = ObjectMixin::hasProperty ($ class , $ name );
3331
34- if ($ name === '' ) {
35- throw new MemberAccessException ("Call to class ' $ class' method without name. " );
36-
37- } elseif ($ isProp === 'event ' ) { // calling event handlers
32+ if (ObjectMixin::hasProperty ($ class , $ name ) === 'event ' ) { // calling event handlers
3833 if (is_array ($ this ->$ name ) || $ this ->$ name instanceof \Traversable) {
3934 foreach ($ this ->$ name as $ handler ) {
4035 Callback::invokeArgs ($ handler , $ args );
@@ -43,35 +38,6 @@ public function __call($name, $args)
4338 throw new UnexpectedValueException ("Property $ class::$ $ name must be array or NULL, " . gettype ($ this ->$ name ) . ' given. ' );
4439 }
4540
46- } elseif ($ isProp && $ this ->$ name instanceof \Closure) { // closure in property
47- trigger_error ("Invoking closure in property via \$obj-> $ name() is deprecated " . ObjectMixin::getSource (), E_USER_DEPRECATED );
48- return call_user_func_array ($ this ->$ name , $ args );
49-
50- } elseif (($ methods = &ObjectMixin::getMethods ($ class )) && isset ($ methods [$ name ]) && is_array ($ methods [$ name ])) { // magic @methods
51- trigger_error ("Magic methods such as $ class:: $ name() are deprecated " . ObjectMixin::getSource (), E_USER_DEPRECATED );
52- list ($ op , $ rp , $ type ) = $ methods [$ name ];
53- if (count ($ args ) !== ($ op === 'get ' ? 0 : 1 )) {
54- throw new InvalidArgumentException ("$ class:: $ name() expects " . ($ op === 'get ' ? 'no ' : '1 ' ) . ' argument, ' . count ($ args ) . ' given. ' );
55-
56- } elseif ($ type && $ args && !ObjectMixin::checkType ($ args [0 ], $ type )) {
57- throw new InvalidArgumentException ("Argument passed to $ class:: $ name() must be $ type, " . gettype ($ args [0 ]) . ' given. ' );
58- }
59-
60- if ($ op === 'get ' ) {
61- return $ rp ->getValue ($ this );
62- } elseif ($ op === 'set ' ) {
63- $ rp ->setValue ($ this , $ args [0 ]);
64- } elseif ($ op === 'add ' ) {
65- $ val = $ rp ->getValue ($ this );
66- $ val [] = $ args [0 ];
67- $ rp ->setValue ($ this , $ val );
68- }
69- return $ this ;
70-
71- } elseif ($ cb = ObjectMixin::getExtensionMethod ($ class , $ name )) { // extension methods
72- trigger_error ("Extension methods such as $ class:: $ name() are deprecated " . ObjectMixin::getSource (), E_USER_DEPRECATED );
73- return Callback::invoke ($ cb , $ this , ...$ args );
74-
7541 } else {
7642 ObjectMixin::strictCall ($ class , $ name );
7743 }
@@ -95,43 +61,18 @@ public static function __callStatic($name, $args)
9561 public function &__get ($ name )
9662 {
9763 $ class = get_class ($ this );
98- $ uname = ucfirst ($ name );
9964
100- if ($ prop = ObjectMixin::getMagicProperty ($ class, $ name) ) { // property getter
65+ if ($ prop = ObjectMixin::getMagicProperties ($ class)[ $ name] ?? NULL ) { // property getter
10166 if (!($ prop & 0b0001 )) {
10267 throw new MemberAccessException ("Cannot read a write-only property $ class:: \$$ name. " );
10368 }
104- $ m = ($ prop & 0b0010 ? 'get ' : 'is ' ) . $ uname ;
69+ $ m = ($ prop & 0b0010 ? 'get ' : 'is ' ) . $ name ;
10570 if ($ prop & 0b0100 ) { // return by reference
10671 return $ this ->$ m ();
10772 } else {
10873 $ val = $ this ->$ m ();
10974 return $ val ;
11075 }
111-
112- } elseif ($ name === '' ) {
113- throw new MemberAccessException ("Cannot read a class ' $ class' property without name. " );
114-
115- } elseif (($ methods = &ObjectMixin::getMethods ($ class )) && isset ($ methods [$ m = 'get ' . $ uname ]) || isset ($ methods [$ m = 'is ' . $ uname ])) { // old property getter
116- trigger_error ("Add annotation @property for $ class:: \$$ name or use $ m() " . ObjectMixin::getSource (), E_USER_DEPRECATED );
117- if ($ methods [$ m ] === 0 ) {
118- $ methods [$ m ] = (new \ReflectionMethod ($ class , $ m ))->returnsReference ();
119- }
120- if ($ methods [$ m ] === TRUE ) {
121- return $ this ->$ m ();
122- } else {
123- $ val = $ this ->$ m ();
124- return $ val ;
125- }
126-
127- } elseif (isset ($ methods [$ name ])) { // public method as closure getter
128- trigger_error ("Accessing methods as properties via \$obj-> $ name is deprecated " . ObjectMixin::getSource (), E_USER_DEPRECATED );
129- $ val = Callback::closure ($ this , $ name );
130- return $ val ;
131-
132- } elseif (isset ($ methods ['set ' . $ uname ])) { // property getter
133- throw new MemberAccessException ("Cannot read a write-only property $ class:: \$$ name. " );
134-
13576 } else {
13677 ObjectMixin::strictGet ($ class , $ name );
13778 }
@@ -145,27 +86,16 @@ public function &__get($name)
14586 public function __set ($ name , $ value )
14687 {
14788 $ class = get_class ($ this );
148- $ uname = ucfirst ($ name );
14989
15090 if (ObjectMixin::hasProperty ($ class , $ name )) { // unsetted property
15191 $ this ->$ name = $ value ;
15292
153- } elseif ($ prop = ObjectMixin::getMagicProperty ($ class, $ name) ) { // property setter
93+ } elseif ($ prop = ObjectMixin::getMagicProperties ($ class)[ $ name] ?? NULL ) { // property setter
15494 if (!($ prop & 0b1000 )) {
15595 throw new MemberAccessException ("Cannot write to a read-only property $ class:: \$$ name. " );
15696 }
15797 $ this ->{'set ' . $ name }($ value );
15898
159- } elseif ($ name === '' ) {
160- throw new MemberAccessException ("Cannot write to a class ' $ class' property without name. " );
161-
162- } elseif (($ methods = &ObjectMixin::getMethods ($ class )) && isset ($ methods [$ m = 'set ' . $ uname ])) { // old property setter
163- trigger_error ("Add annotation @property for $ class:: \$$ name or use $ m() " . ObjectMixin::getSource (), E_USER_DEPRECATED );
164- $ this ->$ m ($ value );
165-
166- } elseif (isset ($ methods ['get ' . $ uname ]) || isset ($ methods ['is ' . $ uname ])) { // property setter
167- throw new MemberAccessException ("Cannot write to a read-only property $ class:: \$$ name. " );
168-
16999 } else {
170100 ObjectMixin::strictSet ($ class , $ name );
171101 }
@@ -190,42 +120,7 @@ public function __unset($name)
190120 */
191121 public function __isset ($ name )
192122 {
193- $ uname = ucfirst ($ name );
194- return ObjectMixin::getMagicProperty (get_class ($ this ), $ name )
195- || ($ name !== '' && ($ methods = ObjectMixin::getMethods (get_class ($ this ))) && (isset ($ methods ['get ' . $ uname ]) || isset ($ methods ['is ' . $ uname ])));
196- }
197-
198-
199- /**
200- * @return Reflection\ClassType|\ReflectionClass
201- * @deprecated
202- */
203- public static function getReflection ()
204- {
205- trigger_error (get_called_class () . '::getReflection() is deprecated ' . ObjectMixin::getSource (), E_USER_DEPRECATED );
206- $ class = class_exists (Reflection \ClassType::class) ? Reflection \ClassType::class : \ReflectionClass::class;
207- return new $ class (get_called_class ());
208- }
209-
210-
211- /**
212- * @return mixed
213- * @deprecated use Nette\Utils\ObjectMixin::setExtensionMethod()
214- */
215- public static function extensionMethod ($ name , $ callback = NULL )
216- {
217- if (strpos ($ name , ':: ' ) === FALSE ) {
218- $ class = get_called_class ();
219- } else {
220- list ($ class , $ name ) = explode (':: ' , $ name );
221- $ class = (new \ReflectionClass ($ class ))->getName ();
222- }
223- trigger_error ("Extension methods such as $ class:: $ name() are deprecated " . ObjectMixin::getSource (), E_USER_DEPRECATED );
224- if ($ callback === NULL ) {
225- return ObjectMixin::getExtensionMethod ($ class , $ name );
226- } else {
227- ObjectMixin::setExtensionMethod ($ class , $ name , $ callback );
228- }
123+ return isset (ObjectMixin::getMagicProperties (get_class ($ this ))[$ name ]);
229124 }
230125
231126}
0 commit comments