init
This commit is contained in:
140
vendor/yiisoft/yii2-debug/panels/AssetPanel.php
vendored
Normal file
140
vendor/yiisoft/yii2-debug/panels/AssetPanel.php
vendored
Normal file
@@ -0,0 +1,140 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\debug\panels;
|
||||
|
||||
use Yii;
|
||||
use yii\base\InvalidConfigException;
|
||||
use yii\helpers\Html;
|
||||
use yii\debug\Panel;
|
||||
use yii\web\AssetBundle;
|
||||
use yii\web\AssetManager;
|
||||
|
||||
/**
|
||||
* Debugger panel that collects and displays asset bundles data.
|
||||
*
|
||||
* @author Artur Fursa <arturfursa@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class AssetPanel extends Panel
|
||||
{
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'Asset Bundles';
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getSummary()
|
||||
{
|
||||
return Yii::$app->view->render('panels/assets/summary', ['panel' => $this]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getDetail()
|
||||
{
|
||||
return Yii::$app->view->render('panels/assets/detail', ['panel' => $this]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
$bundles = Yii::$app->view->assetManager->bundles;
|
||||
if (empty($bundles)) { // bundles can be false
|
||||
return [];
|
||||
}
|
||||
$data = [];
|
||||
foreach ($bundles as $name => $bundle) {
|
||||
if ($bundle instanceof AssetBundle) {
|
||||
$bundleData = (array) $bundle;
|
||||
if (isset($bundleData['publishOptions']['beforeCopy']) && $bundleData['publishOptions']['beforeCopy'] instanceof \Closure) {
|
||||
$bundleData['publishOptions']['beforeCopy'] = '\Closure';
|
||||
}
|
||||
if (isset($bundleData['publishOptions']['afterCopy']) && $bundleData['publishOptions']['afterCopy'] instanceof \Closure) {
|
||||
$bundleData['publishOptions']['afterCopy'] = '\Closure';
|
||||
}
|
||||
$data[$name] = $bundleData;
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function isEnabled()
|
||||
{
|
||||
try {
|
||||
Yii::$app->view->assetManager;
|
||||
} catch (InvalidConfigException $exception) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Additional formatting for view.
|
||||
*
|
||||
* @param AssetBundle[] $bundles Array of bundles to formatting.
|
||||
*
|
||||
* @return AssetBundle[]
|
||||
*/
|
||||
protected function format(array $bundles)
|
||||
{
|
||||
foreach ($bundles as $bundle) {
|
||||
|
||||
$this->cssCount += count($bundle->css);
|
||||
$this->jsCount += count($bundle->js);
|
||||
|
||||
array_walk($bundle->css, function(&$file, $key, $userdata) {
|
||||
$file = Html::a($file, $userdata->baseUrl . '/' . $file, ['target' => '_blank']);
|
||||
}, $bundle);
|
||||
|
||||
array_walk($bundle->js, function(&$file, $key, $userdata) {
|
||||
$file = Html::a($file, $userdata->baseUrl . '/' . $file, ['target' => '_blank']);
|
||||
}, $bundle);
|
||||
|
||||
array_walk($bundle->depends, function(&$depend) {
|
||||
$depend = Html::a($depend, '#' . $depend);
|
||||
});
|
||||
|
||||
$this->formatOptions($bundle->publishOptions);
|
||||
$this->formatOptions($bundle->jsOptions);
|
||||
$this->formatOptions($bundle->cssOptions);
|
||||
}
|
||||
|
||||
return $bundles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format associative array of params to simple value.
|
||||
*
|
||||
* @param array $params
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function formatOptions(array &$params)
|
||||
{
|
||||
if (!is_array($params)) {
|
||||
return $params;
|
||||
}
|
||||
|
||||
foreach ($params as $param => $value) {
|
||||
$params[$param] = Html::tag('strong', '\'' . $param . '\' => ') . (string) $value;
|
||||
}
|
||||
|
||||
return $params;
|
||||
}
|
||||
}
|
||||
109
vendor/yiisoft/yii2-debug/panels/ConfigPanel.php
vendored
Normal file
109
vendor/yiisoft/yii2-debug/panels/ConfigPanel.php
vendored
Normal file
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\debug\panels;
|
||||
|
||||
use Yii;
|
||||
use yii\debug\Panel;
|
||||
|
||||
/**
|
||||
* Debugger panel that collects and displays application configuration and environment.
|
||||
*
|
||||
* @property array $extensions This property is read-only.
|
||||
* @property array $phpInfo This property is read-only.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class ConfigPanel extends Panel
|
||||
{
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'Configuration';
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getSummary()
|
||||
{
|
||||
return Yii::$app->view->render('panels/config/summary', ['panel' => $this]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getDetail()
|
||||
{
|
||||
return Yii::$app->view->render('panels/config/detail', ['panel' => $this]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns data about extensions
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getExtensions()
|
||||
{
|
||||
$data = [];
|
||||
foreach ($this->data['extensions'] as $extension) {
|
||||
$data[$extension['name']] = $extension['version'];
|
||||
}
|
||||
ksort($data);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the BODY contents of the phpinfo() output
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getPhpInfo()
|
||||
{
|
||||
ob_start();
|
||||
phpinfo();
|
||||
$pinfo = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$phpinfo = preg_replace('%^.*<body>(.*)</body>.*$%ms', '$1', $pinfo);
|
||||
$phpinfo = str_replace('<table', '<div class="table-responsive"><table class="table table-condensed table-bordered table-striped table-hover config-php-info-table" ', $phpinfo);
|
||||
$phpinfo = str_replace('</table>', '</table></div>', $phpinfo);
|
||||
return $phpinfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
return [
|
||||
'phpVersion' => PHP_VERSION,
|
||||
'yiiVersion' => Yii::getVersion(),
|
||||
'application' => [
|
||||
'yii' => Yii::getVersion(),
|
||||
'name' => Yii::$app->name,
|
||||
'version' => Yii::$app->version,
|
||||
'language' => Yii::$app->language,
|
||||
'sourceLanguage' => Yii::$app->sourceLanguage,
|
||||
'charset' => Yii::$app->charset,
|
||||
'env' => YII_ENV,
|
||||
'debug' => YII_DEBUG,
|
||||
],
|
||||
'php' => [
|
||||
'version' => PHP_VERSION,
|
||||
'xdebug' => extension_loaded('xdebug'),
|
||||
'apc' => extension_loaded('apc'),
|
||||
'memcache' => extension_loaded('memcache'),
|
||||
'memcached' => extension_loaded('memcached'),
|
||||
],
|
||||
'extensions' => Yii::$app->extensions,
|
||||
];
|
||||
}
|
||||
}
|
||||
347
vendor/yiisoft/yii2-debug/panels/DbPanel.php
vendored
Normal file
347
vendor/yiisoft/yii2-debug/panels/DbPanel.php
vendored
Normal file
@@ -0,0 +1,347 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\debug\panels;
|
||||
|
||||
use Yii;
|
||||
use yii\base\InvalidConfigException;
|
||||
use yii\debug\Panel;
|
||||
use yii\helpers\ArrayHelper;
|
||||
use yii\log\Logger;
|
||||
use yii\debug\models\search\Db;
|
||||
|
||||
/**
|
||||
* Debugger panel that collects and displays database queries performed.
|
||||
*
|
||||
* @property array $profileLogs This property is read-only.
|
||||
* @property string $summaryName Short name of the panel, which will be use in summary. This property is
|
||||
* read-only.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class DbPanel extends Panel
|
||||
{
|
||||
/**
|
||||
* @var integer the threshold for determining whether the request has involved
|
||||
* critical number of DB queries. If the number of queries exceeds this number,
|
||||
* the execution is considered taking critical number of DB queries.
|
||||
*/
|
||||
public $criticalQueryThreshold;
|
||||
/**
|
||||
* @var string the name of the database component to use for executing (explain) queries
|
||||
*/
|
||||
public $db = 'db';
|
||||
/**
|
||||
* @var array the default ordering of the database queries. In the format of
|
||||
* [ property => sort direction ], for example: [ 'duration' => SORT_DESC ]
|
||||
* @since 2.0.7
|
||||
*/
|
||||
public $defaultOrder = [
|
||||
'seq' => SORT_ASC
|
||||
];
|
||||
/**
|
||||
* @var array the default filter to apply to the database queries. In the format
|
||||
* of [ property => value ], for example: [ 'type' => 'SELECT' ]
|
||||
* @since 2.0.7
|
||||
*/
|
||||
public $defaultFilter = [];
|
||||
|
||||
/**
|
||||
* @var array db queries info extracted to array as models, to use with data provider.
|
||||
*/
|
||||
private $_models;
|
||||
/**
|
||||
* @var array current database request timings
|
||||
*/
|
||||
private $_timings;
|
||||
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
$this->actions['db-explain'] = [
|
||||
'class' => 'yii\\debug\\actions\\db\\ExplainAction',
|
||||
'panel' => $this,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'Database';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string short name of the panel, which will be use in summary.
|
||||
*/
|
||||
public function getSummaryName()
|
||||
{
|
||||
return 'DB';
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getSummary()
|
||||
{
|
||||
$timings = $this->calculateTimings();
|
||||
$queryCount = count($timings);
|
||||
$queryTime = number_format($this->getTotalQueryTime($timings) * 1000) . ' ms';
|
||||
|
||||
return Yii::$app->view->render('panels/db/summary', [
|
||||
'timings' => $this->calculateTimings(),
|
||||
'panel' => $this,
|
||||
'queryCount' => $queryCount,
|
||||
'queryTime' => $queryTime,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getDetail()
|
||||
{
|
||||
$searchModel = new Db();
|
||||
|
||||
if (!$searchModel->load(Yii::$app->request->getQueryParams())) {
|
||||
$searchModel->load($this->defaultFilter, '');
|
||||
}
|
||||
|
||||
$models = $this->getModels();
|
||||
$dataProvider = $searchModel->search($models);
|
||||
$dataProvider->getSort()->defaultOrder = $this->defaultOrder;
|
||||
$sumDuplicates = $this->sumDuplicateQueries($models);
|
||||
|
||||
return Yii::$app->view->render('panels/db/detail', [
|
||||
'panel' => $this,
|
||||
'dataProvider' => $dataProvider,
|
||||
'searchModel' => $searchModel,
|
||||
'hasExplain' => $this->hasExplain(),
|
||||
'sumDuplicates' => $sumDuplicates,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates given request profile timings.
|
||||
*
|
||||
* @return array timings [token, category, timestamp, traces, nesting level, elapsed time]
|
||||
*/
|
||||
public function calculateTimings()
|
||||
{
|
||||
if ($this->_timings === null) {
|
||||
$this->_timings = Yii::getLogger()->calculateTimings(isset($this->data['messages']) ? $this->data['messages'] : []);
|
||||
}
|
||||
|
||||
return $this->_timings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
return ['messages' => $this->getProfileLogs()];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all profile logs of the current request for this panel. It includes categories such as:
|
||||
* 'yii\db\Command::query', 'yii\db\Command::execute'.
|
||||
* @return array
|
||||
*/
|
||||
public function getProfileLogs()
|
||||
{
|
||||
$target = $this->module->logTarget;
|
||||
|
||||
return $target->filterMessages($target->messages, Logger::LEVEL_PROFILE, ['yii\db\Command::query', 'yii\db\Command::execute']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns total query time.
|
||||
*
|
||||
* @param array $timings
|
||||
* @return int total time
|
||||
*/
|
||||
protected function getTotalQueryTime($timings)
|
||||
{
|
||||
$queryTime = 0;
|
||||
|
||||
foreach ($timings as $timing) {
|
||||
$queryTime += $timing['duration'];
|
||||
}
|
||||
|
||||
return $queryTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of models that represents logs of the current request.
|
||||
* Can be used with data providers such as \yii\data\ArrayDataProvider.
|
||||
* @return array models
|
||||
*/
|
||||
protected function getModels()
|
||||
{
|
||||
if ($this->_models === null) {
|
||||
$this->_models = [];
|
||||
$timings = $this->calculateTimings();
|
||||
$duplicates = $this->countDuplicateQuery($timings);
|
||||
|
||||
foreach ($timings as $seq => $dbTiming) {
|
||||
$this->_models[] = [
|
||||
'type' => $this->getQueryType($dbTiming['info']),
|
||||
'query' => $dbTiming['info'],
|
||||
'duration' => ($dbTiming['duration'] * 1000), // in milliseconds
|
||||
'trace' => $dbTiming['trace'],
|
||||
'timestamp' => ($dbTiming['timestamp'] * 1000), // in milliseconds
|
||||
'seq' => $seq,
|
||||
'duplicate' => $duplicates[$dbTiming['info']],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $this->_models;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return associative array, where key is query string
|
||||
* and value is number of occurrences the same query in array.
|
||||
*
|
||||
* @param $timings
|
||||
* @return array
|
||||
* @since 2.0.13
|
||||
*/
|
||||
public function countDuplicateQuery($timings)
|
||||
{
|
||||
$query = ArrayHelper::getColumn($timings, 'info');
|
||||
|
||||
return array_count_values($query);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns sum of all duplicated queries
|
||||
*
|
||||
* @param $modelData
|
||||
* @return int
|
||||
* @since 2.0.13
|
||||
*/
|
||||
public function sumDuplicateQueries($modelData)
|
||||
{
|
||||
$numDuplicates = 0;
|
||||
$duplicates = ArrayHelper::getColumn($modelData, 'duplicate');
|
||||
foreach ($duplicates as $duplicate) {
|
||||
if ($duplicate > 1) {
|
||||
$numDuplicates++;
|
||||
}
|
||||
}
|
||||
|
||||
return $numDuplicates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns database query type.
|
||||
*
|
||||
* @param string $timing timing procedure string
|
||||
* @return string query type such as select, insert, delete, etc.
|
||||
*/
|
||||
protected function getQueryType($timing)
|
||||
{
|
||||
$timing = ltrim($timing);
|
||||
preg_match('/^([a-zA-z]*)/', $timing, $matches);
|
||||
|
||||
return count($matches) ? mb_strtoupper($matches[0], 'utf8') : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if given queries count is critical according settings.
|
||||
*
|
||||
* @param int $count queries count
|
||||
* @return bool
|
||||
*/
|
||||
public function isQueryCountCritical($count)
|
||||
{
|
||||
return (($this->criticalQueryThreshold !== null) && ($count > $this->criticalQueryThreshold));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns array query types
|
||||
*
|
||||
* @return array
|
||||
* @since 2.0.3
|
||||
*/
|
||||
public function getTypes()
|
||||
{
|
||||
return array_reduce(
|
||||
$this->_models,
|
||||
function ($result, $item) {
|
||||
$result[$item['type']] = $item['type'];
|
||||
return $result;
|
||||
},
|
||||
[]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function isEnabled()
|
||||
{
|
||||
try {
|
||||
$this->getDb();
|
||||
} catch (InvalidConfigException $exception) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool Whether the DB component has support for EXPLAIN queries
|
||||
* @since 2.0.5
|
||||
*/
|
||||
protected function hasExplain()
|
||||
{
|
||||
$db = $this->getDb();
|
||||
if (!($db instanceof \yii\db\Connection)) {
|
||||
return false;
|
||||
}
|
||||
switch ($db->getDriverName()) {
|
||||
case 'mysql':
|
||||
case 'sqlite':
|
||||
case 'pgsql':
|
||||
case 'cubrid':
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if given query type can be explained.
|
||||
*
|
||||
* @param string $type query type
|
||||
* @return bool
|
||||
*
|
||||
* @since 2.0.5
|
||||
*/
|
||||
public static function canBeExplained($type)
|
||||
{
|
||||
return $type !== 'SHOW';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to the DB component associated with the panel
|
||||
*
|
||||
* @return \yii\db\Connection
|
||||
* @since 2.0.5
|
||||
*/
|
||||
public function getDb()
|
||||
{
|
||||
return Yii::$app->get($this->db);
|
||||
}
|
||||
}
|
||||
110
vendor/yiisoft/yii2-debug/panels/LogPanel.php
vendored
Normal file
110
vendor/yiisoft/yii2-debug/panels/LogPanel.php
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\debug\panels;
|
||||
|
||||
use Yii;
|
||||
use yii\debug\Panel;
|
||||
use yii\helpers\VarDumper;
|
||||
use yii\log\Logger;
|
||||
use yii\debug\models\search\Log;
|
||||
|
||||
/**
|
||||
* Debugger panel that collects and displays logs.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class LogPanel extends Panel
|
||||
{
|
||||
/**
|
||||
* @var array log messages extracted to array as models, to use with data provider.
|
||||
*/
|
||||
private $_models;
|
||||
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'Logs';
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getSummary()
|
||||
{
|
||||
return Yii::$app->view->render('panels/log/summary', ['data' => $this->data, 'panel' => $this]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getDetail()
|
||||
{
|
||||
$searchModel = new Log();
|
||||
$dataProvider = $searchModel->search(Yii::$app->request->getQueryParams(), $this->getModels());
|
||||
|
||||
return Yii::$app->view->render('panels/log/detail', [
|
||||
'dataProvider' => $dataProvider,
|
||||
'panel' => $this,
|
||||
'searchModel' => $searchModel,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
$target = $this->module->logTarget;
|
||||
$except = [];
|
||||
if (isset($this->module->panels['router'])) {
|
||||
$except = $this->module->panels['router']->getCategories();
|
||||
}
|
||||
$messages = $target->filterMessages($target->messages, Logger::LEVEL_ERROR | Logger::LEVEL_INFO | Logger::LEVEL_WARNING | Logger::LEVEL_TRACE, [], $except);
|
||||
foreach ($messages as &$message) {
|
||||
if (!is_string($message[0])) {
|
||||
// exceptions may not be serializable if in the call stack somewhere is a Closure
|
||||
if ($message[0] instanceof \Throwable || $message[0] instanceof \Exception) {
|
||||
$message[0] = (string) $message[0];
|
||||
} else {
|
||||
$message[0] = VarDumper::export($message[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ['messages' => $messages];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of models that represents logs of the current request.
|
||||
* Can be used with data providers, such as \yii\data\ArrayDataProvider.
|
||||
*
|
||||
* @param bool $refresh if need to build models from log messages and refresh them.
|
||||
* @return array models
|
||||
*/
|
||||
protected function getModels($refresh = false)
|
||||
{
|
||||
if ($this->_models === null || $refresh) {
|
||||
$this->_models = [];
|
||||
|
||||
foreach ($this->data['messages'] as $message) {
|
||||
$this->_models[] = [
|
||||
'message' => $message[0],
|
||||
'level' => $message[1],
|
||||
'category' => $message[2],
|
||||
'time' => $message[3] * 1000, // time in milliseconds
|
||||
'trace' => $message[4]
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $this->_models;
|
||||
}
|
||||
}
|
||||
157
vendor/yiisoft/yii2-debug/panels/MailPanel.php
vendored
Normal file
157
vendor/yiisoft/yii2-debug/panels/MailPanel.php
vendored
Normal file
@@ -0,0 +1,157 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\debug\panels;
|
||||
|
||||
use Yii;
|
||||
use yii\base\Event;
|
||||
use yii\debug\models\search\Mail;
|
||||
use yii\debug\Panel;
|
||||
use yii\mail\BaseMailer;
|
||||
use yii\helpers\FileHelper;
|
||||
use yii\mail\MessageInterface;
|
||||
|
||||
/**
|
||||
* Debugger panel that collects and displays the generated emails.
|
||||
*
|
||||
* @property array $messages Messages. This property is read-only.
|
||||
*
|
||||
* @author Mark Jebri <mark.github@yandex.ru>
|
||||
* @since 2.0
|
||||
*/
|
||||
class MailPanel extends Panel
|
||||
{
|
||||
/**
|
||||
* @var string path where all emails will be saved. should be an alias.
|
||||
*/
|
||||
public $mailPath = '@runtime/debug/mail';
|
||||
|
||||
/**
|
||||
* @var array current request sent messages
|
||||
*/
|
||||
private $_messages = [];
|
||||
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
Event::on(BaseMailer::className(), BaseMailer::EVENT_AFTER_SEND, function ($event) {
|
||||
|
||||
/* @var $message MessageInterface */
|
||||
$message = $event->message;
|
||||
$messageData = [
|
||||
'isSuccessful' => $event->isSuccessful,
|
||||
'from' => $this->convertParams($message->getFrom()),
|
||||
'to' => $this->convertParams($message->getTo()),
|
||||
'reply' => $this->convertParams($message->getReplyTo()),
|
||||
'cc' => $this->convertParams($message->getCc()),
|
||||
'bcc' => $this->convertParams($message->getBcc()),
|
||||
'subject' => $message->getSubject(),
|
||||
'charset' => $message->getCharset(),
|
||||
];
|
||||
|
||||
// add more information when message is a SwiftMailer message
|
||||
if ($message instanceof \yii\swiftmailer\Message) {
|
||||
/* @var $swiftMessage \Swift_Message */
|
||||
$swiftMessage = $message->getSwiftMessage();
|
||||
|
||||
$body = $swiftMessage->getBody();
|
||||
if (empty($body)) {
|
||||
$parts = $swiftMessage->getChildren();
|
||||
foreach ($parts as $part) {
|
||||
if (!($part instanceof \Swift_Mime_Attachment)) {
|
||||
/* @var $part \Swift_Mime_MimePart */
|
||||
if ($part->getContentType() === 'text/plain') {
|
||||
$messageData['charset'] = $part->getCharset();
|
||||
$body = $part->getBody();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$messageData['body'] = $body;
|
||||
$messageData['time'] = $swiftMessage->getDate();
|
||||
$messageData['headers'] = $swiftMessage->getHeaders();
|
||||
|
||||
}
|
||||
|
||||
// store message as file
|
||||
$fileName = $event->sender->generateMessageFileName();
|
||||
FileHelper::createDirectory(Yii::getAlias($this->mailPath));
|
||||
file_put_contents(Yii::getAlias($this->mailPath) . '/' . $fileName, $message->toString());
|
||||
$messageData['file'] = $fileName;
|
||||
|
||||
$this->_messages[] = $messageData;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'Mail';
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getSummary()
|
||||
{
|
||||
return Yii::$app->view->render('panels/mail/summary', ['panel' => $this, 'mailCount' => count($this->data)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getDetail()
|
||||
{
|
||||
$searchModel = new Mail();
|
||||
$dataProvider = $searchModel->search(Yii::$app->request->get(), $this->data);
|
||||
|
||||
return Yii::$app->view->render('panels/mail/detail', [
|
||||
'panel' => $this,
|
||||
'dataProvider' => $dataProvider,
|
||||
'searchModel' => $searchModel
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
return $this->getMessages();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns info about messages of current request. Each element is array holding
|
||||
* message info, such as: time, reply, bc, cc, from, to and other.
|
||||
* @return array messages
|
||||
*/
|
||||
public function getMessages()
|
||||
{
|
||||
return $this->_messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $attr
|
||||
* @return string
|
||||
*/
|
||||
private function convertParams($attr)
|
||||
{
|
||||
if (is_array($attr)) {
|
||||
$attr = implode(', ', array_keys($attr));
|
||||
}
|
||||
|
||||
return $attr;
|
||||
}
|
||||
}
|
||||
104
vendor/yiisoft/yii2-debug/panels/ProfilingPanel.php
vendored
Normal file
104
vendor/yiisoft/yii2-debug/panels/ProfilingPanel.php
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\debug\panels;
|
||||
|
||||
use Yii;
|
||||
use yii\debug\Panel;
|
||||
use yii\log\Logger;
|
||||
use yii\debug\models\search\Profile;
|
||||
|
||||
/**
|
||||
* Debugger panel that collects and displays performance profiling info.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class ProfilingPanel extends Panel
|
||||
{
|
||||
/**
|
||||
* @var array current request profile timings
|
||||
*/
|
||||
private $_models;
|
||||
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'Profiling';
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getSummary()
|
||||
{
|
||||
return Yii::$app->view->render('panels/profile/summary', [
|
||||
'memory' => sprintf('%.3f MB', $this->data['memory'] / 1048576),
|
||||
'time' => number_format($this->data['time'] * 1000) . ' ms',
|
||||
'panel' => $this
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getDetail()
|
||||
{
|
||||
$searchModel = new Profile();
|
||||
$dataProvider = $searchModel->search(Yii::$app->request->getQueryParams(), $this->getModels());
|
||||
|
||||
return Yii::$app->view->render('panels/profile/detail', [
|
||||
'panel' => $this,
|
||||
'dataProvider' => $dataProvider,
|
||||
'searchModel' => $searchModel,
|
||||
'memory' => sprintf('%.3f MB', $this->data['memory'] / 1048576),
|
||||
'time' => number_format($this->data['time'] * 1000) . ' ms',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
$target = $this->module->logTarget;
|
||||
$messages = $target->filterMessages($target->messages, Logger::LEVEL_PROFILE);
|
||||
return [
|
||||
'memory' => memory_get_peak_usage(),
|
||||
'time' => microtime(true) - YII_BEGIN_TIME,
|
||||
'messages' => $messages,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns array of profiling models that can be used in a data provider.
|
||||
* @return array models
|
||||
*/
|
||||
protected function getModels()
|
||||
{
|
||||
if ($this->_models === null) {
|
||||
$this->_models = [];
|
||||
$timings = Yii::getLogger()->calculateTimings(isset($this->data['messages']) ? $this->data['messages'] : []);
|
||||
|
||||
foreach ($timings as $seq => $profileTiming) {
|
||||
$this->_models[] = [
|
||||
'duration' => $profileTiming['duration'] * 1000, // in milliseconds
|
||||
'category' => $profileTiming['category'],
|
||||
'info' => $profileTiming['info'],
|
||||
'level' => $profileTiming['level'],
|
||||
'timestamp' => $profileTiming['timestamp'] * 1000, //in milliseconds
|
||||
'seq' => $seq,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $this->_models;
|
||||
}
|
||||
}
|
||||
148
vendor/yiisoft/yii2-debug/panels/RequestPanel.php
vendored
Normal file
148
vendor/yiisoft/yii2-debug/panels/RequestPanel.php
vendored
Normal file
@@ -0,0 +1,148 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\debug\panels;
|
||||
|
||||
use Yii;
|
||||
use yii\base\InlineAction;
|
||||
use yii\debug\Panel;
|
||||
|
||||
/**
|
||||
* Debugger panel that collects and displays request data.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class RequestPanel extends Panel
|
||||
{
|
||||
/**
|
||||
* @var array list of the PHP predefined variables that are allowed to be displayed in the request panel.
|
||||
* Note that a variable must be accessible via `$GLOBALS`. Otherwise it won't be displayed.
|
||||
* @since 2.0.10
|
||||
*/
|
||||
public $displayVars = ['_SERVER', '_GET', '_POST', '_COOKIE', '_FILES', '_SESSION'];
|
||||
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'Request';
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getSummary()
|
||||
{
|
||||
return Yii::$app->view->render('panels/request/summary', ['panel' => $this]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getDetail()
|
||||
{
|
||||
return Yii::$app->view->render('panels/request/detail', ['panel' => $this]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
$headers = Yii::$app->getRequest()->getHeaders();
|
||||
$requestHeaders = [];
|
||||
foreach ($headers as $name => $value) {
|
||||
if (is_array($value) && count($value) == 1) {
|
||||
$requestHeaders[$name] = current($value);
|
||||
} else {
|
||||
$requestHeaders[$name] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
$responseHeaders = [];
|
||||
foreach (headers_list() as $header) {
|
||||
if (($pos = strpos($header, ':')) !== false) {
|
||||
$name = substr($header, 0, $pos);
|
||||
$value = trim(substr($header, $pos + 1));
|
||||
if (isset($responseHeaders[$name])) {
|
||||
if (!is_array($responseHeaders[$name])) {
|
||||
$responseHeaders[$name] = [$responseHeaders[$name], $value];
|
||||
} else {
|
||||
$responseHeaders[$name][] = $value;
|
||||
}
|
||||
} else {
|
||||
$responseHeaders[$name] = $value;
|
||||
}
|
||||
} else {
|
||||
$responseHeaders[] = $header;
|
||||
}
|
||||
}
|
||||
if (Yii::$app->requestedAction) {
|
||||
if (Yii::$app->requestedAction instanceof InlineAction) {
|
||||
$action = get_class(Yii::$app->requestedAction->controller) . '::' . Yii::$app->requestedAction->actionMethod . '()';
|
||||
} else {
|
||||
$action = get_class(Yii::$app->requestedAction) . '::run()';
|
||||
}
|
||||
} else {
|
||||
$action = null;
|
||||
}
|
||||
|
||||
$data = [
|
||||
'flashes' => $this->getFlashes(),
|
||||
'statusCode' => Yii::$app->getResponse()->getStatusCode(),
|
||||
'requestHeaders' => $requestHeaders,
|
||||
'responseHeaders' => $responseHeaders,
|
||||
'route' => Yii::$app->requestedAction ? Yii::$app->requestedAction->getUniqueId() : Yii::$app->requestedRoute,
|
||||
'action' => $action,
|
||||
'actionParams' => Yii::$app->requestedParams,
|
||||
'general' => [
|
||||
'method' => Yii::$app->getRequest()->getMethod(),
|
||||
'isAjax' => Yii::$app->getRequest()->getIsAjax(),
|
||||
'isPjax' => Yii::$app->getRequest()->getIsPjax(),
|
||||
'isFlash' => Yii::$app->getRequest()->getIsFlash(),
|
||||
'isSecureConnection' => Yii::$app->getRequest()->getIsSecureConnection(),
|
||||
],
|
||||
'requestBody' => Yii::$app->getRequest()->getRawBody() == '' ? [] : [
|
||||
'Content Type' => Yii::$app->getRequest()->getContentType(),
|
||||
'Raw' => Yii::$app->getRequest()->getRawBody(),
|
||||
'Decoded to Params' => Yii::$app->getRequest()->getBodyParams(),
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($this->displayVars as $name) {
|
||||
$data[trim($name, '_')] = empty($GLOBALS[$name]) ? [] : $GLOBALS[$name];
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getting flash messages without deleting them or touching deletion counters
|
||||
*
|
||||
* @return array flash messages (key => message).
|
||||
*/
|
||||
protected function getFlashes()
|
||||
{
|
||||
/* @var $session \yii\web\Session */
|
||||
$session = Yii::$app->has('session', true) ? Yii::$app->get('session') : null;
|
||||
if ($session === null || !$session->getIsActive()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$counters = $session->get($session->flashParam, []);
|
||||
$flashes = [];
|
||||
foreach (array_keys($counters) as $key) {
|
||||
if (array_key_exists($key, $_SESSION)) {
|
||||
$flashes[$key] = $_SESSION[$key];
|
||||
}
|
||||
}
|
||||
return $flashes;
|
||||
}
|
||||
}
|
||||
84
vendor/yiisoft/yii2-debug/panels/RouterPanel.php
vendored
Normal file
84
vendor/yiisoft/yii2-debug/panels/RouterPanel.php
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\debug\panels;
|
||||
|
||||
use Yii;
|
||||
use yii\debug\models\Router;
|
||||
use yii\debug\Panel;
|
||||
use yii\log\Logger;
|
||||
|
||||
/**
|
||||
* RouterPanel provides a panel which displays information about routing process.
|
||||
*
|
||||
* @property array $categories Note that the type of this property differs in getter and setter. See
|
||||
* [[getCategories()]] and [[setCategories()]] for details.
|
||||
*
|
||||
* @author Dmitriy Bashkarev <dmitriy@bashkarev.com>
|
||||
* @since 2.0.8
|
||||
*/
|
||||
class RouterPanel extends Panel
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $_categories = [
|
||||
'yii\web\UrlManager::parseRequest',
|
||||
'yii\web\UrlRule::parseRequest',
|
||||
'yii\web\CompositeUrlRule::parseRequest',
|
||||
'yii\rest\UrlRule::parseRequest'
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* @param string|array $values
|
||||
*/
|
||||
public function setCategories($values)
|
||||
{
|
||||
if (!is_array($values)) {
|
||||
$values = [$values];
|
||||
}
|
||||
$this->_categories = array_merge($this->_categories, $values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens categories of the messages.
|
||||
* @return array
|
||||
*/
|
||||
public function getCategories()
|
||||
{
|
||||
return $this->_categories;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'Router';
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getDetail()
|
||||
{
|
||||
return Yii::$app->view->render('panels/router/detail', ['model' => new Router($this->data)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
$target = $this->module->logTarget;
|
||||
return [
|
||||
'messages' => $target::filterMessages($target->messages, Logger::LEVEL_TRACE, $this->_categories)
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
247
vendor/yiisoft/yii2-debug/panels/TimelinePanel.php
vendored
Normal file
247
vendor/yiisoft/yii2-debug/panels/TimelinePanel.php
vendored
Normal file
@@ -0,0 +1,247 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\debug\panels;
|
||||
|
||||
use Yii;
|
||||
use yii\debug\Panel;
|
||||
use yii\debug\models\timeline\Search;
|
||||
use yii\debug\models\timeline\Svg;
|
||||
use yii\base\InvalidConfigException;
|
||||
|
||||
/**
|
||||
* Debugger panel that collects and displays timeline data.
|
||||
*
|
||||
* @property array $colors
|
||||
* @property float $duration This property is read-only.
|
||||
* @property float $start This property is read-only.
|
||||
* @property array $svgOptions
|
||||
*
|
||||
* @author Dmitriy Bashkarev <dmitriy@bashkarev.com>
|
||||
* @since 2.0.7
|
||||
*/
|
||||
class TimelinePanel extends Panel
|
||||
{
|
||||
/**
|
||||
* @var array Color indicators item profile.
|
||||
*
|
||||
* - keys: percentages of time request
|
||||
* - values: hex color
|
||||
*/
|
||||
private $_colors = [
|
||||
20 => '#1e6823',
|
||||
10 => '#44a340',
|
||||
1 => '#8cc665'
|
||||
];
|
||||
/**
|
||||
* @var array log messages extracted to array as models, to use with data provider.
|
||||
*/
|
||||
private $_models;
|
||||
/**
|
||||
* @var float Start request, timestamp (obtained by microtime(true))
|
||||
*/
|
||||
private $_start;
|
||||
/**
|
||||
* @var float End request, timestamp (obtained by microtime(true))
|
||||
*/
|
||||
private $_end;
|
||||
/**
|
||||
* @var float Request duration, milliseconds
|
||||
*/
|
||||
private $_duration;
|
||||
/**
|
||||
* @var Svg|null
|
||||
*/
|
||||
private $_svg;
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $_svgOptions = [
|
||||
'class' => 'yii\debug\models\timeline\Svg'
|
||||
];
|
||||
/**
|
||||
* @var int Used memory in request
|
||||
*/
|
||||
private $_memory;
|
||||
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
if (!isset($this->module->panels['profiling'])) {
|
||||
throw new InvalidConfigException('Unable to determine the profiling panel');
|
||||
}
|
||||
parent::init();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'Timeline';
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getDetail()
|
||||
{
|
||||
$searchModel = new Search();
|
||||
$dataProvider = $searchModel->search(Yii::$app->request->getQueryParams(), $this);
|
||||
|
||||
return Yii::$app->view->render('panels/timeline/detail', [
|
||||
'panel' => $this,
|
||||
'dataProvider' => $dataProvider,
|
||||
'searchModel' => $searchModel,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function load($data)
|
||||
{
|
||||
if (!isset($data['start']) || empty($data['start'])) {
|
||||
throw new \RuntimeException('Unable to determine request start time');
|
||||
}
|
||||
$this->_start = $data['start'] * 1000;
|
||||
|
||||
if (!isset($data['end']) || empty($data['end'])) {
|
||||
throw new \RuntimeException('Unable to determine request end time');
|
||||
}
|
||||
$this->_end = $data['end'] * 1000;
|
||||
|
||||
if (isset($this->module->panels['profiling']->data['time'])) {
|
||||
$this->_duration = $this->module->panels['profiling']->data['time'] * 1000;
|
||||
} else {
|
||||
$this->_duration = $this->_end - $this->_start;
|
||||
}
|
||||
|
||||
if ($this->_duration <= 0) {
|
||||
throw new \RuntimeException('Duration cannot be zero');
|
||||
}
|
||||
|
||||
if (!isset($data['memory']) || empty($data['memory'])) {
|
||||
throw new \RuntimeException('Unable to determine used memory in request');
|
||||
}
|
||||
$this->_memory = $data['memory'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
return [
|
||||
'start' => YII_BEGIN_TIME,
|
||||
'end' => microtime(true),
|
||||
'memory' => memory_get_peak_usage(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets color indicators.
|
||||
* key: percentages of time request, value: hex color
|
||||
* @param array $colors
|
||||
*/
|
||||
public function setColors($colors)
|
||||
{
|
||||
krsort($colors);
|
||||
$this->_colors = $colors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Color indicators item profile,
|
||||
* key: percentages of time request, value: hex color
|
||||
* @return array
|
||||
*/
|
||||
public function getColors()
|
||||
{
|
||||
return $this->_colors;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $options
|
||||
*/
|
||||
public function setSvgOptions($options)
|
||||
{
|
||||
if ($this->_svg !== null) {
|
||||
$this->_svg = null;
|
||||
}
|
||||
$this->_svgOptions = array_merge($this->_svgOptions, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getSvgOptions()
|
||||
{
|
||||
return $this->_svgOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start request, timestamp (obtained by microtime(true))
|
||||
* @return float
|
||||
*/
|
||||
public function getStart()
|
||||
{
|
||||
return $this->_start;
|
||||
}
|
||||
|
||||
/**
|
||||
* Request duration, milliseconds
|
||||
* @return float
|
||||
*/
|
||||
public function getDuration()
|
||||
{
|
||||
return $this->_duration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Memory peak in request, bytes. (obtained by memory_get_peak_usage())
|
||||
* @return int
|
||||
* @since 2.0.8
|
||||
*/
|
||||
public function getMemory()
|
||||
{
|
||||
return $this->_memory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Svg
|
||||
* @since 2.0.8
|
||||
*/
|
||||
public function getSvg()
|
||||
{
|
||||
if ($this->_svg === null) {
|
||||
$this->_svg = Yii::createObject($this->_svgOptions,[$this]);
|
||||
}
|
||||
return $this->_svg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of models that represents logs of the current request.
|
||||
* Can be used with data providers, such as \yii\data\ArrayDataProvider.
|
||||
*
|
||||
* @param bool $refresh if need to build models from log messages and refresh them.
|
||||
* @return array models
|
||||
*/
|
||||
protected function getModels($refresh = false)
|
||||
{
|
||||
if ($this->_models === null || $refresh) {
|
||||
$this->_models = [];
|
||||
if (isset($this->module->panels['profiling']->data['messages'])) {
|
||||
$this->_models = Yii::getLogger()->calculateTimings($this->module->panels['profiling']->data['messages']);
|
||||
}
|
||||
}
|
||||
return $this->_models;
|
||||
}
|
||||
|
||||
}
|
||||
332
vendor/yiisoft/yii2-debug/panels/UserPanel.php
vendored
Normal file
332
vendor/yiisoft/yii2-debug/panels/UserPanel.php
vendored
Normal file
@@ -0,0 +1,332 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\debug\panels;
|
||||
|
||||
use Yii;
|
||||
use yii\base\Controller;
|
||||
use yii\base\Model;
|
||||
use yii\base\InvalidConfigException;
|
||||
use yii\data\ArrayDataProvider;
|
||||
use yii\data\DataProviderInterface;
|
||||
use yii\db\ActiveRecord;
|
||||
use yii\debug\controllers\UserController;
|
||||
use yii\debug\models\search\UserSearchInterface;
|
||||
use yii\debug\models\UserSwitch;
|
||||
use yii\debug\Panel;
|
||||
use yii\filters\AccessControl;
|
||||
use yii\filters\AccessRule;
|
||||
use yii\helpers\ArrayHelper;
|
||||
use yii\helpers\VarDumper;
|
||||
use yii\web\IdentityInterface;
|
||||
use yii\web\User;
|
||||
|
||||
/**
|
||||
* Debugger panel that collects and displays user data.
|
||||
*
|
||||
* @property DataProviderInterface $userDataProvider This property is read-only.
|
||||
* @property Model|UserSearchInterface $usersFilterModel This property is read-only.
|
||||
*
|
||||
* @author Daniel Gomez Pan <pana_1990@hotmail.com>
|
||||
* @since 2.0.8
|
||||
*/
|
||||
class UserPanel extends Panel
|
||||
{
|
||||
/**
|
||||
* @var array the rule which defines who allowed to switch user identity.
|
||||
* Access Control Filter single rule. Ignore: actions, controllers, verbs.
|
||||
* Settable: allow, roles, ips, matchCallback, denyCallback.
|
||||
* By default deny for everyone. Recommendation: can allow for administrator
|
||||
* or developer (if implement) role: ['allow' => true, 'roles' => ['admin']]
|
||||
* @see http://www.yiiframework.com/doc-2.0/guide-security-authorization.html
|
||||
* @since 2.0.10
|
||||
*/
|
||||
public $ruleUserSwitch = [
|
||||
'allow' => false,
|
||||
];
|
||||
/**
|
||||
* @var UserSwitch object of switching users
|
||||
* @since 2.0.10
|
||||
*/
|
||||
public $userSwitch;
|
||||
/**
|
||||
* @var Model|UserSearchInterface Implements of User model with search method.
|
||||
* @since 2.0.10
|
||||
*/
|
||||
public $filterModel;
|
||||
/**
|
||||
* @var array allowed columns for GridView.
|
||||
* @see http://www.yiiframework.com/doc-2.0/yii-grid-gridview.html#$columns-detail
|
||||
* @since 2.0.10
|
||||
*/
|
||||
public $filterColumns = [];
|
||||
/**
|
||||
* @var string|User ID of the user component or a user object
|
||||
* @since 2.0.13
|
||||
*/
|
||||
public $userComponent = 'user';
|
||||
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
if (
|
||||
!$this->isEnabled()
|
||||
|| $this->getUser()->isGuest
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->userSwitch = new UserSwitch(['userComponent' => $this->userComponent]);
|
||||
$this->addAccesRules();
|
||||
|
||||
if (!is_object($this->filterModel)
|
||||
&& class_exists($this->filterModel)
|
||||
&& in_array('yii\debug\models\search\UserSearchInterface', class_implements($this->filterModel), true)
|
||||
) {
|
||||
$this->filterModel = new $this->filterModel;
|
||||
} elseif ($this->getUser() && $this->getUser()->identityClass) {
|
||||
if (is_subclass_of($this->getUser()->identityClass, ActiveRecord::className())) {
|
||||
$this->filterModel = new \yii\debug\models\search\User();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return User|null
|
||||
* @since 2.0.13
|
||||
*/
|
||||
public function getUser()
|
||||
{
|
||||
/* @var $user User */
|
||||
return is_string($this->userComponent) ? Yii::$app->get($this->userComponent, false) : $this->userComponent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add ACF rule. AccessControl attach to debug module.
|
||||
* Access rule for main user.
|
||||
*/
|
||||
private function addAccesRules()
|
||||
{
|
||||
$this->ruleUserSwitch['controllers'] = [$this->module->id . '/user'];
|
||||
|
||||
$this->module->attachBehavior(
|
||||
'access_debug',
|
||||
[
|
||||
'class' => AccessControl::className(),
|
||||
'only' => [$this->module->id . '/user', $this->module->id . '/default'],
|
||||
'user' => $this->userSwitch->getMainUser(),
|
||||
'rules' => [
|
||||
$this->ruleUserSwitch,
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get model for GridView -> FilterModel
|
||||
* @return Model|UserSearchInterface
|
||||
*/
|
||||
public function getUsersFilterModel()
|
||||
{
|
||||
return $this->filterModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get model for GridView -> DataProvider
|
||||
* @return DataProviderInterface
|
||||
*/
|
||||
public function getUserDataProvider()
|
||||
{
|
||||
return $this->getUsersFilterModel()->search(Yii::$app->request->queryParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check is available search of users
|
||||
* @return bool
|
||||
*/
|
||||
public function canSearchUsers()
|
||||
{
|
||||
return (isset($this->filterModel) &&
|
||||
$this->filterModel instanceof Model &&
|
||||
$this->filterModel->hasMethod('search')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check can main user switch identity.
|
||||
* @return bool
|
||||
*/
|
||||
public function canSwitchUser()
|
||||
{
|
||||
if ($this->getUser()->isGuest) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$allowSwitchUser = false;
|
||||
|
||||
$rule = new AccessRule($this->ruleUserSwitch);
|
||||
|
||||
/** @var Controller $userController */
|
||||
$userController = null;
|
||||
$controller = $this->module->createController('user');
|
||||
if (isset($controller[0]) && $controller[0] instanceof UserController) {
|
||||
$userController = $controller[0];
|
||||
}
|
||||
|
||||
//check by rule
|
||||
if ($userController) {
|
||||
$action = $userController->createAction('set-identity');
|
||||
$user = $this->userSwitch->getMainUser();
|
||||
$request = Yii::$app->request;
|
||||
|
||||
$allowSwitchUser = $rule->allows($action, $user, $request) ?: false;
|
||||
}
|
||||
|
||||
return $allowSwitchUser;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'User';
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getSummary()
|
||||
{
|
||||
return Yii::$app->view->render('panels/user/summary', ['panel' => $this]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getDetail()
|
||||
{
|
||||
return Yii::$app->view->render('panels/user/detail', ['panel' => $this]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
$identity = Yii::$app->user->identity;
|
||||
|
||||
if (!isset($identity)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$rolesProvider = null;
|
||||
$permissionsProvider = null;
|
||||
|
||||
try {
|
||||
$authManager = Yii::$app->getAuthManager();
|
||||
|
||||
if ($authManager instanceof \yii\rbac\ManagerInterface) {
|
||||
$roles = ArrayHelper::toArray($authManager->getRolesByUser($this->getUser()->id));
|
||||
foreach ($roles as &$role) {
|
||||
$role['data'] = $this->dataToString($role['data']);
|
||||
}
|
||||
unset($role);
|
||||
$rolesProvider = new ArrayDataProvider([
|
||||
'allModels' => $roles,
|
||||
]);
|
||||
|
||||
$permissions = ArrayHelper::toArray($authManager->getPermissionsByUser($this->getUser()->id));
|
||||
foreach ($permissions as &$permission) {
|
||||
$permission['data'] = $this->dataToString($permission['data']);
|
||||
}
|
||||
unset($permission);
|
||||
|
||||
$permissionsProvider = new ArrayDataProvider([
|
||||
'allModels' => $permissions,
|
||||
]);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
// ignore auth manager misconfiguration
|
||||
}
|
||||
|
||||
$identityData = $this->identityData($identity);
|
||||
foreach ($identityData as $key => $value) {
|
||||
$identityData[$key] = VarDumper::dumpAsString($value);
|
||||
}
|
||||
|
||||
// If the identity is a model, let it specify the attribute labels
|
||||
if ($identity instanceof Model) {
|
||||
$attributes = [];
|
||||
|
||||
foreach (array_keys($identityData) as $attribute) {
|
||||
$attributes[] = [
|
||||
'attribute' => $attribute,
|
||||
'label' => $identity->getAttributeLabel($attribute),
|
||||
];
|
||||
}
|
||||
} else {
|
||||
// Let the DetailView widget figure the labels out
|
||||
$attributes = null;
|
||||
}
|
||||
|
||||
return [
|
||||
'id' => $identity->getId(),
|
||||
'identity' => $identityData,
|
||||
'attributes' => $attributes,
|
||||
'rolesProvider' => $rolesProvider,
|
||||
'permissionsProvider' => $permissionsProvider,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function isEnabled()
|
||||
{
|
||||
try {
|
||||
$this->getUser();
|
||||
} catch (InvalidConfigException $exception) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts mixed data to string
|
||||
*
|
||||
* @param mixed $data
|
||||
* @return string
|
||||
*/
|
||||
protected function dataToString($data)
|
||||
{
|
||||
if (is_string($data)) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
return VarDumper::export($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the array that should be set on [[\yii\widgets\DetailView::model]]
|
||||
*
|
||||
* @param IdentityInterface $identity
|
||||
* @return array
|
||||
*/
|
||||
protected function identityData($identity)
|
||||
{
|
||||
if ($identity instanceof Model) {
|
||||
return $identity->getAttributes();
|
||||
}
|
||||
|
||||
return get_object_vars($identity);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user