10use ReflectionFunction;
11use ReflectionProperty;
52trait DeprecationHelper {
65 protected static $deprecatedPublicProperties = [];
72 private $dynamicPropertiesAccessDeprecated =
false;
94 if ( isset( self::$deprecatedPublicProperties[$property] ) ) {
97 self::$deprecatedPublicProperties[$property] = [
131 if ( isset( self::$deprecatedPublicProperties[$property] ) ) {
134 self::$deprecatedPublicProperties[$property] = [
153 ?
string $class =
null,
154 ?
string $component =
null
156 $this->dynamicPropertiesAccessDeprecated = [ $version, $class ?: __CLASS__, $component ];
163 if ( isset( self::$deprecatedPublicProperties[$name] ) ) {
164 [ $version, $class, $component, $getter ] = self::$deprecatedPublicProperties[$name];
165 $qualifiedName = $class .
'::$' . $name;
166 wfDeprecated( $qualifiedName, $version, $component, 2 );
168 return $this->deprecationHelperCallGetter( $getter );
173 $ownerClass = $this->deprecationHelperGetPropertyOwner( $name );
178 if ( $this->dynamicPropertiesAccessDeprecated ) {
179 [ $version, $class, $component ] = $this->dynamicPropertiesAccessDeprecated;
180 $qualifiedName = $class .
'::$' . $name;
181 wfDeprecated( $qualifiedName, $version, $component, 2 );
188 if ( get_object_vars( $this ) === [] ) {
195 if ( isset( self::$deprecatedPublicProperties[$name] ) ) {
196 [ $version, $class, $component, $getter ] = self::$deprecatedPublicProperties[$name];
197 $qualifiedName = $class .
'::$' . $name;
198 wfDeprecated( $qualifiedName, $version, $component, 2 );
200 return $this->deprecationHelperCallGetter( $getter );
205 $ownerClass = $this->deprecationHelperGetPropertyOwner( $name );
206 $qualifiedName = ( $ownerClass ?: get_class( $this ) ) .
'::$' . $name;
209 throw new Error(
"Cannot access non-public property $qualifiedName" );
210 } elseif ( property_exists( $this, $name ) ) {
218 trigger_error(
"Undefined property: $qualifiedName", E_USER_NOTICE );
223 public function __set( $name, $value ) {
224 if ( get_object_vars( $this ) === [] ) {
228 $this->$name = $value;
232 if ( isset( self::$deprecatedPublicProperties[$name] ) ) {
233 [ $version, $class, $component, , $setter ] = self::$deprecatedPublicProperties[$name];
234 $qualifiedName = $class .
'::$' . $name;
235 wfDeprecated( $qualifiedName, $version, $component, 2 );
237 $this->deprecationHelperCallSetter( $setter, $value );
238 } elseif ( property_exists( $this, $name ) ) {
239 $this->$name = $value;
241 throw new Error(
"Cannot access non-public property $qualifiedName" );
246 $ownerClass = $this->deprecationHelperGetPropertyOwner( $name );
247 $qualifiedName = ( $ownerClass ?: get_class( $this ) ) .
'::$' . $name;
250 throw new Error(
"Cannot access non-public property $qualifiedName" );
252 if ( $this->dynamicPropertiesAccessDeprecated ) {
253 [ $version, $class, $component ] = $this->dynamicPropertiesAccessDeprecated;
254 $qualifiedName = $class .
'::$' . $name;
255 wfDeprecated( $qualifiedName, $version, $component, 2 );
258 $this->$name = $value;
269 private function deprecationHelperGetPropertyOwner( $property ) {
272 $obfuscatedProps = array_keys( (array)$this );
273 $obfuscatedPropTail =
"\0$property";
274 foreach ( $obfuscatedProps as $obfuscatedProp ) {
276 if ( strpos( $obfuscatedProp, $obfuscatedPropTail, 1 ) !==
false ) {
277 $classname = substr( $obfuscatedProp, 1, -strlen( $obfuscatedPropTail ) );
278 if ( $classname ===
'*' ) {
281 return (
new ReflectionProperty( $this, $property ) )->getDeclaringClass()->getName();
293 private function deprecationHelperCallGetter( $getter ) {
294 if ( is_string( $getter ) ) {
295 $getter = [ $this, $getter ];
296 } elseif ( (
new ReflectionFunction( $getter ) )->getClosureThis() !==
null ) {
297 $getter = $getter->bindTo( $this );
306 private function deprecationHelperCallSetter( $setter, $value ) {
307 if ( is_string( $setter ) ) {
308 $setter = [ $this, $setter ];
309 } elseif ( (
new ReflectionFunction( $setter ) )->getClosureThis() !==
null ) {
310 $setter = $setter->bindTo( $this );
316class_alias( DeprecationHelper::class,
'DeprecationHelper' );
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Logs a warning that a deprecated feature was used.