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