1*37748cd8SNickeau<?php 2*37748cd8SNickeau/** 3*37748cd8SNickeau * Copyright (c) 2020. ComboStrap, Inc. and its affiliates. All Rights Reserved. 4*37748cd8SNickeau * 5*37748cd8SNickeau * This source code is licensed under the GPL license found in the 6*37748cd8SNickeau * COPYING file in the root directory of this source tree. 7*37748cd8SNickeau * 8*37748cd8SNickeau * @license GPL 3 (https://www.gnu.org/licenses/gpl-3.0.en.html) 9*37748cd8SNickeau * @author ComboStrap <support@combostrap.com> 10*37748cd8SNickeau * 11*37748cd8SNickeau */ 12*37748cd8SNickeau 13*37748cd8SNickeaunamespace ComboStrap; 14*37748cd8SNickeau 15*37748cd8SNickeaurequire_once(__DIR__ . '/PluginUtility.php'); 16*37748cd8SNickeau 17*37748cd8SNickeauclass LogUtility 18*37748cd8SNickeau{ 19*37748cd8SNickeau 20*37748cd8SNickeau /** 21*37748cd8SNickeau * Constant for the function {@link msg()} 22*37748cd8SNickeau * -1 = error, 0 = info, 1 = success, 2 = notify 23*37748cd8SNickeau * (Not even in order of importance) 24*37748cd8SNickeau */ 25*37748cd8SNickeau const LVL_MSG_ERROR = 4; //-1; 26*37748cd8SNickeau const LVL_MSG_WARNING = 3; //2; 27*37748cd8SNickeau const LVL_MSG_SUCCESS = 2; //1; 28*37748cd8SNickeau const LVL_MSG_INFO = 1; //0; 29*37748cd8SNickeau const LVL_MSG_DEBUG = 0; //3; 30*37748cd8SNickeau 31*37748cd8SNickeau 32*37748cd8SNickeau /** 33*37748cd8SNickeau * Id level to name 34*37748cd8SNickeau */ 35*37748cd8SNickeau const LVL_NAME = array( 36*37748cd8SNickeau 0 => "debug", 37*37748cd8SNickeau 1 => "info", 38*37748cd8SNickeau 3 => "warning", 39*37748cd8SNickeau 2 => "success", 40*37748cd8SNickeau 4 => "error" 41*37748cd8SNickeau ); 42*37748cd8SNickeau 43*37748cd8SNickeau /** 44*37748cd8SNickeau * Id level to name 45*37748cd8SNickeau * {@link msg()} constant 46*37748cd8SNickeau */ 47*37748cd8SNickeau const LVL_TO_MSG_LEVEL = array( 48*37748cd8SNickeau 0 => 3, 49*37748cd8SNickeau 1 => 0, 50*37748cd8SNickeau 2 => 1, 51*37748cd8SNickeau 3 => 2, 52*37748cd8SNickeau 4 => -1 53*37748cd8SNickeau ); 54*37748cd8SNickeau 55*37748cd8SNickeau 56*37748cd8SNickeau const LOGLEVEL_URI_QUERY_PROPERTY = "loglevel"; 57*37748cd8SNickeau 58*37748cd8SNickeau /** 59*37748cd8SNickeau * Send a message to a manager and log it 60*37748cd8SNickeau * Fail if in test 61*37748cd8SNickeau * @param string $message 62*37748cd8SNickeau * @param int $level - the level see LVL constant 63*37748cd8SNickeau * @param string $canonical - the canonical 64*37748cd8SNickeau */ 65*37748cd8SNickeau public static function msg($message, $level = self::LVL_MSG_ERROR, $canonical = "support") 66*37748cd8SNickeau { 67*37748cd8SNickeau 68*37748cd8SNickeau /** 69*37748cd8SNickeau * Log to frontend 70*37748cd8SNickeau */ 71*37748cd8SNickeau self::log2FrontEnd($message, $level, $canonical, true); 72*37748cd8SNickeau 73*37748cd8SNickeau /** 74*37748cd8SNickeau * Log level passed for a page (only for file used) 75*37748cd8SNickeau * to not allow an attacker to see all errors in frontend 76*37748cd8SNickeau */ 77*37748cd8SNickeau global $INPUT; 78*37748cd8SNickeau $loglevelProp = $INPUT->str(self::LOGLEVEL_URI_QUERY_PROPERTY, null); 79*37748cd8SNickeau if (!empty($loglevelProp)) { 80*37748cd8SNickeau $level = $loglevelProp; 81*37748cd8SNickeau } 82*37748cd8SNickeau self::log2file($message, $level, $canonical); 83*37748cd8SNickeau 84*37748cd8SNickeau /** 85*37748cd8SNickeau * If test, we throw an error 86*37748cd8SNickeau */ 87*37748cd8SNickeau if (defined('DOKU_UNITTEST') 88*37748cd8SNickeau && ($level >= self::LVL_MSG_WARNING) 89*37748cd8SNickeau ) { 90*37748cd8SNickeau throw new \RuntimeException(PluginUtility::$PLUGIN_NAME . " - " . $message); 91*37748cd8SNickeau } 92*37748cd8SNickeau } 93*37748cd8SNickeau 94*37748cd8SNickeau /** 95*37748cd8SNickeau * Print log to a file 96*37748cd8SNickeau * 97*37748cd8SNickeau * Adapted from {@link dbglog} 98*37748cd8SNickeau * Note: {@link dbg()} dbg print to the web page 99*37748cd8SNickeau * 100*37748cd8SNickeau * @param string $msg 101*37748cd8SNickeau * @param int $logLevel 102*37748cd8SNickeau * @param null $canonical 103*37748cd8SNickeau */ 104*37748cd8SNickeau static function log2file($msg, $logLevel = self::LVL_MSG_INFO, $canonical = null) 105*37748cd8SNickeau { 106*37748cd8SNickeau 107*37748cd8SNickeau if (defined('DOKU_UNITTEST') || $logLevel >= self::LVL_MSG_WARNING) { 108*37748cd8SNickeau 109*37748cd8SNickeau $prefix = PluginUtility::$PLUGIN_NAME; 110*37748cd8SNickeau if (!empty($canonical)) { 111*37748cd8SNickeau $prefix .= ' - ' . $canonical; 112*37748cd8SNickeau } 113*37748cd8SNickeau $msg = $prefix . ' - ' . $msg; 114*37748cd8SNickeau 115*37748cd8SNickeau global $INPUT; 116*37748cd8SNickeau global $conf; 117*37748cd8SNickeau 118*37748cd8SNickeau $id = PluginUtility::getPageId(); 119*37748cd8SNickeau 120*37748cd8SNickeau $file = $conf['cachedir'] . '/debug.log'; 121*37748cd8SNickeau $fh = fopen($file, 'a'); 122*37748cd8SNickeau if ($fh) { 123*37748cd8SNickeau $sep = " - "; 124*37748cd8SNickeau fwrite($fh, date('c') . $sep . self::LVL_NAME[$logLevel] . $sep . $msg . $sep . $INPUT->server->str('REMOTE_ADDR') . $sep . $id . "\n"); 125*37748cd8SNickeau fclose($fh); 126*37748cd8SNickeau } 127*37748cd8SNickeau } 128*37748cd8SNickeau 129*37748cd8SNickeau } 130*37748cd8SNickeau 131*37748cd8SNickeau /** 132*37748cd8SNickeau * @param $message 133*37748cd8SNickeau * @param $level 134*37748cd8SNickeau * @param $canonical 135*37748cd8SNickeau * @param bool $withIconURL 136*37748cd8SNickeau */ 137*37748cd8SNickeau public static function log2FrontEnd($message, $level, $canonical="support", $withIconURL = true) 138*37748cd8SNickeau { 139*37748cd8SNickeau /** 140*37748cd8SNickeau * If we are not in the console 141*37748cd8SNickeau * and not in test 142*37748cd8SNickeau * we test that the message comes in the front end 143*37748cd8SNickeau * (example {@link \plugin_combo_frontmatter_test} 144*37748cd8SNickeau */ 145*37748cd8SNickeau $isCLI = (php_sapi_name() == 'cli'); 146*37748cd8SNickeau $print = true; 147*37748cd8SNickeau if ($isCLI) { 148*37748cd8SNickeau if (!defined('DOKU_UNITTEST')) { 149*37748cd8SNickeau $print = false; 150*37748cd8SNickeau } 151*37748cd8SNickeau } 152*37748cd8SNickeau if ($print) { 153*37748cd8SNickeau $htmlMsg = PluginUtility::getUrl("", PluginUtility::$PLUGIN_NAME, $withIconURL); 154*37748cd8SNickeau if ($canonical != null) { 155*37748cd8SNickeau $htmlMsg = PluginUtility::getUrl($canonical, ucfirst(str_replace(":", " ", $canonical))); 156*37748cd8SNickeau } 157*37748cd8SNickeau 158*37748cd8SNickeau /** 159*37748cd8SNickeau * Adding page - context information 160*37748cd8SNickeau * We are not creating the page 161*37748cd8SNickeau * direction from {@link Page::createRequestedPageFromEnvironment()} 162*37748cd8SNickeau * because it throws an error message when the environment 163*37748cd8SNickeau * is not good, creating a recursive call. 164*37748cd8SNickeau */ 165*37748cd8SNickeau $id = PluginUtility::getPageId(); 166*37748cd8SNickeau if ($id!=null) { 167*37748cd8SNickeau $page = Page::createPageFromId($id); 168*37748cd8SNickeau if ($page != null) { 169*37748cd8SNickeau $htmlMsg .= " - " . $page->getAnchorLink(); 170*37748cd8SNickeau } 171*37748cd8SNickeau } 172*37748cd8SNickeau 173*37748cd8SNickeau /** 174*37748cd8SNickeau * 175*37748cd8SNickeau */ 176*37748cd8SNickeau $htmlMsg .= " - " . $message; 177*37748cd8SNickeau if ($level > self::LVL_MSG_DEBUG) { 178*37748cd8SNickeau $dokuWikiLevel = self::LVL_TO_MSG_LEVEL[$level]; 179*37748cd8SNickeau msg($htmlMsg, $dokuWikiLevel, '', '', MSG_USERS_ONLY); 180*37748cd8SNickeau } 181*37748cd8SNickeau } 182*37748cd8SNickeau } 183*37748cd8SNickeau 184*37748cd8SNickeau /** 185*37748cd8SNickeau * Log a message to the browser console 186*37748cd8SNickeau * @param $message 187*37748cd8SNickeau */ 188*37748cd8SNickeau public static function log2BrowserConsole($message) 189*37748cd8SNickeau { 190*37748cd8SNickeau // TODO 191*37748cd8SNickeau } 192*37748cd8SNickeau} 193