MediaWiki REL1_34
DeprecationHelper.php
Go to the documentation of this file.
1<?php
46
55 protected $deprecatedPublicProperties = [];
56
68 protected function deprecatePublicProperty(
69 $property, $version, $class = null, $component = null
70 ) {
71 $this->deprecatedPublicProperties[$property] = [ $version, $class ?: __CLASS__, $component ];
72 }
73
74 public function __get( $name ) {
75 if ( isset( $this->deprecatedPublicProperties[$name] ) ) {
76 list( $version, $class, $component ) = $this->deprecatedPublicProperties[$name];
77 $qualifiedName = $class . '::$' . $name;
78 wfDeprecated( $qualifiedName, $version, $component, 3 );
79 return $this->$name;
80 }
81
82 $ownerClass = $this->deprecationHelperGetPropertyOwner( $name );
83 $qualifiedName = ( $ownerClass ?: get_class( $this ) ) . '::$' . $name;
84 if ( $ownerClass ) {
85 // Someone tried to access a normal non-public property. Try to behave like PHP would.
86 trigger_error( "Cannot access non-public property $qualifiedName", E_USER_ERROR );
87 } else {
88 // Non-existing property. Try to behave like PHP would.
89 trigger_error( "Undefined property: $qualifiedName", E_USER_NOTICE );
90 }
91 return null;
92 }
93
94 public function __set( $name, $value ) {
95 if ( isset( $this->deprecatedPublicProperties[$name] ) ) {
96 list( $version, $class, $component ) = $this->deprecatedPublicProperties[$name];
97 $qualifiedName = $class . '::$' . $name;
98 wfDeprecated( $qualifiedName, $version, $component, 3 );
99 $this->$name = $value;
100 return;
101 }
102
103 $ownerClass = $this->deprecationHelperGetPropertyOwner( $name );
104 $qualifiedName = ( $ownerClass ?: get_class( $this ) ) . '::$' . $name;
105 if ( $ownerClass ) {
106 // Someone tried to access a normal non-public property. Try to behave like PHP would.
107 trigger_error( "Cannot access non-public property $qualifiedName", E_USER_ERROR );
108 } else {
109 // Non-existing property. Try to behave like PHP would.
110 $this->$name = $value;
111 }
112 }
113
121 private function deprecationHelperGetPropertyOwner( $property ) {
122 // Returning false is a non-error path and should avoid slow checks like reflection.
123 // Use array cast hack instead.
124 $obfuscatedProps = array_keys( (array)$this );
125 $obfuscatedPropTail = "\0$property";
126 foreach ( $obfuscatedProps as $obfuscatedProp ) {
127 // private props are in the form \0<classname>\0<propname>
128 if ( strpos( $obfuscatedProp, $obfuscatedPropTail, 1 ) !== false ) {
129 $classname = substr( $obfuscatedProp, 1, -strlen( $obfuscatedPropTail ) );
130 if ( $classname === '*' ) {
131 // protected property; we didn't get the name, but we are on an error path
132 // now so it's fine to use reflection
133 return ( new ReflectionProperty( $this, $property ) )->getDeclaringClass()->getName();
134 }
135 return $classname;
136 }
137 }
138 return false;
139 }
140
141}
deprecatePublicProperty( $property, $version, $class=null, $component=null)
Mark a property as deprecated.
__set( $name, $value)
__get( $name)
trait DeprecationHelper
Use this trait in classes which have properties for which public access is deprecated.
deprecationHelperGetPropertyOwner( $property)
Like property_exists but also check for non-visible private properties and returns which class in the...
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Throws a warning that $function is deprecated.