[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * Joomla! Content Management System 5 * 6 * @copyright (C) 2011 Open Source Matters, Inc. <https://www.joomla.org> 7 * @license GNU General Public License version 2 or later; see LICENSE.txt 8 */ 9 10 namespace Joomla\CMS\Log\Logger; 11 12 use Joomla\CMS\Factory; 13 use Joomla\CMS\Filesystem\File; 14 use Joomla\CMS\Filesystem\Folder; 15 use Joomla\CMS\Log\LogEntry; 16 use Joomla\CMS\Log\Logger; 17 use Joomla\CMS\Version; 18 use Joomla\Utilities\IpHelper; 19 20 // phpcs:disable PSR1.Files.SideEffects 21 \defined('JPATH_PLATFORM') or die; 22 // phpcs:enable PSR1.Files.SideEffects 23 24 /** 25 * Joomla! Formatted Text File Log class 26 * 27 * This class is designed to use as a base for building formatted text files for output. By 28 * default it emulates the Syslog style format output. This is a disk based output format. 29 * 30 * @since 1.7.0 31 */ 32 class FormattedtextLogger extends Logger 33 { 34 /** 35 * The format which each entry follows in the log file. 36 * 37 * All fields must be named in all caps and be within curly brackets eg. {FOOBAR}. 38 * 39 * @var string 40 * @since 1.7.0 41 */ 42 protected $format = '{DATETIME} {PRIORITY} {CLIENTIP} {CATEGORY} {MESSAGE}'; 43 44 /** 45 * The parsed fields from the format string. 46 * 47 * @var array 48 * @since 1.7.0 49 */ 50 protected $fields = array(); 51 52 /** 53 * The full filesystem path for the log file. 54 * 55 * @var string 56 * @since 1.7.0 57 */ 58 protected $path; 59 60 /** 61 * If true, all writes will be deferred as long as possible. 62 * NOTE: Deferred logs may never be written if the application encounters a fatal error. 63 * 64 * @var boolean 65 * @since 3.9.0 66 */ 67 protected $defer = false; 68 69 /** 70 * If deferring, entries will be stored here prior to writing. 71 * 72 * @var array 73 * @since 3.9.0 74 */ 75 protected $deferredEntries = array(); 76 77 /** 78 * Constructor. 79 * 80 * @param array &$options Log object options. 81 * 82 * @since 1.7.0 83 */ 84 public function __construct(array &$options) 85 { 86 // Call the parent constructor. 87 parent::__construct($options); 88 89 // The name of the text file defaults to 'error.php' if not explicitly given. 90 if (empty($this->options['text_file'])) { 91 $this->options['text_file'] = 'error.php'; 92 } 93 94 // The name of the text file path defaults to that which is set in configuration if not explicitly given. 95 if (empty($this->options['text_file_path'])) { 96 $this->options['text_file_path'] = Factory::getApplication()->get('log_path', JPATH_ADMINISTRATOR . '/logs'); 97 } 98 99 // False to treat the log file as a php file. 100 if (empty($this->options['text_file_no_php'])) { 101 $this->options['text_file_no_php'] = false; 102 } 103 104 // Build the full path to the log file. 105 $this->path = $this->options['text_file_path'] . '/' . $this->options['text_file']; 106 107 // Use the default entry format unless explicitly set otherwise. 108 if (!empty($this->options['text_entry_format'])) { 109 $this->format = (string) $this->options['text_entry_format']; 110 } 111 112 // Wait as long as possible before writing logs 113 if (!empty($this->options['defer'])) { 114 $this->defer = (bool) $this->options['defer']; 115 } 116 117 // Build the fields array based on the format string. 118 $this->parseFields(); 119 } 120 121 /** 122 * If deferred, write all pending logs. 123 * 124 * @since 3.9.0 125 */ 126 public function __destruct() 127 { 128 // Nothing to do 129 if (!$this->defer || empty($this->deferredEntries)) { 130 return; 131 } 132 133 // Initialise the file if not already done. 134 $this->initFile(); 135 136 // Format all lines and write to file. 137 $lines = array_map(array($this, 'formatLine'), $this->deferredEntries); 138 139 if (!File::append($this->path, implode("\n", $lines) . "\n")) { 140 throw new \RuntimeException('Cannot write to log file.'); 141 } 142 } 143 144 /** 145 * Method to add an entry to the log. 146 * 147 * @param LogEntry $entry The log entry object to add to the log. 148 * 149 * @return void 150 * 151 * @since 1.7.0 152 * @throws \RuntimeException 153 */ 154 public function addEntry(LogEntry $entry) 155 { 156 // Store the entry to be written later. 157 if ($this->defer) { 158 $this->deferredEntries[] = $entry; 159 } else { 160 // Write it immediately. 161 // Initialise the file if not already done. 162 $this->initFile(); 163 164 // Write the new entry to the file. 165 $line = $this->formatLine($entry); 166 $line .= "\n"; 167 168 if (!File::append($this->path, $line)) { 169 throw new \RuntimeException('Cannot write to log file.'); 170 } 171 } 172 } 173 174 /** 175 * Format a line for the log file. 176 * 177 * @param LogEntry $entry The log entry to format as a string. 178 * 179 * @return String 180 * 181 * @since 3.9.0 182 */ 183 protected function formatLine(LogEntry $entry) 184 { 185 // Set some default field values if not already set. 186 if (!isset($entry->clientIP)) { 187 $ip = IpHelper::getIp(); 188 189 if ($ip !== '') { 190 $entry->clientIP = $ip; 191 } 192 } 193 194 // If the time field is missing or the date field isn't only the date we need to rework it. 195 if ((\strlen($entry->date) != 10) || !isset($entry->time)) { 196 // Get the date and time strings in GMT. 197 $entry->datetime = $entry->date->toISO8601(); 198 $entry->time = $entry->date->format('H:i:s', false); 199 $entry->date = $entry->date->format('Y-m-d', false); 200 } 201 202 // Get a list of all the entry keys and make sure they are upper case. 203 $tmp = array_change_key_case(get_object_vars($entry), CASE_UPPER); 204 205 // Decode the entry priority into an English string. 206 $tmp['PRIORITY'] = $this->priorities[$entry->priority]; 207 208 // Fill in field data for the line. 209 $line = $this->format; 210 211 foreach ($this->fields as $field) { 212 $line = str_replace('{' . $field . '}', $tmp[$field] ?? '-', $line); 213 } 214 215 return $line; 216 } 217 218 /** 219 * Method to generate the log file header. 220 * 221 * @return string The log file header 222 * 223 * @since 1.7.0 224 */ 225 protected function generateFileHeader() 226 { 227 $head = array(); 228 229 // Build the log file header. 230 231 // If the no php flag is not set add the php die statement. 232 if (empty($this->options['text_file_no_php'])) { 233 // Blank line to prevent information disclose: https://bugs.php.net/bug.php?id=60677 234 $head[] = '#'; 235 $head[] = '#<?php die(\'Forbidden.\'); ?>'; 236 } 237 238 $head[] = '#Date: ' . gmdate('Y-m-d H:i:s') . ' UTC'; 239 $head[] = '#Software: ' . (new Version())->getLongVersion(); 240 $head[] = ''; 241 242 // Prepare the fields string 243 $head[] = '#Fields: ' . strtolower(str_replace('}', '', str_replace('{', '', $this->format))); 244 $head[] = ''; 245 246 return implode("\n", $head); 247 } 248 249 /** 250 * Method to initialise the log file. This will create the folder path to the file if it doesn't already 251 * exist and also get a new file header if the file doesn't already exist. If the file already exists it 252 * will simply open it for writing. 253 * 254 * @return void 255 * 256 * @since 1.7.0 257 * @throws \RuntimeException 258 */ 259 protected function initFile() 260 { 261 // We only need to make sure the file exists 262 if (File::exists($this->path)) { 263 return; 264 } 265 266 // Make sure the folder exists in which to create the log file. 267 Folder::create(\dirname($this->path)); 268 269 // Build the log file header. 270 $head = $this->generateFileHeader(); 271 272 if (!File::write($this->path, $head)) { 273 throw new \RuntimeException('Cannot write to log file.'); 274 } 275 } 276 277 /** 278 * Method to parse the format string into an array of fields. 279 * 280 * @return void 281 * 282 * @since 1.7.0 283 */ 284 protected function parseFields() 285 { 286 $this->fields = array(); 287 $matches = array(); 288 289 // Get all of the available fields in the format string. 290 preg_match_all('/{(.*?)}/i', $this->format, $matches); 291 292 // Build the parsed fields list based on the found fields. 293 foreach ($matches[1] as $match) { 294 $this->fields[] = strtoupper($match); 295 } 296 } 297 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Sep 7 05:41:13 2022 | Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer |