PluginProbe ʕ •ᴥ•ʔ
FAPI Member / trunk
FAPI Member vtrunk
2.2.33 2.2.32 trunk 1.9.47 2.1.18 2.2.24 2.2.25 2.2.26 2.2.28 2.2.29 2.2.30 2.2.31
fapi-member / libs / nette / utils / src / SmartObject.php
fapi-member / libs / nette / utils / src Last commit date
Iterators 2 years ago Utils 2 years ago HtmlStringable.php 2 years ago SmartObject.php 2 years ago StaticClass.php 2 years ago Translator.php 2 years ago compatibility.php 2 years ago exceptions.php 2 years ago
SmartObject.php
121 lines
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 FapiMember\Library\Nette;
9
10 use FapiMember\Library\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