24use ReflectionFunction;
25use ReflectionProperty;
66trait DeprecationHelper {
77 protected static $deprecatedPublicProperties = [];
84 private $dynamicPropertiesAccessDeprecated =
false;
106 if ( isset( self::$deprecatedPublicProperties[$property] ) ) {
109 self::$deprecatedPublicProperties[$property] = [
142 if ( isset( self::$deprecatedPublicProperties[$property] ) ) {
145 self::$deprecatedPublicProperties[$property] = [
165 ?
string $class =
null,
166 ?
string $component =
null
168 $this->dynamicPropertiesAccessDeprecated = [ $version, $class ?: __CLASS__, $component ];
175 if ( isset( self::$deprecatedPublicProperties[$name] ) ) {
176 [ $version, $class, $component, $getter ] = self::$deprecatedPublicProperties[$name];
177 $qualifiedName = $class .
'::$' . $name;
178 wfDeprecated( $qualifiedName, $version, $component, 2 );
180 return $this->deprecationHelperCallGetter( $getter );
185 $ownerClass = $this->deprecationHelperGetPropertyOwner( $name );
190 if ( $this->dynamicPropertiesAccessDeprecated ) {
191 [ $version, $class, $component ] = $this->dynamicPropertiesAccessDeprecated;
192 $qualifiedName = $class .
'::$' . $name;
193 wfDeprecated( $qualifiedName, $version, $component, 2 );
200 if ( get_object_vars( $this ) === [] ) {
207 if ( isset( self::$deprecatedPublicProperties[$name] ) ) {
208 [ $version, $class, $component, $getter ] = self::$deprecatedPublicProperties[$name];
209 $qualifiedName = $class .
'::$' . $name;
210 wfDeprecated( $qualifiedName, $version, $component, 2 );
212 return $this->deprecationHelperCallGetter( $getter );
217 $ownerClass = $this->deprecationHelperGetPropertyOwner( $name );
218 $qualifiedName = ( $ownerClass ?: get_class( $this ) ) .
'::$' . $name;
221 throw new Error(
"Cannot access non-public property $qualifiedName" );
222 } elseif ( property_exists( $this, $name ) ) {
230 trigger_error(
"Undefined property: $qualifiedName", E_USER_NOTICE );
235 public function __set( $name, $value ) {
236 if ( get_object_vars( $this ) === [] ) {
240 $this->$name = $value;
244 if ( isset( self::$deprecatedPublicProperties[$name] ) ) {
245 [ $version, $class, $component, , $setter ] = self::$deprecatedPublicProperties[$name];
246 $qualifiedName = $class .
'::$' . $name;
247 wfDeprecated( $qualifiedName, $version, $component, 2 );
249 $this->deprecationHelperCallSetter( $setter, $value );
250 } elseif ( property_exists( $this, $name ) ) {
251 $this->$name = $value;
253 throw new Error(
"Cannot access non-public property $qualifiedName" );
258 $ownerClass = $this->deprecationHelperGetPropertyOwner( $name );
259 $qualifiedName = ( $ownerClass ?: get_class( $this ) ) .
'::$' . $name;
262 throw new Error(
"Cannot access non-public property $qualifiedName" );
264 if ( $this->dynamicPropertiesAccessDeprecated ) {
265 [ $version, $class, $component ] = $this->dynamicPropertiesAccessDeprecated;
266 $qualifiedName = $class .
'::$' . $name;
267 wfDeprecated( $qualifiedName, $version, $component, 2 );
270 $this->$name = $value;
281 private function deprecationHelperGetPropertyOwner( $property ) {
284 $obfuscatedProps = array_keys( (array)$this );
285 $obfuscatedPropTail =
"\0$property";
286 foreach ( $obfuscatedProps as $obfuscatedProp ) {
288 if ( strpos( $obfuscatedProp, $obfuscatedPropTail, 1 ) !==
false ) {
289 $classname = substr( $obfuscatedProp, 1, -strlen( $obfuscatedPropTail ) );
290 if ( $classname ===
'*' ) {
293 return (
new ReflectionProperty( $this, $property ) )->getDeclaringClass()->getName();
305 private function deprecationHelperCallGetter( $getter ) {
306 if ( is_string( $getter ) ) {
307 $getter = [ $this, $getter ];
308 } elseif ( (
new ReflectionFunction( $getter ) )->getClosureThis() !==
null ) {
309 $getter = $getter->bindTo( $this );
318 private function deprecationHelperCallSetter( $setter, $value ) {
319 if ( is_string( $setter ) ) {
320 $setter = [ $this, $setter ];
321 } elseif ( (
new ReflectionFunction( $setter ) )->getClosureThis() !==
null ) {
322 $setter = $setter->bindTo( $this );
328class_alias( DeprecationHelper::class,
'DeprecationHelper' );
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Logs a warning that a deprecated feature was used.