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

Commit

Permalink
Merge branch 'hotfix/log-formatter' into releases/2.0.1
Browse files Browse the repository at this point in the history
  • Loading branch information
Show file tree
Hide file tree
Showing 4 changed files with 263 additions and 98 deletions.
114 changes: 114 additions & 0 deletions src/Formatter/Base.php
@@ -0,0 +1,114 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @package Zend_Log
*/

namespace Zend\Log\Formatter;

use DateTime;
use Traversable;
use Zend\Log\Exception;

/**
* @category Zend
* @package Zend_Log
* @subpackage Formatter
*/
class Base implements FormatterInterface
{
/**
* Format specifier for DateTime objects in event data (default: ISO 8601)
*
* @see http://php.net/manual/en/function.date.php
* @var string
*/
protected $dateTimeFormat = self::DEFAULT_DATETIME_FORMAT;

/**
* Class constructor
*
* @see http://php.net/manual/en/function.date.php
* @param null|string $dateTimeFormat Format for DateTime objects
*/
public function __construct($dateTimeFormat = null)
{
if (null !== $dateTimeFormat) {
$this->dateTimeFormat = $dateTimeFormat;
}
}

/**
* Formats data to be written by the writer.
*
* @param array $event event data
* @return array
*/
public function format($event)
{
foreach ($event as $key => $value) {
// Keep extra as an array
if ('extra' === $key) {
$event[$key] = self::format($value);
} else {
$event[$key] = $this->normalize($value);
}
}

return $event;
}

/**
* Normalize all non-scalar data types (except null) in a string value
*
* @param mixed $value
* @return mixed
*/
protected function normalize($value)
{
if (is_scalar($value) || null === $value) {
return $value;
}

if ($value instanceof DateTime) {
$value = $value->format($this->getDateTimeFormat());
} elseif (is_array($value) || $value instanceof Traversable) {
if ($value instanceof Traversable) {
$value = iterator_to_array($value);
}
foreach ($value as $key => $subvalue) {
$value[$key] = $this->normalize($subvalue);
}
$value = json_encode($value);
} elseif (is_object($value) && !method_exists($value,'__toString')) {
$value = sprintf('object(%s) %s', get_class($value), json_encode($value));
} elseif (is_resource($value)) {
$value = sprintf('resource(%s)', get_resource_type($value));
} elseif (!is_object($value)) {
$value = gettype($value);
}

return (string) $value;
}

/**
* {@inheritDoc}
*/
public function getDateTimeFormat()
{
return $this->dateTimeFormat;
}

/**
* {@inheritDoc}
*/
public function setDateTimeFormat($dateTimeFormat)
{
$this->dateTimeFormat = (string) $dateTimeFormat;
return $this;
}
}
57 changes: 14 additions & 43 deletions src/Formatter/Simple.php
Expand Up @@ -18,9 +18,9 @@
* @package Zend_Log
* @subpackage Formatter
*/
class Simple implements FormatterInterface
class Simple extends Base
{
const DEFAULT_FORMAT = '%timestamp% %priorityName% (%priority%): %message% %info%';
const DEFAULT_FORMAT = '%timestamp% %priorityName% (%priority%): %message% %extra%';

/**
* Format specifier for log messages
Expand All @@ -29,14 +29,6 @@ class Simple implements FormatterInterface
*/
protected $format;

/**
* Format specifier for DateTime objects in event data (default: ISO 8601)
*
* @see http://php.net/manual/en/function.date.php
* @var string
*/
protected $dateTimeFormat = self::DEFAULT_DATETIME_FORMAT;

/**
* Class constructor
*
Expand All @@ -53,9 +45,7 @@ public function __construct($format = null, $dateTimeFormat = null)

$this->format = isset($format) ? $format : static::DEFAULT_FORMAT;

if (isset($dateTimeFormat)) {
$this->dateTimeFormat = $dateTimeFormat;
}
parent::__construct($dateTimeFormat);
}

/**
Expand All @@ -68,41 +58,22 @@ public function format($event)
{
$output = $this->format;

if (!isset($event['info'])) {
$event['info'] = '';
}

if (isset($event['timestamp']) && $event['timestamp'] instanceof DateTime) {
$event['timestamp'] = $event['timestamp']->format($this->getDateTimeFormat());
}

$event = parent::format($event);
foreach ($event as $name => $value) {
if ((is_object($value) && !method_exists($value,'__toString'))
|| is_array($value)
) {
$value = gettype($value);
if ('extra' == $name && count($value)) {
$value = $this->normalize($value);
} elseif ('extra' == $name) {
// Don't print an empty array
$value = '';
}

$output = str_replace("%$name%", $value, $output);
}

if (isset($event['extra']) && empty($event['extra'])
&& false !== strpos($this->format, '%extra%')
) {
$output = rtrim($output, ' ');
}
return $output;
}

/**
* {@inheritDoc}
*/
public function getDateTimeFormat()
{
return $this->dateTimeFormat;
}

/**
* {@inheritDoc}
*/
public function setDateTimeFormat($dateTimeFormat)
{
$this->dateTimeFormat = (string) $dateTimeFormat;
return $this;
}
}
113 changes: 113 additions & 0 deletions test/Formatter/BaseTest.php
@@ -0,0 +1,113 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @package Zend_Log
*/

