PluginProbe
Packeta / 2.1
Packeta v2.1
2.3.2 2.3.1 trunk 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.3.0 1.3.1 1.3.2 1.4 1.4.1 1.4.2 1.4.3 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 All 56 releases
packeta / deps / nette / utils / src / SmartObject.php

SmartObject.php in Packeta 2.1, at deps/nette/utils/src/SmartObject.php

121 lines 4.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * This file is part of the Nette Framework (https://nette.org)
5 * Copyright (c) 2004 David Grudl (https://davidgrudl.com)
6 */
7 declare (strict_types=1);
8 namespace Packetery\Nette;
9
10 use Packetery\Nette\Utils\ObjectHelpers;
11 /**
12 * Strict class for better experience.
13 * - 'did you mean' hints
14 * - access to undeclared members throws exceptions
15 * - support for @property annotations
16 * - support for calling event handlers stored in $onEvent via onEvent()
17 */
18 trait SmartObject
19 {
20 /**
21 * @throws MemberAccessException
22 */
23 public function __call(string $name, array $args)
24 {
25 $class = static::class;
26 if (ObjectHelpers::hasProperty($class, $name) === 'event') {
27 // calling event handlers
28 $handlers = $this->{$name} ?? null;
29 if (\is_iterable($handlers)) {
30 foreach ($handlers as $handler) {
31 $handler(...$args);
32 }
33 } elseif ($handlers !== null) {
34 throw new UnexpectedValueException("Property {$class}::\${$name} must be iterable or null, " . \gettype($handlers) . ' given.');
35 }
36 } else {
37 ObjectHelpers::strictCall($class, $name);
38 }
39 }
40 /**
41 * @throws MemberAccessException
42 */
43 public static function __callStatic(string $name, array $args)
44 {
45 ObjectHelpers::strictStaticCall(static::class, $name);
46 }
47 /**
48 * @return mixed
49 * @throws MemberAccessException if the property is not defined.
50 */
51 public function &__get(string $name)
52 {
53 $class = static::class;
54 if ($prop = ObjectHelpers::getMagicProperties($class)[$name] ?? null) {
55 // property getter
56 if (!($prop & 0b1)) {
57 throw new MemberAccessException("Cannot read a write-only property {$class}::\${$name}.");
58 }
59 $m = ($prop & 0b10 ? 'get' : 'is') . \ucfirst($name);
60 if ($prop & 0b10000) {
61 $trace = \debug_backtrace(0, 1)[0];
62 // suppose this method is called from __call()
63 $loc = isset($trace['file'], $trace['line']) ? " in {$trace['file']} on line {$trace['line']}" : '';
64 \trigger_error("Property {$class}::\${$name} is deprecated, use {$class}::{$m}() method{$loc}.", \E_USER_DEPRECATED);
65 }
66 if ($prop & 0b100) {
67 // return by reference
68 return $this->{$m}();
69 } else {
70 $val = $this->{$m}();
71 return $val;
72 }
73 } else {
74 ObjectHelpers::strictGet($class, $name);
75 }
76 }
77 /**
78 * @param mixed $value
79 * @return void
80 * @throws MemberAccessException if the property is not defined or is read-only
81 */
82 public function __set(string $name, $value)
83 {
84 $class = static::class;
85 if (ObjectHelpers::hasProperty($class, $name)) {
86 // unsetted property
87 $this->{$name} = $value;
88 } elseif ($prop = ObjectHelpers::getMagicProperties($class)[$name] ?? null) {
89 // property setter
90 if (!($prop & 0b1000)) {
91 throw new MemberAccessException("Cannot write to a read-only property {$class}::\${$name}.");
92 }
93 $m = 'set' . \ucfirst($name);
94 if ($prop & 0b10000) {
95 $trace = \debug_backtrace(0, 1)[0];
96 // suppose this method is called from __call()
97 $loc = isset($trace['file'], $trace['line']) ? " in {$trace['file']} on line {$trace['line']}" : '';
98 \trigger_error("Property {$class}::\${$name} is deprecated, use {$class}::{$m}() method{$loc}.", \E_USER_DEPRECATED);
99 }
100 $this->{$m}($value);
101 } else {
102 ObjectHelpers::strictSet($class, $name);
103 }
104 }
105 /**
106 * @return void
107 * @throws MemberAccessException
108 */
109 public function __unset(string $name)
110 {
111 $class = static::class;
112 if (!ObjectHelpers::hasProperty($class, $name)) {
113 throw new MemberAccessException("Cannot unset the property {$class}::\${$name}.");
114 }
115 }
116 public function __isset(string $name) : bool
117 {
118 return isset(ObjectHelpers::getMagicProperties(static::class)[$name]);
119 }
120 }
121