xref: /dokuwiki/inc/Debug/DebugHelper.php (revision 0c5eb5e2d51ac941daf403e83ce1e99567c8f78c)
1<?php
2
3
4namespace dokuwiki\Debug;
5
6use Doku_Event;
7
8class DebugHelper
9{
10    const INFO_DEPRECATION_LOG_EVENT = 'INFO_DEPRECATION_LOG';
11
12    /**
13     * Log accesses to deprecated fucntions to the debug log
14     *
15     * @param string $alternative  (optional) The function or method that should be used instead
16     * @param int    $callerOffset (optional) How far the deprecated method is removed from this one
17     *
18     * @triggers \dokuwiki\Debug::INFO_DEPRECATION_LOG_EVENT
19     */
20    public static function dbgDeprecatedFunction($alternative = '', $callerOffset = 1)
21    {
22        global $conf;
23        global $EVENT_HANDLER;
24        if (!$conf['allowdebug'] && !$EVENT_HANDLER->hasHandlerForEvent(self::INFO_DEPRECATION_LOG_EVENT)) {
25            // avoid any work if no one cares
26            return;
27        }
28
29        $backtrace = debug_backtrace();
30        for ($i = 0; $i < $callerOffset; $i += 1) {
31            array_shift($backtrace);
32        }
33
34        list($self, $call) = $backtrace;
35
36        self::triggerDeprecationEvent(
37            $backtrace,
38            $alternative,
39            trim($self['class'] . '::' . $self['function'] . '()', ':'),
40            trim($call['class'] . '::' . $call['function'] . '()', ':'),
41            $call['file'],
42            $call['line']
43        );
44    }
45
46    /**
47     * This marks logs a deprecation warning for a property that should no longer be used
48     *
49     * This is usually called withing a magic getter or setter.
50     * For logging deprecated functions or methods see dbgDeprecatedFunction()
51     *
52     * @param string $class        The class with the deprecated property
53     * @param string $propertyName The name of the deprecated property
54     *
55     * @triggers \dokuwiki\Debug::INFO_DEPRECATION_LOG_EVENT
56     */
57    public static function dbgDeprecatedProperty($class, $propertyName)
58    {
59        global $conf;
60        global $EVENT_HANDLER;
61        if (!$conf['allowdebug'] && !$EVENT_HANDLER->hasHandlerForEvent(self::INFO_DEPRECATION_LOG_EVENT)) {
62            // avoid any work if no one cares
63            return;
64        }
65
66        $backtrace = debug_backtrace();
67        array_shift($backtrace);
68        $call = $backtrace[1];
69        $caller = trim($call['class'] . '::' . $call['function'] . '()', ':');
70        $qualifiedName = $class . '::$' . $propertyName;
71        self::triggerDeprecationEvent(
72            $backtrace,
73            '',
74            $qualifiedName,
75            $caller,
76            $backtrace[0]['file'],
77            $backtrace[0]['line']
78        );
79    }
80
81    /**
82     * @param array  $backtrace
83     * @param string $alternative
84     * @param string $deprecatedThing
85     * @param string $caller
86     * @param string $file
87     * @param int    $line
88     */
89    private static function triggerDeprecationEvent(
90        array $backtrace,
91        $alternative,
92        $deprecatedThing,
93        $caller,
94        $file,
95        $line
96    ) {
97        $data = [
98            'trace' => $backtrace,
99            'alternative' => $alternative,
100            'called' => $deprecatedThing,
101            'caller' => $caller,
102            'file' => $file,
103            'line' => $line,
104        ];
105        $event = new Doku_Event(self::INFO_DEPRECATION_LOG_EVENT, $data);
106        if ($event->advise_before()) {
107            $msg = $event->data['called'] . ' is deprecated. It was called from ';
108            $msg .= $event->data['caller'] . ' in ' . $event->data['file'] . ':' . $event->data['line'];
109            if ($event->data['alternative']) {
110                $msg .= ' ' . $event->data['alternative'] . ' should be used instead!';
111            }
112            dbglog($msg);
113        }
114        $event->advise_after();
115    }
116}
117