• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

nette / utils / 21636962765

03 Feb 2026 03:39PM UTC coverage: 93.312% (+0.05%) from 93.264%
21636962765

push

github

dg
added CLAUDE.md

2065 of 2213 relevant lines covered (93.31%)

0.93 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

94.44
/src/SmartObject.php
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

8
declare(strict_types=1);
9

10
namespace Nette;
11

12
use Nette\Utils\ObjectHelpers;
13

14

15
/**
16
 * Strict class for better experience.
17
 * - 'did you mean' hints
18
 * - access to undeclared members throws exceptions
19
 * - support for @property annotations
20
 * - support for calling event handlers stored in $onEvent via onEvent()
21
 */
22
trait SmartObject
23
{
24
        /**
25
         * @param  list<mixed>  $args
26
         * @return mixed
27
         * @throws MemberAccessException
28
         */
29
        public function __call(string $name, array $args)
1✔
30
        {
31
                $class = static::class;
1✔
32

33
                if (ObjectHelpers::hasProperty($class, $name) === 'event') { // calling event handlers
1✔
34
                        $handlers = $this->$name ?? null;
1✔
35
                        if (is_iterable($handlers)) {
1✔
36
                                foreach ($handlers as $handler) {
1✔
37
                                        $handler(...$args);
1✔
38
                                }
39
                        } elseif ($handlers !== null) {
1✔
40
                                throw new UnexpectedValueException("Property $class::$$name must be iterable or null, " . get_debug_type($handlers) . ' given.');
1✔
41
                        }
42

43
                        return null;
1✔
44
                }
45

46
                ObjectHelpers::strictCall($class, $name);
1✔
47
        }
48

49

50
        /**
51
         * @param  list<mixed>  $args
52
         * @return never
53
         * @throws MemberAccessException
54
         */
55
        public static function __callStatic(string $name, array $args)
1✔
56
        {
57
                ObjectHelpers::strictStaticCall(static::class, $name);
1✔
58
        }
59

60

61
        /**
62
         * @return mixed
63
         * @throws MemberAccessException if the property is not defined.
64
         */
65
        public function &__get(string $name)
1✔
66
        {
67
                $class = static::class;
1✔
68

69
                if ($prop = ObjectHelpers::getMagicProperties($class)[$name] ?? null) { // property getter
1✔
70
                        if (!($prop & 0b0001)) {
1✔
71
                                throw new MemberAccessException("Cannot read a write-only property $class::\$$name.");
1✔
72
                        }
73

74
                        $m = ($prop & 0b0010 ? 'get' : 'is') . ucfirst($name);
1✔
75
                        if ($prop & 0b10000) {
1✔
76
                                $trace = debug_backtrace(0, 1)[0]; // suppose this method is called from __call()
1✔
77
                                $loc = isset($trace['file'], $trace['line'])
1✔
78
                                        ? " in $trace[file] on line $trace[line]"
1✔
79
                                        : '';
×
80
                                trigger_error("Property $class::\$$name is deprecated, use $class::$m() method$loc.", E_USER_DEPRECATED);
1✔
81
                        }
82

83
                        if ($prop & 0b0100) { // return by reference
1✔
84
                                return $this->$m();
1✔
85
                        } else {
86
                                $val = $this->$m();
1✔
87
                                return $val;
1✔
88
                        }
89
                } else {
90
                        ObjectHelpers::strictGet($class, $name);
1✔
91
                }
92
        }
93

94

95
        /**
96
         * @throws MemberAccessException if the property is not defined or is read-only
97
         */
98
        public function __set(string $name, mixed $value): void
1✔
99
        {
100
                $class = static::class;
1✔
101

102
                if (ObjectHelpers::hasProperty($class, $name)) { // unsetted property
1✔
103
                        $this->$name = $value;
1✔
104

105
                } elseif ($prop = ObjectHelpers::getMagicProperties($class)[$name] ?? null) { // property setter
1✔
106
                        if (!($prop & 0b1000)) {
1✔
107
                                throw new MemberAccessException("Cannot write to a read-only property $class::\$$name.");
1✔
108
                        }
109

110
                        $m = 'set' . ucfirst($name);
1✔
111
                        if ($prop & 0b10000) {
1✔
112
                                $trace = debug_backtrace(0, 1)[0]; // suppose this method is called from __call()
1✔
113
                                $loc = isset($trace['file'], $trace['line'])
1✔
114
                                        ? " in $trace[file] on line $trace[line]"
1✔
115
                                        : '';
×
116
                                trigger_error("Property $class::\$$name is deprecated, use $class::$m() method$loc.", E_USER_DEPRECATED);
1✔
117
                        }
118

119
                        $this->$m($value);
1✔
120

121
                } else {
122
                        ObjectHelpers::strictSet($class, $name);
1✔
123
                }
124
        }
1✔
125

126

127
        /**
128
         * @throws MemberAccessException
129
         */
130
        public function __unset(string $name): void
1✔
131
        {
132
                $class = static::class;
1✔
133
                if (!ObjectHelpers::hasProperty($class, $name)) {
1✔
134
                        throw new MemberAccessException("Cannot unset the property $class::\$$name.");
×
135
                }
136
        }
1✔
137

138

139
        public function __isset(string $name): bool
1✔
140
        {
141
                return isset(ObjectHelpers::getMagicProperties(static::class)[$name]);
1✔
142
        }
143
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc