xref: /plugin/combo/ComboStrap/LogUtility.php (revision e7bbc4b8899abf27ca24f9e5cf9b7d23dd40e28e)
137748cd8SNickeau<?php
237748cd8SNickeau/**
337748cd8SNickeau * Copyright (c) 2020. ComboStrap, Inc. and its affiliates. All Rights Reserved.
437748cd8SNickeau *
537748cd8SNickeau * This source code is licensed under the GPL license found in the
637748cd8SNickeau * COPYING  file in the root directory of this source tree.
737748cd8SNickeau *
837748cd8SNickeau * @license  GPL 3 (https://www.gnu.org/licenses/gpl-3.0.en.html)
937748cd8SNickeau * @author   ComboStrap <support@combostrap.com>
1037748cd8SNickeau *
1137748cd8SNickeau */
1237748cd8SNickeau
1337748cd8SNickeaunamespace ComboStrap;
1437748cd8SNickeau
1537748cd8SNickeaurequire_once(__DIR__ . '/PluginUtility.php');
1637748cd8SNickeau
1737748cd8SNickeauclass LogUtility
1837748cd8SNickeau{
1937748cd8SNickeau
2037748cd8SNickeau    /**
2137748cd8SNickeau     * Constant for the function {@link msg()}
2237748cd8SNickeau     * -1 = error, 0 = info, 1 = success, 2 = notify
2337748cd8SNickeau     * (Not even in order of importance)
2437748cd8SNickeau     */
2537748cd8SNickeau    const LVL_MSG_ERROR = 4; //-1;
2637748cd8SNickeau    const LVL_MSG_WARNING = 3; //2;
2737748cd8SNickeau    const LVL_MSG_SUCCESS = 2; //1;
2837748cd8SNickeau    const LVL_MSG_INFO = 1; //0;
2937748cd8SNickeau    const LVL_MSG_DEBUG = 0; //3;
3037748cd8SNickeau
3137748cd8SNickeau
3237748cd8SNickeau    /**
3337748cd8SNickeau     * Id level to name
3437748cd8SNickeau     */
3537748cd8SNickeau    const LVL_NAME = array(
3637748cd8SNickeau        0 => "debug",
3737748cd8SNickeau        1 => "info",
3837748cd8SNickeau        3 => "warning",
3937748cd8SNickeau        2 => "success",
4037748cd8SNickeau        4 => "error"
4137748cd8SNickeau    );
4237748cd8SNickeau
4337748cd8SNickeau    /**
4437748cd8SNickeau     * Id level to name
4537748cd8SNickeau     * {@link msg()} constant
4637748cd8SNickeau     */
4737748cd8SNickeau    const LVL_TO_MSG_LEVEL = array(
4837748cd8SNickeau        0 => 3,
4937748cd8SNickeau        1 => 0,
5037748cd8SNickeau        2 => 1,
5137748cd8SNickeau        3 => 2,
5237748cd8SNickeau        4 => -1
5337748cd8SNickeau    );
5437748cd8SNickeau
5537748cd8SNickeau
5637748cd8SNickeau    const LOGLEVEL_URI_QUERY_PROPERTY = "loglevel";
5737748cd8SNickeau
5837748cd8SNickeau    /**
5937748cd8SNickeau     * Send a message to a manager and log it
6037748cd8SNickeau     * Fail if in test
6137748cd8SNickeau     * @param string $message
6237748cd8SNickeau     * @param int $level - the level see LVL constant
6337748cd8SNickeau     * @param string $canonical - the canonical
6437748cd8SNickeau     */
65c3437056SNickeau    public static function msg(string $message, int $level = self::LVL_MSG_ERROR, string $canonical = "support")
6637748cd8SNickeau    {
6737748cd8SNickeau
68*e7bbc4b8Sgerardnico        $message = trim($message);
69*e7bbc4b8Sgerardnico        if ($message === "") {
70*e7bbc4b8Sgerardnico            $level = LogUtility::LVL_MSG_ERROR;
71*e7bbc4b8Sgerardnico            $message = "The passed message to the log was empty. BackTrace: \n";
72*e7bbc4b8Sgerardnico            ob_start();
73*e7bbc4b8Sgerardnico            debug_print_backtrace();
74*e7bbc4b8Sgerardnico            $trace = ob_get_contents();
75*e7bbc4b8Sgerardnico            ob_end_clean();
76*e7bbc4b8Sgerardnico            $message .= $trace;
77*e7bbc4b8Sgerardnico            self::log2file($message, $level, $canonical);
78*e7bbc4b8Sgerardnico            self::throwErrorIfTest($level, $message);
79*e7bbc4b8Sgerardnico            return;
80*e7bbc4b8Sgerardnico        }
81*e7bbc4b8Sgerardnico
8237748cd8SNickeau        /**
8337748cd8SNickeau         * Log to frontend
8437748cd8SNickeau         */
85c3437056SNickeau        self::log2FrontEnd($message, $level, $canonical);
8637748cd8SNickeau
8737748cd8SNickeau        /**
8837748cd8SNickeau         * Log level passed for a page (only for file used)
8937748cd8SNickeau         * to not allow an attacker to see all errors in frontend
9037748cd8SNickeau         */
9137748cd8SNickeau        global $INPUT;
9237748cd8SNickeau        $loglevelProp = $INPUT->str(self::LOGLEVEL_URI_QUERY_PROPERTY, null);
9337748cd8SNickeau        if (!empty($loglevelProp)) {
9437748cd8SNickeau            $level = $loglevelProp;
9537748cd8SNickeau        }
962f4da794Sgerardnico        /**
972f4da794Sgerardnico         * TODO: Make it a configuration ?
982f4da794Sgerardnico         */
992f4da794Sgerardnico        if ($level >= self::LVL_MSG_WARNING) {
10037748cd8SNickeau            self::log2file($message, $level, $canonical);
1012f4da794Sgerardnico        }
10237748cd8SNickeau
10337748cd8SNickeau        /**
10437748cd8SNickeau         * If test, we throw an error
10537748cd8SNickeau         */
106c3437056SNickeau        self::throwErrorIfTest($level, $message);
10737748cd8SNickeau    }
10837748cd8SNickeau
10937748cd8SNickeau    /**
11037748cd8SNickeau     * Print log to a  file
11137748cd8SNickeau     *
11237748cd8SNickeau     * Adapted from {@link dbglog}
11337748cd8SNickeau     * Note: {@link dbg()} dbg print to the web page
11437748cd8SNickeau     *
11537748cd8SNickeau     * @param string $msg
11637748cd8SNickeau     * @param int $logLevel
11737748cd8SNickeau     * @param null $canonical
11837748cd8SNickeau     */
11937748cd8SNickeau    static function log2file($msg, $logLevel = self::LVL_MSG_INFO, $canonical = null)
12037748cd8SNickeau    {
12137748cd8SNickeau
122c3437056SNickeau        if (PluginUtility::isTest() || $logLevel >= self::LVL_MSG_WARNING) {
12337748cd8SNickeau
12437748cd8SNickeau            $prefix = PluginUtility::$PLUGIN_NAME;
12537748cd8SNickeau            if (!empty($canonical)) {
12637748cd8SNickeau                $prefix .= ' - ' . $canonical;
12737748cd8SNickeau            }
12837748cd8SNickeau            $msg = $prefix . ' - ' . $msg;
12937748cd8SNickeau
13037748cd8SNickeau            global $INPUT;
13137748cd8SNickeau            global $conf;
13237748cd8SNickeau
133c3437056SNickeau            /**
134c3437056SNickeau             * Adding page - context information
135c3437056SNickeau             * We are not using {@link Page::createPageFromRequestedPage()}
136c3437056SNickeau             * because it throws an error message when the environment
137c3437056SNickeau             * is not good, creating a recursive call.
138c3437056SNickeau             */
139c3437056SNickeau            $id = PluginUtility::getMainPageDokuwikiId();
14037748cd8SNickeau
14137748cd8SNickeau            $file = $conf['cachedir'] . '/debug.log';
14237748cd8SNickeau            $fh = fopen($file, 'a');
14337748cd8SNickeau            if ($fh) {
14437748cd8SNickeau                $sep = " - ";
14537748cd8SNickeau                fwrite($fh, date('c') . $sep . self::LVL_NAME[$logLevel] . $sep . $msg . $sep . $INPUT->server->str('REMOTE_ADDR') . $sep . $id . "\n");
14637748cd8SNickeau                fclose($fh);
14737748cd8SNickeau            }
148c3437056SNickeau
149c3437056SNickeau
150c3437056SNickeau            self::throwErrorIfTest($logLevel, $msg);
151c3437056SNickeau
152c3437056SNickeau
15337748cd8SNickeau        }
15437748cd8SNickeau
15537748cd8SNickeau    }
15637748cd8SNickeau
15737748cd8SNickeau    /**
15837748cd8SNickeau     * @param $message
15937748cd8SNickeau     * @param $level
16037748cd8SNickeau     * @param $canonical
16137748cd8SNickeau     * @param bool $withIconURL
16237748cd8SNickeau     */
16337748cd8SNickeau    public static function log2FrontEnd($message, $level, $canonical = "support", $withIconURL = true)
16437748cd8SNickeau    {
16537748cd8SNickeau        /**
16637748cd8SNickeau         * If we are not in the console
16737748cd8SNickeau         * and not in test
16837748cd8SNickeau         * we test that the message comes in the front end
16937748cd8SNickeau         * (example {@link \plugin_combo_frontmatter_test}
17037748cd8SNickeau         */
171c3437056SNickeau        $isTerminal = Console::isConsoleRun();
172c3437056SNickeau        if ($isTerminal) {
17337748cd8SNickeau            if (!defined('DOKU_UNITTEST')) {
174c3437056SNickeau                /**
175c3437056SNickeau                 * such as {@link cli_plugin_combo}
176c3437056SNickeau                 */
177c3437056SNickeau                $userAgent = "cli";
178c3437056SNickeau            } else {
179c3437056SNickeau                $userAgent = "phpunit";
18037748cd8SNickeau            }
181c3437056SNickeau        } else {
182c3437056SNickeau            $userAgent = "browser";
18337748cd8SNickeau        }
184c3437056SNickeau
185c3437056SNickeau        switch ($userAgent) {
186c3437056SNickeau            case "cli":
187c3437056SNickeau                echo "$message\n";
188c3437056SNickeau                break;
189c3437056SNickeau            case "phpunit":
190c3437056SNickeau            case "browser":
191c3437056SNickeau            default:
192c3437056SNickeau                $htmlMsg = PluginUtility::getDocumentationHyperLink("", PluginUtility::$PLUGIN_NAME, $withIconURL);
19337748cd8SNickeau                if ($canonical != null) {
194c3437056SNickeau                    $htmlMsg = PluginUtility::getDocumentationHyperLink($canonical, ucfirst(str_replace(":", " ", $canonical)));
19537748cd8SNickeau                }
19637748cd8SNickeau
19737748cd8SNickeau                /**
19837748cd8SNickeau                 * Adding page - context information
19937748cd8SNickeau                 * We are not creating the page
200c3437056SNickeau                 * direction from {@link Page::createPageFromRequestedPage()}
20137748cd8SNickeau                 * because it throws an error message when the environment
20237748cd8SNickeau                 * is not good, creating a recursive call.
20337748cd8SNickeau                 */
204c3437056SNickeau                $id = PluginUtility::getMainPageDokuwikiId();
20537748cd8SNickeau                if ($id != null) {
206c3437056SNickeau
207c3437056SNickeau                    /**
208c3437056SNickeau                     * We don't use any Page object to not
209c3437056SNickeau                     * create a cycle while building it
210c3437056SNickeau                     */
211c3437056SNickeau                    $url = wl($id, [], true);
212c3437056SNickeau                    $htmlMsg .= " - <a href=\"$url\">$id</a>";
213c3437056SNickeau
21437748cd8SNickeau                }
21537748cd8SNickeau
21637748cd8SNickeau                /**
21737748cd8SNickeau                 *
21837748cd8SNickeau                 */
21937748cd8SNickeau                $htmlMsg .= " - " . $message;
22037748cd8SNickeau                if ($level > self::LVL_MSG_DEBUG) {
22137748cd8SNickeau                    $dokuWikiLevel = self::LVL_TO_MSG_LEVEL[$level];
22237748cd8SNickeau                    msg($htmlMsg, $dokuWikiLevel, '', '', MSG_USERS_ONLY);
22337748cd8SNickeau                }
22437748cd8SNickeau        }
22537748cd8SNickeau    }
22637748cd8SNickeau
22737748cd8SNickeau    /**
22837748cd8SNickeau     * Log a message to the browser console
22937748cd8SNickeau     * @param $message
23037748cd8SNickeau     */
23137748cd8SNickeau    public static function log2BrowserConsole($message)
23237748cd8SNickeau    {
23337748cd8SNickeau        // TODO
23437748cd8SNickeau    }
235c3437056SNickeau
236c3437056SNickeau    private static function throwErrorIfTest($level, $message)
237c3437056SNickeau    {
238c3437056SNickeau        if (PluginUtility::isTest()
239c3437056SNickeau            && ($level >= self::LVL_MSG_WARNING)
240c3437056SNickeau        ) {
241c3437056SNickeau            throw new LogException($message);
242c3437056SNickeau        }
243c3437056SNickeau    }
24437748cd8SNickeau}
245