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

nette / utils / 18957947300

30 Oct 2025 11:31PM UTC coverage: 21.324% (-71.2%) from 92.516%
18957947300

push

github

dg
x

29 of 136 relevant lines covered (21.32%)

0.21 hits per line

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

0.0
/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
         * @return mixed
26
         * @throws MemberAccessException
27
         */
28
        public function __call(string $name, array $args)
29
        {
30
                $class = static::class;
×
31

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

42
                        return null;
×
43
                }
44

45
                ObjectHelpers::strictCall($class, $name);
×
46
        }
47

48

49
        /**
50
         * @throws MemberAccessException
51
         */
52
        public static function __callStatic(string $name, array $args)
53
        {
54
                ObjectHelpers::strictStaticCall(static::class, $name);
×
55
        }
56

57

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

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

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

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

91

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

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

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

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

116
                        $this->$m($value);
×
117

118
                } else {
119
                        ObjectHelpers::strictSet($class, $name);
×
120
                }
121
        }
122

123

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

135

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

© 2025 Coveralls, Inc