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

nette / utils / 22290136219

23 Feb 2026 01:47AM UTC coverage: 93.125% (-0.003%) from 93.128%
22290136219

push

github

dg
added CLAUDE.md

2086 of 2240 relevant lines covered (93.13%)

0.93 hits per line

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

94.55
/src/SmartObject.php
1
<?php declare(strict_types=1);
1✔
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
namespace Nette;
9

10
use Nette\Utils\ObjectHelpers;
11

12

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

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

41
                        return null;
1✔
42
                }
43

44
                ObjectHelpers::strictCall($class, $name);
1✔
45
        }
46

47

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

58

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

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

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

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

92

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

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

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

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

117
                        $this->$m($value);
1✔
118

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

124

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

136

137
        public function __isset(string $name): bool
1✔
138
        {
139
                return isset(ObjectHelpers::getMagicProperties(static::class)[$name]);
1✔
140
        }
141
}
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