namespace ZendTest\Log\Formatter;

use DateTime;
use stdClass;
use EmptyIterator;
use ArrayIterator;
use ZendTest\Log\TestAsset\StringObject;
use Zend\Log\Formatter\Base as BaseFormatter;

/**
* @category Zend
* @package Zend_Log
* @subpackage UnitTests
* @group Zend_Log
*/
class BaseTest extends \PHPUnit_Framework_TestCase
{
public function testDefaultDateTimeFormat()
{
$formatter = new BaseFormatter();
$this->assertEquals(BaseFormatter::DEFAULT_DATETIME_FORMAT, $formatter->getDateTimeFormat());
}

/**
* @dataProvider provideDateTimeFormats
*/
public function testAllowsSpecifyingDateTimeFormatAsConstructorArgument($dateTimeFormat)
{
$formatter = new BaseFormatter($dateTimeFormat);

$this->assertEquals($dateTimeFormat, $formatter->getDateTimeFormat());
}

/**
* @return array
*/
public function provideDateTimeFormats()
{
return array(
array('r'),
array('U'),
array(DateTime::RSS),
);
}

/**
* @dataProvider provideDateTimeFormats
*/
public function testSetDateTimeFormat($dateTimeFormat)
{
$formatter = new BaseFormatter();
$formatter->setDateTimeFormat($dateTimeFormat);

$this->assertEquals($dateTimeFormat, $formatter->getDateTimeFormat());
}

public function testFormatAllTypes()
{
$datetime = new DateTime();
$object = new stdClass();
$object->foo = 'bar';
$formatter = new BaseFormatter();

$event = array(
'timestamp' => $datetime,
'priority' => 1,
'message' => 'tottakai',
'extra' => array(
'float' => 0.2,
'boolean' => false,
'array_empty' => array(),
'array' => range(0, 4),
'traversable_empty' => new EmptyIterator(),
'traversable' => new ArrayIterator(array('id', 42)),
'null' => null,
'object_empty' => new stdClass(),
'object' => $object,
'string object' => new StringObject(),
'resource' => fopen('php://stdout', 'w'),
),
);
$outputExpected = array(
'timestamp' => $datetime->format($formatter->getDateTimeFormat()),
'priority' => 1,
'message' => 'tottakai',
'extra' => array(
'boolean' => false,
'float' => 0.2,
'array_empty' => '[]',
'array' => '[0,1,2,3,4]',
'traversable_empty' => '[]',
'traversable' => '["id",42]',
'null' => null,
'object_empty' => 'object(stdClass) {}',
'object' => 'object(stdClass) {"foo":"bar"}',
'string object' => 'Hello World',
'resource' => 'resource(stream)',
),
);

$this->assertEquals($outputExpected, $formatter->format($event));
}
}

0 comments on commit f66ca80

Please sign in to comment.