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 * 19 * @triggers \dokuwiki\Debug::INFO_DEPRECATION_LOG_EVENT 20 */ 21 public static function dbgDeprecatedFunction($alternative = '', $callerOffset = 1) 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 self::triggerDeprecationEvent( 42 $backtrace, 43 $alternative, 44 trim($self['class'] . '::' . $self['function'] . '()', ':'), 45 trim($call['class'] . '::' . $call['function'] . '()', ':'), 46 $call['file'], 47 $call['line'] 48 ); 49 } 50 51 /** 52 * This marks logs a deprecation warning for a property that should no longer be used 53 * 54 * This is usually called withing a magic getter or setter. 55 * For logging deprecated functions or methods see dbgDeprecatedFunction() 56 * 57 * @param string $class The class with the deprecated property 58 * @param string $propertyName The name of the deprecated property 59 * 60 * @triggers \dokuwiki\Debug::INFO_DEPRECATION_LOG_EVENT 61 */ 62 public static function dbgDeprecatedProperty($class, $propertyName) 63 { 64 global $conf; 65 global $EVENT_HANDLER; 66 if (!$conf['allowdebug'] && !$EVENT_HANDLER->hasHandlerForEvent(self::INFO_DEPRECATION_LOG_EVENT)) { 67 // avoid any work if no one cares 68 return; 69 } 70 71 $backtrace = debug_backtrace(); 72 array_shift($backtrace); 73 $call = $backtrace[1]; 74 $caller = trim($call['class'] . '::' . $call['function'] . '()', ':'); 75 $qualifiedName = $class . '::$' . $propertyName; 76 self::triggerDeprecationEvent( 77 $backtrace, 78 '', 79 $qualifiedName, 80 $caller, 81 $backtrace[0]['file'], 82 $backtrace[0]['line'] 83 ); 84 } 85 86 /** 87 * Trigger a custom deprecation event 88 * 89 * Usually dbgDeprecatedFunction() or dbgDeprecatedProperty() should be used instead. 90 * This method is intended only for those situation where they are not applicable. 91 * 92 * @param string $alternative 93 * @param string $deprecatedThing 94 * @param string $caller 95 * @param string $file 96 * @param int $line 97 * @param int $callerOffset How many lines should be removed from the beginning of the backtrace 98 */ 99 public static function dbgCustomDeprecationEvent( 100 $alternative, 101 $deprecatedThing, 102 $caller, 103 $file, 104 $line, 105 $callerOffset = 1 106 ) { 107 global $conf; 108 /** @var EventHandler $EVENT_HANDLER */ 109 global $EVENT_HANDLER; 110 if (!$conf['allowdebug'] && !$EVENT_HANDLER->hasHandlerForEvent(self::INFO_DEPRECATION_LOG_EVENT)) { 111 // avoid any work if no one cares 112 return; 113 } 114 115 $backtrace = array_slice(debug_backtrace(), $callerOffset); 116 117 self::triggerDeprecationEvent( 118 $backtrace, 119 $alternative, 120 $deprecatedThing, 121 $caller, 122 $file, 123 $line 124 ); 125 126 } 127 128 /** 129 * @param array $backtrace 130 * @param string $alternative 131 * @param string $deprecatedThing 132 * @param string $caller 133 * @param string $file 134 * @param int $line 135 */ 136 private static function triggerDeprecationEvent( 137 array $backtrace, 138 $alternative, 139 $deprecatedThing, 140 $caller, 141 $file, 142 $line 143 ) { 144 $data = [ 145 'trace' => $backtrace, 146 'alternative' => $alternative, 147 'called' => $deprecatedThing, 148 'caller' => $caller, 149 'file' => $file, 150 'line' => $line, 151 ]; 152 $event = new Doku_Event(self::INFO_DEPRECATION_LOG_EVENT, $data); 153 if ($event->advise_before()) { 154 $msg = $event->data['called'] . ' is deprecated. It was called from '; 155 $msg .= $event->data['caller'] . ' in ' . $event->data['file'] . ':' . $event->data['line']; 156 if ($event->data['alternative']) { 157 $msg .= ' ' . $event->data['alternative'] . ' should be used instead!'; 158 } 159 dbglog($msg); 160 } 161 $event->advise_after(); 162 } 163} 164