1<?php 2 3 4namespace dokuwiki\Debug; 5 6use Doku_Event; 7use dokuwiki\Extension\EventHandler; 8 9class DebugHelper 10{ 11 const INFO_DEPRECATION_LOG_EVENT = 'INFO_DEPRECATION_LOG'; 12 13 /** 14 * Log accesses to deprecated fucntions to the debug log 15 * 16 * @param string $alternative (optional) The function or method that should be used instead 17 * @param int $callerOffset (optional) How far the deprecated method is removed from this one 18 * @param string $thing (optional) The deprecated thing, defaults to the calling method 19 * @triggers \dokuwiki\Debug::INFO_DEPRECATION_LOG_EVENT 20 */ 21 public static function dbgDeprecatedFunction($alternative = '', $callerOffset = 1, $thing = '') 22 { 23 global $conf; 24 /** @var EventHandler $EVENT_HANDLER */ 25 global $EVENT_HANDLER; 26 if ( 27 !$conf['allowdebug'] && 28 ($EVENT_HANDLER === null || !$EVENT_HANDLER->hasHandlerForEvent('INFO_DEPRECATION_LOG')) 29 ){ 30 // avoid any work if no one cares 31 return; 32 } 33 34 $backtrace = debug_backtrace(); 35 for ($i = 0; $i < $callerOffset; $i += 1) { 36 array_shift($backtrace); 37 } 38 39 list($self, $call) = $backtrace; 40 41 if (!$thing) { 42 $thing = trim( 43 (!empty($self['class']) ? ($self['class'] . '::') : '') . 44 $self['function'] . '()', ':'); 45 } 46 47 self::triggerDeprecationEvent( 48 $backtrace, 49 $alternative, 50 $thing, 51 trim( 52 (!empty($call['class']) ? ($call['class'] . '::') : '') . 53 $call['function'] . '()', ':'), 54 $call['file'], 55 $call['line'] 56 ); 57 } 58 59 /** 60 * This marks logs a deprecation warning for a property that should no longer be used 61 * 62 * This is usually called withing a magic getter or setter. 63 * For logging deprecated functions or methods see dbgDeprecatedFunction() 64 * 65 * @param string $class The class with the deprecated property 66 * @param string $propertyName The name of the deprecated property 67 * 68 * @triggers \dokuwiki\Debug::INFO_DEPRECATION_LOG_EVENT 69 */ 70 public static function dbgDeprecatedProperty($class, $propertyName) 71 { 72 global $conf; 73 global $EVENT_HANDLER; 74 if (!$conf['allowdebug'] && !$EVENT_HANDLER->hasHandlerForEvent(self::INFO_DEPRECATION_LOG_EVENT)) { 75 // avoid any work if no one cares 76 return; 77 } 78 79 $backtrace = debug_backtrace(); 80 array_shift($backtrace); 81 $call = $backtrace[1]; 82 $caller = trim($call['class'] . '::' . $call['function'] . '()', ':'); 83 $qualifiedName = $class . '::$' . $propertyName; 84 self::triggerDeprecationEvent( 85 $backtrace, 86 '', 87 $qualifiedName, 88 $caller, 89 $backtrace[0]['file'], 90 $backtrace[0]['line'] 91 ); 92 } 93 94 /** 95 * Trigger a custom deprecation event 96 * 97 * Usually dbgDeprecatedFunction() or dbgDeprecatedProperty() should be used instead. 98 * This method is intended only for those situation where they are not applicable. 99 * 100 * @param string $alternative 101 * @param string $deprecatedThing 102 * @param string $caller 103 * @param string $file 104 * @param int $line 105 * @param int $callerOffset How many lines should be removed from the beginning of the backtrace 106 */ 107 public static function dbgCustomDeprecationEvent( 108 $alternative, 109 $deprecatedThing, 110 $caller, 111 $file, 112 $line, 113 $callerOffset = 1 114 ) { 115 global $conf; 116 /** @var EventHandler $EVENT_HANDLER */ 117 global $EVENT_HANDLER; 118 if (!$conf['allowdebug'] && !$EVENT_HANDLER->hasHandlerForEvent(self::INFO_DEPRECATION_LOG_EVENT)) { 119 // avoid any work if no one cares 120 return; 121 } 122 123 $backtrace = array_slice(debug_backtrace(), $callerOffset); 124 125 self::triggerDeprecationEvent( 126 $backtrace, 127 $alternative, 128 $deprecatedThing, 129 $caller, 130 $file, 131 $line 132 ); 133 134 } 135 136 /** 137 * @param array $backtrace 138 * @param string $alternative 139 * @param string $deprecatedThing 140 * @param string $caller 141 * @param string $file 142 * @param int $line 143 */ 144 private static function triggerDeprecationEvent( 145 array $backtrace, 146 $alternative, 147 $deprecatedThing, 148 $caller, 149 $file, 150 $line 151 ) { 152 $data = [ 153 'trace' => $backtrace, 154 'alternative' => $alternative, 155 'called' => $deprecatedThing, 156 'caller' => $caller, 157 'file' => $file, 158 'line' => $line, 159 ]; 160 $event = new Doku_Event(self::INFO_DEPRECATION_LOG_EVENT, $data); 161 if ($event->advise_before()) { 162 $msg = $event->data['called'] . ' is deprecated. It was called from '; 163 $msg .= $event->data['caller'] . ' in ' . $event->data['file'] . ':' . $event->data['line']; 164 if ($event->data['alternative']) { 165 $msg .= ' ' . $event->data['alternative'] . ' should be used instead!'; 166 } 167 dbglog($msg); 168 } 169 $event->advise_after(); 170 } 171} 172