Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
88.17% |
82 / 93 |
|
66.67% |
6 / 9 |
CRAP | |
0.00% |
0 / 1 |
DeprecationHelper | |
89.13% |
82 / 92 |
|
66.67% |
6 / 9 |
39.85 | |
0.00% |
0 / 1 |
deprecatePublicProperty | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
3 | |||
deprecatePublicPropertyFallback | |
100.00% |
10 / 10 |
|
100.00% |
1 / 1 |
3 | |||
deprecateDynamicPropertiesAccess | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
2 | |||
__isset | |
53.33% |
8 / 15 |
|
0.00% |
0 / 1 |
7.54 | |||
__get | |
94.12% |
16 / 17 |
|
0.00% |
0 / 1 |
7.01 | |||
__set | |
90.91% |
20 / 22 |
|
0.00% |
0 / 1 |
8.05 | |||
deprecationHelperGetPropertyOwner | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
4 | |||
deprecationHelperCallGetter | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
3 | |||
deprecationHelperCallSetter | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
3 |
1 | <?php |
2 | /** |
3 | * This program is free software; you can redistribute it and/or modify |
4 | * it under the terms of the GNU General Public License as published by |
5 | * the Free Software Foundation; either version 2 of the License, or |
6 | * (at your option) any later version. |
7 | * |
8 | * This program is distributed in the hope that it will be useful, |
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
11 | * GNU General Public License for more details. |
12 | * |
13 | * You should have received a copy of the GNU General Public License along |
14 | * with this program; if not, write to the Free Software Foundation, Inc., |
15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
16 | * http://www.gnu.org/copyleft/gpl.html |
17 | * |
18 | * @file |
19 | */ |
20 | |
21 | namespace MediaWiki\Debug; |
22 | |
23 | use ReflectionFunction; |
24 | use ReflectionProperty; |
25 | |
26 | /** |
27 | * Trait for issuing warnings on deprecated access. |
28 | * |
29 | * Use this trait in classes which have properties for which public access |
30 | * is deprecated or implementation has been moved to another class. |
31 | * Set the list of properties in $deprecatedPublicProperties |
32 | * and make the properties non-public. The trait will preserve public access |
33 | * but issue deprecation warnings when it is needed. |
34 | * |
35 | * Example usage: |
36 | * class Foo { |
37 | * use DeprecationHelper; |
38 | * protected $bar; |
39 | * public function __construct() { |
40 | * $this->deprecatePublicProperty( 'bar', '1.21', __CLASS__ ); |
41 | * $this->deprecatePublicPropertyFallback( |
42 | * 'movedValue', |
43 | * '1.35', |
44 | * function () { |
45 | * return MediaWikiServices()::getInstance() |
46 | * ->getNewImplementationService()->getValue(); |
47 | * }, |
48 | * function ( $value ) { |
49 | * MediaWikiServices()::getInstance() |
50 | * ->getNewImplementationService()->setValue( $value ); |
51 | * } |
52 | * ); |
53 | * } |
54 | * } |
55 | * |
56 | * $foo = new Foo; |
57 | * $foo->bar; // works but logs a warning |
58 | * $foo->movedValue = 10; // works but logs a warning |
59 | * $movedValue = $foo->movedValue; // also works |
60 | * |
61 | * Cannot be used with classes that have their own __get/__set methods. |
62 | * |
63 | * @since 1.32 |
64 | */ |
65 | trait DeprecationHelper { |
66 | |
67 | /** |
68 | * List of deprecated properties, in <property name> => [<version>, <class>, |
69 | * <component>, <getter>, <setter> ] format where <version> is the MediaWiki version |
70 | * where the property got deprecated, <class> is the |
71 | * the name of the class defining the property, <component> is the MediaWiki component |
72 | * (extension, skin etc.) for use in the deprecation warning) or null if it is MediaWiki. |
73 | * E.g. [ 'mNewRev' => [ '1.32', 'DifferenceEngine', null ] |
74 | * @var string[][] |
75 | */ |
76 | protected static $deprecatedPublicProperties = []; |
77 | |
78 | /** |
79 | * Whether to emit a deprecation warning when unknown properties are accessed. |
80 | * |
81 | * @var bool|array |
82 | */ |
83 | private $dynamicPropertiesAccessDeprecated = false; |
84 | |
85 | /** |
86 | * Mark a property as deprecated. Only use this for properties that used to be public and only |
87 | * call it in the constructor. |
88 | * |
89 | * @note Providing callbacks makes it not serializable |
90 | * |
91 | * @param string $property The name of the property. |
92 | * @param string $version MediaWiki version where the property became deprecated. |
93 | * @param string|null $class The class which has the deprecated property. This can usually be |
94 | * guessed, but PHP can get confused when both the parent class and the subclass use the |
95 | * trait, so it should be specified in classes meant for subclassing. |
96 | * @param string|null $component |
97 | * @see wfDeprecated() |
98 | */ |
99 | protected function deprecatePublicProperty( |
100 | $property, |
101 | $version, |
102 | $class = null, |
103 | $component = null |
104 | ) { |
105 | if ( isset( self::$deprecatedPublicProperties[$property] ) ) { |
106 | return; |
107 | } |
108 | self::$deprecatedPublicProperties[$property] = [ |
109 | $version, |
110 | $class ?: __CLASS__, |
111 | $component, |
112 | null, null |
113 | ]; |
114 | } |
115 | |
116 | /** |
117 | * Mark a removed public property as deprecated and provide fallback getter and setter callables. |
118 | * Only use this for properties that used to be public and only |
119 | * call it in the constructor. |
120 | * |
121 | * @param string $property The name of the property. |
122 | * @param string $version MediaWiki version where the property became deprecated. |
123 | * @param callable|string $getter A user provided getter that implements a `get` logic |
124 | * for the property. If a string is given, it is called as a method on $this. |
125 | * @param callable|string|null $setter A user provided setter that implements a `set` logic |
126 | * for the property. If a string is given, it is called as a method on $this. |
127 | * @param string|null $class The class which has the deprecated property. |
128 | * @param string|null $component |
129 | * |
130 | * @since 1.36 |
131 | * @see wfDeprecated() |
132 | */ |
133 | protected function deprecatePublicPropertyFallback( |
134 | string $property, |
135 | string $version, |
136 | $getter, |
137 | $setter = null, |
138 | $class = null, |
139 | $component = null |
140 | ) { |
141 | if ( isset( self::$deprecatedPublicProperties[$property] ) ) { |
142 | return; |
143 | } |
144 | self::$deprecatedPublicProperties[$property] = [ |
145 | $version, |
146 | $class ?: __CLASS__, |
147 | null, |
148 | $getter, |
149 | $setter, |
150 | $component |
151 | ]; |
152 | } |
153 | |
154 | /** |
155 | * Emit deprecation warnings when dynamic and unknown properties |
156 | * are accessed. |
157 | * |
158 | * @param string $version MediaWiki version where the property became deprecated. |
159 | * @param string|null $class The class which has the deprecated property. |
160 | * @param string|null $component |
161 | */ |
162 | protected function deprecateDynamicPropertiesAccess( |
163 | string $version, |
164 | string $class = null, |
165 | string $component = null |
166 | ) { |