/** * Log to provided file or to a generated file. Filename is relative to site root if it starts with a '/' otherwise is interpreted as relative * to assets folder. Checks to make sure final log file path is inside the web root. * * @param int $level only log above this level * @param string $filePathName log to this file or if not supplied generate one * @return $this */ public function toFile($level, $filePathName = '') { $originalFilePathName = $filePathName; if ($filePathName) { if (substr($filePathName, -4) != '.log') { $filePathName .= ".log"; } } else { $filePathName = $this->config()->get('log_file') ?: Application::log_file(); } if (trim(dirname($filePathName), '.') == '') { $filePathName = ($this->config()->get('log_path') ?: Application::log_path()) . '/' . $filePathName; } if ($path = Application::make_safe_path(dirname($filePathName))) { $this->logFilePathName = Controller::join_links($path, basename($filePathName)); } if (!$this->logFilePathName) { $this->logFilePathName = Application::log_path() . '/' . Application::log_file(); } SS_Log::add_writer(new SS_LogFileWriter($this->logFilePathName), $this->lvl($level)); // log an warning if we got an invalid path above so we know this and can fix if ($filePathName && !Application::make_safe_path(dirname($originalFilePathName))) { $this->warn("Invalid file path outside of web root '{$filePathName}' using '{$this->logFilePathName}' instead"); } if ($filePathName && !is_dir(dirname($originalFilePathName))) { $this->warn("Path for '{$filePathName}' does not exist, using '{$this->logFilePathName}' instead"); } return $this; }