This commit is contained in:
cutemeli
2025-12-22 10:35:30 +00:00
parent 0bfc6c8425
commit 5ce7ca2c5d
38927 changed files with 0 additions and 4594700 deletions

View File

@@ -1,144 +0,0 @@
# Changelog
## [2.3.0](https://github.com/schmittjoh/metadata/tree/2.3.0) (2020-06-06)
**Merged pull requests:**
- Allow PSR-11 container [\#92](https://github.com/schmittjoh/metadata/pull/92) ([goetas](https://github.com/goetas))
## [2.2.0](https://github.com/schmittjoh/metadata/tree/2.2.0) (2020-05-31)
**Merged pull requests:**
- Add cache support for anonymous classes \(\#79\) [\#90](https://github.com/schmittjoh/metadata/pull/90) ([goetas](https://github.com/goetas))
- Merge 1.x [\#91](https://github.com/schmittjoh/metadata/pull/91) ([goetas](https://github.com/goetas))
- add .gitattributes [\#86](https://github.com/schmittjoh/metadata/pull/86) ([Tobion](https://github.com/Tobion))
- Test enhancement [\#84](https://github.com/schmittjoh/metadata/pull/84) ([peter279k](https://github.com/peter279k))
- Improve cache error message [\#80](https://github.com/schmittjoh/metadata/pull/80) ([thePanz](https://github.com/thePanz))
## [2.1.0](https://github.com/schmittjoh/metadata/tree/2.1.0) (2019-09-17)
**Merged pull requests:**
- make sure we only use the cache if write was successful [\#82](https://github.com/schmittjoh/metadata/pull/82) ([dbu](https://github.com/dbu))
- Handle errors when restoring from cache [\#81](https://github.com/schmittjoh/metadata/pull/81) ([dbu](https://github.com/dbu))
- Do not create MethodMetadata::$reflection on constructor/unserialize,… [\#78](https://github.com/schmittjoh/metadata/pull/78) ([ThomasNunninger](https://github.com/ThomasNunninger))
## [2.0.0](https://github.com/schmittjoh/metadata/tree/2.0.0) (2018-11-09)
No changes from **2.0.0-RC1**
## [1.7.0](https://github.com/schmittjoh/metadata/tree/1.7.0) (2018-10-26)
**Merged pull requests:**
- Allow Read-only Cache [\#74](https://github.com/schmittjoh/metadata/pull/74) ([goetas](https://github.com/goetas))
## [2.0.0-RC1](https://github.com/schmittjoh/metadata/tree/2.0.0-RC1) (2018-10-17)
**Merged pull requests:**
- Moved to psr-4 [\#73](https://github.com/schmittjoh/metadata/pull/73) ([samnela](https://github.com/samnela))
## [2.0.0-beta1](https://github.com/schmittjoh/metadata/tree/2.0.0-beta1) (2018-09-12)
**Closed issues:**
- Read-Only Filesystem Support [\#71](https://github.com/schmittjoh/metadata/issues/71)
- Change license to MIT [\#68](https://github.com/schmittjoh/metadata/issues/68)
- Composer.lock is out of date [\#55](https://github.com/schmittjoh/metadata/issues/55)
- consider changing chmod to @chmod [\#50](https://github.com/schmittjoh/metadata/issues/50)
- Big performance hit when upgrading from 1.4.2 to 1.5.0 [\#44](https://github.com/schmittjoh/metadata/issues/44)
- metadata name not present leads to exception [\#39](https://github.com/schmittjoh/metadata/issues/39)
**Merged pull requests:**
- Allow Read-only Cache [\#72](https://github.com/schmittjoh/metadata/pull/72) ([pdugas](https://github.com/pdugas))
- Code style [\#70](https://github.com/schmittjoh/metadata/pull/70) ([goetas](https://github.com/goetas))
- Change license to MIT [\#69](https://github.com/schmittjoh/metadata/pull/69) ([goetas](https://github.com/goetas))
- simplified class metadata [\#67](https://github.com/schmittjoh/metadata/pull/67) ([goetas](https://github.com/goetas))
- Fix an exception message [\#65](https://github.com/schmittjoh/metadata/pull/65) ([hason](https://github.com/hason))
- Actualized version constant. [\#64](https://github.com/schmittjoh/metadata/pull/64) ([Aliance](https://github.com/Aliance))
## [1.6.0](https://github.com/schmittjoh/metadata/tree/1.6.0) (2016-12-05)
**Closed issues:**
- Consider switching to the MIT/BSD license or a dual license otherwise [\#58](https://github.com/schmittjoh/metadata/issues/58)
- Unexpected return value [\#52](https://github.com/schmittjoh/metadata/issues/52)
- Why 0666 mode for cache file [\#48](https://github.com/schmittjoh/metadata/issues/48)
- Tons of I/O operations caused by NullMetadata [\#45](https://github.com/schmittjoh/metadata/issues/45)
**Merged pull requests:**
- Add PsrCacheAdapter [\#63](https://github.com/schmittjoh/metadata/pull/63) ([nicolas-grekas](https://github.com/nicolas-grekas))
- 50 suspress chmod warning [\#53](https://github.com/schmittjoh/metadata/pull/53) ([gusdecool](https://github.com/gusdecool))
- Adaption for complying with SPDX identifiers [\#51](https://github.com/schmittjoh/metadata/pull/51) ([valioDOTch](https://github.com/valioDOTch))
## [1.5.1](https://github.com/schmittjoh/metadata/tree/1.5.1) (2014-07-12)
**Merged pull requests:**
- Added more PHP versions and HHVM [\#47](https://github.com/schmittjoh/metadata/pull/47) ([Nyholm](https://github.com/Nyholm))
- Fix NullMetadata performance issue [\#46](https://github.com/schmittjoh/metadata/pull/46) ([adrienbrault](https://github.com/adrienbrault))
- Fixed logic bug. [\#41](https://github.com/schmittjoh/metadata/pull/41) ([flip111](https://github.com/flip111))
- Update FileCache.php added fallback option when rename fails on windows [\#40](https://github.com/schmittjoh/metadata/pull/40) ([flip111](https://github.com/flip111))
## [1.5.0](https://github.com/schmittjoh/metadata/tree/1.5.0) (2013-11-05)
**Closed issues:**
- Branch alias [\#38](https://github.com/schmittjoh/metadata/issues/38)
**Merged pull requests:**
- Don't make MetadataFactory final [\#37](https://github.com/schmittjoh/metadata/pull/37) ([bakura10](https://github.com/bakura10))
- Cache when there is no metadata for a class [\#36](https://github.com/schmittjoh/metadata/pull/36) ([adrienbrault](https://github.com/adrienbrault))
- Allow to add drivers to a driver chain [\#35](https://github.com/schmittjoh/metadata/pull/35) ([bakura10](https://github.com/bakura10))
## [1.4.2](https://github.com/schmittjoh/metadata/tree/1.4.2) (2013-09-13)
**Closed issues:**
- Update changelog [\#33](https://github.com/schmittjoh/metadata/issues/33)
- Error in Symfony2's production environment \(only\) caused with version \>= 1.4.0 [\#32](https://github.com/schmittjoh/metadata/issues/32)
**Merged pull requests:**
- Set cache files to be world readable [\#34](https://github.com/schmittjoh/metadata/pull/34) ([tommygnr](https://github.com/tommygnr))
## [1.4.1](https://github.com/schmittjoh/metadata/tree/1.4.1) (2013-08-27)
## [1.4.0](https://github.com/schmittjoh/metadata/tree/1.4.0) (2013-08-25)
## [1.3.0](https://github.com/schmittjoh/metadata/tree/1.3.0) (2013-01-22)
**Closed issues:**
- Ability to eager-load possible metadata [\#19](https://github.com/schmittjoh/metadata/issues/19)
**Merged pull requests:**
- misc cleanup [\#23](https://github.com/schmittjoh/metadata/pull/23) ([vicb](https://github.com/vicb))
- \[Cache\] Remove a race condition [\#22](https://github.com/schmittjoh/metadata/pull/22) ([vicb](https://github.com/vicb))
- Added configs for ci services [\#21](https://github.com/schmittjoh/metadata/pull/21) ([j](https://github.com/j))
- Advanced metadata implementation. [\#20](https://github.com/schmittjoh/metadata/pull/20) ([j](https://github.com/j))
- Remove incorrect docblocks [\#18](https://github.com/schmittjoh/metadata/pull/18) ([adrienbrault](https://github.com/adrienbrault))
## [1.2.0-RC](https://github.com/schmittjoh/metadata/tree/1.2.0-RC) (2012-08-21)
**Closed issues:**
- install version 1.0.0 with composer [\#9](https://github.com/schmittjoh/metadata/issues/9)
- create version/tag 1.1.1 [\#3](https://github.com/schmittjoh/metadata/issues/3)
**Merged pull requests:**
- Added the branch alias and changed the constraint on common [\#8](https://github.com/schmittjoh/metadata/pull/8) ([stof](https://github.com/stof))
- Add trait test [\#6](https://github.com/schmittjoh/metadata/pull/6) ([Seldaek](https://github.com/Seldaek))
- Fix locating files for classes without namespace [\#5](https://github.com/schmittjoh/metadata/pull/5) ([Seldaek](https://github.com/Seldaek))
- Add ApcCache [\#4](https://github.com/schmittjoh/metadata/pull/4) ([henrikbjorn](https://github.com/henrikbjorn))
## [1.1.1](https://github.com/schmittjoh/metadata/tree/1.1.1) (2012-01-02)
**Closed issues:**
- More documentation requested [\#1](https://github.com/schmittjoh/metadata/issues/1)
**Merged pull requests:**
- Add composer.json [\#2](https://github.com/schmittjoh/metadata/pull/2) ([Seldaek](https://github.com/Seldaek))
## [1.1.0](https://github.com/schmittjoh/metadata/tree/1.1.0) (2011-10-04)
## [1.0.0](https://github.com/schmittjoh/metadata/tree/1.0.0) (2011-07-09)
\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*

View File

@@ -1,44 +0,0 @@
# Contribute
Thank you for contributing!
Before we can merge your Pull-Request here are some guidelines that you need to follow.
These guidelines exist not to annoy you, but to keep the code base clean, unified and future proof.
## Coding Standard
This project uses [PHP_CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer) to enforce coding standards.
The coding standard rules are defined in the **phpcs.xml.dist** file (part of this repository).
The project follows a relaxed version of the Doctrine Coding standards v4.
Your Pull-Request must be compliant with the said standard.
To check your code you can run `vendor/bin/phpcs`. This command will give you a list of violations in your code (if any).
The most common errors can be automatically fixed just by running `vendor/bin/phpcbf`.
## Unit-Tests
Please try to add a test for your pull-request. This project uses [PHPUnit](https://phpunit.de/) as testing framework.
You can run the unit-tests by calling `vendor/bin/phpunit`.
New features without tests can't be merged.
## CI
We automatically run your pull request through [Travis CI](https://www.travis-ci.org)
and [Scrutinizer CI](https://scrutinizer-ci.com/).
If you break the tests, we cannot merge your code,
so please make sure that your code is working before opening up a Pull-Request.
## Issues and Bugs
To create a new issue, you can use the GitHub issue tracking system.
Please try to avoid opening support-related tickets. For support related questions please use more appropriate
channels as Q&A platforms (such as Stackoverflow), Forums, Local PHP user groups.
## Getting merged
Please allow us time to review your pull requests.
We will give our best to review everything as fast as possible, but cannot always live up to our own expectations.
Thank you very much again for your contribution!

View File

@@ -1,19 +0,0 @@
Copyright (c) 2018 Johannes M. Schmitt
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1,55 +0,0 @@
Metadata is a library for class/method/property metadata management in PHP
==========================================================================
| [Master (2.x)][Master] | [1.x][1.x] |
|:----------------:|:----------:|
| [![Build status][Master image]][Master] | [![Build status][1.x image]][1.x] |
| [![Coverage Status][Master coverage image]][Master coverage] | [![Coverage Status][1.x coverage image]][1.x coverage] |
Overview
--------
This library provides some commonly needed base classes for managing metadata
for classes, methods and properties. The metadata can come from many different
sources (annotations, YAML/XML/PHP configuration files).
The metadata classes are used to abstract away that source and provide a common
interface for all of them.
Usage
-----
The library provides three classes that you can extend to add your application
specific properties, and flags: ``ClassMetadata``, ``MethodMetadata``, and
``PropertyMetadata``
After you have added, your properties in sub-classes, you also need to add
``DriverInterface`` implementations which know how to populate these classes
from the different metadata sources.
Finally, you can use the ``MetadataFactory`` to retrieve the metadata::
```php
<?php
use Metadata\MetadataFactory;
use Metadata\Driver\DriverChain;
$driver = new DriverChain(array(
/** Annotation, YAML, XML, PHP, ... drivers */
));
$factory = new MetadataFactory($driver);
$metadata = $factory->getMetadataForClass('MyNamespace\MyObject');
```
[Master image]: https://img.shields.io/travis/schmittjoh/metadata/master.svg?style=flat-square
[Master]: https://travis-ci.org/schmittjoh/metadata
[Master coverage image]: https://img.shields.io/scrutinizer/coverage/g/schmittjoh/metadata/master.svg?style=flat-square
[Master coverage]: https://scrutinizer-ci.com/g/schmittjoh/metadata/?branch=master
[1.x image]: https://img.shields.io/travis/schmittjoh/metadata/1.x.svg?style=flat-square
[1.x]: https://github.com/schmittjoh/metadata/tree/1.x
[1.x coverage image]: https://img.shields.io/scrutinizer/coverage/g/schmittjoh/metadata/1.x.svg?style=flat-square
[1.x coverage]: https://scrutinizer-ci.com/g/schmittjoh/metadata/?branch=1.x

View File

@@ -1,62 +0,0 @@
From 2.2.3 to 2.3.0
====================
- The `\Serializable` PHP interface is deprecated, the methods of this interface will be removed in 3.0.
This change is done to allow the use of the new `__serialize` and `__unserialize` PHP's strategy.
If you were extending the metadata classes, your custom serialization methods were looking probably as something as this:
```php
class MyMetadata extends PropertyMetadata
{
// ... more code
public function serialize()
{
$data = parent::serialize();
return \serialize([$data, $this->customMetadataProp]);
}
public function unserialize($str)
{
list($str, $this->customMetadataProp) = \unserialize($str);
parent::unserialize($str);
}
}
```
After this change, your code should look like this:
```php
class MyMetadata extends PropertyMetadata
{
// ... more code
protected function serializeToArray(): array
{
$data = parent::serializeToArray();
return [$data, $this->customMetadataProp];
}
protected function unserializeFromArray(array $data): void
{
list($data, $this->customMetadataProp) = $data;
parent::unserializeFromArray($data);
}
}
```
From 1.7.0 to 2.0.0
====================
- Type-hinting everywhere where allowed by PHP 7.2 and strict types are used now
- `Metadata\Cache\CacheInterface` changed, methods have different names and signature; all the classes implementing
that interface have been modified accordingly
- `getValue` and `setValue` methods have been removed from `Metadata\PropertyMetadata`, getting/setting properties is not
responsibility of this library anymore
- the `$reflection` property has been removed from `Metadata\PropertyMetadata`;
metadata information do not require (and do not offer) reflection anymore

View File

@@ -1,45 +0,0 @@
{
"name": "jms/metadata",
"description": "Class/method/property metadata management in PHP",
"keywords": ["annotations","metadata","yaml","xml"],
"type": "library",
"license": "MIT",
"authors": [
{
"name": "Johannes M. Schmitt",
"email": "schmittjoh@gmail.com"
},
{
"name": "Asmir Mustafic",
"email": "goetas@gmail.com"
}
],
"require": {
"php": "^7.2|^8.0"
},
"require-dev" : {
"doctrine/cache" : "^1.0",
"doctrine/coding-standard": "^8.0",
"phpunit/phpunit": "^8.5|^9.0",
"psr/container": "^1.0|^2.0",
"symfony/cache" : "^3.1|^4.0|^5.0",
"symfony/dependency-injection" : "^3.1|^4.0|^5.0",
"mikey179/vfsstream": "^1.6.7"
},
"autoload": {
"psr-4": { "Metadata\\": "src/" }
},
"autoload-dev": {
"psr-4": { "Metadata\\Tests\\": "tests/" }
},
"extra": {
"branch-alias": {
"dev-master": "2.x-dev"
}
},
"config": {
"allow-plugins": {
"dealerdirect/phpcodesniffer-composer-installer": true
}
}
}

View File

@@ -1,23 +0,0 @@
<?php
declare(strict_types=1);
namespace Metadata;
/**
* Interface for advanced Metadata Factory implementations.
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
* @author Jordan Stout <j@jrdn.org>
*/
interface AdvancedMetadataFactoryInterface extends MetadataFactoryInterface
{
/**
* Gets all the possible classes.
*
* @return string[]
*
* @throws \RuntimeException When driver does not an advanced driver.
*/
public function getAllClassNames(): array;
}

View File

@@ -1,25 +0,0 @@
<?php
declare(strict_types=1);
namespace Metadata\Cache;
use Metadata\ClassMetadata;
interface CacheInterface
{
/**
* Loads a class metadata instance from the cache
*/
public function load(string $class): ?ClassMetadata;
/**
* Puts a class metadata instance into the cache
*/
public function put(ClassMetadata $metadata): void;
/**
* Evicts the class metadata for the given class from the cache.
*/
public function evict(string $class): void;
}

View File

@@ -1,16 +0,0 @@
<?php
declare(strict_types=1);
namespace Metadata\Cache;
/**
* @author Alexander Strizhak <gam6itko@gmail.com>
*/
interface ClearableCacheInterface
{
/**
* Clear all classes metadata from the cache.
*/
public function clear(): bool;
}

View File

@@ -1,55 +0,0 @@
<?php
declare(strict_types=1);
namespace Metadata\Cache;
use Doctrine\Common\Cache\Cache;
use Metadata\ClassMetadata;
/**
* @author Henrik Bjornskov <henrik@bjrnskov.dk>
*/
class DoctrineCacheAdapter implements CacheInterface, ClearableCacheInterface
{
/**
* @var string
*/
private $prefix;
/**
* @var Cache
*/
private $cache;
public function __construct(string $prefix, Cache $cache)
{
$this->prefix = $prefix;
$this->cache = $cache;
}
public function load(string $class): ?ClassMetadata
{
$cache = $this->cache->fetch($this->prefix . $class);
return false === $cache ? null : $cache;
}
public function put(ClassMetadata $metadata): void
{
$this->cache->save($this->prefix . $metadata->name, $metadata);
}
public function evict(string $class): void
{
$this->cache->delete($this->prefix . $class);
}
public function clear(): bool
{
if (method_exists($this->cache, 'deleteAll')) { // or $this->cache instanceof ClearableCache
return call_user_func([$this->cache, 'deleteAll']);
}
return false;
}
}

View File

@@ -1,134 +0,0 @@
<?php
declare(strict_types=1);
namespace Metadata\Cache;
use Metadata\ClassMetadata;
class FileCache implements CacheInterface, ClearableCacheInterface
{
/**
* @var string
*/
private $dir;
public function __construct(string $dir)
{
if (!is_dir($dir) && false === @mkdir($dir, 0777, true)) {
throw new \InvalidArgumentException(sprintf('Can\'t create directory for cache at "%s"', $dir));
}
$this->dir = rtrim($dir, '\\/');
}
public function load(string $class): ?ClassMetadata
{
$path = $this->getCachePath($class);
if (!is_readable($path)) {
return null;
}
try {
$metadata = include $path;
if ($metadata instanceof ClassMetadata) {
return $metadata;
}
// if the file does not return anything, the return value is integer `1`.
} catch (\Error $e) {
// ignore corrupted cache
}
return null;
}
public function put(ClassMetadata $metadata): void
{
if (!is_writable($this->dir)) {
throw new \InvalidArgumentException(sprintf('The directory "%s" is not writable.', $this->dir));
}
$path = $this->getCachePath($metadata->name);
if (!is_writable(dirname($path))) {
throw new \RuntimeException(sprintf('Cache file "%s" is not writable.', $path));
}
$tmpFile = tempnam($this->dir, 'metadata-cache');
if (false === $tmpFile) {
$this->evict($metadata->name);
return;
}
$data = '<?php return unserialize(' . var_export(serialize($metadata), true) . ');';
$bytesWritten = file_put_contents($tmpFile, $data);
// use strlen and not mb_strlen. if there is utf8 in the code, it also writes more bytes.
if ($bytesWritten !== strlen($data)) {
@unlink($tmpFile);
// also evict the cache to not use an outdated version.
$this->evict($metadata->name);
return;
}
// Let's not break filesystems which do not support chmod.
@chmod($tmpFile, 0666 & ~umask());
$this->renameFile($tmpFile, $path);
}
/**
* Renames a file with fallback for windows
*/
private function renameFile(string $source, string $target): void
{
if (false === @rename($source, $target)) {
if (defined('PHP_WINDOWS_VERSION_BUILD')) {
if (false === copy($source, $target)) {
throw new \RuntimeException(sprintf('(WIN) Could not write new cache file to %s.', $target));
}
if (false === unlink($source)) {
throw new \RuntimeException(sprintf('(WIN) Could not delete temp cache file to %s.', $source));
}
} else {
throw new \RuntimeException(sprintf('Could not write new cache file to %s.', $target));
}
}
}
public function evict(string $class): void
{
$path = $this->getCachePath($class);
if (file_exists($path)) {
@unlink($path);
}
}
public function clear(): bool
{
$result = true;
$files = glob($this->dir . '/*.cache.php');
foreach ($files as $file) {
if (is_file($file)) {
$result = $result && @unlink($file);
}
}
return $result;
}
/**
* This function computes the cache file path.
*
* If anonymous class is to be cached, it contains invalid path characters that need to be removed/replaced
* Example of anonymous class name: class@anonymous\x00/app/src/Controller/DefaultController.php0x7f82a7e026ec
*/
private function getCachePath(string $key): string
{
$fileName = str_replace(['\\', "\0", '@', '/', '$', '{', '}', ':'], '-', $key);
return $this->dir . '/' . $fileName . '.cache.php';
}
}

View File

@@ -1,69 +0,0 @@
<?php
declare(strict_types=1);
namespace Metadata\Cache;
use Metadata\ClassMetadata;
use Psr\Cache\CacheItemPoolInterface;
class PsrCacheAdapter implements CacheInterface, ClearableCacheInterface
{
/**
* @var string
*/
private $prefix;
/**
* @var CacheItemPoolInterface
*/
private $pool;
/**
* @var CacheItemPoolInterface
*/
private $lastItem;
public function __construct(string $prefix, CacheItemPoolInterface $pool)
{
$this->prefix = $prefix;
$this->pool = $pool;
}
public function load(string $class): ?ClassMetadata
{
$this->lastItem = $this->pool->getItem($this->sanitizeCacheKey($this->prefix . $class));
return $this->lastItem->get();
}
public function put(ClassMetadata $metadata): void
{
$key = $this->sanitizeCacheKey($this->prefix . $metadata->name);
if (null === $this->lastItem || $this->lastItem->getKey() !== $key) {
$this->lastItem = $this->pool->getItem($key);
}
$this->pool->save($this->lastItem->set($metadata));
}
public function evict(string $class): void
{
$this->pool->deleteItem($this->sanitizeCacheKey($this->prefix . $class));
}
public function clear(): bool
{
return $this->pool->clear();
}
/**
* If anonymous class is to be cached, it contains invalid path characters that need to be removed/replaced
* Example of anonymous class name: class@anonymous\x00/app/src/Controller/DefaultController.php0x7f82a7e026ec
*/
private function sanitizeCacheKey(string $key): string
{
return str_replace(['\\', "\0", '@', '/', '$', '{', '}', ':'], '-', $key);
}
}

View File

@@ -1,44 +0,0 @@
<?php
declare(strict_types=1);
namespace Metadata;
/**
* Represents the metadata for the entire class hierarchy.
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
class ClassHierarchyMetadata
{
/**
* @var ClassMetadata[]
*/
public $classMetadata = [];
public function addClassMetadata(ClassMetadata $metadata): void
{
$this->classMetadata[$metadata->name] = $metadata;
}
public function getRootClassMetadata(): ?ClassMetadata
{
return reset($this->classMetadata);
}
public function getOutsideClassMetadata(): ?ClassMetadata
{
return end($this->classMetadata);
}
public function isFresh(int $timestamp): bool
{
foreach ($this->classMetadata as $metadata) {
if (!$metadata->isFresh($timestamp)) {
return false;
}
}
return true;
}
}

View File

@@ -1,100 +0,0 @@
<?php
declare(strict_types=1);
namespace Metadata;
/**
* Base class for class metadata.
*
* This class is intended to be extended to add your own application specific
* properties, and flags.
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
class ClassMetadata implements \Serializable
{
use SerializationHelper;
/**
* @var string
*/
public $name;
/**
* @var MethodMetadata[]
*/
public $methodMetadata = [];
/**
* @var PropertyMetadata[]
*/
public $propertyMetadata = [];
/**
* @var string[]
*/
public $fileResources = [];
/**
* @var int
*/
public $createdAt;
public function __construct(string $name)
{
$this->name = $name;
$this->createdAt = time();
}
public function addMethodMetadata(MethodMetadata $metadata): void
{
$this->methodMetadata[$metadata->name] = $metadata;
}
public function addPropertyMetadata(PropertyMetadata $metadata): void
{
$this->propertyMetadata[$metadata->name] = $metadata;
}
public function isFresh(?int $timestamp = null): bool
{
if (null === $timestamp) {
$timestamp = $this->createdAt;
}
foreach ($this->fileResources as $filepath) {
if (!file_exists($filepath)) {
return false;
}
if ($timestamp < filemtime($filepath)) {
return false;
}
}
return true;
}
protected function serializeToArray(): array
{
return [
$this->name,
$this->methodMetadata,
$this->propertyMetadata,
$this->fileResources,
$this->createdAt,
];
}
protected function unserializeFromArray(array $data): void
{
[
$this->name,
$this->methodMetadata,
$this->propertyMetadata,
$this->fileResources,
$this->createdAt,
] = $data;
}
}

View File

@@ -1,56 +0,0 @@
<?php
declare(strict_types=1);
namespace Metadata\Driver;
use Metadata\ClassMetadata;
/**
* Base file driver implementation.
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
abstract class AbstractFileDriver implements AdvancedDriverInterface
{
/**
* @var FileLocatorInterface|FileLocator
*/
private $locator;
public function __construct(FileLocatorInterface $locator)
{
$this->locator = $locator;
}
public function loadMetadataForClass(\ReflectionClass $class): ?ClassMetadata
{
if (null === $path = $this->locator->findFileForClass($class, $this->getExtension())) {
return null;
}
return $this->loadMetadataFromFile($class, $path);
}
/**
* {@inheritDoc}
*/
public function getAllClassNames(): array
{
if (!$this->locator instanceof AdvancedFileLocatorInterface) {
throw new \RuntimeException(sprintf('Locator "%s" must be an instance of "AdvancedFileLocatorInterface".', get_class($this->locator)));
}
return $this->locator->findAllClasses($this->getExtension());
}
/**
* Parses the content of the file, and converts it to the desired metadata.
*/
abstract protected function loadMetadataFromFile(\ReflectionClass $class, string $file): ?ClassMetadata;
/**
* Returns the extension of the file.
*/
abstract protected function getExtension(): string;
}

View File

@@ -1,20 +0,0 @@
<?php
declare(strict_types=1);
namespace Metadata\Driver;
/**
* Forces advanced logic to drivers.
*
* @author Jordan Stout <j@jrdn.org>
*/
interface AdvancedDriverInterface extends DriverInterface
{
/**
* Gets all the metadata class names known to this driver.
*
* @return string[]
*/
public function getAllClassNames(): array;
}

View File

@@ -1,20 +0,0 @@
<?php
declare(strict_types=1);
namespace Metadata\Driver;
/**
* Forces advanced logic on a file locator.
*
* @author Jordan Stout <j@jrdn.org>
*/
interface AdvancedFileLocatorInterface extends FileLocatorInterface
{
/**
* Finds all possible metadata files.*
*
* @return string[]
*/
public function findAllClasses(string $extension): array;
}

View File

@@ -1,65 +0,0 @@
<?php
declare(strict_types=1);
namespace Metadata\Driver;
use Metadata\ClassMetadata;
final class DriverChain implements AdvancedDriverInterface
{
/**
* @var DriverInterface[]
*/
private $drivers;
/**
* @param DriverInterface[] $drivers
*/
public function __construct(array $drivers = [])
{
$this->drivers = $drivers;
}
public function addDriver(DriverInterface $driver): void
{
$this->drivers[] = $driver;
}
public function loadMetadataForClass(\ReflectionClass $class): ?ClassMetadata
{
foreach ($this->drivers as $driver) {
if (null !== $metadata = $driver->loadMetadataForClass($class)) {
return $metadata;
}
}
return null;
}
/**
* {@inheritDoc}
*/
public function getAllClassNames(): array
{
$classes = [];
foreach ($this->drivers as $driver) {
if (!$driver instanceof AdvancedDriverInterface) {
throw new \RuntimeException(
sprintf(
'Driver "%s" must be an instance of "AdvancedDriverInterface" to use ' .
'"DriverChain::getAllClassNames()".',
get_class($driver)
)
);
}
$driverClasses = $driver->getAllClassNames();
if (!empty($driverClasses)) {
$classes = array_merge($classes, $driverClasses);
}
}
return $classes;
}
}

View File

@@ -1,12 +0,0 @@
<?php
declare(strict_types=1);
namespace Metadata\Driver;
use Metadata\ClassMetadata;
interface DriverInterface
{
public function loadMetadataForClass(\ReflectionClass $class): ?ClassMetadata;
}

View File

@@ -1,80 +0,0 @@
<?php
declare(strict_types=1);
namespace Metadata\Driver;
class FileLocator implements AdvancedFileLocatorInterface, TraceableFileLocatorInterface
{
/**
* @var string[]
*/
private $dirs;
/**
* @param string[] $dirs
*/
public function __construct(array $dirs)
{
$this->dirs = $dirs;
}
/**
* @return array<string, bool>
*/
public function getPossibleFilesForClass(\ReflectionClass $class, string $extension): array
{
$possibleFiles = [];
foreach ($this->dirs as $prefix => $dir) {
if ('' !== $prefix && 0 !== strpos($class->getNamespaceName(), $prefix)) {
continue;
}
$len = '' === $prefix ? 0 : strlen($prefix) + 1;
$path = $dir . '/' . str_replace('\\', '.', substr($class->name, $len)) . '.' . $extension;
$existsPath = file_exists($path);
$possibleFiles[$path] = $existsPath;
if ($existsPath) {
return $possibleFiles;
}
}
return $possibleFiles;
}
public function findFileForClass(\ReflectionClass $class, string $extension): ?string
{
foreach ($this->getPossibleFilesForClass($class, $extension) as $path => $existsPath) {
if ($existsPath) {
return $path;
}
}
return null;
}
/**
* {@inheritDoc}
*/
public function findAllClasses(string $extension): array
{
$classes = [];
foreach ($this->dirs as $prefix => $dir) {
/** @var \RecursiveIteratorIterator|\SplFileInfo[] $iterator */
$iterator = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($dir),
\RecursiveIteratorIterator::LEAVES_ONLY
);
$nsPrefix = '' !== $prefix ? $prefix . '\\' : '';
foreach ($iterator as $file) {
if (($fileName = $file->getBasename('.' . $extension)) === $file->getBasename()) {
continue;
}
$classes[] = $nsPrefix . str_replace('.', '\\', $fileName);
}
}
return $classes;
}
}

View File

@@ -1,10 +0,0 @@
<?php
declare(strict_types=1);
namespace Metadata\Driver;
interface FileLocatorInterface
{
public function findFileForClass(\ReflectionClass $class, string $extension): ?string;
}

View File

@@ -1,40 +0,0 @@
<?php
declare(strict_types=1);
namespace Metadata\Driver;
use Metadata\ClassMetadata;
use Psr\Container\ContainerInterface as PsrContainerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
class LazyLoadingDriver implements DriverInterface
{
/**
* @var ContainerInterface|PsrContainerInterface
*/
private $container;
/**
* @var string
*/
private $realDriverId;
/**
* @param ContainerInterface|PsrContainerInterface $container
*/
public function __construct($container, string $realDriverId)
{
if (!$container instanceof PsrContainerInterface && !$container instanceof ContainerInterface) {
throw new \InvalidArgumentException(sprintf('The container must be an instance of %s or %s (%s given).', PsrContainerInterface::class, ContainerInterface::class, \is_object($container) ? \get_class($container) : \gettype($container)));
}
$this->container = $container;
$this->realDriverId = $realDriverId;
}
public function loadMetadataForClass(\ReflectionClass $class): ?ClassMetadata
{
return $this->container->get($this->realDriverId)->loadMetadataForClass($class);
}
}

View File

@@ -1,15 +0,0 @@
<?php
declare(strict_types=1);
namespace Metadata\Driver;
interface TraceableFileLocatorInterface extends FileLocatorInterface
{
/**
* Finds all possible metadata files for a class
*
* @return string[]
*/
public function getPossibleFilesForClass(\ReflectionClass $class, string $extension): array;
}

View File

@@ -1,24 +0,0 @@
<?php
declare(strict_types=1);
namespace Metadata;
class MergeableClassMetadata extends ClassMetadata implements MergeableInterface
{
public function merge(MergeableInterface $object): void
{
if (!$object instanceof MergeableClassMetadata) {
throw new \InvalidArgumentException('$object must be an instance of MergeableClassMetadata.');
}
$this->name = $object->name;
$this->methodMetadata = array_merge($this->methodMetadata, $object->methodMetadata);
$this->propertyMetadata = array_merge($this->propertyMetadata, $object->propertyMetadata);
$this->fileResources = array_merge($this->fileResources, $object->fileResources);
if ($object->createdAt < $this->createdAt) {
$this->createdAt = $object->createdAt;
}
}
}

View File

@@ -1,10 +0,0 @@
<?php
declare(strict_types=1);
namespace Metadata;
interface MergeableInterface
{
public function merge(MergeableInterface $object): void;
}

View File

@@ -1,217 +0,0 @@
<?php
declare(strict_types=1);
namespace Metadata;
use Metadata\Cache\CacheInterface;
use Metadata\Driver\AdvancedDriverInterface;
use Metadata\Driver\DriverInterface;
class MetadataFactory implements AdvancedMetadataFactoryInterface
{
/**
* @var DriverInterface
*/
private $driver;
/**
* @var CacheInterface
*/
private $cache;
/**
* @var ClassMetadata[]
*/
private $loadedMetadata = [];
/**
* @var ClassMetadata[]
*/
private $loadedClassMetadata = [];
/**
* @var string|null
*/
private $hierarchyMetadataClass;
/**
* @var bool
*/
private $includeInterfaces = false;
/**
* @var bool
*/
private $debug = false;
public function __construct(DriverInterface $driver, ?string $hierarchyMetadataClass = 'Metadata\ClassHierarchyMetadata', bool $debug = false)
{
$this->driver = $driver;
$this->hierarchyMetadataClass = $hierarchyMetadataClass;
$this->debug = $debug;
}
public function setIncludeInterfaces(bool $include): void
{
$this->includeInterfaces = $include;
}
public function setCache(CacheInterface $cache): void
{
$this->cache = $cache;
}
/**
* {@inheritDoc}
*/
public function getMetadataForClass(string $className)
{
if (isset($this->loadedMetadata[$className])) {
return $this->filterNullMetadata($this->loadedMetadata[$className]);
}
$metadata = null;
foreach ($this->getClassHierarchy($className) as $class) {
if (isset($this->loadedClassMetadata[$name = $class->getName()])) {
if (null !== $classMetadata = $this->filterNullMetadata($this->loadedClassMetadata[$name])) {
$this->addClassMetadata($metadata, $classMetadata);
}
continue;
}
// check the cache
if (null !== $this->cache) {
if (($classMetadata = $this->cache->load($class->getName())) instanceof NullMetadata) {
$this->loadedClassMetadata[$name] = $classMetadata;
continue;
}
if (null !== $classMetadata) {
if (!$classMetadata instanceof ClassMetadata) {
throw new \LogicException(sprintf(
'The cache must return instances of ClassMetadata for class %s, but got %s.',
$className,
var_export($classMetadata, true)
));
}
if ($this->debug && !$classMetadata->isFresh()) {
$this->cache->evict($classMetadata->name);
} else {
$this->loadedClassMetadata[$name] = $classMetadata;
$this->addClassMetadata($metadata, $classMetadata);
continue;
}
}
}
// load from source
if (null !== $classMetadata = $this->driver->loadMetadataForClass($class)) {
$this->loadedClassMetadata[$name] = $classMetadata;
$this->addClassMetadata($metadata, $classMetadata);
if (null !== $this->cache) {
$this->cache->put($classMetadata);
}
continue;
}
if (null !== $this->cache && !$this->debug) {
$this->cache->put(new NullMetadata($class->getName()));
}
}
if (null === $metadata) {
$metadata = new NullMetadata($className);
}
return $this->filterNullMetadata($this->loadedMetadata[$className] = $metadata);
}
/**
* {@inheritDoc}
*/
public function getAllClassNames(): array
{
if (!$this->driver instanceof AdvancedDriverInterface) {
throw new \RuntimeException(
sprintf('Driver "%s" must be an instance of "AdvancedDriverInterface".', get_class($this->driver))
);
}
return $this->driver->getAllClassNames();
}
/**
* @param MergeableInterface|ClassHierarchyMetadata $metadata
*/
private function addClassMetadata(&$metadata, ClassMetadata $toAdd): void
{
if ($toAdd instanceof MergeableInterface) {
if (null === $metadata) {
$metadata = clone $toAdd;
} else {
$metadata->merge($toAdd);
}
} else {
if (null === $metadata) {
$class = $this->hierarchyMetadataClass;
$metadata = new $class();
}
$metadata->addClassMetadata($toAdd);
}
}
/**
* @return \ReflectionClass[]
*/
private function getClassHierarchy(string $class): array
{
$classes = [];
$refl = new \ReflectionClass($class);
do {
$classes[] = $refl;
$refl = $refl->getParentClass();
} while (false !== $refl);
$classes = array_reverse($classes, false);
if (!$this->includeInterfaces) {
return $classes;
}
$addedInterfaces = [];
$newHierarchy = [];
foreach ($classes as $class) {
foreach ($class->getInterfaces() as $interface) {
if (isset($addedInterfaces[$interface->getName()])) {
continue;
}
$addedInterfaces[$interface->getName()] = true;
$newHierarchy[] = $interface;
}
$newHierarchy[] = $class;
}
return $newHierarchy;
}
/**
* @param ClassMetadata|ClassHierarchyMetadata|MergeableInterface $metadata
*
* @return ClassMetadata|ClassHierarchyMetadata|MergeableInterface
*/
private function filterNullMetadata($metadata = null)
{
return !$metadata instanceof NullMetadata ? $metadata : null;
}
}

View File

@@ -1,29 +0,0 @@
<?php
declare(strict_types=1);
namespace Metadata;
/**
* Interface for Metadata Factory implementations.
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
interface MetadataFactoryInterface
{
/**
* Returns the gathered metadata for the given class name.
*
* If the drivers return instances of MergeableClassMetadata, these will be
* merged prior to returning. Otherwise, all metadata for the inheritance
* hierarchy will be returned as ClassHierarchyMetadata unmerged.
*
* If no metadata is available, null is returned.
*
* @return ClassHierarchyMetadata|MergeableClassMetadata|null
*
* @phpcsSuppress SlevomatCodingStandard.TypeHints.ReturnTypeHint.MissingNativeTypeHint
* @phpcsSuppress SlevomatCodingStandard.TypeHints.TypeHintDeclaration.UselessReturnAnnotation
*/
public function getMetadataForClass(string $className);
}

View File

@@ -1,90 +0,0 @@
<?php
declare(strict_types=1);
namespace Metadata;
/**
* Base class for method metadata.
*
* This class is intended to be extended to add your application specific
* properties, and flags.
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
* @property $reflection
*/
class MethodMetadata implements \Serializable
{
use SerializationHelper;
/**
* @var string
*/
public $class;
/**
* @var string
*/
public $name;
/**
* @var \ReflectionMethod
*/
private $reflection;
public function __construct(string $class, string $name)
{
$this->class = $class;
$this->name = $name;
}
/**
* @param mixed[] $args
*
* @return mixed
*/
public function invoke(object $obj, array $args = [])
{
return $this->getReflection()->invokeArgs($obj, $args);
}
/**
* @return mixed
*/
public function __get(string $propertyName)
{
if ('reflection' === $propertyName) {
return $this->getReflection();
}
return $this->$propertyName;
}
/**
* @param mixed $value
*/
public function __set(string $propertyName, $value): void
{
$this->$propertyName = $value;
}
private function getReflection(): \ReflectionMethod
{
if (null === $this->reflection) {
$this->reflection = new \ReflectionMethod($this->class, $this->name);
$this->reflection->setAccessible(true);
}
return $this->reflection;
}
protected function serializeToArray(): array
{
return [$this->class, $this->name];
}
protected function unserializeFromArray(array $data): void
{
[$this->class, $this->name] = $data;
}
}

View File

@@ -1,14 +0,0 @@
<?php
declare(strict_types=1);
namespace Metadata;
/**
* Represents the metadata for a class that has not metadata.
*
* @author Adrien Brault <adrien.brault@gmail.com>
*/
class NullMetadata extends ClassMetadata
{
}

View File

@@ -1,47 +0,0 @@
<?php
declare(strict_types=1);
namespace Metadata;
/**
* Base class for property metadata.
*
* This class is intended to be extended to add your application specific
* properties, and flags.
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
class PropertyMetadata implements \Serializable
{
use SerializationHelper;
/**
* @var string
*/
public $class;
/**
* @var string
*/
public $name;
public function __construct(string $class, string $name)
{
$this->class = $class;
$this->name = $name;
}
protected function serializeToArray(): array
{
return [
$this->class,
$this->name,
];
}
protected function unserializeFromArray(array $data): void
{
[$this->class, $this->name] = $data;
}
}

View File

@@ -1,40 +0,0 @@
<?php
declare(strict_types=1);
namespace Metadata;
trait SerializationHelper
{
/**
* @deprecated Use serializeToArray
*
* @return string
*/
public function serialize()
{
return serialize($this->serializeToArray());
}
/**
* @deprecated Use unserializeFromArray
*
* @param string $str
*
* @return void
*/
public function unserialize($str)
{
$this->unserializeFromArray(unserialize($str));
}
public function __serialize(): array
{
return [$this->serialize()];
}
public function __unserialize(array $data): void
{
$this->unserialize($data[0]);
}
}

View File

@@ -1,6 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="phpunit" type="PHPUnitRunConfigurationType" factoryName="PHPUnit">
<TestRunner configuration_file="$PROJECT_DIR$/phpunit.xml.dist" scope="XML" />
<method v="2" />
</configuration>
</component>

View File

@@ -1,546 +0,0 @@
# Changelog
New versions can be found on the [realeases page](https://github.com/schmittjoh/serializer/releases)
## [3.15.0](https://github.com/schmittjoh/serializer/tree/3.15.0) (2021-10-14)
**Merged pull requests:**
- allow the groups annotation to use "groups" as parameter name [\#1351](https://github.com/schmittjoh/serializer/pull/1351) ([goetas](https://github.com/goetas))
- Allow stable PHPStan PHPDoc Parser [\#1346](https://github.com/schmittjoh/serializer/pull/1346) ([mbabker](https://github.com/mbabker))
- Symfony 6 and DBAL 3 compat [\#1345](https://github.com/schmittjoh/serializer/pull/1345) ([mbabker](https://github.com/mbabker))
- Proposed fix for serializing custom DateTimeInterface implementations [\#1344](https://github.com/schmittjoh/serializer/pull/1344) ([andrei-dascalu](https://github.com/andrei-dascalu))
- Allow to add prefix to twig helpers [\#1341](https://github.com/schmittjoh/serializer/pull/1341) ([goetas](https://github.com/goetas))
- Fix phpstan return type [\#1329](https://github.com/schmittjoh/serializer/pull/1329) ([dgafka](https://github.com/dgafka))
## [3.14.0](https://github.com/schmittjoh/serializer/tree/3.14.0) (2021-08-06)
**Merged pull requests:**
- Avoid duplicate/invalid definitions when loading the php attributes using the annotation driver [\#1340](https://github.com/schmittjoh/serializer/pull/1340) ([goetas](https://github.com/goetas))
## [3.14.0-rc2](https://github.com/schmittjoh/serializer/tree/3.14.0-rc2) (2021-08-06)
**Merged pull requests:**
- run php8 ci on high and low deps [\#1339](https://github.com/schmittjoh/serializer/pull/1339) ([goetas](https://github.com/goetas))
- php8 attributes are enabled by default on php8 or higher [\#1338](https://github.com/schmittjoh/serializer/pull/1338) ([goetas](https://github.com/goetas))
- Allow positional php8 attributes [\#1337](https://github.com/schmittjoh/serializer/pull/1337) ([goetas](https://github.com/goetas))
- Drop Travis [\#1306](https://github.com/schmittjoh/serializer/pull/1306) ([simPod](https://github.com/simPod))
## [3.14.0-rc1](https://github.com/schmittjoh/serializer/tree/3.14.0-rc1) (2021-08-01)
**Merged pull requests:**
- Add PHP attributes support [\#1332](https://github.com/schmittjoh/serializer/pull/1332) ([goetas](https://github.com/goetas))
- Deprecate `@ReadOnly` annotation in favor of `@ReadOnlyProperty` [\#1333](https://github.com/schmittjoh/serializer/pull/1333) ([mbabker](https://github.com/mbabker))
## [3.13.0](https://github.com/schmittjoh/serializer/tree/3.13.0) (2021-07-05)
**Merged pull requests:**
- Use FilesystemAdapter when possible to fix compatibility with doctrine/cache 2 [\#1328](https://github.com/schmittjoh/serializer/pull/1328) ([rasmustnilsson](https://github.com/rasmustnilsson))
- Use PsrCachedReader and drop doctrine/cache [\#1327](https://github.com/schmittjoh/serializer/pull/1327) ([simPod](https://github.com/simPod))
- Check data can be casted before actual casting [\#1317](https://github.com/schmittjoh/serializer/pull/1317) ([scaytrase](https://github.com/scaytrase))
- Add methods for data\_collector [\#1316](https://github.com/schmittjoh/serializer/pull/1316) ([gam6itko](https://github.com/gam6itko))
- fix iterable::class that does not exist [\#1315](https://github.com/schmittjoh/serializer/pull/1315) ([Tobion](https://github.com/Tobion))
- useful error when data is not an object [\#1313](https://github.com/schmittjoh/serializer/pull/1313) ([dbu](https://github.com/dbu))
- Fix callback-method setup using XmlDriver [\#1310](https://github.com/schmittjoh/serializer/pull/1310) ([curzio-della-santa](https://github.com/curzio-della-santa))
## [3.12.3](https://github.com/schmittjoh/serializer/tree/3.12.3) (2021-04-25)
**Merged pull requests:**
- \[docs\] Add documentation to deserialize on existing objects [\#1308](https://github.com/schmittjoh/serializer/pull/1308) ([gam6itko](https://github.com/gam6itko))
- Allow phpstan/phpdoc-parser v0.5 [\#1307](https://github.com/schmittjoh/serializer/pull/1307) ([simPod](https://github.com/simPod))
## [3.12.2](https://github.com/schmittjoh/serializer/tree/3.12.2) (2021-03-23)
**Fixed bugs:**
- `Undefined offset: 0` when using `@var null|string` instead of `@var string|null` [\#1301](https://github.com/schmittjoh/serializer/pull/1301) ([ruudk](https://github.com/ruudk))
**Merged pull requests:**
- move around some doc block classes [\#1304](https://github.com/schmittjoh/serializer/pull/1304) ([goetas](https://github.com/goetas))
## [3.12.1](https://github.com/schmittjoh/serializer/tree/3.12.1) (2021-03-21)
**Fixed bugs:**
- Fix for issue \#1286: loading fails when deserializing XML [\#1289](https://github.com/schmittjoh/serializer/pull/1289) ([jviersel-ipronto](https://github.com/jviersel-ipronto))
- Fix DocBlockTypeResolver crash on PHP 7.3 and less [\#1288](https://github.com/schmittjoh/serializer/pull/1288) ([simPod](https://github.com/simPod))
- Doctrine `json` field type can contain not only an array [\#1295](https://github.com/schmittjoh/serializer/pull/1295) ([gam6itko](https://github.com/gam6itko))
**Merged pull requests:**
- add missing CustomPropertyOrderingStrategyTest [\#1296](https://github.com/schmittjoh/serializer/pull/1296) ([gam6itko](https://github.com/gam6itko))
- fix \#314 [\#1293](https://github.com/schmittjoh/serializer/pull/1293) ([gam6itko](https://github.com/gam6itko))
- Show all toctree on index page [\#1292](https://github.com/schmittjoh/serializer/pull/1292) ([gam6itko](https://github.com/gam6itko))
# Changelog
## [3.12.0](https://github.com/schmittjoh/serializer/tree/3.12.0) (2021-03-04)
**Fixed bugs:**
- Remove from the serialization groups if no match [\#1291](https://github.com/schmittjoh/serializer/pull/1291) ([goetas](https://github.com/goetas))
**Merged pull requests:**
- \[DOCS\] Add 'Deserialization Exclusion Strategy with Groups' topic [\#1287](https://github.com/schmittjoh/serializer/pull/1287) ([gam6itko](https://github.com/gam6itko))
- Add ascii\_string, dateinterval, and json to doctrine type mapping [\#1281](https://github.com/schmittjoh/serializer/pull/1281) ([dontub](https://github.com/dontub))
- Cleanup [\#1278](https://github.com/schmittjoh/serializer/pull/1278) ([simPod](https://github.com/simPod))
- Drop coverage badge [\#1277](https://github.com/schmittjoh/serializer/pull/1277) ([simPod](https://github.com/simPod))
- Introduce PHPStan [\#1276](https://github.com/schmittjoh/serializer/pull/1276) ([simPod](https://github.com/simPod))
- Replace Scrutinizer with GA [\#1275](https://github.com/schmittjoh/serializer/pull/1275) ([simPod](https://github.com/simPod))
- Add throws tag [\#1273](https://github.com/schmittjoh/serializer/pull/1273) ([VincentLanglet](https://github.com/VincentLanglet))
## [3.11.0](https://github.com/schmittjoh/serializer/tree/3.11.0) (2020-12-29)
**Implemented enhancements:**
- Allow installing and build on PHP 8 [\#1267](https://github.com/schmittjoh/serializer/pull/1267) ([sanmai](https://github.com/sanmai))
- Use phpstan/phpdoc-parser to retrieve additional type information from PhpDoc [\#1261](https://github.com/schmittjoh/serializer/pull/1261) ([Namoshek](https://github.com/Namoshek))
- DoctrineObjectConstructor Using array\_key\_exists\(\) on objects is deprecated in php7.4 [\#1253](https://github.com/schmittjoh/serializer/pull/1253) ([gam6itko](https://github.com/gam6itko))
- Add Composer cache for v2 on Travis CI [\#1266](https://github.com/schmittjoh/serializer/pull/1266) ([sanmai](https://github.com/sanmai))
- Allow interfaces for DocBlock [\#1256](https://github.com/schmittjoh/serializer/pull/1256) ([marein](https://github.com/marein))
- Allow interfaces for typed properties [\#1254](https://github.com/schmittjoh/serializer/pull/1254) ([marein](https://github.com/marein))
## [3.10.0](https://github.com/schmittjoh/serializer/tree/3.10.0) (2020-10-29)
**Implemented enhancements:**
- Allow null to be visited if is a root object [\#1250](https://github.com/schmittjoh/serializer/pull/1250) ([goetas](https://github.com/goetas))
- Resolve collections from DocBlock [\#1214](https://github.com/schmittjoh/serializer/pull/1214) ([dgafka](https://github.com/dgafka))
**Merged pull requests:**
- Bump CS [\#1249](https://github.com/schmittjoh/serializer/pull/1249) ([simPod](https://github.com/simPod))
- Removed redundant property initialization [\#1232](https://github.com/schmittjoh/serializer/pull/1232) ([xepozz](https://github.com/xepozz))
## [3.9.0](https://github.com/schmittjoh/serializer/tree/3.9.0) (2020-08-26)
**Implemented enhancements:**
- Add support for skippable \(de\)serialization handlers [\#1238](https://github.com/schmittjoh/serializer/pull/1238) ([bobvandevijver](https://github.com/bobvandevijver))
- added support for milliseconds in DateInterval deserialization [\#1234](https://github.com/schmittjoh/serializer/pull/1234) ([ivoba](https://github.com/ivoba))
**Fixed bugs:**
- Do not load entities when deserializing if their identifier is not ex… [\#1247](https://github.com/schmittjoh/serializer/pull/1247) ([goetas](https://github.com/goetas))
- Do not use excluded fields when fetching entities [\#1246](https://github.com/schmittjoh/serializer/pull/1246) ([goetas](https://github.com/goetas))
- Ensure accessors are cached per property when using reflection [\#1237](https://github.com/schmittjoh/serializer/pull/1237) ([goetas](https://github.com/goetas))
**Closed issues:**
- Annotation cache does not honor naming strategy [\#1244](https://github.com/schmittjoh/serializer/issues/1244)
- Authorization Bypass Vulnerability - v1.14.1 [\#1242](https://github.com/schmittjoh/serializer/issues/1242)
- @SkipWhenEmpty and @Exclude combination leads to unexpected behavior [\#1240](https://github.com/schmittjoh/serializer/issues/1240)
- How to pass MetadataFactory::create\(\) into SerializationVisitorInterface::startVisitingObject\(\)? [\#1226](https://github.com/schmittjoh/serializer/issues/1226)
- Custom type in array key is not respected when serializing to JSON [\#1223](https://github.com/schmittjoh/serializer/issues/1223)
- xml:id or xml:lang attributes handling [\#1221](https://github.com/schmittjoh/serializer/issues/1221)
- Accessing static property as non static [\#1156](https://github.com/schmittjoh/serializer/issues/1156)
- AbstractVisitor::getElementType\(\) must be of the type array or null, string returned [\#1027](https://github.com/schmittjoh/serializer/issues/1027)
**Merged pull requests:**
- remove missing deprecated removal on hasData [\#1245](https://github.com/schmittjoh/serializer/pull/1245) ([rflavien](https://github.com/rflavien))
- Change return type of SerializerBuilder::build\(\) to Serializer [\#1241](https://github.com/schmittjoh/serializer/pull/1241) ([icanhazstring](https://github.com/icanhazstring))
- docs: add note about array key type being ignored when serializing [\#1235](https://github.com/schmittjoh/serializer/pull/1235) ([eduardoweiland](https://github.com/eduardoweiland))
- Sort packages in composer.json [\#1228](https://github.com/schmittjoh/serializer/pull/1228) ([simPod](https://github.com/simPod))
- fix xml embeddable data getReference for DoctrineObjectConstructor [\#1224](https://github.com/schmittjoh/serializer/pull/1224) ([gam6itko](https://github.com/gam6itko))
- fixed exception for strict\_types [\#1222](https://github.com/schmittjoh/serializer/pull/1222) ([ivoba](https://github.com/ivoba))
## [3.8.0](https://github.com/schmittjoh/serializer/tree/3.8.0) (2020-06-28)
**Implemented enhancements:**
- Use doctrine/lexer instead of hoa/compiler [\#1212](https://github.com/schmittjoh/serializer/pull/1212) ([goetas](https://github.com/goetas))
**Fixed bugs:**
- Consider exclude rules on parents if defined [\#1206](https://github.com/schmittjoh/serializer/pull/1206) ([goetas](https://github.com/goetas))
**Closed issues:**
- Serializer Group [\#1213](https://github.com/schmittjoh/serializer/issues/1213)
- Notice: Accessing static property Proxies\\_\_CG\_\_\examplemodel\inherit\Customers::$lazyPropertiesNames as non static [\#1209](https://github.com/schmittjoh/serializer/issues/1209)
- Unserialization failure after upgrading to 3.7.0 \(`excludeIf` related?\) [\#1207](https://github.com/schmittjoh/serializer/issues/1207)
- \[RFC\] Removing abandoned hoa from serializer [\#1182](https://github.com/schmittjoh/serializer/issues/1182)
- hoa/protocol package conflicts with laravel helper [\#1154](https://github.com/schmittjoh/serializer/issues/1154)
**Merged pull requests:**
- Remove conflicts to hoa packages [\#1216](https://github.com/schmittjoh/serializer/pull/1216) ([alexander-schranz](https://github.com/alexander-schranz))
- Test also agains twig 3 [\#1215](https://github.com/schmittjoh/serializer/pull/1215) ([alexander-schranz](https://github.com/alexander-schranz))
- Allow doctrine/persistence v2/v3 [\#1210](https://github.com/schmittjoh/serializer/pull/1210) ([goetas](https://github.com/goetas))
- Fix deprecated assertFileNotExist [\#1197](https://github.com/schmittjoh/serializer/pull/1197) ([mpoiriert](https://github.com/mpoiriert))
## [3.7.0](https://github.com/schmittjoh/serializer/tree/3.7.0) (2020-05-23)
**Implemented enhancements:**
- Allow deserialization of typehinted DateTimeInterface to DateTime class [\#1193](https://github.com/schmittjoh/serializer/pull/1193) ([goetas](https://github.com/goetas))
- Infer types from PHP 7.4 type declarations [\#1192](https://github.com/schmittjoh/serializer/pull/1192) ([goetas](https://github.com/goetas))
- Support conditional exclude for classes [\#1099](https://github.com/schmittjoh/serializer/pull/1099) ([arneee](https://github.com/arneee))
**Fixed bugs:**
- Exclude if at class level are not merge [\#1203](https://github.com/schmittjoh/serializer/issues/1203)
- Class level expression exclusion strategy should work with hierarchies [\#1204](https://github.com/schmittjoh/serializer/pull/1204) ([goetas](https://github.com/goetas))
**Closed issues:**
- Specify Type as nullable? [\#1191](https://github.com/schmittjoh/serializer/issues/1191)
- Does someone know how to use phpdoc with serializer? [\#1185](https://github.com/schmittjoh/serializer/issues/1185)
- Serializer doesn't keep types but convert them if not it can [\#1181](https://github.com/schmittjoh/serializer/issues/1181)
- ConditionalExpose/Exclude annotation does not work on class level [\#1098](https://github.com/schmittjoh/serializer/issues/1098)
**Merged pull requests:**
- \[Docs\] Improve documentation on dynamic exclusion strategy [\#1188](https://github.com/schmittjoh/serializer/pull/1188) ([arneee](https://github.com/arneee))
- Fix Support conditional exclude for classes [\#1187](https://github.com/schmittjoh/serializer/pull/1187) ([arneee](https://github.com/arneee))
- Fix travis tests [\#1183](https://github.com/schmittjoh/serializer/pull/1183) ([peter279k](https://github.com/peter279k))
- Replace "Exclude" by "Expose" [\#1180](https://github.com/schmittjoh/serializer/pull/1180) ([kpn13](https://github.com/kpn13))
- add .gitattributes [\#1177](https://github.com/schmittjoh/serializer/pull/1177) ([Tobion](https://github.com/Tobion))
## [3.6.0](https://github.com/schmittjoh/serializer/tree/3.6.0) (2020-03-21)
**Implemented enhancements:**
- DateTime parsed invalid date [\#1152](https://github.com/schmittjoh/serializer/issues/1152)
- do not hide Exceptions from custom handlers but correctly handle null [\#1169](https://github.com/schmittjoh/serializer/pull/1169) ([Hikariii](https://github.com/Hikariii))
**Fixed bugs:**
- Handle discriminator groups [\#1175](https://github.com/schmittjoh/serializer/pull/1175) ([goetas](https://github.com/goetas))
**Closed issues:**
- thrown Exceptions are hidden when serializing complex objects with a handler [\#1168](https://github.com/schmittjoh/serializer/issues/1168)
**Merged pull requests:**
- test serializing entity that uses Discriminator and extends some base… [\#1174](https://github.com/schmittjoh/serializer/pull/1174) ([FrKevin](https://github.com/FrKevin))
- Handle ObjectConstructor returning NULL [\#1172](https://github.com/schmittjoh/serializer/pull/1172) ([jankramer](https://github.com/jankramer))
- test symfony translator contract [\#1171](https://github.com/schmittjoh/serializer/pull/1171) ([goetas](https://github.com/goetas))
## [3.5.0](https://github.com/schmittjoh/serializer/tree/3.5.0) (2020-02-22)
**Implemented enhancements:**
- Improved return type for fluent methods in Context [\#1162](https://github.com/schmittjoh/serializer/pull/1162) ([wouterj](https://github.com/wouterj))
- Handle array format for dateHandler [\#1108](https://github.com/schmittjoh/serializer/pull/1108) ([VincentLanglet](https://github.com/VincentLanglet))
**Fixed bugs:**
- Make sure serialzation context is immutable [\#1159](https://github.com/schmittjoh/serializer/pull/1159) ([goetas](https://github.com/goetas))
**Merged pull requests:**
- Allow for newer PHPUnit [\#1166](https://github.com/schmittjoh/serializer/pull/1166) ([sanmai](https://github.com/sanmai))
- \[Docs\] Explain recursion in FileLocator [\#1155](https://github.com/schmittjoh/serializer/pull/1155) ([ruudk](https://github.com/ruudk))
- Changed CI environment to stable PHP 7.4 [\#1153](https://github.com/schmittjoh/serializer/pull/1153) ([grogy](https://github.com/grogy))
## [1.14.1](https://github.com/schmittjoh/serializer/tree/1.14.1) (2020-02-22)
**Closed issues:**
- Virtual Property do not get serialized if getter name conflict with a class property [\#1164](https://github.com/schmittjoh/serializer/issues/1164)
- SerializationGraphNavigator not receiving correct serializeNull config during initialize [\#1158](https://github.com/schmittjoh/serializer/issues/1158)
- SerializationGraphNavigator unaware of serializeNull change of context when altered in PreSerializeEvent [\#1157](https://github.com/schmittjoh/serializer/issues/1157)
- Memory leaks [\#1150](https://github.com/schmittjoh/serializer/issues/1150)
- Properties with @Groups annotations included in output when no SerializationContext given. [\#1149](https://github.com/schmittjoh/serializer/issues/1149)
**Merged pull requests:**
- PHP7.4 ternary operator deprecation [\#1163](https://github.com/schmittjoh/serializer/pull/1163) ([adhocore](https://github.com/adhocore))
- Test 1.x on PHP 7.3 on Travis; fix builds for PHP 5.5 [\#1119](https://github.com/schmittjoh/serializer/pull/1119) ([sanmai](https://github.com/sanmai))
## [3.4.0](https://github.com/schmittjoh/serializer/tree/3.4.0) (2019-12-14)
**Implemented enhancements:**
- Symfony 5.0 compatibility [\#1145](https://github.com/schmittjoh/serializer/pull/1145) ([goetas](https://github.com/goetas))
- Support new doctrine ODM proxy objects [\#1139](https://github.com/schmittjoh/serializer/pull/1139) ([notrix](https://github.com/notrix))
- Visitor interfaces in handlers [\#1129](https://github.com/schmittjoh/serializer/pull/1129) ([derzkiy](https://github.com/derzkiy))
**Closed issues:**
- \[Improvement\] Ability to define a global exclusion\_policy: ALL for all classes. [\#1144](https://github.com/schmittjoh/serializer/issues/1144)
- Embed JSON string without extra escape [\#1142](https://github.com/schmittjoh/serializer/issues/1142)
- Make possible to set ArrayCollectionHandler classes from outside [\#1131](https://github.com/schmittjoh/serializer/issues/1131)
**Merged pull requests:**
- Remove PHP 7.4 from `allow\_failures` matrix [\#1138](https://github.com/schmittjoh/serializer/pull/1138) ([carusogabriel](https://github.com/carusogabriel))
- Remove unnecessary cast [\#1133](https://github.com/schmittjoh/serializer/pull/1133) ([carusogabriel](https://github.com/carusogabriel))
- Fix PHPUnit deprecations [\#1123](https://github.com/schmittjoh/serializer/pull/1123) ([Majkl578](https://github.com/Majkl578))
## [3.3.0](https://github.com/schmittjoh/serializer/tree/3.3.0) (2019-09-20)
**Implemented enhancements:**
- Update major version that v2.x deprecation will be removed [\#1134](https://github.com/schmittjoh/serializer/pull/1134) ([carusogabriel](https://github.com/carusogabriel))
- Implement short expose syntax for XML as it is available for YAML [\#1127](https://github.com/schmittjoh/serializer/pull/1127) ([goetas](https://github.com/goetas))
**Fixed bugs:**
- Avoid implicit expose of a property instead of virtual-property [\#1126](https://github.com/schmittjoh/serializer/pull/1126) ([goetas](https://github.com/goetas))
**Closed issues:**
- Accessing static property as non static [\#1122](https://github.com/schmittjoh/serializer/issues/1122)
- Travis builds on 1.x are failing [\#1120](https://github.com/schmittjoh/serializer/issues/1120)
**Merged pull requests:**
- Allow failures on php "7.4snapshot" \(waiting for stable symfony 4.4\) [\#1128](https://github.com/schmittjoh/serializer/pull/1128) ([goetas](https://github.com/goetas))
## [3.2.0](https://github.com/schmittjoh/serializer/tree/3.2.0) (2019-09-04)
**Fixed bugs:**
- PHP7.4: Deprecated warning - serializationContext.php on line 152 [\#1111](https://github.com/schmittjoh/serializer/issues/1111)
**Closed issues:**
- StaticPropertyMetadata first constructor argument not nullable [\#1116](https://github.com/schmittjoh/serializer/issues/1116)
- Add support for PSR-7 URIInterface objects [\#1115](https://github.com/schmittjoh/serializer/issues/1115)
- Upgraded 2.4 -\> 3.4 / Symfony 4.3.3 [\#1112](https://github.com/schmittjoh/serializer/issues/1112)
- Empty namespace [\#1087](https://github.com/schmittjoh/serializer/issues/1087)
- Format constants \(JSON, XML\) [\#1079](https://github.com/schmittjoh/serializer/issues/1079)
- @ExclusionPolicy\(policy="ALL"\) causes PHP notice message [\#1073](https://github.com/schmittjoh/serializer/issues/1073)
**Merged pull requests:**
- Explain once and for all the use of StaticPropertyMetadata [\#1118](https://github.com/schmittjoh/serializer/pull/1118) ([goetas](https://github.com/goetas))
- PHP 7.4 compatibility [\#1113](https://github.com/schmittjoh/serializer/pull/1113) ([goetas](https://github.com/goetas))
- Fix typos in UPGRADING.md [\#1107](https://github.com/schmittjoh/serializer/pull/1107) ([jdreesen](https://github.com/jdreesen))
- Fix exclusion policy bug [\#1106](https://github.com/schmittjoh/serializer/pull/1106) ([spam312sn](https://github.com/spam312sn))
- Add Doctrine 2 immutable datetime types to field mapping. [\#1104](https://github.com/schmittjoh/serializer/pull/1104) ([Sonny812](https://github.com/Sonny812))
## [3.1.1](https://github.com/schmittjoh/serializer/tree/3.1.1) (2019-06-28)
**Fixed bugs:**
- Could not deserialize object if all properties have not type [\#1102](https://github.com/schmittjoh/serializer/issues/1102)
- Revert "Move type check when deserializing into the graph navigator" [\#1103](https://github.com/schmittjoh/serializer/pull/1103) ([goetas](https://github.com/goetas))
## [3.1.0](https://github.com/schmittjoh/serializer/tree/3.1.0) (2019-06-25)
**Implemented enhancements:**
- Add support for iterable and Iterator [\#1096](https://github.com/schmittjoh/serializer/pull/1096) ([simPod](https://github.com/simPod))
- Implement "empty" XML namespace handling [\#1095](https://github.com/schmittjoh/serializer/pull/1095) ([discordier](https://github.com/discordier))
- Move type check when deserializing into the graph navigator [\#1080](https://github.com/schmittjoh/serializer/pull/1080) ([goetas](https://github.com/goetas))
- Allow loading different YAML extensions [\#1078](https://github.com/schmittjoh/serializer/pull/1078) ([scaytrase](https://github.com/scaytrase))
**Fixed bugs:**
- Fix for failing doctrine object constructor on embeddable class [\#1031](https://github.com/schmittjoh/serializer/pull/1031) ([notrix](https://github.com/notrix))
**Closed issues:**
- Behavior serializeNull -\> not always honored in 2.\* \(but was in 1.\*\) [\#1101](https://github.com/schmittjoh/serializer/issues/1101)
- Support for iterable [\#1094](https://github.com/schmittjoh/serializer/issues/1094)
- Prevent deserialisation with missing required field [\#1090](https://github.com/schmittjoh/serializer/issues/1090)
- Allow using @XmlValue together with @Accessor/@AccessType [\#1083](https://github.com/schmittjoh/serializer/issues/1083)
- Support \*.yaml extension [\#1077](https://github.com/schmittjoh/serializer/issues/1077)
- Instructions for upgrading from addData in 1.x don't work [\#1030](https://github.com/schmittjoh/serializer/issues/1030)
**Merged pull requests:**
- Add psalm specific generic return type for deserialize [\#1091](https://github.com/schmittjoh/serializer/pull/1091) ([bdsl](https://github.com/bdsl))
- Fix: Typo [\#1084](https://github.com/schmittjoh/serializer/pull/1084) ([localheinz](https://github.com/localheinz))
## [3.0.1](https://github.com/schmittjoh/serializer/tree/3.0.1) (2019-04-23)
**Fixed bugs:**
- Do not throw exception when visiting null in custom handler [\#1076](https://github.com/schmittjoh/serializer/pull/1076) ([goetas](https://github.com/goetas))
## [3.0.0](https://github.com/schmittjoh/serializer/tree/3.0.0) (2019-04-23)
**Breaking changes:**
- Revert v2 nested groups and release 3.0 [\#1071](https://github.com/schmittjoh/serializer/pull/1071) ([goetas](https://github.com/goetas))
**Implemented enhancements:**
- use Twig 2.7 namespaces [\#1061](https://github.com/schmittjoh/serializer/pull/1061) ([IonBazan](https://github.com/IonBazan))
**Closed issues:**
- \[RFC\] revert \#946 and release new major [\#1058](https://github.com/schmittjoh/serializer/issues/1058)
**Merged pull requests:**
- Fix Travis-CI scripts always passing [\#1075](https://github.com/schmittjoh/serializer/pull/1075) ([IonBazan](https://github.com/IonBazan))
## [1.14.0](https://github.com/schmittjoh/serializer/tree/1.14.0) (2019-04-17)
## [2.3.0](https://github.com/schmittjoh/serializer/tree/2.3.0) (2019-04-17)
**Implemented enhancements:**
- Expose and test GroupsExclusionStrategy::getGroupsFor\(\) [\#1069](https://github.com/schmittjoh/serializer/pull/1069) ([goetas](https://github.com/goetas))
- add options property to XmlDeserializationVisitorFactory and XmlDeserializationVisitor, propagate defined value from factory to simplexml\_load\_string call [\#1068](https://github.com/schmittjoh/serializer/pull/1068) ([kopeckyales](https://github.com/kopeckyales))
**Closed issues:**
- Override existing property with another [\#1067](https://github.com/schmittjoh/serializer/issues/1067)
- disabling cdata by default [\#1065](https://github.com/schmittjoh/serializer/issues/1065)
- unwrap child class instance [\#1064](https://github.com/schmittjoh/serializer/issues/1064)
- Make JsonDeserializationVisitor extendable [\#1055](https://github.com/schmittjoh/serializer/issues/1055)
**Merged pull requests:**
- doc update: registerHandler\(\) example [\#1072](https://github.com/schmittjoh/serializer/pull/1072) ([cebe](https://github.com/cebe))
- Updated suggestion for `JsonSerializationVisitor::addData` replacement [\#1066](https://github.com/schmittjoh/serializer/pull/1066) ([theoboldt](https://github.com/theoboldt))
- Add fix to UPGRADING.md [\#1062](https://github.com/schmittjoh/serializer/pull/1062) ([Jean85](https://github.com/Jean85))
## [2.2.0](https://github.com/schmittjoh/serializer/tree/2.2.0) (2019-02-27)
**Implemented enhancements:**
- Add Iterator Handler [\#1034](https://github.com/schmittjoh/serializer/pull/1034) ([scyzoryck](https://github.com/scyzoryck))
**Fixed bugs:**
- xmlRootPrefix missing from unserialized metadata [\#1050](https://github.com/schmittjoh/serializer/issues/1050)
- Non-locale aware encoding of doubles, closes \#1041 [\#1042](https://github.com/schmittjoh/serializer/pull/1042) ([Grundik](https://github.com/Grundik))
**Closed issues:**
- GROUP BY [\#1051](https://github.com/schmittjoh/serializer/issues/1051)
- Using @Until and @Since on class level [\#1048](https://github.com/schmittjoh/serializer/issues/1048)
- \[Semantical Error\] The annotation \"@generated\" in class JMS\\Serializer\\Type\\InnerParser was never imported [\#1046](https://github.com/schmittjoh/serializer/issues/1046)
- ReflectionException when \(de\)serializing unless fully qualified classname is used [\#1045](https://github.com/schmittjoh/serializer/issues/1045)
- Add use of annotation registry to docs [\#1044](https://github.com/schmittjoh/serializer/issues/1044)
- Values of type "double" should not use locale-specific encoding [\#1041](https://github.com/schmittjoh/serializer/issues/1041)
- SF4: JMS serializer seems to be ignoring global naming strategy [\#1037](https://github.com/schmittjoh/serializer/issues/1037)
- @SerializedName not being ignored since 2.x is bug or feature? [\#1036](https://github.com/schmittjoh/serializer/issues/1036)
- What should I use instead of the dropped GenericDeserializationVisitor class? [\#1035](https://github.com/schmittjoh/serializer/issues/1035)
- DateTime and DateTimeImmutable from PHP 7.1 serialization and deserialization with microseconds [\#1033](https://github.com/schmittjoh/serializer/issues/1033)
- Provide an option to the SerializeBuilder to set AccessType to a specified value globally [\#1025](https://github.com/schmittjoh/serializer/issues/1025)
- Serialize Generator [\#1023](https://github.com/schmittjoh/serializer/issues/1023)
**Merged pull requests:**
- Test on php 7.3 [\#1054](https://github.com/schmittjoh/serializer/pull/1054) ([goetas](https://github.com/goetas))
- xmlRootPrefix missing from unserialized metadata [\#1053](https://github.com/schmittjoh/serializer/pull/1053) ([goetas](https://github.com/goetas))
- Allow @Since and @Until within @VirtualProperty on class level [\#1049](https://github.com/schmittjoh/serializer/pull/1049) ([tjveldhuizen](https://github.com/tjveldhuizen))
- Document use of AnnotationRegistry [\#1047](https://github.com/schmittjoh/serializer/pull/1047) ([andig](https://github.com/andig))
- Fix result of code example [\#1039](https://github.com/schmittjoh/serializer/pull/1039) ([henrikthesing](https://github.com/henrikthesing))
## [2.1.0](https://github.com/schmittjoh/serializer/tree/2.1.0) (2019-01-11)
**Closed issues:**
- Compile error Declaration of \[...\] must be compatible with \[...\] [\#1024](https://github.com/schmittjoh/serializer/issues/1024)
- Exclude field for depth [\#1022](https://github.com/schmittjoh/serializer/issues/1022)
**Merged pull requests:**
- fixed typo [\#1029](https://github.com/schmittjoh/serializer/pull/1029) ([sasezaki](https://github.com/sasezaki))
## [2.0.2](https://github.com/schmittjoh/serializer/tree/2.0.2) (2018-12-12)
**Fixed bugs:**
- jms serialzier 2.0 Error in debug mode [\#1018](https://github.com/schmittjoh/serializer/issues/1018)
- AbstractDoctrineTypeDriver::normalizeFieldType\(\) must be of the type string, null given [\#1015](https://github.com/schmittjoh/serializer/issues/1015)
- allow empty strings and numbers as metadata type parameters [\#1019](https://github.com/schmittjoh/serializer/pull/1019) ([goetas](https://github.com/goetas))
- internal classes have false in reflection::getFilename\(\) [\#1013](https://github.com/schmittjoh/serializer/pull/1013) ([chregu](https://github.com/chregu))
**Closed issues:**
- DateTime converted to ArrayObject instead of string in custom visitor class [\#1017](https://github.com/schmittjoh/serializer/issues/1017)
**Merged pull requests:**
- Doctrine driver normalizeFieldType method does not handle nulls [\#1020](https://github.com/schmittjoh/serializer/pull/1020) ([goetas](https://github.com/goetas))
- fixed a typo [\#1014](https://github.com/schmittjoh/serializer/pull/1014) ([themasch](https://github.com/themasch))
## [2.0.1](https://github.com/schmittjoh/serializer/tree/2.0.1) (2018-11-29)
## [2.0.0](https://github.com/schmittjoh/serializer/tree/2.0.0) (2018-11-09)
## [2.0.0-RC1](https://github.com/schmittjoh/serializer/tree/2.0.0-RC1) (2018-10-17)
## [2.0.0-beta1](https://github.com/schmittjoh/serializer/tree/2.0.0-beta1) (2018-09-12)
## [1.13.0](https://github.com/schmittjoh/serializer/tree/1.13.0) (2018-07-25)
## [1.12.1](https://github.com/schmittjoh/serializer/tree/1.12.1) (2018-06-01)
## [1.12.0](https://github.com/schmittjoh/serializer/tree/1.12.0) (2018-05-25)
## [1.11.0](https://github.com/schmittjoh/serializer/tree/1.11.0) (2018-02-04)
## [1.10.0](https://github.com/schmittjoh/serializer/tree/1.10.0) (2017-11-30)
## [1.9.2](https://github.com/schmittjoh/serializer/tree/1.9.2) (2017-11-22)
## [1.9.1](https://github.com/schmittjoh/serializer/tree/1.9.1) (2017-10-27)
## [1.9.0](https://github.com/schmittjoh/serializer/tree/1.9.0) (2017-09-28)
## [1.8.1](https://github.com/schmittjoh/serializer/tree/1.8.1) (2017-07-13)
## [1.8.0](https://github.com/schmittjoh/serializer/tree/1.8.0) (2017-07-12)
## [1.7.1](https://github.com/schmittjoh/serializer/tree/1.7.1) (2017-05-15)
## [1.7.0](https://github.com/schmittjoh/serializer/tree/1.7.0) (2017-05-10)
## [1.7.0-RC2](https://github.com/schmittjoh/serializer/tree/1.7.0-RC2) (2017-05-05)
## [1.7.0-RC1](https://github.com/schmittjoh/serializer/tree/1.7.0-RC1) (2017-04-25)
## [1.6.2](https://github.com/schmittjoh/serializer/tree/1.6.2) (2017-04-17)
## [1.6.1](https://github.com/schmittjoh/serializer/tree/1.6.1) (2017-04-12)
## [1.6.0](https://github.com/schmittjoh/serializer/tree/1.6.0) (2017-03-24)
## [1.6.0-RC1](https://github.com/schmittjoh/serializer/tree/1.6.0-RC1) (2017-03-14)
## [1.5.0](https://github.com/schmittjoh/serializer/tree/1.5.0) (2017-02-14)
## [1.5.0-RC1](https://github.com/schmittjoh/serializer/tree/1.5.0-RC1) (2017-01-19)
## [1.4.2](https://github.com/schmittjoh/serializer/tree/1.4.2) (2016-11-13)
## [1.4.1](https://github.com/schmittjoh/serializer/tree/1.4.1) (2016-11-02)
## [1.4.0](https://github.com/schmittjoh/serializer/tree/1.4.0) (2016-10-31)
## [1.3.1](https://github.com/schmittjoh/serializer/tree/1.3.1) (2016-08-23)
## [1.3.0](https://github.com/schmittjoh/serializer/tree/1.3.0) (2016-08-17)
## [1.2.0](https://github.com/schmittjoh/serializer/tree/1.2.0) (2016-08-03)
## [1.1.0](https://github.com/schmittjoh/serializer/tree/1.1.0) (2015-10-27)
## [1.0.0](https://github.com/schmittjoh/serializer/tree/1.0.0) (2015-06-16)
## [0.16.0](https://github.com/schmittjoh/serializer/tree/0.16.0) (2014-03-18)
## [0.15.0](https://github.com/schmittjoh/serializer/tree/0.15.0) (2014-02-10)
## [0.14.0](https://github.com/schmittjoh/serializer/tree/0.14.0) (2013-12-04)
## [0.13.0](https://github.com/schmittjoh/serializer/tree/0.13.0) (2013-07-29)
## [0.12.0](https://github.com/schmittjoh/serializer/tree/0.12.0) (2013-03-28)
## [0.11.0](https://github.com/schmittjoh/serializer/tree/0.11.0) (2013-01-29)
\* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)*

View File

@@ -1,83 +0,0 @@
# Contribute
Thank you for contributing!
Before we can merge your Pull-Request here are some guidelines that you need to follow.
These guidelines exist not to annoy you, but to keep the code base clean, unified and future proof.
## Coding Standard
This project uses [PHP_CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer) to enforce coding standards.
The coding standard rules are defined in the **phpcs.xml.dist** file (part of this repository).
The project follows a relaxed version of the Doctrine Coding standards v4.
Your Pull-Request must be compliant with the said standard.
To check your code you can run `vendor/bin/phpcs`. This command will give you a list of violations in your code (if any).
The most common errors can be automatically fixed just by running `vendor/bin/phpcbf`.
## Dependencies
We're using [`composer/composer`](https://github.com/composer/composer) to manage dependencies
## Unit-Tests
Please try to add a test for your pull-request. This project uses [PHPUnit](https://phpunit.de/) as testing framework.
You can run the unit-tests by calling `vendor/bin/phpunit`.
New features without tests can't be merged.
## Documentation
The documentation is stored in the `doc` folder and is written using the [rST](http://docutils.sourceforge.net/rst.html) language.
If you are adding a new feature, you must update the documentation.
To test doc rendering before submitting your PR, you will need [Sphinx](http://www.sphinx-doc.org/en/stable/).
To install `Sphinx` just run:
```bash
pip install --requirement doc/requirements.txt --user
```
When that is done, just run:
```bash
cd doc && sphinx-build -W -b html -d _build/doctrees . _build/html
```
## CI
We automatically run your pull request through [Github Actions](https://github.com/schmittjoh/serializer/actions).
If you break the tests, we cannot merge your code,
so please make sure that your code is working before opening up a Pull-Request.
## Issues and Bugs
To create a new issue, you can use the GitHub issue tracking system.
Please try to avoid opening support-related tickets. For support related questions please use more appropriate
channels as Q&A platforms (such as Stackoverflow), Forums, Local PHP user groups.
If you are a Symfony user, please try to distinguish between issues related to the Bundle and issues related to this
library.
## Getting merged
Please allow us time to review your pull requests.
We will give our best to review everything as fast as possible, but cannot always live up to our own expectations.
Please, write [commit messages that make
sense](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html),
and [rebase your branch](http://git-scm.com/book/en/Git-Branching-Rebasing)
before submitting your Pull Request.
One may ask you to [squash your
commits](http://gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html)
too. This is used to "clean" your Pull Request before merging it (we don't want
commits such as "fix tests", "fix 2", "fix 3", etc.).
Pull requests without tests most probably will not be merged.
Documentation PRs obviously do not require tests.
Thank you very much again for your contribution!

View File

@@ -1,19 +0,0 @@
Copyright (c) 2018 Johannes M. Schmitt
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1,7 +0,0 @@
# Generating changelog
Use: https://github.com/skywinder/Github-Changelog-Generator
```bash
github_changelog_generator --user=schmittjoh --project=serializer --pull-requests --no-compare-link -t GITHUB-TOKEN
```

View File

@@ -1,74 +0,0 @@
> # UKRAINE NEEDS YOUR HELP NOW!
>
> On 24 February 2022, Russian [President Vladimir Putin ordered an invasion of Ukraine by Russian Armed Forces](https://www.bbc.com/news/world-europe-60504334).
>
> Your support is urgently needed.
>
> - Donate to the volunteers. Here is the volunteer fund helping the Ukrainian army to provide all the necessary equipment:
> https://bank.gov.ua/en/news/all/natsionalniy-bank-vidkriv-spetsrahunok-dlya-zboru-koshtiv-na-potrebi-armiyi or https://savelife.in.ua/en/donate/
> - Triple-check social media sources. Russian disinformation is attempting to coverup and distort the reality in Ukraine.
> - Help Ukrainian refugees who are fleeing Russian attacks and shellings: https://www.globalcitizen.org/en/content/ways-to-help-ukraine-conflict/
> - Put pressure on your political representatives to provide help to Ukraine.
> - Believe in the Ukrainian people, they will not surrender, they don't have another Ukraine.
>
> THANK YOU!
----
# jms/serializer
[![GitHub Actions][GA Image]][GA Link]
[![Packagist][Packagist Image]][Packagist Link]
![alt text](doc/logo-small.png)
## Introduction
This library allows you to (de-)serialize data of any complexity. Currently, it supports XML and JSON.
It also provides you with a rich tool-set to adapt the output to your specific needs.
Built-in features include:
- (De-)serialize data of any complexity; circular references and complex exclusion strategies are handled gracefully.
- Supports many built-in PHP types (such as dates, intervals)
- Integrates with Doctrine ORM, et. al.
- Supports versioning, e.g. for APIs
- Configurable via XML, YAML, or Annotations
## Documentation
Learn more about the serializer in its [documentation](http://jmsyst.com/libs/serializer).
## Notes
You are browsing the code for the 3.x version, if you are interested in the 1.x or 2.x version,
check the [1.x][1.x] and [2.x][2.x] branches.
The version `3.x` is the supported version (`master` branch).
The `1.x` and `2.x` versions are not supported anymore.
For the `1.x` and `2.x` branches there will be no additional feature releases.
Security issues will be fixed till the 1st January 2020 and
only critical bugs might receive fixes until the 1st September 2019.
Instructions on how to upgrade to 3.x are available in the [UPGRADING][UPGRADING] document.
## Professional Support
For eventual paid support please write an email to [goetas@gmail.com](mailto:goetas@gmail.com).
[CHANGELOG]: https://github.com/schmittjoh/serializer/blob/master/CHANGELOG.md
[UPGRADING]: https://github.com/schmittjoh/serializer/blob/master/UPGRADING.md
[GA Image]: https://github.com/schmittjoh/serializer/workflows/CI/badge.svg
[GA Link]: https://github.com/schmittjoh/serializer/actions?query=workflow%3A%22CI%22+branch%3Amaster
[Packagist Image]: https://img.shields.io/packagist/v/jms/serializer.svg
[Packagist Link]: https://packagist.org/packages/jms/serializer
[1.x]: https://github.com/schmittjoh/serializer/tree/1.x
[2.x]: https://github.com/schmittjoh/serializer/tree/2.x

View File

@@ -1,114 +0,0 @@
Unreleased
==========
- Use symfony/cache for FileSystem cache implementation instead of doctrine/cache
- Deprecated the `@ReadOnly` annotation due to `readonly` becoming a keyword in PHP 8.1, use the `@ReadOnlyProperty` annotation instead
- Doctrine type `decimal` is now correctly mapped to `string` instead of `float`
- `@var/param list<T>` is now mapped to `list<T>` type instead of `array<int, T>`
From 3.x to 3.30.0
==================
Starting from this release [doctrine/annotations](https://github.com/doctrine/annotations) is an optional package.
If you still want to use them, please make sure that you require in `composer.json` file.
We strongly recommend to start using [Attributes](https://www.php.net/manual/en/language.attributes.overview.php) with PHP 8.
You can easily migrate annotations to attributes with [rector](https://github.com/rectorphp/rector) and `Rector\Symfony\Set\SymfonySetList::ANNOTATIONS_TO_ATTRIBUTES` rules.
From 2.x to 3.0.0
=================
Upgrading from 2.x to 3.x should require almost no effort.
The only change is the revert of "deeper branch group exclusion strategy" introduced in 2.0.0 and now reverted as it
was in 1.x. If you are not using this feature, then upgrading requires no changes at all.
The deprecations introduced in 2.x are still present in 3.0.0, said features are most likely to be removed in the next major version.
From 1.x to 3.0.0
=================
Please follow the upgrade **"From 1.13.0 to 2.0.0"**, skipping the section:
> "deeper branch group exclusion strategy" has a different behaviour, the latest group is used instead of falling back to "Default"
The deprecations introduced in 2.x are still present in 3.0.0, said features are most likley to be removed in an next major.
From 1.13.0 to 2.0.0
====================
If you are on version `1.x`, it is suggested to migrate directly to `3.0.0` (since `2.x` is not maintained anymore).
**Main changes**
- The minimum PHP version is 7.2, type hints are used almost everywhere, most of the method signatures changed
- `JsonSerializationVisitor::getRoot` and `JsonSerializationVisitor::setRoot` have been removed, their
use is not necessary anymore
- Removed `AdvancedNamingStrategyInterface`, the serialized name is now compiled and can not be changed at runtime
- "deeper branch group exclusion strategy" has a different behaviour, the latest group is used instead of falling back
to "Default"
- Most of the classes are marked as `final`, inheritance is discouraged for all the cases, use composition instead
- Most of the visitor configurations and options have been moved to visitor factories
- Removed the abstract classes `GenericSerializationVisitor` and `GenericDeserializationVisitor`.
- Removed deprecated method `VisitorInterface::getNavigator`, use `Context::getNavigator` instead
- Removed deprecated method `JsonSerializationVisitor::addData`,
use `::visitProperty(new StaticPropertyMetadata('', 'name', 'value'), 'value')` instead
- Removed Propel and PhpCollection support
- Changed default date format from ISO8601 to RFC3339
- Event listeners/handlers class names are case sensitive now
- Removed `AbstractVisitor::getNamingStrategy` method
- Removed Symfony 2.x support
- Removed YAML serialization support
- Removed PHP Driver metadata support
- Removed in-object handler callbacks (`@HandlerCallback` annotation), use event listeners instead
- Changed `SerializerInterface::serialize` signature
- Changed `ArrayTransformerInterface::toArray` signature
- Changed `GraphNavigator::accept` signature
- Removed `Serializer::setSerializationContextFactory` and `Serializer::setDeserializationContextFactory`
- Removed `Serializer::getMetadataFactory`
- As default now JSON preserves trailing zeros when serializing a float
- When using a discriminator map, parent class should either be declared abstract, or included into the discriminator
map
- For the `Context` class (and its childs `SerializationContext` and `DeserializationContext`), `$attributes` property has become `private`, so it's no longer accessible; use `getAttribute()` instead
- When implementing custom type handlers and `$context->shouldSerializeNull()` is `false` (it is `false` by default),
handlers should throw `NotAcceptableException` exception when `null` is visited.
Before:
```php
public function serializeDateTimeToJson(JsonSerializationVisitor $visitor, $data, array $type, Context $context)
{
// handle custom serialization here
return $data;
}
```
After:
```php
public function serializeDateTimeToJson(JsonSerializationVisitor $visitor, $data, array $type, Context $context)
{
if (!$context->shouldSerializeNull() && $data === null) {
throw new NotAcceptableException();
}
// handle custom serialization here
return $data;
}
```
**Deprecations** (will be removed in 4.0)
- `JsonSerializationVisitor::setData` will be removed,
use `::visitProperty(new StaticPropertyMetadata('', 'name', 'value'), 'value')` instead
- `JsonSerializationVisitor::hasData` will be removed
- `VisitorInterface` is internal, use `SerializationVisitorInterface` and `DeserializationVisitorInterface` instead
- `GraphNavigator` is internal, use `GraphNavigatorInterface` instead
- `enum<'Type'>` and similar are deprecated, use `enum<Type>` instead
**Other**
- Elements (as classes, interfaces, methods, properties...)
marked as `@internal` shall not be used in user-land code. BC is not guaranteed on this elements.
- PSR-4 is used
- [Here](https://github.com/schmittjoh/serializer/milestone/3) a list of issues and pull requests landed in 2.0

View File

@@ -1,84 +0,0 @@
{
"name": "jms/serializer",
"type": "library",
"description": "Library for (de-)serializing data of any complexity; supports XML, and JSON.",
"keywords": [
"serialization",
"deserialization",
"json",
"jaxb",
"xml"
],
"homepage": "http://jmsyst.com/libs/serializer",
"license": "MIT",
"authors": [
{
"name": "Johannes M. Schmitt",
"email": "schmittjoh@gmail.com"
},
{
"name": "Asmir Mustafic",
"email": "goetas@gmail.com"
}
],
"require": {
"php": "^7.4 || ^8.0",
"doctrine/instantiator": "^1.3.1 || ^2.0",
"doctrine/lexer": "^2.0 || ^3.0",
"jms/metadata": "^2.6",
"phpstan/phpdoc-parser": "^1.20 || ^2.0"
},
"suggest": {
"doctrine/collections": "Required if you like to use doctrine collection types as ArrayCollection.",
"symfony/cache": "Required if you like to use cache functionality.",
"symfony/uid": "Required if you'd like to serialize UID objects.",
"symfony/yaml": "Required if you'd like to use the YAML metadata format."
},
"require-dev": {
"ext-pdo_sqlite": "*",
"doctrine/annotations": "^1.14 || ^2.0",
"slevomat/coding-standard": "dev-master#f2cc4c553eae68772624ffd7dd99022343b69c31 as 8.11.9999",
"doctrine/coding-standard": "^12.0",
"doctrine/orm": "^2.14 || ^3.0",
"doctrine/persistence": "^2.5.2 || ^3.0",
"doctrine/phpcr-odm": "^1.5.2 || ^2.0",
"jackalope/jackalope-doctrine-dbal": "^1.3",
"ocramius/proxy-manager": "^1.0 || ^2.0",
"phpbench/phpbench": "^1.0",
"phpstan/phpstan": "^2.0",
"phpunit/phpunit": "^9.0 || ^10.0 || ^11.0",
"psr/container": "^1.0 || ^2.0",
"rector/rector": "^1.0.0 || ^2.0@dev",
"symfony/dependency-injection": "^5.4 || ^6.0 || ^7.0",
"symfony/expression-language": "^5.4 || ^6.0 || ^7.0",
"symfony/filesystem": "^5.4 || ^6.0 || ^7.0",
"symfony/form": "^5.4 || ^6.0 || ^7.0",
"symfony/translation": "^5.4 || ^6.0 || ^7.0",
"symfony/uid": "^5.4 || ^6.0 || ^7.0",
"symfony/validator": "^5.4 || ^6.0 || ^7.0",
"symfony/yaml": "^5.4 || ^6.0 || ^7.0",
"twig/twig": "^1.34 || ^2.4 || ^3.0"
},
"autoload": {
"psr-4": {
"JMS\\Serializer\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"JMS\\Serializer\\Tests\\": "tests/"
}
},
"config": {
"sort-packages": true,
"allow-plugins": {
"composer/package-versions-deprecated": true,
"dealerdirect/phpcodesniffer-composer-installer": true
}
},
"extra": {
"branch-alias": {
"dev-master": "3.x-dev"
}
}
}

View File

@@ -1,55 +0,0 @@
THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.
BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS.
1. Definitions
"Adaptation" means a work based upon the Work, or upon the Work and other pre-existing works, such as a translation, adaptation, derivative work, arrangement of music or other alterations of a literary or artistic work, or phonogram or performance and includes cinematographic adaptations or any other form in which the Work may be recast, transformed, or adapted including in any form recognizably derived from the original, except that a work that constitutes a Collection will not be considered an Adaptation for the purpose of this License. For the avoidance of doubt, where the Work is a musical work, performance or phonogram, the synchronization of the Work in timed-relation with a moving image ("synching") will be considered an Adaptation for the purpose of this License.
"Collection" means a collection of literary or artistic works, such as encyclopedias and anthologies, or performances, phonograms or broadcasts, or other works or subject matter other than works listed in Section 1(f) below, which, by reason of the selection and arrangement of their contents, constitute intellectual creations, in which the Work is included in its entirety in unmodified form along with one or more other contributions, each constituting separate and independent works in themselves, which together are assembled into a collective whole. A work that constitutes a Collection will not be considered an Adaptation (as defined above) for the purposes of this License.
"Distribute" means to make available to the public the original and copies of the Work through sale or other transfer of ownership.
"Licensor" means the individual, individuals, entity or entities that offer(s) the Work under the terms of this License.
"Original Author" means, in the case of a literary or artistic work, the individual, individuals, entity or entities who created the Work or if no individual or entity can be identified, the publisher; and in addition (i) in the case of a performance the actors, singers, musicians, dancers, and other persons who act, sing, deliver, declaim, play in, interpret or otherwise perform literary or artistic works or expressions of folklore; (ii) in the case of a phonogram the producer being the person or legal entity who first fixes the sounds of a performance or other sounds; and, (iii) in the case of broadcasts, the organization that transmits the broadcast.
"Work" means the literary and/or artistic work offered under the terms of this License including without limitation any production in the literary, scientific and artistic domain, whatever may be the mode or form of its expression including digital form, such as a book, pamphlet and other writing; a lecture, address, sermon or other work of the same nature; a dramatic or dramatico-musical work; a choreographic work or entertainment in dumb show; a musical composition with or without words; a cinematographic work to which are assimilated works expressed by a process analogous to cinematography; a work of drawing, painting, architecture, sculpture, engraving or lithography; a photographic work to which are assimilated works expressed by a process analogous to photography; a work of applied art; an illustration, map, plan, sketch or three-dimensional work relative to geography, topography, architecture or science; a performance; a broadcast; a phonogram; a compilation of data to the extent it is protected as a copyrightable work; or a work performed by a variety or circus performer to the extent it is not otherwise considered a literary or artistic work.
"You" means an individual or entity exercising rights under this License who has not previously violated the terms of this License with respect to the Work, or who has received express permission from the Licensor to exercise rights under this License despite a previous violation.
"Publicly Perform" means to perform public recitations of the Work and to communicate to the public those public recitations, by any means or process, including by wire or wireless means or public digital performances; to make available to the public Works in such a way that members of the public may access these Works from a place and at a place individually chosen by them; to perform the Work to the public by any means or process and the communication to the public of the performances of the Work, including by public digital performance; to broadcast and rebroadcast the Work by any means including signs, sounds or images.
"Reproduce" means to make copies of the Work by any means including without limitation by sound or visual recordings and the right of fixation and reproducing fixations of the Work, including storage of a protected performance or phonogram in digital form or other electronic medium.
2. Fair Dealing Rights. Nothing in this License is intended to reduce, limit, or restrict any uses free from copyright or rights arising from limitations or exceptions that are provided for in connection with the copyright protection under copyright law or other applicable laws.
3. License Grant. Subject to the terms and conditions of this License, Licensor hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the duration of the applicable copyright) license to exercise the rights in the Work as stated below:
to Reproduce the Work, to incorporate the Work into one or more Collections, and to Reproduce the Work as incorporated in the Collections; and,
to Distribute and Publicly Perform the Work including as incorporated in Collections.
The above rights may be exercised in all media and formats whether now known or hereafter devised. The above rights include the right to make such modifications as are technically necessary to exercise the rights in other media and formats, but otherwise you have no rights to make Adaptations. Subject to 8(f), all rights not expressly granted by Licensor are hereby reserved, including but not limited to the rights set forth in Section 4(d).
4. Restrictions. The license granted in Section 3 above is expressly made subject to and limited by the following restrictions:
You may Distribute or Publicly Perform the Work only under the terms of this License. You must include a copy of, or the Uniform Resource Identifier (URI) for, this License with every copy of the Work You Distribute or Publicly Perform. You may not offer or impose any terms on the Work that restrict the terms of this License or the ability of the recipient of the Work to exercise the rights granted to that recipient under the terms of the License. You may not sublicense the Work. You must keep intact all notices that refer to this License and to the disclaimer of warranties with every copy of the Work You Distribute or Publicly Perform. When You Distribute or Publicly Perform the Work, You may not impose any effective technological measures on the Work that restrict the ability of a recipient of the Work from You to exercise the rights granted to that recipient under the terms of the License. This Section 4(a) applies to the Work as incorporated in a Collection, but this does not require the Collection apart from the Work itself to be made subject to the terms of this License. If You create a Collection, upon notice from any Licensor You must, to the extent practicable, remove from the Collection any credit as required by Section 4(c), as requested.
You may not exercise any of the rights granted to You in Section 3 above in any manner that is primarily intended for or directed toward commercial advantage or private monetary compensation. The exchange of the Work for other copyrighted works by means of digital file-sharing or otherwise shall not be considered to be intended for or directed toward commercial advantage or private monetary compensation, provided there is no payment of any monetary compensation in connection with the exchange of copyrighted works.
If You Distribute, or Publicly Perform the Work or Collections, You must, unless a request has been made pursuant to Section 4(a), keep intact all copyright notices for the Work and provide, reasonable to the medium or means You are utilizing: (i) the name of the Original Author (or pseudonym, if applicable) if supplied, and/or if the Original Author and/or Licensor designate another party or parties (e.g., a sponsor institute, publishing entity, journal) for attribution ("Attribution Parties") in Licensor's copyright notice, terms of service or by other reasonable means, the name of such party or parties; (ii) the title of the Work if supplied; (iii) to the extent reasonably practicable, the URI, if any, that Licensor specifies to be associated with the Work, unless such URI does not refer to the copyright notice or licensing information for the Work. The credit required by this Section 4(c) may be implemented in any reasonable manner; provided, however, that in the case of a Collection, at a minimum such credit will appear, if a credit for all contributing authors of Collection appears, then as part of these credits and in a manner at least as prominent as the credits for the other contributing authors. For the avoidance of doubt, You may only use the credit required by this Section for the purpose of attribution in the manner set out above and, by exercising Your rights under this License, You may not implicitly or explicitly assert or imply any connection with, sponsorship or endorsement by the Original Author, Licensor and/or Attribution Parties, as appropriate, of You or Your use of the Work, without the separate, express prior written permission of the Original Author, Licensor and/or Attribution Parties.
For the avoidance of doubt:
Non-waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme cannot be waived, the Licensor reserves the exclusive right to collect such royalties for any exercise by You of the rights granted under this License;
Waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme can be waived, the Licensor reserves the exclusive right to collect such royalties for any exercise by You of the rights granted under this License if Your exercise of such rights is for a purpose or use which is otherwise than noncommercial as permitted under Section 4(b) and otherwise waives the right to collect royalties through any statutory or compulsory licensing scheme; and,
Voluntary License Schemes. The Licensor reserves the right to collect royalties, whether individually or, in the event that the Licensor is a member of a collecting society that administers voluntary licensing schemes, via that society, from any exercise by You of the rights granted under this License that is for a purpose or use which is otherwise than noncommercial as permitted under Section 4(b).
Except as otherwise agreed in writing by the Licensor or as may be otherwise permitted by applicable law, if You Reproduce, Distribute or Publicly Perform the Work either by itself or as part of any Collections, You must not distort, mutilate, modify or take other derogatory action in relation to the Work which would be prejudicial to the Original Author's honor or reputation.
5. Representations, Warranties and Disclaimer
UNLESS OTHERWISE MUTUALLY AGREED BY THE PARTIES IN WRITING, LICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.
6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
7. Termination
This License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License. Individuals or entities who have received Collections from You under this License, however, will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this License.
Subject to the above terms and conditions, the license granted here is perpetual (for the duration of the applicable copyright in the Work). Notwithstanding the above, Licensor reserves the right to release the Work under different license terms or to stop distributing the Work at any time; provided, however that any such election will not serve to withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated above.
8. Miscellaneous
Each time You Distribute or Publicly Perform the Work or a Collection, the Licensor offers to the recipient a license to the Work on the same terms and conditions as the license granted to You under this License.
If any provision of this License is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action by the parties to this agreement, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
No term or provision of this License shall be deemed waived and no breach consented to unless such waiver or consent shall be in writing and signed by the party to be charged with such waiver or consent.
This License constitutes the entire agreement between the parties with respect to the Work licensed here. There are no understandings, agreements or representations with respect to the Work not specified here. Licensor shall not be bound by any additional provisions that may appear in any communication from You. This License may not be modified without the mutual written agreement of the Licensor and You.
The rights granted under, and the subject matter referenced, in this License were drafted utilizing the terminology of the Berne Convention for the Protection of Literary and Artistic Works (as amended on September 28, 1979), the Rome Convention of 1961, the WIPO Copyright Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 and the Universal Copyright Convention (as revised on July 24, 1971). These rights and subject matter take effect in the relevant jurisdiction in which the License terms are sought to be enforced according to the corresponding provisions of the implementation of those treaty provisions in the applicable national law. If the standard suite of rights granted under applicable copyright law includes additional rights not granted under this License, such additional rights are deemed to be included in the License; this License is not intended to restrict the license of any rights under applicable law.

View File

@@ -1,41 +0,0 @@
# -*- coding: utf-8 -*-
import sys, os
# -- General configuration -----------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['sensio.sphinx.configurationblock', 'sensio.sphinx.phpcode']
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix of source filenames.
source_suffix = '.rst'
# The master toctree document.
master_doc = 'index'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = ['_build']
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# This will be used when using the shorthand notation
highlight_language = 'php'
# -- Options for HTML output ---------------------------------------------------
import sphinx_rtd_theme
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
html_theme = 'sphinx_rtd_theme'
# Add any paths that contain custom themes here, relative to this directory.
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
# Output file base name for HTML help builder.
htmlhelp_basename = 'doc'

View File

@@ -1,106 +0,0 @@
Configuration
=============
.. note ::
If you are using Symfony2, this section is mostly irrelevant for you as the entire integration is provided by
JMSSerializerBundle; please see `its documentation <http://jmsyst.com/bundles/JMSSerializerBundle>`_. If you are
using another framework, there also might be a module, or other special integration. Please check packagist, or
whatever registry usually holds such information for your framework.
If you are using the standalone library and you want to use annotations, the annotation registry must be initialized::
Doctrine\Common\Annotations\AnnotationRegistry::registerLoader('class_exists');
Constructing a Serializer
-------------------------
This library provides a special builder object which makes constructing serializer instances a breeze in any PHP
project. In its shortest version, it's just a single line of code::
$serializer = JMS\Serializer\SerializerBuilder::create()->build();
This serializer is fully functional, but you might want to tweak it a bit for example to configure a cache directory.
Configuring a Cache Directory
-----------------------------
The serializer collects several metadata about your objects from various sources such as YML, XML, or annotations. In
order to make this process as efficient as possible, it is encourage to let the serializer cache that information. For
that, you can configure a cache directory::
$builder = new JMS\Serializer\SerializerBuilder();
$serializer =
JMS\Serializer\SerializerBuilder::create()
->setCacheDir($someWritableDir)
->setDebug($trueOrFalse)
->build();
As you can see, we also added a call to the ``setDebug`` method. In debug mode, the serializer will perform a bit more
filesystem checks to see whether the data that it has cached is still valid. These checks are useful during development
so that you do not need to manually clear cache folders, however in production they are just unnecessary overhead. The
debug setting allows you to make the behavior environment specific.
Adding Custom Handlers
----------------------
If you have created custom handlers, you can add them to the serializer easily::
$serializer =
JMS\Serializer\SerializerBuilder::create()
->addDefaultHandlers()
->configureHandlers(function(JMS\Serializer\Handler\HandlerRegistry $registry) {
$registry->registerHandler(JMS\Serializer\GraphNavigatorInterface::DIRECTION_SERIALIZATION, 'MyObject', 'json',
function($visitor, MyObject $obj, array $type) {
return $obj->getName();
}
);
})
->build();
For more complex handlers, it is advisable to extract them to dedicated classes,
see :doc:`handlers documentation <handlers>`.
Configuring Metadata Locations
------------------------------
This library supports several metadata sources. By default, it uses Doctrine annotations, but you may also store
metadata in XML, or YML files. For the latter, it is necessary to configure a metadata directory where those files
are located::
$serializer =
JMS\Serializer\SerializerBuilder::create()
->addMetadataDir($someDir)
->build();
The serializer would expect the metadata files to be named like the fully qualified class names where all ``\`` are
replaced with ``.``. So, if you class would be named ``Vendor\Package\Foo``, the metadata file would need to be located
at ``$someDir/Vendor.Package.Foo.(xml|yml)``. If not found, ``$someDir/Vendor.Package.(xml|yml)`` will be tried, then ``$someDir/Vendor.Package.(xml|yml)`` and so on. For more information, see the :doc:`reference <reference>`.
Setting a default SerializationContext factory
----------------------------------------------
To avoid to pass an instance of SerializationContext
every time you call method ``serialize()`` (or ``toArray()``),
you can set a ``SerializationContextFactory`` to the Serializer.
Example using the SerializerBuilder::
use JMS\Serializer\SerializationContext;
$serializer = JMS\Serializer\SerializerBuilder::create()
->setSerializationContextFactory(function () {
return SerializationContext::create()
->setSerializeNull(true)
;
})
->build()
;
Then, calling ``$serializer->serialize($data, 'json');`` will generate
a serialization context from your callable and use it.
.. note ::
You can also set a default DeserializationContextFactory with
``->setDeserializationContextFactory(function () { /* ... */ })``
to be used with methods ``deserialize()`` and ``fromArray()``.

View File

@@ -1,7 +0,0 @@
Cookbook
========
.. toctree ::
:glob:
cookbook/*

View File

@@ -1,47 +0,0 @@
Serializing arrays and hashes
=============================
Introduction
------------
Serializing arrays and hashes (a concept that in PHP has not explicit boundaries)
can be challenging. The serializer offers via ``@Type`` annotation different options
to configure its behavior, but if we try to serialize directly an array
(not as a property of an object), we need to use context information to determine the
array "type"
Examples
--------
In case of a JSON serialization:
.. code-block :: php
<?php
// default (let the PHP's json_encode function decide)
$serializer->serialize([1, 2]); // [1, 2]
$serializer->serialize(['a', 'b']); // ['a', 'b']
$serializer->serialize(['c' => 'd']); // {"c" => "d"}
// same as default (let the PHP's json_encode function decide)
$serializer->serialize([1, 2], SerializationContext::create()->setInitialType('array')); // [1, 2]
$serializer->serialize([1 => 2], SerializationContext::create()->setInitialType('array')); // {"1": 2}
$serializer->serialize(['a', 'b'], SerializationContext::create()->setInitialType('array')); // ['a', 'b']
$serializer->serialize(['c' => 'd'], SerializationContext::create()->setInitialType('array')); // {"c" => "d"}
// typehint as strict array, keys will be always discarded
$serializer->serialize([], SerializationContext::create()->setInitialType('array<integer>')); // []
$serializer->serialize([1, 2], SerializationContext::create()->setInitialType('array<integer>')); // [1, 2]
$serializer->serialize(['a', 'b'], SerializationContext::create()->setInitialType('array<integer>')); // ['a', 'b']
$serializer->serialize(['c' => 'd'], SerializationContext::create()->setInitialType('array<string>')); // ["d"]
// typehint as hash, keys will be always considered
$serializer->serialize([], SerializationContext::create()->setInitialType('array<integer,integer>')); // {}
$serializer->serialize([1, 2], SerializationContext::create()->setInitialType('array<integer,integer>')); // {"0" : 1, "1" : 2}
$serializer->serialize(['a', 'b'], SerializationContext::create()->setInitialType('array<integer,integer>')); // {"0" : "a", "1" : "b"}
$serializer->serialize(['c' => 'd'], SerializationContext::create()->setInitialType('array<string,string>')); // {"c" : "d"}
.. note ::
This applies only for the JSON serialization.

View File

@@ -1,408 +0,0 @@
Exclusion Strategies
====================
Introduction
------------
The serializer supports different exclusion strategies. Each strategy allows
you to define which properties of your objects should be serialized.
General Exclusion Strategies
----------------------------
If you would like to always expose, or exclude certain properties. Then, you can
do this with the annotations ``@ExclusionPolicy``, ``@Exclude``, and ``@Expose``.
The default exclusion policy is to exclude nothing. That is, all properties of the
object will be serialized. If you only want to expose a few of the properties,
then it is easier to change the exclusion policy, and only mark these few properties:
.. code-block :: php
<?php
use JMS\Serializer\Annotation\ExclusionPolicy;
use JMS\Serializer\Annotation\Expose;
/**
* The following annotations tells the serializer to skip all properties which
* have not marked with @Expose.
*
* @ExclusionPolicy("all")
*/
class MyObject
{
private $foo;
private $bar;
/**
* @Expose
*/
private $name;
}
.. note ::
A property that is excluded by ``@Exclude`` cannot be exposed anymore by any
of the following strategies, but is always hidden.
Versioning Objects
------------------
JMSSerializerBundle comes by default with a very neat feature which allows
you to add versioning support to your objects, e.g. if you want to
expose them via an API that is consumed by a third-party:
.. code-block :: php
<?php
class VersionedObject
{
/**
* @Until("1.0.x")
*/
private $name;
/**
* @Since("1.1")
* @SerializedName("name")
*/
private $name2;
}
.. note ::
``@Until``, and ``@Since`` both accept a standardized PHP version number.
If you have annotated your objects like above, you can serializing different
versions like this::
use JMS\Serializer\SerializationContext;
$serializer->serialize(new VersionObject(), 'json', SerializationContext::create()->setVersion(1));
Creating Different Views of Your Objects
----------------------------------------
Another default exclusion strategy is to create different views of your objects.
Let's say you would like to serialize your object in a different view depending
whether it is displayed in a list view or in a details view.
You can achieve that by using the ``@Groups`` annotation on your properties. Any
property without an explicit ``@Groups`` annotation will be included in a
``Default`` group, which can be used when specifying groups in the serialization
context.
.. code-block :: php
use JMS\Serializer\Annotation\Groups;
class BlogPost
{
/** @Groups({"list", "details"}) */
private $id;
/** @Groups({"list", "details"}) */
private $title;
/** @Groups({"list"}) */
private $nbComments;
/** @Groups({"details"}) */
private $comments;
private $createdAt;
}
You can then tell the serializer which groups to serialize in your controller::
use JMS\Serializer\SerializationContext;
$serializer->serialize(new BlogPost(), 'json', SerializationContext::create()->setGroups(array('list')));
//will output $id, $title and $nbComments.
$serializer->serialize(new BlogPost(), 'json', SerializationContext::create()->setGroups(array('Default', 'list')));
//will output $id, $title, $nbComments and $createdAt.
Overriding Groups of Deeper Branches of the Graph
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In some cases you want to control more precisely what is serialized because you may have the same class at different
depths of the object graph.
For example if you have a User that has a manager and friends::
use JMS\Serializer\Annotation\Groups;
class User
{
private $name;
/** @Groups({"manager_group"}) */
private $manager;
/** @Groups({"friends_group"}) */
private $friends;
public function __construct($name, User $manager = null, array $friends = null)
{
$this->name = $name;
$this->manager = $manager;
$this->friends = $friends;
}
}
And the following object graph::
$john = new User(
'John',
new User(
'John Manager',
new User('The boss'),
array(
new User('John Manager friend 1'),
)
),
array(
new User(
'John friend 1',
new User('John friend 1 manager')
),
new User(
'John friend 2',
new User('John friend 2 manager')
),
)
);
You can override groups on specific paths::
use JMS\Serializer\SerializationContext;
$context = SerializationContext::create()->setGroups(array(
'Default', // Serialize John's name
'manager_group', // Serialize John's manager
'friends_group', // Serialize John's friends
'manager' => array( // Override the groups for the manager of John
'Default', // Serialize John manager's name
'friends_group', // Serialize John manager's friends. If you do not override the groups for the friends, it will default to Default.
),
'friends' => array( // Override the groups for the friends of John
'manager_group' // Serialize John friends' managers.
'manager' => array( // Override the groups for the John friends' manager
'Default', // This would be the default if you did not override the groups of the manager property.
),
),
));
$serializer->serialize($john, 'json', $context);
This would result in the following json::
{
"name": "John",
"manager": {
"name": "John Manager",
"friends": [
{
"name": "John Manager friend 1"
}
]
},
"friends": [
{
"manager": {
"name": "John friend 1 manager"
},
},
{
"manager": {
"name": "John friend 2 manager"
},
},
]
}
Deserialization Exclusion Strategy with Groups
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can use ``@Groups`` to cut off unwanted properties while deserialization.
.. code-block:: php
use JMS\Serializer\Annotation\Groups;
class GroupsObject
{
/**
* @Groups({"foo"})
*/
public $foo;
/**
* @Groups({"foo","bar"})
*/
public $foobar;
/**
* @Groups({"bar", "Default"})
*/
public $bar;
/**
* @Type("string")
*/
public $none;
}
.. code-block:: php
$data = [
'foo' => 'foo',
'foobar' => 'foobar',
'bar' => 'bar',
'none' => 'none',
];
$context = DeserializationContext::create()->setGroups(['foo']);
$object = $serializer->fromArray($data, GroupsObject::class, $context);
// $object->foo is 'foo'
// $object->foobar is 'foobar'
// $object->bar is null
// $object->none is null
Limiting serialization depth of some properties
-----------------------------------------------
You can limit the depth of what will be serialized in a property with the
``@MaxDepth`` annotation.
This exclusion strategy is a bit different from the others, because it will
affect the serialized content of others classes than the one you apply the
annotation to.
.. code-block :: php
use JMS\Serializer\Annotation\MaxDepth;
class User
{
private $username;
/** @MaxDepth(1) */
private $friends;
/** @MaxDepth(2) */
private $posts;
}
class Post
{
private $title;
private $author;
}
In this example, serializing a user, because the max depth of the ``$friends``
property is 1, the user friends would be serialized, but not their friends;
and because the the max depth of the ``$posts`` property is 2, the posts would
be serialized, and their author would also be serialized.
You need to tell the serializer to take into account MaxDepth checks::
use JMS\Serializer\SerializationContext;
$serializer->serialize($data, 'json', SerializationContext::create()->enableMaxDepthChecks());
Dynamic exclusion strategy
--------------------------
If the previous exclusion strategies are not enough, is possible to use the ``ExpressionLanguageExclusionStrategy``
that uses the `symfony expression language`_ to
allow a more sophisticated exclusion strategies using ``@Exclude(if="expression")`` and ``@Expose(if="expression")`` methods.
This also works on class level, but is only evaluated during ``serialze`` and does not have any effect during ``deserialze``.
.. code-block :: php
<?php
/**
* @Exclude(if="true")
*/
class MyObject
{
/**
* @Exclude(if="true")
*/
private $name;
/**
* @Expose(if="true")
*/
private $name2;
}
.. note ::
``true`` is just a generic expression, you can use any expression allowed by the Symfony Expression Language
To enable this feature you have to set the Expression Evaluator when initializing the serializer.
.. code-block :: php
<?php
use JMS\Serializer\Expression\ExpressionEvaluator;
use JMS\Serializer\Expression\SerializerBuilder;
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
$serializer = SerializerBuilder::create()
->setExpressionEvaluator(new ExpressionEvaluator(new ExpressionLanguage()))
->build();
.. _symfony expression language: https://github.com/symfony/expression-language
By default the serializer exposes three variables (`object`, `context` and `property_metadata` for use in an expression. This enables you to create custom exclusion strategies similar to i.e. the `GroupExclusionStrategy`_. In the below example, `someMethod` would receive all three variables.
.. code-block :: php
<?php
class MyObject
{
/**
* @Exclude(if="someMethod(object, context, property_metadata)")
*/
private $name;
/**
* @Expose(if="someMethod(object, context, property_metadata)")
*/
private $name2;
}
.. _GroupExclusionStrategy: https://github.com/schmittjoh/serializer/blob/master/src/Exclusion/GroupsExclusionStrategy.php
Using dynamic excludes on class level is also handy when you need to filter out certain objects in a collection, for example based on user permissions.
The following example shows how to exclude `Account` objects when serializing the `Person` object, if the `Account` is either expired or the user does not have the permission to view the account by calling `is_granted` with the `Account` object.
.. code-block :: php
<?php
class Person
{
/**
* @Type("array<Account>")
*/
public $accounts;
}
/**
* @Exclude(if="object.expired || !is_granted('view',object)")
*/
class Account
{
/**
* @Type("boolean")
*/
public $expired;
}

View File

@@ -1,56 +0,0 @@
Object constructor
==================
Deserialize on existing objects
-------------------------------
By default, a brand new instance of target class is created during deserialization. To deserialize into an existing object, you need to perform the following steps.
1. Create new class which implements ObjectConstructorInterface
.. code-block:: php
<?php declare(strict_types=1);
namespace Acme\ObjectConstructor;
use JMS\Serializer\Construction\ObjectConstructorInterface;
use JMS\Serializer\DeserializationContext;
use JMS\Serializer\Metadata\ClassMetadata;
use JMS\Serializer\Visitor\DeserializationVisitorInterface;
class ExistingObjectConstructor implements ObjectConstructorInterface
{
public const ATTRIBUTE = 'deserialization-constructor-target';
private $fallbackConstructor;
public function __construct(ObjectConstructorInterface $fallbackConstructor)
{
$this->fallbackConstructor = $fallbackConstructor;
}
public function construct(DeserializationVisitorInterface $visitor, ClassMetadata $metadata, $data, array $type, DeserializationContext $context): ?object
{
if ($context->hasAttribute(self::ATTRIBUTE)) {
return $context->getAttribute(self::ATTRIBUTE);
}
return $this->fallbackConstructor->construct($visitor, $metadata, $data, $type, $context);
}
}
2. Register ExistingObjectConstructor.
You should pass ExistingObjectConstructor to DeserializationGraphNavigatorFactory constructor.
3. Add special attribute to DeserializationContext
.. code-block:: php
$context = DeserializationContext::create();
$context->setAttribute('deserialization-constructor-target', $document);
$serializer->deserialize($data, get_class($document), 'json');

View File

@@ -1,16 +0,0 @@
stdClass
========
The serializer offers support for serializing ``stdClass`` objects, however the use of
``stdClass`` objects is discouraged.
The current implementation serializes all the properties of a ``stdClass`` object in
the order they appear.
There are many known limitations when dealing with ``stdClass`` objects.
More in detail, it is not possible to:
- change serialization order of properties
- apply per-property exclusion policies
- specify any extra serialization information for properties that are part of the ``stdClass`` object, as serialization name, type, xml structure and so on
- deserialize data into ``stdClass`` objects

View File

@@ -1,85 +0,0 @@
Event System
============
The serializer dispatches different events during the serialization, and
deserialization process which you can use to hook in and alter the default
behavior.
Register an Event Listener, or Subscriber
-----------------------------------------
The difference between listeners, and subscribers is that listener do not know to which events they listen
while subscribers contain that information. Thus, subscribers are easier to share, and re-use. Listeners
on the other hand, can be simple callables and do not require a dedicated class.
.. code-block :: php
class MyEventSubscriber implements JMS\Serializer\EventDispatcher\EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return array(
array(
'event' => 'serializer.pre_serialize',
'method' => 'onPreSerialize',
'class' => 'AppBundle\\Entity\\SpecificClass', // if no class, subscribe to every serialization
'format' => 'json', // optional format
'priority' => 0, // optional priority
),
);
}
public function onPreSerialize(JMS\Serializer\EventDispatcher\PreSerializeEvent $event)
{
// do something
}
}
$builder
->configureListeners(function(JMS\Serializer\EventDispatcher\EventDispatcher $dispatcher) {
$dispatcher->addListener('serializer.pre_serialize',
function(JMS\Serializer\EventDispatcher\PreSerializeEvent $event) {
// do something
}
);
$dispatcher->addSubscriber(new MyEventSubscriber());
})
;
Events
------
serializer.pre_serialize
~~~~~~~~~~~~~~~~~~~~~~~~
This is dispatched before a type is visited. You have access to the visitor,
data, and type. Listeners may modify the type that is being used for
serialization.
**Event Object**: ``JMS\Serializer\EventDispatcher\PreSerializeEvent``
serializer.post_serialize
~~~~~~~~~~~~~~~~~~~~~~~~~
This is dispatched right before a type is left. You can for example use this
to add additional data for an object that you normally do not save inside
objects such as links.
**Event Object**: ``JMS\Serializer\EventDispatcher\ObjectEvent``
serializer.pre_deserialize
~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. versionadded : 0.12
Event was added
This is dispatched before an object is deserialized. You can use this to
modify submitted data, or modify the type that is being used for deserialization.
**Event Object**: ``JMS\Serializer\EventDispatcher\PreDeserializeEvent``
serializer.post_deserialize
~~~~~~~~~~~~~~~~~~~~~~~~~~~
This is dispatched after a type is processed. You can use it to normalize
submitted data if you require external services for example, or also to
perform validation of the submitted data.
**Event Object**: ``JMS\Serializer\EventDispatcher\ObjectEvent``

View File

@@ -1,85 +0,0 @@
Handlers
========
Introduction
------------
Handlers allow you to change the serialization, or deserialization process
for a single type/format combination.
Handlers are simple callback which receive three arguments: the visitor,
the data, and the type.
Simple Callables
----------------
You can register simple callables on the builder object::
$builder
->configureHandlers(function(JMS\Serializer\Handler\HandlerRegistry $registry) {
$registry->registerHandler('serialization', 'MyObject', 'json',
function($visitor, MyObject $obj, array $type) {
return $obj->getName();
}
);
})
;
.. note ::
Be aware that when you call `configureHandlers` default handlers (like `DateHandler`)
won't be added and you will have to call `addDefaultHandlers` on the Builder
Subscribing Handlers
--------------------
Subscribing handlers contain the configuration themselves which makes them easier to share with other users,
and easier to set-up in general::
use JMS\Serializer\Handler\SubscribingHandlerInterface;
use JMS\Serializer\GraphNavigator;
use JMS\Serializer\JsonSerializationVisitor;
use JMS\Serializer\JsonDeserializationVisitor;
use JMS\Serializer\Context;
class MyHandler implements SubscribingHandlerInterface
{
public static function getSubscribingMethods()
{
return [
[
'direction' => GraphNavigator::DIRECTION_SERIALIZATION,
'format' => 'json',
'type' => 'DateTime',
'method' => 'serializeDateTimeToJson',
],
[
'direction' => GraphNavigator::DIRECTION_DESERIALIZATION,
'format' => 'json',
'type' => 'DateTime',
'method' => 'deserializeDateTimeToJson',
],
];
}
public function serializeDateTimeToJson(JsonSerializationVisitor $visitor, \DateTime $date, array $type, Context $context)
{
return $date->format($type['params'][0]);
}
public function deserializeDateTimeToJson(JsonDeserializationVisitor $visitor, $dateAsString, array $type, Context $context)
{
return new \DateTime($dateAsString);
}
}
Also, this type of handler is registered via the builder object::
$builder
->configureHandlers(function(JMS\Serializer\Handler\HandlerRegistry $registry) {
$registry->registerSubscribingHandler(new MyHandler());
})
;
Skippable Subscribing Handlers
-------------------------------
In case you need to be able to fall back to the default deserialization behavior instead of using your custom
handler, you can simply throw a `SkipHandlerException` from you custom handler method to do so.

View File

@@ -1,62 +0,0 @@
Serializer
==========
.. image:: logo-small.png
Introduction
------------
This library allows you to (de-)serialize data of any complexity. Currently, it supports XML and JSON.
It also provides you with a rich tool-set to adapt the output to your specific needs.
Built-in features include:
- (De-)serialize data of any complexity; circular references are handled gracefully.
- Supports many built-in PHP types (such as dates)
- Integrates with Doctrine ORM, et. al.
- Supports versioning, e.g. for APIs
- Configurable via XML, YAML, or Doctrine Annotations
Installation
------------
This library can be easily installed via composer
.. code-block :: bash
composer require jms/serializer
or just add it to your ``composer.json`` file directly.
Usage
-----
For standalone projects usage of the provided builder is encouraged::
$serializer = JMS\Serializer\SerializerBuilder::create()->build();
$jsonContent = $serializer->serialize($data, 'json');
echo $jsonContent; // or return it in a Response
Documentation
-------------
.. toctree ::
:maxdepth: 2
configuration
usage
event_system
handlers
reference
cookbook
License
-------
The code is released under the business-friendly `MIT license`_.
Documentation is subject to the `Attribution-NonCommercial-NoDerivs 3.0 Unported
license`_.
.. _MIT license: https://opensource.org/licenses/MIT
.. _Attribution-NonCommercial-NoDerivs 3.0 Unported license: http://creativecommons.org/licenses/by-nc-nd/3.0/

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

View File

@@ -1,8 +0,0 @@
Reference
=========
.. toctree ::
:glob:
:maxdepth: 1
reference/*

File diff suppressed because it is too large Load Diff

View File

@@ -1,112 +0,0 @@
XML Reference
-------------
::
<!-- MyBundle\Resources\config\serializer\Fully.Qualified.ClassName.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<serializer>
<class name="Fully\Qualified\ClassName" exclusion-policy="ALL" xml-root-name="foo-bar" exclude="true"
exclude-if="expr" accessor-order="custom" custom-accessor-order="propertyName1,propertyName2,...,propertyNameN"
access-type="public_method" discriminator-field-name="type" discriminator-disabled="false" read-only="false">
<xml-namespace prefix="atom" uri="http://www.w3.org/2005/Atom"/>
<xml-discriminator attribute="true" cdata="false" namespace=""/>
<discriminator-class value="some-value">ClassName</discriminator-class>
<discriminator-groups>
<group>foo</group>
</discriminator-groups>
<property name="some-property"
exclude="true"
expose="true"
exclude-if="expr"
expose-if="expr"
skip-when-empty="false"
type="string"
serialized-name="foo"
since-version="1.0"
until-version="1.1"
xml-attribute="true"
xml-value="true"
access-type="public_method"
accessor-getter="getSomeProperty"
accessor-setter="setSomeProperty"
inline="true"
read-only="true"
groups="foo,bar"
xml-key-value-pairs="true"
xml-attribute-map="true"
max-depth="2"
>
<!-- You can also specify the type as element which is necessary if
your type contains "<" or ">" characters. -->
<type><![CDATA[]]></type>
<xml-list inline="true" entry-name="foobar" namespace="http://www.w3.org/2005/Atom" skip-when-empty="true" />
<xml-map inline="true" key-attribute-name="foo" entry-name="bar" namespace="http://www.w3.org/2005/Atom" />
<xml-element cdata="false" namespace="http://www.w3.org/2005/Atom"/>
<groups>
<value>foo</value>
<value>bar</value>
</groups>
<union-discriminator field="foo">
<map>
<class key="a">SomeClassFQCN1</class>
<class key="b">SomeClassFQCN2</class>
<class key="c">SomeClassFQCN3</class>
</map>
</union-discriminator>
</property>
<callback-method name="foo" type="pre-serialize" />
<callback-method name="bar" type="post-serialize" />
<callback-method name="baz" type="post-deserialize" />
<virtual-property method="public_method"
name="some-property"
exclude="true"
expose="true"
skip-when-empty="false"
type="string"
serialized-name="foo"
since-version="1.0"
until-version="1.1"
xml-attribute="true"
access-type="public_method"
accessor-getter="getSomeProperty"
accessor-setter="setSomeProperty"
inline="true"
read-only="true"
groups="foo,bar"
xml-key-value-pairs="true"
xml-attribute-map="true"
max-depth="2"
>
<virtual-property expression="object.getName()"
name="some-property"
exclude="true"
expose="true"
type="string"
serialized-name="foo"
since-version="1.0"
until-version="1.1"
xml-attribute="true"
access-type="public_method"
accessor-getter="getSomeProperty"
accessor-setter="setSomeProperty"
inline="true"
read-only="true"
groups="foo,bar"
xml-key-value-pairs="true"
xml-attribute-map="true"
max-depth="2"
>
<!-- You can also specify the type as element which is necessary if
your type contains "<" or ">" characters. -->
<type><![CDATA[]]></type>
<groups>
<value>foo</value>
<value>bar</value>
</groups>
<xml-list inline="true" entry-name="foobar" namespace="http://www.w3.org/2005/Atom" skip-when-empty="true" />
<xml-map inline="true" key-attribute-name="foo" entry-name="bar" namespace="http://www.w3.org/2005/Atom" />
</virtual-property>
</class>
</serializer>

View File

@@ -1,98 +0,0 @@
YAML Reference
--------------
.. code-block :: yaml
# Vendor\MyBundle\Resources\config\serializer\Model.ClassName.yml
Vendor\MyBundle\Model\ClassName:
exclusion_policy: ALL
xml_root_name: foobar
xml_root_namespace: http://your.default.namespace
exclude: true
exclude_if: expr
read_only: false
access_type: public_method # defaults to property
accessor_order: custom
custom_accessor_order: [propertyName1, propertyName2, ..., propertyNameN]
discriminator:
field_name: type
disabled: false
map:
some-value: ClassName
groups: [foo, bar]
xml_attribute: true
xml_element:
cdata: false
namespace: http://www.w3.org/2005/Atom
virtual_properties:
getSomeProperty:
name: optional-prop-name
serialized_name: foo
type: integer
expression_prop:
name: optional-prop-name
exp: object.getName()
serialized_name: foo
type: integer
xml_namespaces:
"": http://your.default.namespace
atom: http://www.w3.org/2005/Atom
properties:
some-property:
exclude: true
expose: true
exclude_if: expr
expose_if: expr
skip_when_empty: false
access_type: public_method # defaults to property
accessor: # access_type must be set to public_method
getter: getSomeOtherProperty
setter: setSomeOtherProperty
type: string
serialized_name: foo
since_version: 1.0
until_version: 1.1
groups: [foo, bar]
xml_attribute: true
xml_value: true
inline: true
read_only: true
xml_key_value_pairs: true
xml_list:
inline: true
entry_name: foo
namespace: http://www.w3.org/2005/Atom
xml_map:
inline: true
key_attribute_name: foo
entry_name: bar
namespace: http://www.w3.org/2005/Atom
xml_attribute_map: true
xml_element:
cdata: false
namespace: http://www.w3.org/2005/Atom
max_depth: 2
union_discriminator:
filed: foo
map:
a: SomeClassFQCN1
b: SomeClassFQCN2
c: SomeClassFQCN3
callback_methods:
pre_serialize: [foo, bar]
post_serialize: [foo, bar]
post_deserialize: [foo, bar]
Constants
---------
In some cases, it may be helpful to reference constants in your YAML files.
You can do this by prefixing the constant with the special `!php/const` syntax.
.. code-block :: yaml
Vendor\MyBundle\Model\ClassName:
properties:
some-property:
serialized_name: !php/const Vendor\MyBundle\Model\ClassName::SOME_CONSTANT

View File

@@ -1,6 +0,0 @@
Sphinx==1.8.5
git+https://github.com/fabpot/sphinx-php.git
sphinx_rtd_theme
Jinja2<3.0
MarkupSafe<2.1
alabaster<0.7.14

View File

@@ -1,36 +0,0 @@
Usage
=====
Serializing Objects
-------------------
Most common usage is probably to serialize objects. This can be achieved
very easily:
.. configuration-block ::
.. code-block :: php
<?php
$serializer = JMS\Serializer\SerializerBuilder::create()->build();
$serializer->serialize($object, 'json');
$serializer->serialize($object, 'xml');
.. code-block :: jinja
{{ object | serialize }} {# uses JSON #}
{{ object | serialize('json') }}
{{ object | serialize('xml') }}
Deserializing Objects
---------------------
You can also deserialize objects from their XML, or JSON representation. For
example, when accepting data via an API.
.. code-block :: php
<?php
$serializer = JMS\Serializer\SerializerBuilder::create()->build();
$object = $serializer->deserialize($jsonData, \MyNamespace\MyObject::class, 'json');

View File

@@ -1,15 +0,0 @@
{
"runner.bootstrap": "tests/bootstrap.php",
"runner.iterations": 3,
"runner.revs": 1,
"report.generators": {
"memory": {
"extends": "aggregate",
"cols": [
"benchmark",
"mem_peak"
]
}
}
}

View File

@@ -1,27 +0,0 @@
includes:
- phpstan/ignore-by-php-version.neon.php
parameters:
level: 3
ignoreErrors:
- '~Class Doctrine\\Common\\Persistence\\Proxy not found~'
- '~Class Doctrine\\ODM\\MongoDB\\PersistentCollection not found~'
- '~Class Symfony\\(Contracts|Component)\\Translation\\TranslatorInterface not found~'
- '#Class JMS\\Serializer\\Annotation\\DeprecatedReadOnly extends @final class JMS\\Serializer\\Annotation\\ReadOnlyProperty.#'
- '#^Call to an undefined method Doctrine\\Persistence\\Mapping\\ClassMetadata\<object\>\:\:getFieldValue\(\)\.$#'
- '#^Call to an undefined method JMS\\Serializer\\Visitor\\DeserializationVisitorInterface\:\:getCurrentObject\(\)\.$#'
- '#^Call to method trans\(\) on an unknown class Symfony\\Component\\Translation\\TranslatorInterface\.$#'
- '#^Call to method transChoice\(\) on an unknown class Symfony\\Component\\Translation\\TranslatorInterface\.$#'
- '#^Property JMS\\Serializer\\Handler\\FormErrorHandler\:\:\$translator has unknown class Symfony\\Component\\Translation\\TranslatorInterface as its type\.$#'
- '#^Cannot call method appendChild\(\) on null\.$#'
- '#^Call to an undefined method JMS\\Serializer\\VisitorInterface\:\:setData\(\)\.$#'
- '#^Call to method expects\(\) on an unknown class Symfony\\Component\\Translation\\TranslatorInterface\.$#'
- '#^Call to an undefined method JMS\\Serializer\\VisitorInterface\:\:hasData\(\)\.$#'
- '#^Method JMS\\Serializer\\GraphNavigator\\DeserializationGraphNavigator\:\:resolveMetadata\(\) should return JMS\\Serializer\\Metadata\\ClassMetadata\|null#'
- '#^ArrayObject<\*NEVER\*, \*NEVER\*> does not accept list<string\|null>\.#'
- '#^ArrayObject<\*NEVER\*, \*NEVER\*> does not accept array<string, ArrayObject>\.#'
paths:
- %currentWorkingDirectory%/src
- %currentWorkingDirectory%/tests
excludePaths:
- tests/Fixtures/*
reportUnmatchedIgnoredErrors: false

View File

@@ -1,10 +0,0 @@
<?php
declare(strict_types=1);
use Rector\Config\RectorConfig;
return RectorConfig::configure()->withPaths([
__DIR__ . '/src',
])
->withPhp74Sets();

View File

@@ -1,115 +0,0 @@
<?php
declare(strict_types=1);
namespace JMS\Serializer;
use JMS\Serializer\Exception\NonFloatCastableTypeException;
use JMS\Serializer\Exception\NonIntCastableTypeException;
use JMS\Serializer\Exception\NonStringCastableTypeException;
use JMS\Serializer\Type\Type;
/**
* @internal
*
* @phpstan-import-type TypeArray from Type
*/
abstract class AbstractVisitor implements VisitorInterface
{
/**
* @var GraphNavigatorInterface|null
*/
protected $navigator;
public function setNavigator(GraphNavigatorInterface $navigator): void
{
$this->navigator = $navigator;
}
/**
* {@inheritdoc}
*/
public function prepare($data)
{
return $data;
}
/**
* @param TypeArray $typeArray
*/
protected function getElementType(array $typeArray): ?array
{
if (false === isset($typeArray['params'][0])) {
return null;
}
if (isset($typeArray['params'][1]) && \is_array($typeArray['params'][1])) {
return $typeArray['params'][1];
} else {
return $typeArray['params'][0];
}
}
/**
* logic according to strval https://www.php.net/manual/en/function.strval.php
* "You cannot use strval() on arrays or on objects that do not implement the __toString() method."
*
* @param mixed $value
*/
protected function assertValueCanBeCastToString($value): void
{
if (is_array($value)) {
throw new NonStringCastableTypeException($value);
}
if (is_object($value) && !method_exists($value, '__toString')) {
throw new NonStringCastableTypeException($value);
}
}
/**
* logic according to intval https://www.php.net/manual/en/function.intval.php
* "intval() should not be used on objects, as doing so will emit an E_NOTICE level error and return 1."
*
* @param mixed $value
*/
protected function assertValueCanBeCastToInt($value): void
{
if (is_object($value) && !$value instanceof \SimpleXMLElement) {
throw new NonIntCastableTypeException($value);
}
}
/**
* logic according to floatval https://www.php.net/manual/en/function.floatval.php
* "floatval() should not be used on objects, as doing so will emit an E_NOTICE level error and return 1."
*
* @param mixed $value
*/
protected function assertValueCanCastToFloat($value): void
{
if (is_object($value) && !$value instanceof \SimpleXMLElement) {
throw new NonFloatCastableTypeException($value);
}
}
protected function mapRoundMode(?string $roundMode = null): int
{
switch ($roundMode) {
case 'HALF_DOWN':
$roundMode = PHP_ROUND_HALF_DOWN;
break;
case 'HALF_EVEN':
$roundMode = PHP_ROUND_HALF_EVEN;
break;
case 'HALF_ODD':
$roundMode = PHP_ROUND_HALF_ODD;
break;
case 'HALF_UP':
default:
$roundMode = PHP_ROUND_HALF_UP;
}
return $roundMode;
}
}

View File

@@ -1,25 +0,0 @@
<?php
declare(strict_types=1);
namespace JMS\Serializer\Accessor;
use JMS\Serializer\DeserializationContext;
use JMS\Serializer\Metadata\PropertyMetadata;
use JMS\Serializer\SerializationContext;
/**
* @author Asmir Mustafic <goetas@gmail.com>
*/
interface AccessorStrategyInterface
{
/**
* @return mixed
*/
public function getValue(object $object, PropertyMetadata $metadata, SerializationContext $context);
/**
* @param mixed $value
*/
public function setValue(object $object, $value, PropertyMetadata $metadata, DeserializationContext $context): void;
}

View File

@@ -1,143 +0,0 @@
<?php
declare(strict_types=1);
namespace JMS\Serializer\Accessor;
use JMS\Serializer\DeserializationContext;
use JMS\Serializer\Exception\ExpressionLanguageRequiredException;
use JMS\Serializer\Exception\LogicException;
use JMS\Serializer\Exception\UninitializedPropertyException;
use JMS\Serializer\Expression\CompilableExpressionEvaluatorInterface;
use JMS\Serializer\Expression\Expression;
use JMS\Serializer\Expression\ExpressionEvaluatorInterface;
use JMS\Serializer\Metadata\ExpressionPropertyMetadata;
use JMS\Serializer\Metadata\PropertyMetadata;
use JMS\Serializer\Metadata\StaticPropertyMetadata;
use JMS\Serializer\SerializationContext;
/**
* @author Asmir Mustafic <goetas@gmail.com>
*/
final class DefaultAccessorStrategy implements AccessorStrategyInterface
{
/**
* @var callable[]
*/
private $readAccessors = [];
/**
* @var callable[]
*/
private $writeAccessors = [];
/**
* @var \ReflectionProperty[]
*/
private $propertyReflectionCache = [];
/**
* @var ExpressionEvaluatorInterface
*/
private $evaluator;
public function __construct(?ExpressionEvaluatorInterface $evaluator = null)
{
$this->evaluator = $evaluator;
}
/**
* {@inheritdoc}
*/
public function getValue(object $object, PropertyMetadata $metadata, SerializationContext $context)
{
if ($metadata instanceof StaticPropertyMetadata) {
return $metadata->getValue();
}
if ($metadata instanceof ExpressionPropertyMetadata) {
if (null === $this->evaluator) {
throw new ExpressionLanguageRequiredException(sprintf('The property %s on %s requires the expression accessor strategy to be enabled.', $metadata->name, $metadata->class));
}
$variables = ['object' => $object, 'context' => $context, 'property_metadata' => $metadata];
if (($metadata->expression instanceof Expression) && ($this->evaluator instanceof CompilableExpressionEvaluatorInterface)) {
return $this->evaluator->evaluateParsed($metadata->expression, $variables);
}
return $this->evaluator->evaluate($metadata->expression, $variables);
}
if (null !== $metadata->getter) {
return $object->{$metadata->getter}();
}
if ($metadata->forceReflectionAccess) {
$ref = $this->propertyReflectionCache[$metadata->class][$metadata->name] ?? null;
if (null === $ref) {
$ref = new \ReflectionProperty($metadata->class, $metadata->name);
$ref->setAccessible(true);
$this->propertyReflectionCache[$metadata->class][$metadata->name] = $ref;
}
return $ref->getValue($object);
}
$accessor = $this->readAccessors[$metadata->class] ?? null;
if (null === $accessor) {
$accessor = \Closure::bind(static fn ($o, $name) => $o->$name, null, $metadata->class);
$this->readAccessors[$metadata->class] = $accessor;
}
try {
return $accessor($object, $metadata->name);
} catch (\Error $e) {
// handle uninitialized properties in PHP >= 7.4
if (preg_match('/^Typed property ([\w\\\\@]+)::\$(\w+) must not be accessed before initialization$/', $e->getMessage(), $matches)) {
throw new UninitializedPropertyException(sprintf('Uninitialized property "%s::$%s".', $metadata->class, $metadata->name), 0, $e);
}
throw $e;
}
}
/**
* {@inheritdoc}
*/
public function setValue(object $object, $value, PropertyMetadata $metadata, DeserializationContext $context): void
{
if (true === $metadata->readOnly) {
throw new LogicException(sprintf('%s on %s is read only.', $metadata->name, $metadata->class));
}
if (null !== $metadata->setter) {
$object->{$metadata->setter}($value);
return;
}
if ($metadata->forceReflectionAccess) {
$ref = $this->propertyReflectionCache[$metadata->class][$metadata->name] ?? null;
if (null === $ref) {
$ref = new \ReflectionProperty($metadata->class, $metadata->name);
$ref->setAccessible(true);
$this->propertyReflectionCache[$metadata->class][$metadata->name] = $ref;
}
$ref->setValue($object, $value);
return;
}
$accessor = $this->writeAccessors[$metadata->class] ?? null;
if (null === $accessor) {
$accessor = \Closure::bind(static function ($o, $name, $value): void {
$o->$name = $value;
}, null, $metadata->class);
$this->writeAccessors[$metadata->class] = $accessor;
}
$accessor($object, $metadata->name, $value);
}
}

View File

@@ -1,28 +0,0 @@
<?php
declare(strict_types=1);
namespace JMS\Serializer\Annotation;
/**
* @Annotation
* @Target({"CLASS", "PROPERTY"})
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::TARGET_PROPERTY)]
final class AccessType implements SerializerAttribute
{
use AnnotationUtilsTrait;
/**
* @Required
* @var string|null
*/
public $type;
public function __construct(array $values = [], ?string $type = null)
{
$this->loadAnnotationParameters(get_defined_vars());
}
}

View File

@@ -1,32 +0,0 @@
<?php
declare(strict_types=1);
namespace JMS\Serializer\Annotation;
/**
* @Annotation
* @Target("PROPERTY")
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
#[\Attribute(\Attribute::TARGET_PROPERTY)]
final class Accessor implements SerializerAttribute
{
use AnnotationUtilsTrait;
/**
* @var string|null
*/
public $getter = null;
/**
* @var string|null
*/
public $setter = null;
public function __construct(array $values = [], ?string $getter = null, ?string $setter = null)
{
$this->loadAnnotationParameters(get_defined_vars());
}
}

View File

@@ -1,35 +0,0 @@
<?php
declare(strict_types=1);
namespace JMS\Serializer\Annotation;
/**
* Controls the order of properties in a class.
*
* @Annotation
* @Target("CLASS")
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
#[\Attribute(\Attribute::TARGET_CLASS)]
final class AccessorOrder implements SerializerAttribute
{
use AnnotationUtilsTrait;
/**
* @Required
* @var string|null
*/
public $order = null;
/**
* @var array<string>
*/
public $custom = [];
public function __construct(array $values = [], ?string $order = null, array $custom = [])
{
$this->loadAnnotationParameters(get_defined_vars());
}
}

View File

@@ -1,40 +0,0 @@
<?php
declare(strict_types=1);
namespace JMS\Serializer\Annotation;
use JMS\Serializer\Exception\InvalidArgumentException;
trait AnnotationUtilsTrait
{
private function loadAnnotationParameters(array $vars): void
{
if (!array_key_exists('values', $vars)) {
$values = [];
} elseif (!is_array($vars['values'])) {
$values = ['value' => $vars['values']];
} else {
$values = $vars['values'];
}
unset($vars['values']);
if (array_key_exists('value', $values)) {
$values[key($vars)] = $values['value'];
unset($values['value']);
}
foreach ($values as $key => $value) {
$vars[$key] = $value;
}
foreach ($vars as $key => $value) {
if (!property_exists(static::class, $key)) {
throw new InvalidArgumentException(sprintf('Unknown property "%s" on annotation "%s".', $key, static::class));
}
$this->{$key} = $value;
}
}
}

View File

@@ -1,16 +0,0 @@
<?php
declare(strict_types=1);
namespace JMS\Serializer\Annotation;
/**
* @Annotation
* @Target({"CLASS","PROPERTY"})
*
* @deprecated use `@ReadOnlyProperty` instead
*/
#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::TARGET_PROPERTY)]
final class DeprecatedReadOnly extends ReadOnlyProperty
{
}

View File

@@ -1,32 +0,0 @@
<?php
declare(strict_types=1);
namespace JMS\Serializer\Annotation;
/**
* @Annotation
* @Target("CLASS")
*/
#[\Attribute(\Attribute::TARGET_CLASS)]
class Discriminator implements SerializerAttribute
{
use AnnotationUtilsTrait;
/** @var array<string> */
public $map = [];
/** @var string */
public $field = 'type';
/** @var bool */
public $disabled = false;
/** @var string[] */
public $groups = [];
public function __construct(array $values = [], string $field = 'type', array $groups = [], array $map = [], bool $disabled = false)
{
$this->loadAnnotationParameters(get_defined_vars());
}
}

View File

@@ -1,25 +0,0 @@
<?php
declare(strict_types=1);
namespace JMS\Serializer\Annotation;
/**
* @Annotation
* @Target({"PROPERTY", "CLASS", "METHOD", "ANNOTATION"})
*/
#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD)]
final class Exclude implements SerializerAttribute
{
use AnnotationUtilsTrait;
/**
* @var string|null
*/
public $if;
public function __construct(array $values = [], ?string $if = null)
{
$this->loadAnnotationParameters(get_defined_vars());
}
}

View File

@@ -1,36 +0,0 @@
<?php
declare(strict_types=1);
namespace JMS\Serializer\Annotation;
use JMS\Serializer\Exception\RuntimeException;
/**
* @Annotation
* @Target("CLASS")
*/
#[\Attribute(\Attribute::TARGET_CLASS)]
final class ExclusionPolicy implements SerializerAttribute
{
use AnnotationUtilsTrait;
public const NONE = 'NONE';
public const ALL = 'ALL';
/**
* @var string|null
*/
public $policy = 'NONE';
public function __construct($values = [], ?string $policy = null)
{
$this->loadAnnotationParameters(get_defined_vars());
$this->policy = strtoupper($this->policy);
if (self::NONE !== $this->policy && self::ALL !== $this->policy) {
throw new RuntimeException('Exclusion policy must either be "ALL", or "NONE".');
}
}
}

View File

@@ -1,25 +0,0 @@
<?php
declare(strict_types=1);
namespace JMS\Serializer\Annotation;
/**
* @Annotation
* @Target({"PROPERTY", "METHOD", "ANNOTATION"})
*/
#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::TARGET_PROPERTY)]
final class Expose implements SerializerAttribute
{
use AnnotationUtilsTrait;
/**
* @var string|null
*/
public $if = null;
public function __construct(array $values = [], ?string $if = null)
{
$this->loadAnnotationParameters(get_defined_vars());
}
}

View File

@@ -1,35 +0,0 @@
<?php
declare(strict_types=1);
namespace JMS\Serializer\Annotation;
/**
* @Annotation
* @Target({"PROPERTY","METHOD","ANNOTATION"})
*/
#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::TARGET_PROPERTY)]
final class Groups implements SerializerAttribute
{
use AnnotationUtilsTrait;
/** @var array<string> @Required */
public $groups = [];
public function __construct(array $values = [], array $groups = [])
{
$vars = get_defined_vars();
/*
if someone wants to set as Groups(['value' => '...']) this check will miserably fail (only one group with 'value' as only key).
That is because doctrine annotations uses for @Groups("abc") the same values content (buy validation will fail since groups has to be an array).
All the other cases should work as expected.
The alternative here is to use the explicit syntax Groups(groups=['value' => '...'])
*/
if (count($values) > 0 && ((!isset($values['value']) && !isset($values['groups'])) || count($values) > 1) && 0 === count($groups)) {
$vars['groups'] = $values;
$vars['values'] = [];
}
$this->loadAnnotationParameters($vars);
}
}

View File

@@ -1,14 +0,0 @@
<?php
declare(strict_types=1);
namespace JMS\Serializer\Annotation;
/**
* @Annotation
* @Target({"PROPERTY","METHOD","ANNOTATION"})
*/
#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::TARGET_PROPERTY)]
final class Inline implements SerializerAttribute
{
}

View File

@@ -1,26 +0,0 @@
<?php
declare(strict_types=1);
namespace JMS\Serializer\Annotation;
/**
* @Annotation
* @Target({"PROPERTY","METHOD","ANNOTATION"})
*/
#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::TARGET_PROPERTY)]
final class MaxDepth implements SerializerAttribute
{
use AnnotationUtilsTrait;
/**
* @Required
* @var int
*/
public $depth;
public function __construct($values = [], int $depth = 0)
{
$this->loadAnnotationParameters(get_defined_vars());
}
}

View File

@@ -1,21 +0,0 @@
<?php
declare(strict_types=1);
namespace JMS\Serializer\Annotation;
/**
* This annotation can be defined on methods which are called after the
* deserialization of the object is complete.
*
* These methods do not necessarily have to be public.
*
* @Annotation
* @Target("METHOD")
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
#[\Attribute(\Attribute::TARGET_METHOD)]
final class PostDeserialize implements SerializerAttribute
{
}

View File

@@ -1,14 +0,0 @@
<?php
declare(strict_types=1);
namespace JMS\Serializer\Annotation;
/**
* @Annotation
* @Target("METHOD")
*/
#[\Attribute(\Attribute::TARGET_METHOD)]
final class PostSerialize implements SerializerAttribute
{
}

View File

@@ -1,22 +0,0 @@
<?php
declare(strict_types=1);
namespace JMS\Serializer\Annotation;
/**
* This annotation can be declared on methods which should be called
* before the Serialization process.
*
* These methods do not need to be public, and should do any clean-up, or
* preparation of the object that is necessary.
*
* @Annotation
* @Target("METHOD")
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
#[\Attribute(\Attribute::TARGET_METHOD)]
final class PreSerialize implements SerializerAttribute
{
}

View File

@@ -1,7 +0,0 @@
<?php
declare(strict_types=1);
use JMS\Serializer\Annotation\DeprecatedReadOnly;
class_alias(DeprecatedReadOnly::class, 'JMS\Serializer\Annotation\ReadOnly');

View File

@@ -1,27 +0,0 @@
<?php
declare(strict_types=1);
namespace JMS\Serializer\Annotation;
/**
* @Annotation
* @Target({"CLASS","PROPERTY"})
*
* @final
*/
#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::TARGET_PROPERTY)]
/* final */ class ReadOnlyProperty implements SerializerAttribute
{
use AnnotationUtilsTrait;
/**
* @var bool
*/
public $readOnly = true;
public function __construct(array $values = [], bool $readOnly = true)
{
$this->loadAnnotationParameters(get_defined_vars());
}
}

View File

@@ -1,25 +0,0 @@
<?php
declare(strict_types=1);
namespace JMS\Serializer\Annotation;
/**
* @Annotation
* @Target({"PROPERTY","METHOD", "ANNOTATION"})
*/
#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::TARGET_PROPERTY)]
final class SerializedName implements SerializerAttribute
{
use AnnotationUtilsTrait;
/**
* @var string|null
*/
public $name = null;
public function __construct($values = [], ?string $name = null)
{
$this->loadAnnotationParameters(get_defined_vars());
}
}

View File

@@ -1,12 +0,0 @@
<?php
declare(strict_types=1);
namespace JMS\Serializer\Annotation;
/**
* Marker interface for serializer attributes
*/
interface SerializerAttribute
{
}

View File

@@ -1,14 +0,0 @@
<?php
declare(strict_types=1);
namespace JMS\Serializer\Annotation;
/**
* @Annotation
* @Target({"PROPERTY", "METHOD", "ANNOTATION"})
*/
#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::TARGET_PROPERTY)]
final class Since extends Version
{
}

View File

@@ -1,14 +0,0 @@
<?php
declare(strict_types=1);
namespace JMS\Serializer\Annotation;
/**
* @Annotation
* @Target({"PROPERTY","METHOD","ANNOTATION"})
*/
#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::TARGET_PROPERTY)]
final class SkipWhenEmpty implements SerializerAttribute
{
}

View File

@@ -1,46 +0,0 @@
<?php
declare(strict_types=1);
namespace JMS\Serializer\Annotation;
/**
* @Annotation
* @Target({"PROPERTY", "METHOD","ANNOTATION"})
*/
#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::TARGET_PROPERTY)]
final class Type implements SerializerAttribute
{
use AnnotationUtilsTrait;
/**
* @Required
* @var string|\Stringable|null
*/
public $name = null;
public function __construct($values = [], $name = null)
{
if ((null !== $name) && !is_string($name) && !(is_object($name) && method_exists($name, '__toString'))) {
throw new \RuntimeException(
'Type must be either string, null or object implements __toString() method.',
);
}
if (is_object($name)) {
$name = (string) $name;
}
if (is_object($values)) {
if (false === method_exists($values, '__toString')) {
throw new \RuntimeException(
'Type must be either string or object implements __toString() method.',
);
}
$values = (string) $values;
}
$this->loadAnnotationParameters(get_defined_vars());
}
}

View File

@@ -1,26 +0,0 @@
<?php
declare(strict_types=1);
namespace JMS\Serializer\Annotation;
/**
* @Annotation
* @Target({"PROPERTY"})
*/
#[\Attribute(\Attribute::TARGET_PROPERTY)]
final class UnionDiscriminator implements SerializerAttribute
{
use AnnotationUtilsTrait;
/** @var array<string> */
public $map = [];
/** @var string */
public $field = 'type';
public function __construct(array $values = [], string $field = 'type', array $map = [])
{
$this->loadAnnotationParameters(get_defined_vars());
}
}

View File

@@ -1,14 +0,0 @@
<?php
declare(strict_types=1);
namespace JMS\Serializer\Annotation;
/**
* @Annotation
* @Target({"PROPERTY", "METHOD", "ANNOTATION"})
*/
#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::TARGET_PROPERTY)]
final class Until extends Version
{
}

View File

@@ -1,21 +0,0 @@
<?php
declare(strict_types=1);
namespace JMS\Serializer\Annotation;
abstract class Version implements SerializerAttribute
{
use AnnotationUtilsTrait;
/**
* @Required
* @var string|null
*/
public $version = null;
public function __construct($values = [], ?string $version = null)
{
$this->loadAnnotationParameters(get_defined_vars());
}
}

View File

@@ -1,53 +0,0 @@
<?php
declare(strict_types=1);
namespace JMS\Serializer\Annotation;
/**
* @Annotation
* @Target({"METHOD", "CLASS"})
*
* @author Alexander Klimenkov <alx.devel@gmail.com>
*/
#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::TARGET_CLASS | \Attribute::IS_REPEATABLE)]
final class VirtualProperty implements SerializerAttribute
{
use AnnotationUtilsTrait;
/**
* @var string|null
*/
public $exp = null;
/**
* @var string|null
*/
public $name = null;
/**
* @var array
*/
public $options = [];
public function __construct($values = [], ?string $name = null, ?string $exp = null, array $options = [])
{
$vars = get_defined_vars();
unset($vars['options']);
$this->loadAnnotationParameters($vars);
if (0 !== count($options)) {
$this->options = $options;
}
foreach ($options as $option) {
if (is_array($option) && class_exists($option[0])) {
$this->options[] = new $option[0]([], ...$option[1]);
continue;
}
$this->options[] = $option;
}
}
}

View File

@@ -1,25 +0,0 @@
<?php
declare(strict_types=1);
namespace JMS\Serializer\Annotation;
/**
* @Annotation
* @Target({"PROPERTY", "METHOD","ANNOTATION"})
*/
#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::TARGET_PROPERTY)]
final class XmlAttribute implements SerializerAttribute
{
use AnnotationUtilsTrait;
/**
* @var string|null
*/
public $namespace = null;
public function __construct($values = [], ?string $namespace = null)
{
$this->loadAnnotationParameters(get_defined_vars());
}
}

View File

@@ -1,14 +0,0 @@
<?php
declare(strict_types=1);
namespace JMS\Serializer\Annotation;
/**
* @Annotation
* @Target({"PROPERTY", "METHOD"})
*/
#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::TARGET_PROPERTY)]
final class XmlAttributeMap implements SerializerAttribute
{
}

View File

@@ -1,35 +0,0 @@
<?php
declare(strict_types=1);
namespace JMS\Serializer\Annotation;
abstract class XmlCollection implements SerializerAttribute
{
use AnnotationUtilsTrait;
/**
* @var string
*/
public $entry = 'entry';
/**
* @var bool
*/
public $inline = false;
/**
* @var string|null
*/
public $namespace = null;
/**
* @var bool
*/
public $skipWhenEmpty = true;
public function __construct(array $values = [], string $entry = 'entry', bool $inline = false, ?string $namespace = null, bool $skipWhenEmpty = true)
{
$this->loadAnnotationParameters(get_defined_vars());
}
}

View File

@@ -1,35 +0,0 @@
<?php
declare(strict_types=1);
namespace JMS\Serializer\Annotation;
/**
* @Annotation
* @Target("CLASS")
*/
#[\Attribute(\Attribute::TARGET_CLASS)]
class XmlDiscriminator implements SerializerAttribute
{
use AnnotationUtilsTrait;
/**
* @var bool
*/
public $attribute = false;
/**
* @var bool
*/
public $cdata = true;
/**
* @var string|null
*/
public $namespace = null;
public function __construct(array $values = [], bool $attribute = false, bool $cdata = false, ?string $namespace = null)
{
$this->loadAnnotationParameters(get_defined_vars());
}
}

View File

@@ -1,30 +0,0 @@
<?php
declare(strict_types=1);
namespace JMS\Serializer\Annotation;
/**
* @Annotation
* @Target({"PROPERTY", "METHOD","ANNOTATION"})
*/
#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::TARGET_PROPERTY)]
final class XmlElement implements SerializerAttribute
{
use AnnotationUtilsTrait;
/**
* @var bool
*/
public $cdata = true;
/**
* @var string|null
*/
public $namespace = null;
public function __construct(array $values = [], bool $cdata = true, ?string $namespace = null)
{
$this->loadAnnotationParameters(get_defined_vars());
}
}

View File

@@ -1,14 +0,0 @@
<?php
declare(strict_types=1);
namespace JMS\Serializer\Annotation;
/**
* @Annotation
* @Target({"PROPERTY","METHOD","ANNOTATION"})
*/
#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::TARGET_PROPERTY)]
final class XmlKeyValuePairs implements SerializerAttribute
{
}

View File

@@ -1,14 +0,0 @@
<?php
declare(strict_types=1);
namespace JMS\Serializer\Annotation;
/**
* @Annotation
* @Target({"PROPERTY","METHOD","ANNOTATION"})
*/
#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::TARGET_PROPERTY)]
final class XmlList extends XmlCollection
{
}

View File

@@ -1,25 +0,0 @@
<?php
declare(strict_types=1);
namespace JMS\Serializer\Annotation;
/**
* @Annotation
* @Target({"PROPERTY","METHOD","ANNOTATION"})
*/
#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::TARGET_PROPERTY)]
final class XmlMap extends XmlCollection
{
use AnnotationUtilsTrait;
/**
* @var string
*/
public $keyAttribute = '_key';
public function __construct(array $values = [], string $keyAttribute = '_key', string $entry = 'entry', bool $inline = false, ?string $namespace = null, bool $skipWhenEmpty = true)
{
$this->loadAnnotationParameters(get_defined_vars());
}
}

View File

@@ -1,31 +0,0 @@
<?php
declare(strict_types=1);
namespace JMS\Serializer\Annotation;
/**
* @Annotation
* @Target("CLASS")
*/
#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::IS_REPEATABLE)]
final class XmlNamespace implements SerializerAttribute
{
use AnnotationUtilsTrait;
/**
* @Required
* @var string|null
*/
public $uri = null;
/**
* @var string
*/
public $prefix = '';
public function __construct(array $values = [], ?string $uri = null, string $prefix = '')
{
$this->loadAnnotationParameters(get_defined_vars());
}
}

View File

@@ -1,36 +0,0 @@
<?php
declare(strict_types=1);
namespace JMS\Serializer\Annotation;
/**
* @Annotation
* @Target("CLASS")
*/
#[\Attribute(\Attribute::TARGET_CLASS)]
final class XmlRoot implements SerializerAttribute
{
use AnnotationUtilsTrait;
/**
* @Required
* @var string|null
*/
public $name = null;
/**
* @var string|null
*/
public $namespace = null;
/**
* @var string|null
*/
public $prefix = null;
public function __construct($values = [], ?string $name = null, ?string $namespace = null, ?string $prefix = null)
{
$this->loadAnnotationParameters(get_defined_vars());
}
}

Some files were not shown because too many files have changed in this diff Show More