This repository has been archived by the owner on Jan 30, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 51
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'feature/zendframework/zendframework#6058-timestamp-log-…
…filter' into develop Close zendframework/zendframework#6058
- Loading branch information
Showing
2 changed files
with
287 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
<?php | ||
/** | ||
* Zend Framework (http://framework.zend.com/) | ||
* | ||
* @link http://github.com/zendframework/zf2 for the canonical source repository | ||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com) | ||
* @license http://framework.zend.com/license/new-bsd New BSD License | ||
*/ | ||
|
||
namespace Zend\Log\Filter; | ||
|
||
use DateTime; | ||
use Traversable; | ||
use Zend\Log\Exception; | ||
use Zend\Stdlib\ArrayUtils; | ||
|
||
/** | ||
* Filters log events based on the time when they were triggered. | ||
* | ||
* @author Nikola Posa <posa.nikola@gmail.com> | ||
*/ | ||
class Timestamp implements FilterInterface | ||
{ | ||
/** | ||
* DateTime instance or desired value based on $dateFormatChar. | ||
* | ||
* @var int|DateTime | ||
*/ | ||
protected $value; | ||
|
||
/** | ||
* PHP idate()-compliant format character. | ||
* | ||
* @var string|null | ||
*/ | ||
protected $dateFormatChar; | ||
|
||
/** | ||
* @var string | ||
*/ | ||
protected $operator; | ||
|
||
/** | ||
* @param int|DateTime|array|Traversable $value DateTime instance or desired value based on $dateFormatChar | ||
* @param string $dateFormatChar PHP idate()-compliant format character | ||
* @param string $operator Comparison operator | ||
* @return Timestamp | ||
* @throws Exception\InvalidArgumentException | ||
*/ | ||
public function __construct($value, $dateFormatChar = null, $operator = '<=') | ||
{ | ||
if ($value instanceof Traversable) { | ||
$value = ArrayUtils::iteratorToArray($value); | ||
} | ||
|
||
if (is_array($value)) { | ||
$dateFormatChar = isset($value['dateFormatChar']) ? $value['dateFormatChar'] : null; | ||
$operator = isset($value['operator']) ? $value['operator'] : null; | ||
$value = isset($value['value']) ? $value['value'] : null; | ||
} | ||
|
||
if ($value instanceof DateTime) { | ||
$this->value = $value; | ||
} else { | ||
if (!is_int($value)) { | ||
throw new Exception\InvalidArgumentException(sprintf( | ||
'Value must be either DateTime instance or integer; received "%s"', | ||
gettype($value) | ||
)); | ||
} | ||
if (!is_string($dateFormatChar)) { | ||
throw new Exception\InvalidArgumentException(sprintf( | ||
'Date format character must be supplied as string; received "%s"', | ||
gettype($dateFormatChar) | ||
)); | ||
} | ||
|
||
$this->value = $value; | ||
$this->dateFormatChar = $dateFormatChar; | ||
} | ||
|
||
if ($operator === null) { | ||
$operator = '<='; | ||
} elseif (!in_array( | ||
$operator, | ||
array('<', 'lt', '<=', 'le', '>', 'gt', '>=', 'ge', '==', '=', 'eq', '!=', '<>') | ||
)) { | ||
throw new Exception\InvalidArgumentException( | ||
"Unsupported comparison operator: '$operator'" | ||
); | ||
} | ||
|
||
$this->operator = $operator; | ||
} | ||
|
||
/** | ||
* Returns TRUE if timestamp is accepted, otherwise FALSE is returned. | ||
* | ||
* @param array $event event data | ||
* @return bool | ||
*/ | ||
public function filter(array $event) | ||
{ | ||
if (! isset($event['timestamp'])) { | ||
return false; | ||
} | ||
|
||
$datetime = $event['timestamp']; | ||
|
||
if (! ($datetime instanceof DateTime || is_int($datetime) || is_string($datetime))) { | ||
return false; | ||
} | ||
|
||
$timestamp = $datetime instanceof DateTime ? $datetime->getTimestamp() : (int) $datetime; | ||
|
||
if ($this->value instanceof DateTime) { | ||
return version_compare($timestamp, $this->value->getTimestamp(), $this->operator); | ||
} | ||
|
||
return version_compare( | ||
idate($this->dateFormatChar, $timestamp), | ||
$this->value, | ||
$this->operator | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
<?php | ||
/** | ||
* Zend Framework (http://framework.zend.com/) | ||
* | ||
* @link http://github.com/zendframework/zf2 for the canonical source repository | ||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com) | ||
* @license http://framework.zend.com/license/new-bsd New BSD License | ||
*/ | ||
|
||
namespace ZendTest\Log\Filter; | ||
|
||
use ArrayObject; | ||
use DateTime; | ||
use PHPUnit_Framework_TestCase as TestCase; | ||
use Zend\Log\Filter\Timestamp as TimestampFilter; | ||
|
||
/** | ||
* @author Nikola Posa <posa.nikola@gmail.com> | ||
* | ||
* @covers \Zend\Log\Filter\Timestamp | ||
*/ | ||
class TimestampTest extends TestCase | ||
{ | ||
/** | ||
* @dataProvider dateTimeDataProvider | ||
*/ | ||
public function testComparisonWhenValueIsSuppliedAsDateTimeObject($timestamp, $dateTimeValue, $operator, $expectation) | ||
{ | ||
$filter = new TimestampFilter($dateTimeValue, null, $operator); | ||
|
||
$result = $filter->filter(array('timestamp' => $timestamp)); | ||
|
||
if ($expectation === true) { | ||
$this->assertTrue($result); | ||
} else { | ||
$this->assertFalse($result); | ||
} | ||
} | ||
|
||
/** | ||
* @dataProvider datePartDataProvider | ||
*/ | ||
public function testComparisonWhenValueIsSuppliedAsDatePartValue($timestamp, $datePartVal, $datePartChar, $operator, $expectation) | ||
{ | ||
$filter = new TimestampFilter($datePartVal, $datePartChar, $operator); | ||
|
||
$result = $filter->filter(array('timestamp' => $timestamp)); | ||
|
||
if ($expectation === true) { | ||
$this->assertTrue($result); | ||
} else { | ||
$this->assertFalse($result); | ||
} | ||
} | ||
|
||
/** | ||
* @expectedException \Zend\Log\Exception\InvalidArgumentException | ||
*/ | ||
public function testConstructorThrowsOnInvalidValue() | ||
{ | ||
new TimestampFilter('foo'); | ||
} | ||
|
||
/** | ||
* @expectedException \Zend\Log\Exception\InvalidArgumentException | ||
*/ | ||
public function testConstructorThrowsWhenDateFormatCharIsMissing() | ||
{ | ||
new TimestampFilter(3); | ||
} | ||
|
||
/** | ||
* @expectedException \Zend\Log\Exception\InvalidArgumentException | ||
*/ | ||
public function testConstructorThrowsOnUnsupportedComparisonOperator() | ||
{ | ||
new TimestampFilter(10, 'H', 'foobar'); | ||
} | ||
|
||
public function testFilterCreatedFromArray() | ||
{ | ||
$config = array( | ||
'value' => 10, | ||
'dateFormatChar' => 'm', | ||
'operator' => '==', | ||
); | ||
$filter = new TimestampFilter($config); | ||
|
||
$this->assertAttributeEquals($config['value'], 'value', $filter); | ||
$this->assertAttributeEquals($config['dateFormatChar'], 'dateFormatChar', $filter); | ||
$this->assertAttributeEquals($config['operator'], 'operator', $filter); | ||
} | ||
|
||
public function testFilterCreatedFromTraversable() | ||
{ | ||
$config = new ArrayObject(array( | ||
'value' => 10, | ||
'dateFormatChar' => 'm', | ||
'operator' => '==', | ||
)); | ||
$filter = new TimestampFilter($config); | ||
|
||
$this->assertAttributeEquals($config['value'], 'value', $filter); | ||
$this->assertAttributeEquals($config['dateFormatChar'], 'dateFormatChar', $filter); | ||
$this->assertAttributeEquals($config['operator'], 'operator', $filter); | ||
} | ||
|
||
/** | ||
* @param array $message | ||
* | ||
* @dataProvider ignoredMessages | ||
*/ | ||
public function testIgnoresMessagesWithoutTimestamp(array $message) | ||
{ | ||
$filter = new TimestampFilter(new DateTime('-10 years')); | ||
|
||
$this->assertFalse($filter->filter($message)); | ||
} | ||
|
||
public function dateTimeDataProvider() | ||
{ | ||
$march2 = new DateTime('2014-03-02'); | ||
$march3 = new DateTime('2014-03-03'); | ||
|
||
return array( | ||
array(new DateTime('2014-03-03'), new DateTime('2014-03-03'), '>=', true), | ||
array(new DateTime('2014-10-10'), new DateTime('2014-03-03'),'>=', true), | ||
array(new DateTime('2014-03-03'), new DateTime('2014-10-10'), 'gt', false), | ||
array(new DateTime('2013-03-03'), new DateTime('2014-03-03'), 'ge', false), | ||
array(new DateTime('2014-03-03'), new DateTime('2014-03-03'), '==', true), | ||
array(new DateTime('2014-02-02'), new DateTime('2014-03-03'), '<', true), | ||
array(new DateTime('2014-03-03'), new DateTime('2014-03-03'), 'lt', false), | ||
array($march3->getTimestamp(), new DateTime('2014-03-03'), 'lt', false), | ||
array($march2->getTimestamp(), new DateTime('2014-03-03'), 'lt', true), | ||
array((string) $march3->getTimestamp(), new DateTime('2014-03-03'), 'lt', false), | ||
array((string) $march2->getTimestamp(), new DateTime('2014-03-03'), 'lt', true), | ||
); | ||
} | ||
|
||
public function datePartDataProvider() | ||
{ | ||
return array( | ||
array(new DateTime('2014-03-03 10:15:00'), 10, 'H', '==', true), | ||
array(new DateTime('2013-03-03 22:00:00'), 10, 'H', '=', false), | ||
array(new DateTime('2014-03-04 10:15:00'), 3, 'd', 'gt', true), | ||
array(new DateTime('2014-03-04 10:15:00'), 10, 'd', '<', true), | ||
array(new DateTime('2014-03-03 10:15:00'), 1, 'm', 'eq', false), | ||
array(new DateTime('2014-03-03 10:15:00'), 2, 'm', 'ge', true), | ||
array(new DateTime('2014-03-03 10:15:00'), 20, 'H', '!=', true), | ||
); | ||
} | ||
|
||
public function ignoredMessages() | ||
{ | ||
return array( | ||
array(array()), | ||
array(array('hello world')), | ||
array(array('timestamp' => null)), | ||
); | ||
} | ||
} |