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 */ 65*c3437056SNickeau public static function msg(string $message, int $level = self::LVL_MSG_ERROR, string $canonical = "support") 6637748cd8SNickeau { 6737748cd8SNickeau 6837748cd8SNickeau /** 6937748cd8SNickeau * Log to frontend 7037748cd8SNickeau */ 71*c3437056SNickeau self::log2FrontEnd($message, $level, $canonical); 7237748cd8SNickeau 7337748cd8SNickeau /** 7437748cd8SNickeau * Log level passed for a page (only for file used) 7537748cd8SNickeau * to not allow an attacker to see all errors in frontend 7637748cd8SNickeau */ 7737748cd8SNickeau global $INPUT; 7837748cd8SNickeau $loglevelProp = $INPUT->str(self::LOGLEVEL_URI_QUERY_PROPERTY, null); 7937748cd8SNickeau if (!empty($loglevelProp)) { 8037748cd8SNickeau $level = $loglevelProp; 8137748cd8SNickeau } 822f4da794Sgerardnico /** 832f4da794Sgerardnico * TODO: Make it a configuration ? 842f4da794Sgerardnico */ 852f4da794Sgerardnico if ($level >= self::LVL_MSG_WARNING) { 8637748cd8SNickeau self::log2file($message, $level, $canonical); 872f4da794Sgerardnico } 8837748cd8SNickeau 8937748cd8SNickeau /** 9037748cd8SNickeau * If test, we throw an error 9137748cd8SNickeau */ 92*c3437056SNickeau self::throwErrorIfTest($level, $message); 9337748cd8SNickeau } 9437748cd8SNickeau 9537748cd8SNickeau /** 9637748cd8SNickeau * Print log to a file 9737748cd8SNickeau * 9837748cd8SNickeau * Adapted from {@link dbglog} 9937748cd8SNickeau * Note: {@link dbg()} dbg print to the web page 10037748cd8SNickeau * 10137748cd8SNickeau * @param string $msg 10237748cd8SNickeau * @param int $logLevel 10337748cd8SNickeau * @param null $canonical 10437748cd8SNickeau */ 10537748cd8SNickeau static function log2file($msg, $logLevel = self::LVL_MSG_INFO, $canonical = null) 10637748cd8SNickeau { 10737748cd8SNickeau 108*c3437056SNickeau if (PluginUtility::isTest() || $logLevel >= self::LVL_MSG_WARNING) { 10937748cd8SNickeau 11037748cd8SNickeau $prefix = PluginUtility::$PLUGIN_NAME; 11137748cd8SNickeau if (!empty($canonical)) { 11237748cd8SNickeau $prefix .= ' - ' . $canonical; 11337748cd8SNickeau } 11437748cd8SNickeau $msg = $prefix . ' - ' . $msg; 11537748cd8SNickeau 11637748cd8SNickeau global $INPUT; 11737748cd8SNickeau global $conf; 11837748cd8SNickeau 119*c3437056SNickeau /** 120*c3437056SNickeau * Adding page - context information 121*c3437056SNickeau * We are not using {@link Page::createPageFromRequestedPage()} 122*c3437056SNickeau * because it throws an error message when the environment 123*c3437056SNickeau * is not good, creating a recursive call. 124*c3437056SNickeau */ 125*c3437056SNickeau $id = PluginUtility::getMainPageDokuwikiId(); 12637748cd8SNickeau 12737748cd8SNickeau $file = $conf['cachedir'] . '/debug.log'; 12837748cd8SNickeau $fh = fopen($file, 'a'); 12937748cd8SNickeau if ($fh) { 13037748cd8SNickeau $sep = " - "; 13137748cd8SNickeau fwrite($fh, date('c') . $sep . self::LVL_NAME[$logLevel] . $sep . $msg . $sep . $INPUT->server->str('REMOTE_ADDR') . $sep . $id . "\n"); 13237748cd8SNickeau fclose($fh); 13337748cd8SNickeau } 134*c3437056SNickeau 135*c3437056SNickeau 136*c3437056SNickeau self::throwErrorIfTest($logLevel, $msg); 137*c3437056SNickeau 138*c3437056SNickeau 13937748cd8SNickeau } 14037748cd8SNickeau 14137748cd8SNickeau } 14237748cd8SNickeau 14337748cd8SNickeau /** 14437748cd8SNickeau * @param $message 14537748cd8SNickeau * @param $level 14637748cd8SNickeau * @param $canonical 14737748cd8SNickeau * @param bool $withIconURL 14837748cd8SNickeau */ 14937748cd8SNickeau public static function log2FrontEnd($message, $level, $canonical = "support", $withIconURL = true) 15037748cd8SNickeau { 15137748cd8SNickeau /** 15237748cd8SNickeau * If we are not in the console 15337748cd8SNickeau * and not in test 15437748cd8SNickeau * we test that the message comes in the front end 15537748cd8SNickeau * (example {@link \plugin_combo_frontmatter_test} 15637748cd8SNickeau */ 157*c3437056SNickeau $isTerminal = Console::isConsoleRun(); 158*c3437056SNickeau if ($isTerminal) { 15937748cd8SNickeau if (!defined('DOKU_UNITTEST')) { 160*c3437056SNickeau /** 161*c3437056SNickeau * such as {@link cli_plugin_combo} 162*c3437056SNickeau */ 163*c3437056SNickeau $userAgent = "cli"; 164*c3437056SNickeau } else { 165*c3437056SNickeau $userAgent = "phpunit"; 16637748cd8SNickeau } 167*c3437056SNickeau } else { 168*c3437056SNickeau $userAgent = "browser"; 16937748cd8SNickeau } 170*c3437056SNickeau 171*c3437056SNickeau switch ($userAgent) { 172*c3437056SNickeau case "cli": 173*c3437056SNickeau echo "$message\n"; 174*c3437056SNickeau break; 175*c3437056SNickeau case "phpunit": 176*c3437056SNickeau case "browser": 177*c3437056SNickeau default: 178*c3437056SNickeau $htmlMsg = PluginUtility::getDocumentationHyperLink("", PluginUtility::$PLUGIN_NAME, $withIconURL); 17937748cd8SNickeau if ($canonical != null) { 180*c3437056SNickeau $htmlMsg = PluginUtility::getDocumentationHyperLink($canonical, ucfirst(str_replace(":", " ", $canonical))); 18137748cd8SNickeau } 18237748cd8SNickeau 18337748cd8SNickeau /** 18437748cd8SNickeau * Adding page - context information 18537748cd8SNickeau * We are not creating the page 186*c3437056SNickeau * direction from {@link Page::createPageFromRequestedPage()} 18737748cd8SNickeau * because it throws an error message when the environment 18837748cd8SNickeau * is not good, creating a recursive call. 18937748cd8SNickeau */ 190*c3437056SNickeau $id = PluginUtility::getMainPageDokuwikiId(); 19137748cd8SNickeau if ($id != null) { 192*c3437056SNickeau 193*c3437056SNickeau /** 194*c3437056SNickeau * We don't use any Page object to not 195*c3437056SNickeau * create a cycle while building it 196*c3437056SNickeau */ 197*c3437056SNickeau $url = wl($id,[],true); 198*c3437056SNickeau $htmlMsg .= " - <a href=\"$url\">$id</a>"; 199*c3437056SNickeau 20037748cd8SNickeau } 20137748cd8SNickeau 20237748cd8SNickeau /** 20337748cd8SNickeau * 20437748cd8SNickeau */ 20537748cd8SNickeau $htmlMsg .= " - " . $message; 20637748cd8SNickeau if ($level > self::LVL_MSG_DEBUG) { 20737748cd8SNickeau $dokuWikiLevel = self::LVL_TO_MSG_LEVEL[$level]; 20837748cd8SNickeau msg($htmlMsg, $dokuWikiLevel, '', '', MSG_USERS_ONLY); 20937748cd8SNickeau } 21037748cd8SNickeau } 21137748cd8SNickeau } 21237748cd8SNickeau 21337748cd8SNickeau /** 21437748cd8SNickeau * Log a message to the browser console 21537748cd8SNickeau * @param $message 21637748cd8SNickeau */ 21737748cd8SNickeau public static function log2BrowserConsole($message) 21837748cd8SNickeau { 21937748cd8SNickeau // TODO 22037748cd8SNickeau } 221*c3437056SNickeau 222*c3437056SNickeau private static function throwErrorIfTest($level, $message) 223*c3437056SNickeau { 224*c3437056SNickeau if (PluginUtility::isTest() 225*c3437056SNickeau && ($level >= self::LVL_MSG_WARNING) 226*c3437056SNickeau ) { 227*c3437056SNickeau throw new LogException($message); 228*c3437056SNickeau } 229*c3437056SNickeau } 23037748cd8SNickeau} 231