TYPO3 CMS  TYPO3_8-7
FileWriter.php
Go to the documentation of this file.
1 <?php
3 
4 /*
5  * This file is part of the TYPO3 CMS project.
6  *
7  * It is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License, either version 2
9  * of the License, or any later version.
10  *
11  * For the full copyright and license information, please read the
12  * LICENSE.txt file that was distributed with this source code.
13  *
14  * The TYPO3 project - inspiring people to share!
15  */
16 
22 
27 {
33  protected $logFile = '';
34 
40  protected $defaultLogFileTemplate = 'typo3temp/var/logs/typo3_%s.log';
41 
51  protected static $logFileHandles = [];
52 
59  public function __construct(array $options = [])
60  {
61  // the parent constructor reads $options and sets them
62  parent::__construct($options);
63  if (empty($options['logFile'])) {
64  $this->setLogFile($this->getDefaultLogFileName());
65  }
66  }
67 
71  public function __destruct()
72  {
73  $this->closeLogFile();
74  }
75 
83  public function setLogFile($relativeLogFile)
84  {
85  $logFile = $relativeLogFile;
86  // Skip handling if logFile is a stream resource. This is used by unit tests with vfs:// directories
87  if (false === strpos($logFile, '://') && !PathUtility::isAbsolutePath($logFile)) {
89  if (empty($logFile)) {
90  throw new InvalidLogWriterConfigurationException('Log file path "' . $relativeLogFile . '" is not valid!', 1444374805);
91  }
92  }
93  $this->logFile = $logFile;
94  $this->openLogFile();
95 
96  return $this;
97  }
98 
104  public function getLogFile()
105  {
106  return $this->logFile;
107  }
108 
116  public function writeLog(LogRecord $record)
117  {
118  $timestamp = date('r', (int)$record->getCreated());
119  $levelName = LogLevel::getName($record->getLevel());
120  $data = '';
121  $recordData = $record->getData();
122  if (!empty($recordData)) {
123  // According to PSR3 the exception-key may hold an \Exception
124  // Since json_encode() does not encode an exception, we run the _toString() here
125  if (isset($recordData['exception']) && $recordData['exception'] instanceof \Exception) {
126  $recordData['exception'] = (string)$recordData['exception'];
127  }
128  $data = '- ' . json_encode($recordData);
129  }
130 
131  $message = sprintf(
132  '%s [%s] request="%s" component="%s": %s %s',
133  $timestamp,
134  $levelName,
135  $record->getRequestId(),
136  $record->getComponent(),
137  $record->getMessage(),
138  $data
139  );
140 
141  if (false === fwrite(self::$logFileHandles[$this->logFile], $message . LF)) {
142  throw new \RuntimeException('Could not write log record to log file', 1345036335);
143  }
144 
145  return $this;
146  }
147 
153  protected function openLogFile()
154  {
155  if (is_resource(self::$logFileHandles[$this->logFile])) {
156  return;
157  }
158 
159  $this->createLogFile();
160  self::$logFileHandles[$this->logFile] = fopen($this->logFile, 'a');
161  if (!is_resource(self::$logFileHandles[$this->logFile])) {
162  throw new \RuntimeException('Could not open log file "' . $this->logFile . '"', 1321804422);
163  }
164  }
165 
169  protected function closeLogFile()
170  {
171  if (is_resource(self::$logFileHandles[$this->logFile])) {
172  fclose(self::$logFileHandles[$this->logFile]);
173  unset(self::$logFileHandles[$this->logFile]);
174  }
175  }
176 
181  protected function createLogFile()
182  {
183  if (file_exists($this->logFile)) {
184  return;
185  }
186  $logFileDirectory = dirname($this->logFile);
187  if (!@is_dir($logFileDirectory)) {
188  GeneralUtility::mkdir_deep($logFileDirectory);
189  // create .htaccess file if log file is within the site path
190  if (PathUtility::getCommonPrefix([PATH_site, $logFileDirectory]) === PATH_site) {
191  // only create .htaccess, if we created the directory on our own
192  $this->createHtaccessFile($logFileDirectory . '/.htaccess');
193  }
194  }
195  // create the log file
196  GeneralUtility::writeFile($this->logFile, '');
197  }
198 
204  protected function createHtaccessFile($htaccessFile)
205  {
206  // write .htaccess file to protect the log file
207  if (!empty($GLOBALS['TYPO3_CONF_VARS']['SYS']['generateApacheHtaccess']) && !file_exists($htaccessFile)) {
208  $htaccessContent = '
209 # Apache < 2.3
210 <IfModule !mod_authz_core.c>
211  Order allow,deny
212  Deny from all
213  Satisfy All
214 </IfModule>
215 
216 # Apache ≥ 2.3
217 <IfModule mod_authz_core.c>
218  Require all denied
219 </IfModule>
220  ';
221  GeneralUtility::writeFile($htaccessFile, $htaccessContent);
222  }
223  }
224 
233  protected function getDefaultLogFileName()
234  {
235  return sprintf($this->defaultLogFileTemplate, substr(GeneralUtility::hmac($this->defaultLogFileTemplate, 'defaultLogFile'), 0, 10));
236  }
237 }
static mkdir_deep($directory, $deepDirectory='')
static getCommonPrefix(array $paths)
static hmac($input, $additionalSecret='')
static getFileAbsFileName($filename, $_=null, $_2=null)
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']
static writeFile($file, $content, $changePermissions=false)
static getName($level)
Definition: LogLevel.php:118