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