Skip to content
This repository has been archived by the owner on Jan 30, 2020. It is now read-only.

Commit

Permalink
Merge branch 'feature/zendframework/zendframework#6058-timestamp-log-…
Browse files Browse the repository at this point in the history
…filter' into develop

Close zendframework/zendframework#6058
  • Loading branch information
Ocramius committed May 3, 2014
5 parents 31f2348 + db2794e + 6fca41f + b652dfb + 717a493 commit eda5e97
Show file tree
Hide file tree
Showing 2 changed files with 287 additions and 0 deletions.
126 changes: 126 additions & 0 deletions src/Filter/Timestamp.php
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
);
}
}
161 changes: 161 additions & 0 deletions test/Filter/TimestampTest.php
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)),
);
}
}

0 comments on commit eda5e97

Please # to comment.