/** * @inheritdoc */ public function formatMessage($message) { list($text, $level, $category, $timestamp) = $message; $level = Logger::getLevelName($level); if (!is_string($text)) { // exceptions may not be serializable if in the call stack somewhere is a Closure if ($text instanceof \Exception) { $text = (string) $text; } else { $text = VarDumper::export($text); } } $prefix = $this->getMessagePrefix($message); return "{$prefix}[{$level}][{$category}] {$text}"; }
/** * Stores log messages to DB. */ public function export() { $tableName = $this->db->quoteTableName($this->logTable); $sql = "INSERT INTO {$tableName} ([[level]], [[category]], [[log_time]], [[prefix]], [[message]])\n VALUES (:level, :category, :log_time, :prefix, :message)"; $command = $this->db->createCommand($sql); foreach ($this->messages as $message) { list($text, $level, $category, $timestamp) = $message; if (!is_string($text)) { // exceptions may not be serializable if in the call stack somewhere is a Closure if ($text instanceof \Exception) { $text = (string) $text; } else { $text = VarDumper::export($text); } } $command->bindValues([':level' => $level, ':category' => $category, ':log_time' => $timestamp, ':prefix' => $this->getMessagePrefix($message), ':message' => $text])->execute(); } }
/** * Writes category messages into PHP file * * @param array $messages * @param string $fileName name of the file to write to * @param boolean $overwrite if existing file should be overwritten without backup * @param boolean $removeUnused if obsolete translations should be removed * @param boolean $sort if translations should be sorted * @param string $category message category * @param boolean $markUnused if obsolete translations should be marked */ protected function saveMessagesCategoryToPHP($messages, $fileName, $overwrite, $removeUnused, $sort, $category, $markUnused) { if (is_file($fileName)) { $rawExistingMessages = (require $fileName); $existingMessages = $rawExistingMessages; sort($messages); ksort($existingMessages); if (array_keys($existingMessages) === $messages && (!$sort || array_keys($rawExistingMessages) === $messages)) { $this->stdout("Nothing new in \"{$category}\" category... Nothing to save.\n\n", Console::FG_GREEN); return; } unset($rawExistingMessages); $merged = []; $untranslated = []; foreach ($messages as $message) { if (array_key_exists($message, $existingMessages) && $existingMessages[$message] !== '') { $merged[$message] = $existingMessages[$message]; } else { $untranslated[] = $message; } } ksort($merged); sort($untranslated); $todo = []; foreach ($untranslated as $message) { $todo[$message] = ''; } ksort($existingMessages); foreach ($existingMessages as $message => $translation) { if (!$removeUnused && !isset($merged[$message]) && !isset($todo[$message])) { if (!empty($translation) && (!$markUnused || strncmp($translation, '@@', 2) === 0 && substr_compare($translation, '@@', -2, 2) === 0)) { $todo[$message] = $translation; } else { $todo[$message] = '@@' . $translation . '@@'; } } } $merged = array_merge($todo, $merged); if ($sort) { ksort($merged); } if (false === $overwrite) { $fileName .= '.merged'; } $this->stdout("Translation merged.\n"); } else { $merged = []; foreach ($messages as $message) { $merged[$message] = ''; } ksort($merged); } $array = VarDumper::export($merged); $content = <<<EOD <?php /** * Message translations. * * This file is automatically generated by 'yii {$this->id}' command. * It contains the localizable messages extracted from source code. * You may modify this file by translating the extracted messages. * * Each array element represents the translation (value) of a message (key). * If the value is empty, the message is considered as not translated. * Messages that no longer need translation will have their translations * enclosed between a pair of '@@' marks. * * Message string can be used with plural forms format. Check i18n section * of the guide for details. * * NOTE: this file must be saved in UTF-8 encoding. */ return {$array}; EOD; file_put_contents($fileName, $content); $this->stdout("Translation saved.\n\n", Console::FG_GREEN); }
/** * Handles uncaught PHP exceptions. * * This method is implemented as a PHP exception handler. * * @param \Exception $exception the exception that is not caught */ public function handleException($exception) { if ($exception instanceof ExitException) { return; } $this->exception = $exception; // disable error capturing to avoid recursive errors while handling exceptions $this->unregister(); // set preventive HTTP status code to 500 in case error handling somehow fails and headers are sent // HTTP exceptions will override this value in renderException() if (PHP_SAPI !== 'cli') { http_response_code(500); } try { $this->logException($exception); if ($this->discardExistingOutput) { $this->clearOutput(); } $this->renderException($exception); if (!LEAPS_ENV_TEST) { Leaps::getLogger()->flush(true); if (defined('HHVM_VERSION')) { flush(); } exit(1); } } catch (\Exception $e) { // an other exception could be thrown while displaying the exception $msg = "An Error occurred while handling another error:\n"; $msg .= (string) $e; $msg .= "\nPrevious exception:\n"; $msg .= (string) $exception; if (LEAPS_DEBUG) { if (PHP_SAPI === 'cli') { echo $msg . "\n"; } else { echo '<pre>' . htmlspecialchars($msg, ENT_QUOTES, Leaps::$app->charset) . '</pre>'; } } else { echo 'An internal server error occurred.'; } $msg .= "\n\$_SERVER = " . VarDumper::export($_SERVER); error_log($msg); if (defined('HHVM_VERSION')) { flush(); } exit(1); } $this->exception = null; }
/** * Saves the authorization data to a PHP script file. * * @param array $data the authorization data * @param string $file the file path. * @see loadFromFile() */ protected function saveToFile($data, $file) { file_put_contents($file, "<?php\nreturn " . VarDumper::export($data) . ";\n", LOCK_EX); }
/** * Creates template of configuration file for [[actionCompress]]. * @param string $configFile output file name. * @return integer CLI exit code * @throws \yii\console\Exception on failure. */ public function actionTemplate($configFile) { $jsCompressor = VarDumper::export($this->jsCompressor); $cssCompressor = VarDumper::export($this->cssCompressor); $template = <<<EOD <?php /** * Configuration file for the "yii asset" console command. */ // In the console environment, some path aliases may not exist. Please define these: // Yii::setAlias('@webroot', __DIR__ . '/../web'); // Yii::setAlias('@web', '/'); return [ // Adjust command/callback for JavaScript files compressing: 'jsCompressor' => {$jsCompressor}, // Adjust command/callback for CSS files compressing: 'cssCompressor' => {$cssCompressor}, // The list of asset bundles to compress: 'bundles' => [ // 'app\\assets\\AppAsset', // 'yii\\web\\YiiAsset', // 'yii\\web\\JqueryAsset', ], // Asset bundle for compression output: 'targets' => [ 'all' => [ 'class' => 'yii\\web\\AssetBundle', 'basePath' => '@webroot/assets', 'baseUrl' => '@web/assets', 'js' => 'js/all-{hash}.js', 'css' => 'css/all-{hash}.css', ], ], // Asset manager configuration: 'assetManager' => [ //'basePath' => '@webroot/assets', //'baseUrl' => '@web/assets', ], ]; EOD; if (file_exists($configFile)) { if (!$this->confirm("File '{$configFile}' already exists. Do you wish to overwrite it?")) { return self::EXIT_CODE_NORMAL; } } if (!file_put_contents($configFile, $template)) { throw new Exception("Unable to write template file '{$configFile}'."); } else { $this->stdout("Configuration file template created at '{$configFile}'.\n\n", Console::FG_GREEN); return self::EXIT_CODE_NORMAL; } }
/** * Formats a log message for display as a string. * * @param array $message the log message to be formatted. * The message structure follows that in [[Logger::messages]]. * @return string the formatted message */ public function formatMessage($message) { list($text, $level, $category, $timestamp) = $message; $level = Logger::getLevelName($level); if (!is_string($text)) { // exceptions may not be serializable if in the call stack somewhere is a Closure if ($text instanceof \Exception) { $text = (string) $text; } else { $text = VarDumper::export($text); } } $traces = []; if (isset($message[4])) { foreach ($message[4] as $trace) { $traces[] = "in {$trace['file']}:{$trace['line']}"; } } $prefix = $this->getMessagePrefix($message); return date('Y-m-d H:i:s', $timestamp) . " {$prefix}[{$level}][{$category}] {$text}" . (empty($traces) ? '' : "\n " . implode("\n ", $traces)); }
/** * Renders the request information. * * @return string the rendering result */ public function renderRequest() { $request = ''; foreach (['_GET', '_POST', '_SERVER', '_FILES', '_COOKIE', '_SESSION', '_ENV'] as $name) { if (!empty($GLOBALS[$name])) { $request .= '$' . $name . ' = ' . VarDumper::export($GLOBALS[$name]) . ";\n\n"; } } return '<pre>' . rtrim($request, "\n") . '</pre>'; }