Passed
Push — master ( c0a3a7...3b84a4 )
by Jeroen
58:51
created

engine/classes/Elgg/DeprecationWrapper.php (1 issue)

Checks if the types of the passed arguments in a function/method call are compatible.

Bug Minor
1
<?php
2
namespace Elgg;
3
/**
4
 * Wrap an object and display warnings whenever the object's variables are
5
 * accessed or a method is used. It can also be used to wrap a string.
6
 *
7
 * Note that the wrapper will not share the type of the wrapped object and will
8
 * fail type hints, instanceof, etc.
9
 *
10
 * This was introduced for deprecating passing particular variables to views
11
 * automatically in elgg_view().
12
 * It can be removed once that use is no longer required.
13
 *
14
 * Wraps:
15
 *  url string in ViewsService
16
 *  config object in ViewsService
17
 *  user object in ViewsService
18
 *  session object in session lib
19
 *  config object in ElggPlugin::includeFile
20
 *
21
 * @access private
22
 *
23
 * @package Elgg.Core
24
 */
25
class DeprecationWrapper implements \ArrayAccess {
26
	/** @var object */
27
	protected $object;
28
29
	/** @var string */
30
	protected $string;
31
32
	/** @var string */
33
	protected $message;
34
35
	/** @var string */
36
	protected $version;
37
38
	/** @var callable */
39
	protected $reporter;
40
41
	/**
42
	 * Create the wrapper
43
	 *
44
	 * @param mixed    $object   The object or string to wrap
45
	 * @param string   $message  The deprecation message to display when used
46
	 * @param string   $version  The Elgg version this was deprecated
47
	 * @param callable $reporter function called to report deprecation
48
	 */
49 4
	public function __construct($object, $message, $version, $reporter = 'elgg_deprecated_notice') {
50 4
		if (is_object($object)) {
51 3
			$this->object = $object;
52
		} else {
53 1
			$this->string = $object;
54
		}
55 4
		$this->message = $message;
56 4
		$this->version = $version;
57 4
		$this->reporter = $reporter;
58 4
	}
59
60
	/**
61
	 * Get a property on the object
62
	 *
63
	 * @param string $name Property name
64
	 * @return mixed
65
	 */
66 1
	public function __get($name) {
67 1
		$this->displayWarning();
68 1
		return $this->object->$name;
69
	}
70
71
	/**
72
	 * Set a property on the object
73
	 *
74
	 * @param string $name  Property name
75
	 * @param mixed  $value Property value
76
	 * @return void
77
	 */
78
	public function __set($name, $value) {
79
		$this->displayWarning();
80
		$this->object->$name = $value;
81
	}
82
83
	/**
84
	 * Is a property set?
85
	 *
86
	 * @param string $name Property name
87
	 * @return bool
88
	 */
89
	public function __isset($name) {
90
		$this->displayWarning();
91
		return isset($this->object->$name);
92
	}
93
94
	/**
95
	 * Call a method on the object
96
	 *
97
	 * @param string $name      Method name
98
	 * @param array  $arguments Method arguments
99
	 * @return mixed
100
	 */
101 1
	public function __call($name, $arguments) {
102 1
		$this->displayWarning();
103 1
		return call_user_func_array([$this->object, $name], $arguments);
104
	}
105
106
	/**
107
	 * Get the object as string
108
	 *
109
	 * @return string
110
	 */
111 2
	public function __toString() {
112 2
		$this->displayWarning();
113 2
		if (isset($this->string)) {
114 1
			return $this->string;
115
		} else {
116 1
			return (string) $this->object;
117
		}
118
	}
119
120
	/**
121
	 * Display a warning
122
	 *
123
	 * @return void
124
	 */
125 4
	protected function displayWarning() {
126
		// display 3 levels in the function stack to get back to original use
127
		// 1 for __get/__call/__toString()
128
		// 1 for displayWarning()
129
		// 1 for call_user_func()
130 4
		call_user_func($this->reporter, $this->message, $this->version, 3);
131 4
	}
132
133
	/**
134
	 * Array access interface
135
	 *
136
	 * @see \ArrayAccess::offsetSet()
137
	 *
138
	 * @param mixed $key   Name
139
	 * @param mixed $value Value
140
	 *
141
	 * @return void
142
	 */
143 2
	public function offsetSet($key, $value) {
144 2
		$this->displayWarning();
145 2
		if (is_object($this->object) && !$this->object instanceof \ArrayAccess) {
146 1
			$this->object->$key = $value;
147
		} else {
148 1
			if ($key === null) {
149
				// Yes this is necessary. Otherwise $key will be interpreted as empty string
150 1
				$this->object[] = $value;
151
			} else {
152 1
				$this->object[$key] = $value;
153
			}
154
		}
155 2
	}
156
157
	/**
158
	 * Array access interface
159
	 *
160
	 * @see \ArrayAccess::offsetGet()
161
	 *
162
	 * @param mixed $key Name
163
	 *
164
	 * @return mixed
165
	 */
166 2
	public function offsetGet($key) {
167 2
		$this->displayWarning();
168 2
		if (is_object($this->object) && !$this->object instanceof \ArrayAccess) {
169 1
			return $this->object->$key;
170
		} else {
171 1
			return $this->object[$key];
172
		}
173
	}
174
175
	/**
176
	 * Array access interface
177
	 *
178
	 * @see \ArrayAccess::offsetUnset()
179
	 *
180
	 * @param mixed $key Name
181
	 *
182
	 * @return void
183
	 */
184 1
	public function offsetUnset($key) {
185 1
		$this->displayWarning();
186 1
		if (is_object($this->object) && !$this->object instanceof \ArrayAccess) {
187
			unset($this->object->$key);
188
		} else {
189 1
			unset($this->object[$key]);
190
		}
191 1
	}
192
193
	/**
194
	 * Array access interface
195
	 *
196
	 * @see \ArrayAccess::offsetExists()
197
	 *
198
	 * @param mixed $offset Offset
199
	 *
200
	 * @return bool
201
	 */
202
	public function offsetExists($offset) {
203
		$this->displayWarning();
204
		if (is_object($this->object) && !$this->object instanceof \ArrayAccess) {
205
			return isset($this->object->$offset);
206
		} else {
207
			return array_key_exists($offset, $this->object);
0 ignored issues
show
It seems like $this->object can also be of type ArrayAccess; however, parameter $search of array_key_exists() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

207
			return array_key_exists($offset, /** @scrutinizer ignore-type */ $this->object);
Loading history...
208
		}
209
	}
210
}
211
212