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