MediaWiki  master
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 }
__get( $name)
deprecationHelperGetPropertyOwner( $property)
Like property_exists but also check for non-visible private properties and returns which class in the...
deprecatePublicProperty( $property, $version, $class=null, $component=null)
Mark a property as deprecated.
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Throws a warning that $function is deprecated.
__set( $name, $value)