mirror of
https://github.com/yiisoft/yii2.git
synced 2025-08-16 07:11:19 +08:00
Fixes #11462: Added support of filtering rules to yii\log\Target::$logVar
, added \yii\helpers\BaseArrayHelper::filter()
method
This commit is contained in:

committed by
Alexander Makarov

parent
16e4cab8f1
commit
30bb9bd7c8
@ -21,6 +21,8 @@ Yii Framework 2 Change Log
|
|||||||
- Enh #11438: Configurable `yii\helpers\Markdown` default flavor (mdmunir)
|
- Enh #11438: Configurable `yii\helpers\Markdown` default flavor (mdmunir)
|
||||||
- Enh #11729: Added `yii\grid\CheckboxColumn::$cssClass` property to specify a class added to checkbox input (thiagotalma)
|
- Enh #11729: Added `yii\grid\CheckboxColumn::$cssClass` property to specify a class added to checkbox input (thiagotalma)
|
||||||
- Bug #11459: Fixed flash messages not destroyed when `session.auto_start = 1` set in php.ini (cartmanchen)
|
- Bug #11459: Fixed flash messages not destroyed when `session.auto_start = 1` set in php.ini (cartmanchen)
|
||||||
|
- Enh: Added support of filtering rules to `yii\log\Target::$logVar`. (Viktor Pikaev)
|
||||||
|
- Enh: Added `\yii\helpers\BaseArrayHelper::filter()` method. (Viktor Pikaev)
|
||||||
- Bug #11498: Fixed inability to save serialized object into PostgreSQL binary column (klimov-paul)
|
- Bug #11498: Fixed inability to save serialized object into PostgreSQL binary column (klimov-paul)
|
||||||
- Bug #11507: Fixed `yii\validators\EachValidator::validateAttribute()` does not respect `skipOnEmpty` rule parameter (webdevsega)
|
- Bug #11507: Fixed `yii\validators\EachValidator::validateAttribute()` does not respect `skipOnEmpty` rule parameter (webdevsega)
|
||||||
- Bug #11523: Fixed `yii\web\User::checkRedirectAcceptable()` to treat acceptable content type `*/*` as `*` (silverfire)
|
- Bug #11523: Fixed `yii\web\User::checkRedirectAcceptable()` to treat acceptable content type `*/*` as `*` (silverfire)
|
||||||
|
@ -755,4 +755,93 @@ class BaseArrayHelper
|
|||||||
throw new InvalidParamException('Argument $needles must be an array or implement Traversable');
|
throw new InvalidParamException('Argument $needles must be an array or implement Traversable');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filters array by specified rules.
|
||||||
|
*
|
||||||
|
* For example:
|
||||||
|
* ```php
|
||||||
|
* $array = [
|
||||||
|
* 'A' => [1, 2],
|
||||||
|
* 'B' => [
|
||||||
|
* 'C' => 1,
|
||||||
|
* 'D' => 2,
|
||||||
|
* ],
|
||||||
|
* 'E' => 1,
|
||||||
|
* ];
|
||||||
|
*
|
||||||
|
* $result = \yii\helpers\ArrayHelper::filter($array, ['A']);
|
||||||
|
* // $result will be:
|
||||||
|
* // [
|
||||||
|
* // 'A' => [1, 2],
|
||||||
|
* // ]
|
||||||
|
*
|
||||||
|
* $result = \yii\helpers\ArrayHelper::filter($array, ['A', 'B.C']);
|
||||||
|
* // $result will be:
|
||||||
|
* // [
|
||||||
|
* // 'A' => [1, 2],
|
||||||
|
* // 'B' => ['C' => 1],
|
||||||
|
* // ]
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* $result = \yii\helpers\ArrayHelper::filter($array, ['B', '!B.C']);
|
||||||
|
* // $result will be:
|
||||||
|
* // [
|
||||||
|
* // 'B' => ['D' => 2],
|
||||||
|
* // ]
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @param array $array Source array.
|
||||||
|
* @param array $filters List of array keys which should be passed or removed from results.
|
||||||
|
* Each item should contains one of the next rules:
|
||||||
|
* - `var` - `$array['var']` will be passed to result.
|
||||||
|
* - `var.key` = only `$array['var']['key'] will be passed to result.
|
||||||
|
* - `!var.key` = `$array['var']['key'] will be removed from result.
|
||||||
|
* @return array Filtering array
|
||||||
|
*/
|
||||||
|
public static function filter($array, $filters)
|
||||||
|
{
|
||||||
|
$result = [];
|
||||||
|
$forbiddenVars = [];
|
||||||
|
|
||||||
|
foreach ($filters as $var) {
|
||||||
|
$keys = explode('.', $var);
|
||||||
|
$globalKey = $keys[0];
|
||||||
|
$localKey = isset($keys[1]) ? $keys[1] : null;
|
||||||
|
|
||||||
|
if ($globalKey[0] === '!') {
|
||||||
|
$forbiddenVars[] = [
|
||||||
|
substr($globalKey, 1),
|
||||||
|
$localKey,
|
||||||
|
];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($array[$globalKey])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ($localKey === null) {
|
||||||
|
$result[$globalKey] = $array[$globalKey];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!isset($array[$globalKey][$localKey])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!isset($result[$globalKey])) {
|
||||||
|
$result[$globalKey] = [];
|
||||||
|
}
|
||||||
|
$result[$globalKey][$localKey] = $array[$globalKey][$localKey];
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($forbiddenVars as $var) {
|
||||||
|
$globalKey=$var[0];
|
||||||
|
$localKey=$var[1];
|
||||||
|
if (isset($result[$globalKey])) {
|
||||||
|
unset($result[$globalKey][$localKey]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ namespace yii\log;
|
|||||||
use Yii;
|
use Yii;
|
||||||
use yii\base\Component;
|
use yii\base\Component;
|
||||||
use yii\base\InvalidConfigException;
|
use yii\base\InvalidConfigException;
|
||||||
|
use yii\helpers\ArrayHelper;
|
||||||
use yii\helpers\VarDumper;
|
use yii\helpers\VarDumper;
|
||||||
use yii\web\Request;
|
use yii\web\Request;
|
||||||
|
|
||||||
@ -57,6 +58,11 @@ abstract class Target extends Component
|
|||||||
* @var array list of the PHP predefined variables that should be logged in a message.
|
* @var array list of the PHP predefined variables that should be logged in a message.
|
||||||
* Note that a variable must be accessible via `$GLOBALS`. Otherwise it won't be logged.
|
* Note that a variable must be accessible via `$GLOBALS`. Otherwise it won't be logged.
|
||||||
* Defaults to `['_GET', '_POST', '_FILES', '_COOKIE', '_SESSION', '_SERVER']`.
|
* Defaults to `['_GET', '_POST', '_FILES', '_COOKIE', '_SESSION', '_SERVER']`.
|
||||||
|
* Each element should be in one of next forms:
|
||||||
|
* - `var` - `var` will be logged.
|
||||||
|
* - `var.key` - only `var[key]` key will be logged.
|
||||||
|
* - `!var.key` - `var[key]` key will be excluded.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
public $logVars = ['_GET', '_POST', '_FILES', '_COOKIE', '_SESSION', '_SERVER'];
|
public $logVars = ['_GET', '_POST', '_FILES', '_COOKIE', '_SESSION', '_SERVER'];
|
||||||
/**
|
/**
|
||||||
@ -122,14 +128,12 @@ abstract class Target extends Component
|
|||||||
*/
|
*/
|
||||||
protected function getContextMessage()
|
protected function getContextMessage()
|
||||||
{
|
{
|
||||||
$context = [];
|
$context = ArrayHelper::filter($GLOBALS,$this->logVars);
|
||||||
foreach ($this->logVars as $name) {
|
$result = [];
|
||||||
if (!empty($GLOBALS[$name])) {
|
foreach ($context as $key => $value) {
|
||||||
$context[] = "\${$name} = " . VarDumper::dumpAsString($GLOBALS[$name]);
|
$result[] = "\${$key} = " . VarDumper::dumpAsString($value);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return implode("\n\n", $result);
|
||||||
return implode("\n\n", $context);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -778,5 +778,44 @@ class ArrayHelperTest extends TestCase
|
|||||||
$this->assertFalse(ArrayHelper::isTraversable(null));
|
$this->assertFalse(ArrayHelper::isTraversable(null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testFilter()
|
||||||
|
{
|
||||||
|
$array = [
|
||||||
|
'A' => [
|
||||||
|
'B' => 1,
|
||||||
|
'C' => 2,
|
||||||
|
],
|
||||||
|
'G' => 1,
|
||||||
|
];
|
||||||
|
$this->assertEquals(ArrayHelper::filter($array, ['A']), [
|
||||||
|
'A' => [
|
||||||
|
'B' => 1,
|
||||||
|
'C' => 2,
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
$this->assertEquals(ArrayHelper::filter($array, ['A.B']), [
|
||||||
|
'A' => [
|
||||||
|
'B' => 1,
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
$this->assertEquals(ArrayHelper::filter($array, ['A', '!A.B']), [
|
||||||
|
'A' => [
|
||||||
|
'C' => 2,
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
$this->assertEquals(ArrayHelper::filter($array, ['!A.B', 'A']), [
|
||||||
|
'A' => [
|
||||||
|
'C' => 2,
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
$this->assertEquals(ArrayHelper::filter($array, ['A', 'G']), [
|
||||||
|
'A' => [
|
||||||
|
'B' => 1,
|
||||||
|
'C' => 2,
|
||||||
|
],
|
||||||
|
'G' => 1,
|
||||||
|
]);
|
||||||
|
$this->assertEquals(ArrayHelper::filter($array, ['X']), []);
|
||||||
|
$this->assertEquals(ArrayHelper::filter($array, ['X.Y']), []);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,6 +75,54 @@ class TargetTest extends TestCase
|
|||||||
$this->assertEquals('test' . $e, static::$messages[$i++][0]);
|
$this->assertEquals('test' . $e, static::$messages[$i++][0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testGetContextMessage()
|
||||||
|
{
|
||||||
|
$target = new TestTarget([
|
||||||
|
'logVars' => [
|
||||||
|
'A', '!A.A_b', 'A.A_d',
|
||||||
|
'B.B_a',
|
||||||
|
'C', 'C.C_a',
|
||||||
|
'D',
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
$GLOBALS['A'] = [
|
||||||
|
'A_a' => 1,
|
||||||
|
'A_b' => 1,
|
||||||
|
'A_c' => 1,
|
||||||
|
];
|
||||||
|
$GLOBALS['B'] = [
|
||||||
|
'B_a' => 1,
|
||||||
|
'B_b' => 1,
|
||||||
|
'B_c' => 1,
|
||||||
|
];
|
||||||
|
$GLOBALS['C'] = [
|
||||||
|
'C_a' => 1,
|
||||||
|
'C_b' => 1,
|
||||||
|
'C_c' => 1,
|
||||||
|
];
|
||||||
|
$GLOBALS['E'] = [
|
||||||
|
'C_a' => 1,
|
||||||
|
'C_b' => 1,
|
||||||
|
'C_c' => 1,
|
||||||
|
];
|
||||||
|
$context = $target->getContextMessage();
|
||||||
|
$this->assertContains('A_a', $context);
|
||||||
|
$this->assertNotContains('A_b', $context);
|
||||||
|
$this->assertContains('A_c', $context);
|
||||||
|
$this->assertContains('B_a', $context);
|
||||||
|
$this->assertNotContains('B_b', $context);
|
||||||
|
$this->assertNotContains('B_c', $context);
|
||||||
|
$this->assertContains('C_a', $context);
|
||||||
|
$this->assertContains('C_b', $context);
|
||||||
|
$this->assertContains('C_c', $context);
|
||||||
|
$this->assertNotContains('D_a', $context);
|
||||||
|
$this->assertNotContains('D_b', $context);
|
||||||
|
$this->assertNotContains('D_c', $context);
|
||||||
|
$this->assertNotContains('E_a', $context);
|
||||||
|
$this->assertNotContains('E_b', $context);
|
||||||
|
$this->assertNotContains('E_c', $context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TestTarget extends Target
|
class TestTarget extends Target
|
||||||
@ -90,4 +138,12 @@ class TestTarget extends Target
|
|||||||
TargetTest::$messages = array_merge(TargetTest::$messages, $this->messages);
|
TargetTest::$messages = array_merge(TargetTest::$messages, $this->messages);
|
||||||
$this->messages = [];
|
$this->messages = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function getContextMessage()
|
||||||
|
{
|
||||||
|
return parent::getContextMessage();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user