2017-08-01 16:22:43 +01:00
< ? php
/*
* This file is part of the Symfony package .
*
* ( c ) Fabien Potencier < fabien @ symfony . com >
*
* For the full copyright and license information , please view the LICENSE
* file that was distributed with this source code .
*/
namespace Symfony\Component\Serializer\Normalizer ;
use Symfony\Component\Serializer\Exception\InvalidArgumentException ;
use Symfony\Component\Serializer\Exception\UnexpectedValueException ;
/**
* Normalizes an instance of { @ see \DateInterval } to an interval string .
* Denormalizes an interval string to an instance of { @ see \DateInterval } .
*
* @ author Jérôme Parmentier < jerome @ prmntr . me >
*/
2018-04-27 13:29:13 +01:00
class DateIntervalNormalizer implements NormalizerInterface , DenormalizerInterface , CacheableSupportsMethodInterface
2017-08-01 16:22:43 +01:00
{
const FORMAT_KEY = 'dateinterval_format' ;
2019-01-16 20:35:37 +00:00
private $defaultContext = [
2018-10-03 16:09:15 +01:00
self :: FORMAT_KEY => 'P%yY%mM%dDT%hH%iM%sS' ,
2019-01-16 20:35:37 +00:00
];
2017-08-01 16:22:43 +01:00
2018-10-03 16:09:15 +01:00
/**
* @ param array $defaultContext
*/
2019-01-16 20:35:37 +00:00
public function __construct ( $defaultContext = [])
2017-08-01 16:22:43 +01:00
{
2018-10-03 16:09:15 +01:00
if ( ! \is_array ( $defaultContext )) {
@ trigger_error ( sprintf ( 'The "format" parameter is deprecated since Symfony 4.2, use the "%s" key of the context instead.' , self :: FORMAT_KEY ), E_USER_DEPRECATED );
2019-01-16 20:35:37 +00:00
$defaultContext = [ self :: FORMAT_KEY => ( string ) $defaultContext ];
2018-10-03 16:09:15 +01:00
}
$this -> defaultContext = array_merge ( $this -> defaultContext , $defaultContext );
2017-08-01 16:22:43 +01:00
}
/**
* { @ inheritdoc }
*
* @ throws InvalidArgumentException
*/
2019-01-16 09:39:14 +00:00
public function normalize ( $object , $format = null , array $context = [])
2017-08-01 16:22:43 +01:00
{
if ( ! $object instanceof \DateInterval ) {
throw new InvalidArgumentException ( 'The object must be an instance of "\DateInterval".' );
}
2018-10-03 16:09:15 +01:00
return $object -> format ( $context [ self :: FORMAT_KEY ] ? ? $this -> defaultContext [ self :: FORMAT_KEY ]);
2017-08-01 16:22:43 +01:00
}
/**
* { @ inheritdoc }
*/
public function supportsNormalization ( $data , $format = null )
{
return $data instanceof \DateInterval ;
}
2018-04-30 22:41:10 +01:00
/**
* { @ inheritdoc }
*/
public function hasCacheableSupportsMethod () : bool
{
return __CLASS__ === \get_class ( $this );
}
2017-08-01 16:22:43 +01:00
/**
* { @ inheritdoc }
*
* @ throws InvalidArgumentException
* @ throws UnexpectedValueException
*/
2019-01-16 09:39:14 +00:00
public function denormalize ( $data , $class , $format = null , array $context = [])
2017-08-01 16:22:43 +01:00
{
2018-07-26 09:45:46 +01:00
if ( ! \is_string ( $data )) {
throw new InvalidArgumentException ( sprintf ( 'Data expected to be a string, %s given.' , \gettype ( $data )));
2017-08-01 16:22:43 +01:00
}
if ( ! $this -> isISO8601 ( $data )) {
throw new UnexpectedValueException ( 'Expected a valid ISO 8601 interval string.' );
}
2018-10-03 16:09:15 +01:00
$dateIntervalFormat = $context [ self :: FORMAT_KEY ] ? ? $this -> defaultContext [ self :: FORMAT_KEY ];
2017-08-01 16:22:43 +01:00
$valuePattern = '/^' . preg_replace ( '/%([yYmMdDhHiIsSwW])(\w)/' , '(?P<$1>\d+)$2' , $dateIntervalFormat ) . '$/' ;
if ( ! preg_match ( $valuePattern , $data )) {
throw new UnexpectedValueException ( sprintf ( 'Value "%s" contains intervals not accepted by format "%s".' , $data , $dateIntervalFormat ));
}
try {
return new \DateInterval ( $data );
} catch ( \Exception $e ) {
throw new UnexpectedValueException ( $e -> getMessage (), $e -> getCode (), $e );
}
}
/**
* { @ inheritdoc }
*/
public function supportsDenormalization ( $data , $type , $format = null )
{
return \DateInterval :: class === $type ;
}
private function isISO8601 ( $string )
{
return preg_match ( '/^P(?=\w*(?:\d|%\w))(?:\d+Y|%[yY]Y)?(?:\d+M|%[mM]M)?(?:(?:\d+D|%[dD]D)|(?:\d+W|%[wW]W))?(?:T(?:\d+H|[hH]H)?(?:\d+M|[iI]M)?(?:\d+S|[sS]S)?)?$/' , $string );
}
}