DeprecationWrapper.php 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. <?php
  2. namespace Elgg;
  3. /**
  4. * Wrap an object and display warnings whenever the object's variables are
  5. * accessed or a method is used. It can also be used to wrap a string.
  6. *
  7. * Note that the wrapper will not share the type of the wrapped object and will
  8. * fail type hints, instanceof, etc.
  9. *
  10. * This was introduced for deprecating passing particular variabled to views
  11. * automatically in elgg_view(). It also used to wrap the deprecated global $SESSION.
  12. * It can be removed once that use is no longer required.
  13. *
  14. * Wraps:
  15. * url string in ViewsService
  16. * config object in ViewsService
  17. * user object in ViewsService
  18. * session object in session lib
  19. * config object in ElggPlugin::includeFile
  20. *
  21. * @access private
  22. *
  23. * @package Elgg.Core
  24. */
  25. class DeprecationWrapper implements \ArrayAccess {
  26. /** @var object */
  27. protected $object;
  28. /** @var string */
  29. protected $string;
  30. /** @var string */
  31. protected $message;
  32. /** @var string */
  33. protected $version;
  34. /** @var callable */
  35. protected $reporter;
  36. /**
  37. * Create the wrapper
  38. *
  39. * @param mixed $object The object or string to wrap
  40. * @param string $message The deprecation message to display when used
  41. * @param string $version The Elgg version this was deprecated
  42. * @param callable $reporter function called to report deprecation
  43. */
  44. public function __construct($object, $message, $version, $reporter = 'elgg_deprecated_notice') {
  45. if (is_object($object)) {
  46. $this->object = $object;
  47. } else {
  48. $this->string = $object;
  49. }
  50. $this->message = $message;
  51. $this->version = $version;
  52. $this->reporter = $reporter;
  53. }
  54. /**
  55. * Get a property on the object
  56. *
  57. * @param string $name Property name
  58. * @return mixed
  59. */
  60. public function __get($name) {
  61. $this->displayWarning();
  62. return $this->object->$name;
  63. }
  64. /**
  65. * Set a property on the object
  66. *
  67. * @param string $name Property name
  68. * @param mixed $value Property value
  69. * @return void
  70. */
  71. public function __set($name, $value) {
  72. $this->displayWarning();
  73. $this->object->$name = $value;
  74. }
  75. /**
  76. * Call a method on the object
  77. *
  78. * @param string $name Method name
  79. * @param array $arguments Method arguments
  80. * @return mixed
  81. */
  82. public function __call($name, $arguments) {
  83. $this->displayWarning();
  84. return call_user_func_array(array($this->object, $name), $arguments);
  85. }
  86. /**
  87. * Get the object as string
  88. *
  89. * @return string
  90. */
  91. public function __toString() {
  92. $this->displayWarning();
  93. if (isset($this->string)) {
  94. return $this->string;
  95. } else {
  96. return (string) $this->object;
  97. }
  98. }
  99. /**
  100. * Display a warning
  101. *
  102. * @return void
  103. */
  104. protected function displayWarning() {
  105. // display 3 levels in the function stack to get back to original use
  106. // 1 for __get/__call/__toString()
  107. // 1 for displayWarning()
  108. // 1 for call_user_func()
  109. call_user_func($this->reporter, $this->message, $this->version, 3);
  110. }
  111. /**
  112. * Array access interface
  113. *
  114. * @see \ArrayAccess::offsetSet()
  115. *
  116. * @param mixed $key Name
  117. * @param mixed $value Value
  118. *
  119. * @return void
  120. */
  121. public function offsetSet($key, $value) {
  122. $this->displayWarning();
  123. if (is_object($this->object) && !$this->object instanceof \ArrayAccess) {
  124. $this->object->$key = $value;
  125. } else {
  126. if ($key === null) {
  127. // Yes this is necessary. Otherwise $key will be interpreted as empty string
  128. $this->object[] = $value;
  129. } else {
  130. $this->object[$key] = $value;
  131. }
  132. }
  133. }
  134. /**
  135. * Array access interface
  136. *
  137. * @see \ArrayAccess::offsetGet()
  138. *
  139. * @param mixed $key Name
  140. *
  141. * @return mixed
  142. */
  143. public function offsetGet($key) {
  144. $this->displayWarning();
  145. if (is_object($this->object) && !$this->object instanceof \ArrayAccess) {
  146. return $this->object->$key;
  147. } else {
  148. return $this->object[$key];
  149. }
  150. }
  151. /**
  152. * Array access interface
  153. *
  154. * @see \ArrayAccess::offsetUnset()
  155. *
  156. * @param mixed $key Name
  157. *
  158. * @return void
  159. */
  160. public function offsetUnset($key) {
  161. $this->displayWarning();
  162. if (is_object($this->object) && !$this->object instanceof \ArrayAccess) {
  163. unset($this->object->$key);
  164. } else {
  165. unset($this->object[$key]);
  166. }
  167. }
  168. /**
  169. * Array access interface
  170. *
  171. * @see \ArrayAccess::offsetExists()
  172. *
  173. * @param mixed $offset Offset
  174. *
  175. * @return bool
  176. */
  177. public function offsetExists($offset) {
  178. $this->displayWarning();
  179. if (is_object($this->object) && !$this->object instanceof \ArrayAccess) {
  180. return isset($this->object->$offset);
  181. } else {
  182. return array_key_exists($offset, $this->object);
  183. }
  184. }
  185. }