├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── composer.json
├── phpunit.xml
├── src
├── DeepCopySerializer.php
├── JsonSerializer.php
├── Serializer.php
├── Serializer
│ ├── HHVM
│ │ ├── DatePeriodSerializer.php
│ │ ├── DateTimeImmutableSerializer.php
│ │ └── DateTimeSerializer.php
│ └── InternalClasses
│ │ ├── DateIntervalSerializer.php
│ │ ├── DatePeriodSerializer.php
│ │ ├── DateTimeZoneSerializer.php
│ │ └── SplFixedArraySerializer.php
├── SerializerException.php
├── Strategy
│ ├── JsonStrategy.php
│ ├── NullStrategy.php
│ ├── StrategyInterface.php
│ ├── XmlStrategy.php
│ └── YamlStrategy.php
├── Transformer
│ ├── AbstractTransformer.php
│ ├── ArrayTransformer.php
│ ├── FlatArrayTransformer.php
│ ├── JsonTransformer.php
│ ├── XmlTransformer.php
│ └── YamlTransformer.php
├── XmlSerializer.php
└── YamlSerializer.php
└── tests
├── DeepCopySerializerTest.php
├── Dummy
├── ComplexObject
│ ├── Comment.php
│ ├── Post.php
│ ├── User.php
│ └── ValueObject
│ │ ├── CommentId.php
│ │ ├── PostId.php
│ │ └── UserId.php
└── SimpleObject
│ └── Post.php
├── JsonSerializerTest.php
├── SerializerTest.php
├── SupportClasses
├── AllVisibilities.php
├── ArrayAccessClass.php
├── ChildOfSplFixedArray.php
├── EmptyClass.php
├── MagicClass.php
└── TraversableClass.php
├── Transformer
├── ArrayTransformerTest.php
├── FlatArrayTransformerTest.php
├── JsonTransformerTest.php
├── XmlTransformerTest.php
└── YamlTransformerTest.php
├── XmlSerializerTest.php
└── YamlSerializerTest.php
/.gitignore:
--------------------------------------------------------------------------------
1 | bin/
2 | vendor/
3 | composer.lock
4 | build/
5 | .coveralls.yml
6 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 | php:
3 | - "5.6"
4 | - "7.0"
5 | - "7.1"
6 |
7 | before_script:
8 | - composer install
9 |
10 | script:
11 | - bin/phpunit --coverage-text
12 |
13 | branches:
14 | only:
15 | - master
16 |
17 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Nil Portugués Calderó
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Serializer for PHP
2 | =========================
3 |
4 | [](https://travis-ci.org/nilportugues/php-serializer)
5 | [](https://scrutinizer-ci.com/g/nilportugues/serializer/?branch=master) [](https://insight.sensiolabs.com/projects/7ae05bba-985d-4359-8a00-3209f85f1d77)
6 | [](https://packagist.org/packages/nilportugues/serializer)
7 | [](https://packagist.org/packages/nilportugues/serializer) [](https://packagist.org/packages/nilportugues/serializer)
8 | [](https://paypal.me/nilportugues)
9 |
10 | - [Installation](#installation)
11 | - [Introduction](#introduction)
12 | - [Features](#features)
13 | - [Serialization](#serialization)
14 | - [Serializers (JSON, XML, YAML)](#serializers-json-xml-yaml)
15 | - [Example](#example)
16 | - [Custom Serializers](#custom-serializers)
17 | - [Data Transformation](#data-transformation)
18 | - [Array Transformer](#array-transformer)
19 | - [Flat Array Transformer](#flat-array-transformer)
20 | - [XML Transformer](#xml-transformer)
21 | - [YAML Transformer](#yaml-transformer)
22 | - [JSON Transformer](#json-transformer)
23 | - [JSend Transformer](#jsend-transformer)
24 | - [JSON API Transformer](#json-api-transformer)
25 | - [HAL+JSON Transformer](#haljson-transformer)
26 | - [Quality](#quality)
27 | - [Contribute](#contribute)
28 | - [Author](#author)
29 | - [License](#license)
30 |
31 | ## Installation
32 |
33 | Use [Composer](https://getcomposer.org) to install the package:
34 |
35 | ```json
36 | $ composer require nilportugues/serializer
37 | ```
38 |
39 | ## Introduction
40 |
41 | **What is serialization?**
42 |
43 | In the context of data storage, serialization is the process of translating data structures or object state into a format that can be stored (for example, in a file or memory buffer, or transmitted across a network connection link) and reconstructed later in the same or another computer environment.
44 |
45 |
46 | **Why not `serialize()` and `unserialize()`?**
47 |
48 | These native functions rely on having the serialized classes loaded and available at runtime and tie your unserialization process to a `PHP` platform.
49 |
50 | If the serialized string contains a reference to a class that cannot be instantiated (e.g. class was renamed, moved namespace, removed or changed to abstract) PHP will immediately die with a fatal error.
51 |
52 | Is this a problem? Yes it is. Serialized data is now **unusable**.
53 |
54 | ## Features
55 |
56 | - Serialize to **JSON**, **XML** and **YAML** formats.
57 | - Serializes **exact copies** of the object provided:
58 | - **All object properties**, public, protected and private are serialized.
59 | - All properties from the current object, and all the inherited properties are read and serialized.
60 | - Handles internal class serialization for objects such as SplFixedArray or classes implementing Traversable.
61 | - Basic **Data Transformers provided** to convert objects to different output formats.
62 | - **Production-ready**.
63 | - **Extensible:** easily write your out `Serializer` format or data `Transformers`.
64 |
65 |
66 | ## Serialization
67 | For the serializer to work, all you need to do is pass in a PHP Object to the serializer and a Strategy to implement its string representation.
68 |
69 |
70 | ### Serializers (JSON, XML, YAML)
71 |
72 | - [NilPortugues\Serializer\JsonSerializer](https://github.com/nilportugues/serializer/blob/master/src/JsonSerializer.php)
73 | - [NilPortugues\Serializer\XmlSerializer](https://github.com/nilportugues/serializer/blob/master/src/XmlSerializer.php)
74 | - [NilPortugues\Serializer\YamlSerializer](https://github.com/nilportugues/serializer/blob/master/src/YamlSerializer.php)
75 |
76 | ### Example
77 |
78 | In the following example a `$post` object is serialized into JSON.
79 |
80 | **Code**
81 |
82 | ```php
83 | use NilPortugues\Serializer\Serializer;
84 | use NilPortugues\Serializer\Strategy\JsonStrategy;
85 |
86 | //Example object
87 | $post = new Post(
88 | new PostId(9),
89 | 'Hello World',
90 | 'Your first post',
91 | new User(
92 | new UserId(1),
93 | 'Post Author'
94 | ),
95 | [
96 | new Comment(
97 | new CommentId(1000),
98 | 'Have no fear, sers, your king is safe.',
99 | new User(new UserId(2), 'Barristan Selmy'),
100 | [
101 | 'created_at' => (new DateTime('2015/07/18 12:13:00'))->format('c'),
102 | 'accepted_at' => (new DateTime('2015/07/19 00:00:00'))->format('c'),
103 | ]
104 | ),
105 | ]
106 | );
107 |
108 | //Serialization
109 | $serializer = new JsonSerializer();
110 |
111 | $serializedObject = $serializer->serialize($post);
112 |
113 | //Returns: true
114 | var_dump($post == $serializer->unserialize($serializedObject));
115 |
116 | echo $serializedObject;
117 | ```
118 |
119 | The object, before it's transformed into an output format, is an array with all the necessary data to be rebuild using unserialize method.
120 |
121 | **Output**
122 |
123 | ```json
124 | {
125 | "@type": "Acme\\\\Domain\\\\Dummy\\\\Post",
126 | "postId": {
127 | "@type": "Acme\\\\Domain\\\\Dummy\\\\ValueObject\\\\PostId",
128 | "postId": {
129 | "@scalar": "integer",
130 | "@value": 14
131 | }
132 | },
133 | "title": {
134 | "@scalar": "string",
135 | "@value": "Hello World"
136 | },
137 | "content": {
138 | "@scalar": "string",
139 | "@value": "Your first post"
140 | },
141 | "author": {
142 | "@type": "Acme\\\\Domain\\\\Dummy\\\\User",
143 | "userId": {
144 | "@type": "Acme\\\\Domain\\\\Dummy\\\\ValueObject\\\\UserId",
145 | "userId": {
146 | "@scalar": "integer",
147 | "@value": 1
148 | }
149 | },
150 | "name": {
151 | "@scalar": "string",
152 | "@value": "Post Author"
153 | }
154 | },
155 | "comments": {
156 | "@map": "array",
157 | "@value": [
158 | {
159 | "@type": "Acme\\\\Domain\\\\Dummy\\\\Comment",
160 | "commentId": {
161 | "@type": "Acme\\\\Domain\\\\Dummy\\\\ValueObject\\\\CommentId",
162 | "commentId": {
163 | "@scalar": "integer",
164 | "@value": 1000
165 | }
166 | },
167 | "dates": {
168 | "@map": "array",
169 | "@value": {
170 | "created_at": {
171 | "@scalar": "string",
172 | "@value": "2015-07-18T12:13:00+00:00"
173 | },
174 | "accepted_at": {
175 | "@scalar": "string",
176 | "@value": "2015-07-19T00:00:00+00:00"
177 | }
178 | }
179 | },
180 | "comment": {
181 | "@scalar": "string",
182 | "@value": "Have no fear, sers, your king is safe."
183 | },
184 | "user": {
185 | "@type": "Acme\\\\Domain\\\\Dummy\\\\User",
186 | "userId": {
187 | "@type": "Acme\\\\Domain\\\\Dummy\\\\ValueObject\\\\UserId",
188 | "userId": {
189 | "@scalar": "integer",
190 | "@value": 2
191 | }
192 | },
193 | "name": {
194 | "@scalar": "string",
195 | "@value": "Barristan Selmy"
196 | }
197 | }
198 | }
199 | ]
200 | }
201 | }'
202 | ```
203 |
204 | ### Custom Serializers
205 |
206 | If a custom serialization strategy is preferred, the `Serializer` class should be used instead. A `CustomStrategy` must implement the `StrategyInterface`.
207 |
208 | Usage is as follows:
209 |
210 | ```php
211 | use NilPortugues\Serializer\Serializer;
212 | use NilPortugues\Serializer\Strategy\CustomStrategy;
213 |
214 | $serializer = new Serializer(new CustomStrategy());
215 |
216 | echo $serializer->serialize($post);
217 | ```
218 |
219 | ----
220 |
221 |
222 | ## Data Transformation
223 |
224 | Transformer classes **greatly differ** from a `Strategy` class because these cannot `unserialize()` as all class references are lost in the process of transformation.
225 |
226 | To obtain transformations instead of the `Serializer` class usage of `DeepCopySerializer` is required.
227 |
228 | The Serializer library comes with a set of defined Transformers that implement the `StrategyInterface`.
229 | Usage is as simple as before, pass a Transformer as a `$strategy`.
230 |
231 | **For instance:**
232 |
233 | ```php
234 | //...same as before ...
235 |
236 | $serializer = new DeepCopySerializer(new JsonTransformer());
237 | echo $serializer->serialize($post);
238 | ```
239 |
240 | Following, there are some examples and its output, given the `$post` object as data to be Transformed.
241 |
242 | ### Array Transformer
243 |
244 | - [`NilPortugues\Serializer\Transformer\ArrayTransformer`](https://github.com/nilportugues/serializer/blob/master/src/Transformer/ArrayTransformer.php)
245 |
246 |
247 | ```php
248 | array(
249 | 'postId' => 9,
250 | 'title' => 'Hello World',
251 | 'content' => 'Your first post',
252 | 'author' => array(
253 | 'userId' => 1,
254 | 'name' => 'Post Author',
255 | ),
256 | 'comments' => array(
257 | 0 => array(
258 | 'commentId' => 1000,
259 | 'dates' => array(
260 | 'created_at' => '2015-07-18T12:13:00+02:00',
261 | 'accepted_at' => '2015-07-19T00:00:00+02:00',
262 | ),
263 | 'comment' => 'Have no fear, sers, your king is safe.',
264 | 'user' => array(
265 | 'userId' => 2,
266 | 'name' => 'Barristan Selmy',
267 | ),
268 | ),
269 | ),
270 | );
271 | ```
272 |
273 | ### Flat Array Transformer
274 |
275 | - [`NilPortugues\Serializer\Transformer\FlatArrayTransformer`](https://github.com/nilportugues/serializer/blob/master/src/Transformer/FlatArrayTransformer.php)
276 |
277 | ```php
278 | array(
279 | 'postId' => 9,
280 | 'title' => 'Hello World',
281 | 'content' => 'Your first post',
282 | 'author.userId' => 1,
283 | 'author.name' => 'Post Author',
284 | 'comments.0.commentId' => 1000,
285 | 'comments.0.dates.created_at' => '2015-07-18T12:13:00+02:00',
286 | 'comments.0.dates.accepted_at' => '2015-07-19T00:00:00+02:00',
287 | 'comments.0.comment' => 'Have no fear, sers, your king is safe.',
288 | 'comments.0.user.userId' => 2,
289 | 'comments.0.user.name' => 'Barristan Selmy',
290 | );
291 | ```
292 |
293 | ### XML Transformer
294 |
295 | - [`NilPortugues\Serializer\Transformer\XmlTransformer`](https://github.com/nilportugues/serializer/blob/master/src/Transformer/XmlTransformer.php)
296 |
297 | ```xml
298 |
299 |
300 | 9
301 | Hello World
302 | Your first post
303 |
304 | 1
305 | Post Author
306 |
307 |
308 |
309 | 1000
310 |
311 | 2015-07-18T12:13:00+02:00
312 | 2015-07-19T00:00:00+02:00
313 |
314 | Have no fear, sers, your king is safe.
315 |
316 | 2
317 | Barristan Selmy
318 |
319 |
320 |
321 |
322 | ```
323 |
324 | ### YAML Transformer
325 |
326 | - [`NilPortugues\Serializer\Transformer\YamlTransformer`](https://github.com/nilportugues/serializer/blob/master/src/Transformer/YamlTransformer.php)
327 |
328 | ```yml
329 | title: 'Hello World'
330 | content: 'Your first post'
331 | author:
332 | userId: 1
333 | name: 'Post Author'
334 | comments:
335 | - { commentId: 1000, dates: { created_at: '2015-07-18T12:13:00+02:00', accepted_at: '2015-07-19T00:00:00+02:00' }, comment: 'Have no fear, sers, your king is safe.', user: { userId: 2, name: 'Barristan Selmy' } }
336 | ```
337 |
338 |
339 | ### Json Transformer
340 |
341 | JsonTransformer comes in 2 flavours. For object to JSON transformation the following transformer should be used:
342 |
343 | - [`NilPortugues\Serializer\Transformer\JsonTransformer`](https://github.com/nilportugues/serializer/blob/master/src/Transformer/JsonTransformer.php)
344 |
345 | **Output**
346 |
347 | ```json
348 | {
349 | "postId": 9,
350 | "title": "Hello World",
351 | "content": "Your first post",
352 | "author": {
353 | "userId": 1,
354 | "name": "Post Author"
355 | },
356 | "comments": [
357 | {
358 | "commentId": 1000,
359 | "dates": {
360 | "created_at": "2015-07-18T13:34:55+02:00",
361 | "accepted_at": "2015-07-18T14:09:55+02:00"
362 | },
363 | "comment": "Have no fear, sers, your king is safe.",
364 | "user": {
365 | "userId": 2,
366 | "name": "Barristan Selmy"
367 | }
368 | }
369 | ]
370 | }
371 | ```
372 |
373 | If your desired output is for **API consumption**, you may like to check out the JsonTransformer library, or require it using:
374 |
375 | ```json
376 | $ composer require nilportugues/json
377 | ```
378 |
379 |
380 | ### JSend Transformer
381 |
382 | JSend Transformer has been built to transform data into valid **JSend** specification resources.
383 |
384 | Please check out the [JSend Transformer](https://github.com/nilportugues/jsend-transformer) or download it using:
385 |
386 | ```json
387 | $ composer require nilportugues/jsend
388 | ```
389 |
390 |
391 | ### JSON API Transformer
392 |
393 | JSON API Transformer has been built to transform data into valid **JSON API** specification resources.
394 |
395 | Please check out the [JSON API Transformer](https://github.com/nilportugues/jsonapi-transformer) or download it using:
396 |
397 | ```json
398 | $ composer require nilportugues/json-api
399 | ```
400 |
401 |
402 | ### HAL+JSON Transformer
403 |
404 | HAL+JSON Transformer has been built for **HAL+JSON API creation**. Given an object and a series of mappings a valid HAL+JSON resource representation is given as output.
405 |
406 | Please check out the [HAL+JSON API Transformer](https://github.com/nilportugues/hal-json-transformer) or download it using:
407 |
408 | ```json
409 | $ composer require nilportugues/haljson
410 | ```
411 |
412 | ----
413 |
414 |
415 | ## Quality
416 |
417 | To run the PHPUnit tests at the command line, go to the tests directory and issue `phpunit`.
418 |
419 | This library attempts to comply with [PSR-2](http://www.php-fig.org/psr/psr-2/) and [PSR-4](http://www.php-fig.org/psr/psr-4/).
420 |
421 | If you notice compliance oversights, please send a patch via pull request.
422 |
423 | ## Contribute
424 |
425 | Contributions to the package are always welcome!
426 |
427 | * Report any bugs or issues you find on the [issue tracker](https://github.com/nilportugues/serializer/issues/new).
428 | * You can grab the source code at the package's [Git repository](https://github.com/nilportugues/serializer).
429 |
430 | ## Authors
431 |
432 | * [Nil Portugués Calderó](http://nilportugues.com)
433 | * [The Community Contributors](https://github.com/nilportugues/serializer/graphs/contributors)
434 |
435 | ## License
436 | The code base is licensed under the MIT license.
437 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "nilportugues/serializer",
3 | "type": "library",
4 | "description": "Serialize PHP variables, including objects, in any format. Support to unserialize it too.",
5 | "keywords": ["json", "serialize", "serializer"],
6 | "homepage": "http://nilportugues.com",
7 | "license": "MIT",
8 | "authors": [
9 |
10 | {
11 | "name": "Nil Portugués Calderó",
12 | "email": "contact@nilportugues.com",
13 | "role": "Project Lead Developer"
14 | },
15 | {
16 | "name": "Zumba Fitness, LLC",
17 | "email": "engineering@zumba.com",
18 | "role": "Author of the original idea: https://github.com/zumba/json-serializer"
19 | },
20 | {
21 | "name": "Juan Basso",
22 | "email": "juan.basso@zumba.com",
23 | "role": "Author of the original idea: https://github.com/zumba/json-serializer"
24 | }
25 | ],
26 | "require": {
27 | "php": ">=5.6.0",
28 | "symfony/yaml": "2.*|3.*|4.*"
29 | },
30 | "require-dev": {
31 | "phpunit/phpunit": "5.*",
32 | "nilportugues/php_backslasher": "~0.2",
33 | "fabpot/php-cs-fixer": "^1.9",
34 | "doctrine/collections": "^1.3"
35 | },
36 | "autoload": {
37 | "psr-4": {
38 | "NilPortugues\\Serializer\\": "src/"
39 | }
40 | },
41 | "autoload-dev": {
42 | "psr-4": {
43 | "NilPortugues\\Test\\Serializer\\": "tests/"
44 | }
45 | },
46 | "config": {
47 | "bin-dir": "bin/"
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | ./tests
31 |
32 |
33 |
34 |
35 |
36 | ./src/
37 |
38 | ./src/Mapping/
39 | ./src/Serializer/
40 | ./vendor/
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/src/DeepCopySerializer.php:
--------------------------------------------------------------------------------
1 |
5 | * Date: 8/28/15
6 | * Time: 1:44 AM.
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace NilPortugues\Serializer;
13 |
14 | use ReflectionClass;
15 |
16 | class DeepCopySerializer extends Serializer
17 | {
18 | /**
19 | * Extract the data from an object.
20 | *
21 | * @param mixed $value
22 | *
23 | * @return array
24 | */
25 | protected function serializeObject($value)
26 | {
27 | if (self::$objectStorage->contains($value)) {
28 | return self::$objectStorage[$value];
29 | }
30 |
31 | $reflection = new ReflectionClass($value);
32 | $className = $reflection->getName();
33 |
34 | $serialized = $this->serializeInternalClass($value, $className, $reflection);
35 | self::$objectStorage->attach($value, $serialized);
36 |
37 | return $serialized;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/JsonSerializer.php:
--------------------------------------------------------------------------------
1 |
5 | * Date: 8/29/15
6 | * Time: 12:42 PM.
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace NilPortugues\Serializer;
13 |
14 | use NilPortugues\Serializer\Strategy\JsonStrategy;
15 |
16 | class JsonSerializer extends Serializer
17 | {
18 | /**
19 | *
20 | */
21 | public function __construct()
22 | {
23 | parent::__construct(new JsonStrategy());
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/Serializer.php:
--------------------------------------------------------------------------------
1 | 'serializeArray',
59 | 'integer' => 'serializeScalar',
60 | 'double' => 'serializeScalar',
61 | 'boolean' => 'serializeScalar',
62 | 'string' => 'serializeScalar',
63 | ];
64 |
65 | /**
66 | * Hack specific serialization classes.
67 | *
68 | * @var array
69 | */
70 | protected $unserializationMapHHVM = [];
71 |
72 | /**
73 | * @param StrategyInterface $strategy
74 | */
75 | public function __construct(StrategyInterface $strategy)
76 | {
77 |
78 | $this->serializationStrategy = $strategy;
79 | }
80 |
81 | /**
82 | * This is handly specially in order to add additional data before the
83 | * serialization process takes place using the transformer public methods, if any.
84 | *
85 | * @return StrategyInterface
86 | */
87 | public function getTransformer()
88 | {
89 | return $this->serializationStrategy;
90 | }
91 |
92 | /**
93 | * Serialize the value in JSON.
94 | *
95 | * @param mixed $value
96 | *
97 | * @return string JSON encoded
98 | *
99 | * @throws SerializerException
100 | */
101 | public function serialize($value)
102 | {
103 | $this->reset();
104 |
105 | return $this->serializationStrategy->serialize($this->serializeData($value));
106 | }
107 |
108 | /**
109 | * Reset variables.
110 | */
111 | protected function reset()
112 | {
113 | self::$objectStorage = new SplObjectStorage();
114 | self::$objectMapping = [];
115 | self::$objectMappingIndex = 0;
116 | }
117 |
118 | /**
119 | * Parse the data to be json encoded.
120 | *
121 | * @param mixed $value
122 | *
123 | * @return mixed
124 | *
125 | * @throws SerializerException
126 | */
127 | protected function serializeData($value)
128 | {
129 | $this->guardForUnsupportedValues($value);
130 |
131 | if ($this->isInstanceOf($value, 'SplFixedArray')) {
132 | return SplFixedArraySerializer::serialize($this, $value);
133 | }
134 |
135 | if (\is_object($value)) {
136 | return $this->serializeObject($value);
137 | }
138 |
139 | $type = (\gettype($value) && $value !== null) ? \gettype($value) : 'string';
140 | $func = $this->serializationMap[$type];
141 |
142 | return $this->$func($value);
143 | }
144 |
145 | /**
146 | * Check if a class is instance or extends from the expected instance.
147 | *
148 | * @param mixed $value
149 | * @param string $classFQN
150 | *
151 | * @return bool
152 | */
153 | private function isInstanceOf($value, $classFQN)
154 | {
155 | return is_object($value)
156 | && (strtolower(get_class($value)) === strtolower($classFQN) || \is_subclass_of($value, $classFQN, true));
157 | }
158 |
159 | /**
160 | * @param mixed $value
161 | *
162 | * @throws SerializerException
163 | */
164 | protected function guardForUnsupportedValues($value)
165 | {
166 | if ($value instanceof Closure) {
167 | throw new SerializerException('Closures are not supported in Serializer');
168 | }
169 |
170 | if ($value instanceof \DatePeriod) {
171 | throw new SerializerException(
172 | 'DatePeriod is not supported in Serializer. Loop through it and serialize the output.'
173 | );
174 | }
175 |
176 | if (\is_resource($value)) {
177 | throw new SerializerException('Resource is not supported in Serializer');
178 | }
179 | }
180 |
181 | /**
182 | * Unserialize the value from string.
183 | *
184 | * @param mixed $value
185 | *
186 | * @return mixed
187 | */
188 | public function unserialize($value)
189 | {
190 | if (\is_array($value) && isset($value[self::SCALAR_TYPE])) {
191 | return $this->unserializeData($value);
192 | }
193 |
194 | $this->reset();
195 |
196 | return $this->unserializeData($this->serializationStrategy->unserialize($value));
197 | }
198 |
199 | /**
200 | * Parse the json decode to convert to objects again.
201 | *
202 | * @param mixed $value
203 | *
204 | * @return mixed
205 | */
206 | protected function unserializeData($value)
207 | {
208 | if ($value === null || !is_array($value)) {
209 | return $value;
210 | }
211 |
212 | if (isset($value[self::MAP_TYPE]) && !isset($value[self::CLASS_IDENTIFIER_KEY])) {
213 | $value = $value[self::SCALAR_VALUE];
214 |
215 | return $this->unserializeData($value);
216 | }
217 |
218 | if (isset($value[self::SCALAR_TYPE])) {
219 | return $this->getScalarValue($value);
220 | }
221 |
222 | if (isset($value[self::CLASS_PARENT_KEY]) && 0 === strcmp($value[self::CLASS_PARENT_KEY], 'SplFixedArray')) {
223 | return SplFixedArraySerializer::unserialize($this, $value[self::CLASS_IDENTIFIER_KEY], $value);
224 | }
225 |
226 | if (isset($value[self::CLASS_IDENTIFIER_KEY])) {
227 | return $this->unserializeObject($value);
228 | }
229 |
230 | return \array_map([$this, __FUNCTION__], $value);
231 | }
232 |
233 | /**
234 | * @param $value
235 | *
236 | * @return float|int|null|bool
237 | */
238 | protected function getScalarValue($value)
239 | {
240 | switch ($value[self::SCALAR_TYPE]) {
241 | case 'integer':
242 | return \intval($value[self::SCALAR_VALUE]);
243 | case 'float':
244 | return \floatval($value[self::SCALAR_VALUE]);
245 | case 'boolean':
246 | return $value[self::SCALAR_VALUE];
247 | case 'NULL':
248 | return self::NULL_VAR;
249 | }
250 |
251 | return $value[self::SCALAR_VALUE];
252 | }
253 |
254 | /**
255 | * Convert the serialized array into an object.
256 | *
257 | * @param array $value
258 | *
259 | * @return object
260 | *
261 | * @throws SerializerException
262 | */
263 | protected function unserializeObject(array $value)
264 | {
265 | $className = $value[self::CLASS_IDENTIFIER_KEY];
266 | unset($value[self::CLASS_IDENTIFIER_KEY]);
267 |
268 | if (isset($value[self::MAP_TYPE])) {
269 | unset($value[self::MAP_TYPE]);
270 | unset($value[self::SCALAR_VALUE]);
271 | }
272 |
273 | if ($className[0] === '@') {
274 | return self::$objectMapping[substr($className, 1)];
275 | }
276 |
277 | if (!class_exists($className)) {
278 | throw new SerializerException('Unable to find class '.$className);
279 | }
280 |
281 | return (null === ($obj = $this->unserializeDateTimeFamilyObject($value, $className)))
282 | ? $this->unserializeUserDefinedObject($value, $className) : $obj;
283 | }
284 |
285 | /**
286 | * @param array $value
287 | * @param string $className
288 | *
289 | * @return mixed
290 | */
291 | protected function unserializeDateTimeFamilyObject(array $value, $className)
292 | {
293 | $obj = null;
294 |
295 | if ($this->isDateTimeFamilyObject($className)) {
296 | $obj = $this->restoreUsingUnserialize($className, $value);
297 | self::$objectMapping[self::$objectMappingIndex++] = $obj;
298 | }
299 |
300 | return $obj;
301 | }
302 |
303 | /**
304 | * @param string $className
305 | *
306 | * @return bool
307 | */
308 | protected function isDateTimeFamilyObject($className)
309 | {
310 | $isDateTime = false;
311 |
312 | foreach ($this->dateTimeClassType as $class) {
313 | $isDateTime = $isDateTime || \is_subclass_of($className, $class, true) || $class === $className;
314 | }
315 |
316 | return $isDateTime;
317 | }
318 |
319 | /**
320 | * @param string $className
321 | * @param array $attributes
322 | *
323 | * @return mixed
324 | */
325 | protected function restoreUsingUnserialize($className, array $attributes)
326 | {
327 | foreach ($attributes as &$attribute) {
328 | $attribute = $this->unserializeData($attribute);
329 | }
330 |
331 | $obj = (object) $attributes;
332 | $serialized = \preg_replace(
333 | '|^O:\d+:"\w+":|',
334 | 'O:'.strlen($className).':"'.$className.'":',
335 | \serialize($obj)
336 | );
337 |
338 | return \unserialize($serialized);
339 | }
340 |
341 | /**
342 | * @param array $value
343 | * @param string $className
344 | *
345 | * @return object
346 | */
347 | protected function unserializeUserDefinedObject(array $value, $className)
348 | {
349 | $ref = new ReflectionClass($className);
350 | $obj = $ref->newInstanceWithoutConstructor();
351 |
352 | self::$objectMapping[self::$objectMappingIndex++] = $obj;
353 | $this->setUnserializedObjectProperties($value, $ref, $obj);
354 |
355 | if (\method_exists($obj, '__wakeup')) {
356 | $obj->__wakeup();
357 | }
358 |
359 | return $obj;
360 | }
361 |
362 | /**
363 | * @param array $value
364 | * @param ReflectionClass $ref
365 | * @param mixed $obj
366 | *
367 | * @return mixed
368 | */
369 | protected function setUnserializedObjectProperties(array $value, ReflectionClass $ref, $obj)
370 | {
371 | foreach ($value as $property => $propertyValue) {
372 | try {
373 | $propRef = $ref->getProperty($property);
374 | $propRef->setAccessible(true);
375 | $propRef->setValue($obj, $this->unserializeData($propertyValue));
376 | } catch (ReflectionException $e) {
377 | $obj->$property = $this->unserializeData($propertyValue);
378 | }
379 | }
380 |
381 | return $obj;
382 | }
383 |
384 | /**
385 | * @param $value
386 | *
387 | * @return string
388 | */
389 | protected function serializeScalar($value)
390 | {
391 | $type = \gettype($value);
392 | if ($type === 'double') {
393 | $type = 'float';
394 | }
395 |
396 | return [
397 | self::SCALAR_TYPE => $type,
398 | self::SCALAR_VALUE => $value,
399 | ];
400 | }
401 |
402 | /**
403 | * @param array $value
404 | *
405 | * @return array
406 | */
407 | protected function serializeArray(array $value)
408 | {
409 | if (\array_key_exists(self::MAP_TYPE, $value)) {
410 | return $value;
411 | }
412 |
413 | $toArray = [self::MAP_TYPE => 'array', self::SCALAR_VALUE => []];
414 | foreach ($value as $key => $field) {
415 | $toArray[self::SCALAR_VALUE][$key] = $this->serializeData($field);
416 | }
417 |
418 | return $this->serializeData($toArray);
419 | }
420 |
421 | /**
422 | * Extract the data from an object.
423 | *
424 | * @param mixed $value
425 | *
426 | * @return array
427 | */
428 | protected function serializeObject($value)
429 | {
430 | if (self::$objectStorage->contains($value)) {
431 | return [self::CLASS_IDENTIFIER_KEY => '@'.self::$objectStorage[$value]];
432 | }
433 |
434 | self::$objectStorage->attach($value, self::$objectMappingIndex++);
435 |
436 | $reflection = new ReflectionClass($value);
437 | $className = $reflection->getName();
438 |
439 | return $this->serializeInternalClass($value, $className, $reflection);
440 | }
441 |
442 | /**
443 | * @param mixed $value
444 | * @param string $className
445 | * @param ReflectionClass $ref
446 | *
447 | * @return array
448 | */
449 | protected function serializeInternalClass($value, $className, ReflectionClass $ref)
450 | {
451 | $paramsToSerialize = $this->getObjectProperties($ref, $value);
452 | $data = [self::CLASS_IDENTIFIER_KEY => $className];
453 | $data += \array_map([$this, 'serializeData'], $this->extractObjectData($value, $ref, $paramsToSerialize));
454 |
455 | return $data;
456 | }
457 |
458 | /**
459 | * Return the list of properties to be serialized.
460 | *
461 | * @param ReflectionClass $ref
462 | * @param $value
463 | *
464 | * @return array
465 | */
466 | protected function getObjectProperties(ReflectionClass $ref, $value)
467 | {
468 | $props = [];
469 | foreach ($ref->getProperties() as $prop) {
470 | $props[] = $prop->getName();
471 | }
472 |
473 | return \array_unique(\array_merge($props, \array_keys(\get_object_vars($value))));
474 | }
475 |
476 | /**
477 | * Extract the object data.
478 | *
479 | * @param mixed $value
480 | * @param \ReflectionClass $rc
481 | * @param array $properties
482 | *
483 | * @return array
484 | */
485 | protected function extractObjectData($value, ReflectionClass $rc, array $properties)
486 | {
487 | $data = [];
488 |
489 | $this->extractCurrentObjectProperties($value, $rc, $properties, $data);
490 | $this->extractAllInhertitedProperties($value, $rc, $data);
491 |
492 | return $data;
493 | }
494 |
495 | /**
496 | * @param mixed $value
497 | * @param ReflectionClass $rc
498 | * @param array $properties
499 | * @param array $data
500 | */
501 | protected function extractCurrentObjectProperties($value, ReflectionClass $rc, array $properties, array &$data)
502 | {
503 | foreach ($properties as $propertyName) {
504 | try {
505 | $propRef = $rc->getProperty($propertyName);
506 | $propRef->setAccessible(true);
507 | $data[$propertyName] = $propRef->getValue($value);
508 | } catch (ReflectionException $e) {
509 | $data[$propertyName] = $value->$propertyName;
510 | }
511 | }
512 | }
513 |
514 | /**
515 | * @param mixed $value
516 | * @param ReflectionClass $rc
517 | * @param array $data
518 | */
519 | protected function extractAllInhertitedProperties($value, ReflectionClass $rc, array &$data)
520 | {
521 | do {
522 | $rp = array();
523 | /* @var $property \ReflectionProperty */
524 | foreach ($rc->getProperties() as $property) {
525 | $property->setAccessible(true);
526 | $rp[$property->getName()] = $property->getValue($value);
527 | }
528 | $data = \array_merge($rp, $data);
529 | } while ($rc = $rc->getParentClass());
530 | }
531 | }
532 |
--------------------------------------------------------------------------------
/src/Serializer/HHVM/DatePeriodSerializer.php:
--------------------------------------------------------------------------------
1 |
5 | * Date: 7/4/15
6 | * Time: 12:41 AM.
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace NilPortugues\Serializer\Serializer\HHVM;
13 |
14 | /**
15 | * Class DatePeriodSerializer.
16 | */
17 | class DatePeriodSerializer
18 | {
19 | //HHVM's implementation is completely different
20 | /*
21 | [start:DatePeriod:private] => DateTime Object
22 | (
23 | [date] => 2012-07-01 00:00:00.000000
24 | [timezone_type] => 3
25 | [timezone] => UTC
26 | )
27 |
28 | [interval:DatePeriod:private] => DateInterval Object
29 | (
30 | )
31 |
32 | [end:DatePeriod:private] => DateTime Object
33 | (
34 | [date] => 2012-08-05 00:00:00.000000
35 | [timezone_type] => 3
36 | [timezone] => UTC
37 | )
38 |
39 | [options:DatePeriod:private] =>
40 | [current:DatePeriod:private] => DateTime Object
41 | (
42 | [date] => 2012-08-05 00:00:00.000000
43 | [timezone_type] => 3
44 | [timezone] => UTC
45 | )
46 |
47 | [recurrances:DatePeriod:private] => 4
48 | [iterKey:DatePeriod:private] => 5
49 |
50 | */
51 | }
52 |
--------------------------------------------------------------------------------
/src/Serializer/HHVM/DateTimeImmutableSerializer.php:
--------------------------------------------------------------------------------
1 |
5 | * Date: 7/3/15
6 | * Time: 6:00 PM.
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace NilPortugues\Serializer\Serializer\HHVM;
13 |
14 | use NilPortugues\Serializer\Serializer;
15 | use NilPortugues\Serializer\Serializer\InternalClasses\DateTimeZoneSerializer;
16 | use ReflectionClass;
17 |
18 | final class DateTimeImmutableSerializer
19 | {
20 | /**
21 | * @param Serializer $serializer
22 | * @param string $className
23 | * @param array $value
24 | *
25 | * @return object
26 | */
27 | public static function unserialize(Serializer $serializer, $className, array $value)
28 | {
29 | $dateTimeZone = DateTimeZoneSerializer::unserialize(
30 | $serializer,
31 | 'DateTimeZone',
32 | array($serializer->unserialize($value['data']['timezone']))
33 | );
34 |
35 | $ref = new ReflectionClass($className);
36 |
37 | return $ref->newInstanceArgs(
38 | array($serializer->unserialize($value['data']['date']), $dateTimeZone)
39 | );
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/Serializer/HHVM/DateTimeSerializer.php:
--------------------------------------------------------------------------------
1 |
5 | * Date: 7/3/15
6 | * Time: 6:00 PM.
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace NilPortugues\Serializer\Serializer\HHVM;
13 |
14 | use NilPortugues\Serializer\Serializer;
15 | use NilPortugues\Serializer\Serializer\InternalClasses\DateTimeZoneSerializer;
16 | use ReflectionClass;
17 |
18 | final class DateTimeSerializer
19 | {
20 | /**
21 | * @param Serializer $serializer
22 | * @param string $className
23 | * @param array $value
24 | *
25 | * @return object
26 | */
27 | public static function unserialize(Serializer $serializer, $className, array $value)
28 | {
29 | $dateTimeZone = DateTimeZoneSerializer::unserialize(
30 | $serializer,
31 | 'DateTimeZone',
32 | array($serializer->unserialize($value['timezone']))
33 | );
34 |
35 | $ref = new ReflectionClass($className);
36 |
37 | return $ref->newInstanceArgs(
38 | array($serializer->unserialize($value['date']), $dateTimeZone)
39 | );
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/Serializer/InternalClasses/DateIntervalSerializer.php:
--------------------------------------------------------------------------------
1 |
5 | * Date: 7/3/15
6 | * Time: 6:00 PM.
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace NilPortugues\Serializer\Serializer\InternalClasses;
13 |
14 | use DateInterval;
15 | use NilPortugues\Serializer\Serializer;
16 | use ReflectionClass;
17 |
18 | class DateIntervalSerializer
19 | {
20 | /**
21 | * @param Serializer $serializer
22 | * @param string $className
23 | * @param array $value
24 | *
25 | * @return object
26 | */
27 | public static function unserialize(Serializer $serializer, $className, array $value)
28 | {
29 | $ref = new ReflectionClass($className);
30 |
31 | return self::fillObjectProperties(self::getTypedValue($serializer, $value), $ref);
32 | }
33 |
34 | /**
35 | * @param array $value
36 | * @param ReflectionClass $ref
37 | *
38 | * @return object
39 | */
40 | protected static function fillObjectProperties(array $value, ReflectionClass $ref)
41 | {
42 | $obj = $ref->newInstanceArgs([$value['construct']]);
43 | unset($value['construct']);
44 |
45 | foreach ($value as $k => $v) {
46 | $obj->$k = $v;
47 | }
48 |
49 | return $obj;
50 | }
51 |
52 | /**
53 | * @param Serializer $serializer
54 | * @param array $value
55 | *
56 | * @return mixed
57 | */
58 | protected static function getTypedValue(Serializer $serializer, array $value)
59 | {
60 | foreach ($value as &$v) {
61 | $v = $serializer->unserialize($v);
62 | }
63 |
64 | return $value;
65 | }
66 |
67 | /**
68 | * @param Serializer $serializer
69 | * @param DateInterval $dateInterval
70 | *
71 | * @return mixed
72 | */
73 | public static function serialize(Serializer $serializer, DateInterval $dateInterval)
74 | {
75 | return array(
76 | Serializer::CLASS_IDENTIFIER_KEY => \get_class($dateInterval),
77 | 'construct' => array(
78 | Serializer::SCALAR_TYPE => 'string',
79 | Serializer::SCALAR_VALUE => \sprintf(
80 | 'P%sY%sM%sDT%sH%sM%sS',
81 | $dateInterval->y,
82 | $dateInterval->m,
83 | $dateInterval->d,
84 | $dateInterval->h,
85 | $dateInterval->i,
86 | $dateInterval->s
87 | ),
88 | ),
89 | 'invert' => array(
90 | Serializer::SCALAR_TYPE => 'integer',
91 | Serializer::SCALAR_VALUE => (empty($dateInterval->invert)) ? 0 : 1,
92 | ),
93 | 'days' => array(
94 | Serializer::SCALAR_TYPE => \gettype($dateInterval->days),
95 | Serializer::SCALAR_VALUE => $dateInterval->days,
96 | ),
97 | );
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/src/Serializer/InternalClasses/DatePeriodSerializer.php:
--------------------------------------------------------------------------------
1 |
5 | * Date: 7/4/15
6 | * Time: 12:43 AM.
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace NilPortugues\Serializer\Serializer\InternalClasses;
13 |
14 | /**
15 | * Class DatePeriodSerializer.
16 | */
17 | class DatePeriodSerializer
18 | {
19 | /*
20 | [start] => DateTime Object
21 | (
22 | [date] => 2012-07-01 00:00:00
23 | [timezone_type] => 3
24 | [timezone] => Europe/Madrid
25 | )
26 |
27 | [current] => DateTime Object
28 | (
29 | [date] => 2012-08-05 00:00:00
30 | [timezone_type] => 3
31 | [timezone] => Europe/Madrid
32 | )
33 |
34 | [end] =>
35 | [interval] => DateInterval Object
36 | (
37 | [y] => 0
38 | [m] => 0
39 | [d] => 7
40 | [h] => 0
41 | [i] => 0
42 | [s] => 0
43 | [weekday] => 0
44 | [weekday_behavior] => 0
45 | [first_last_day_of] => 0
46 | [invert] => 0
47 | [days] =>
48 | [special_type] => 0
49 | [special_amount] => 0
50 | [have_weekday_relative] => 0
51 | [have_special_relative] => 0
52 | )
53 |
54 | [recurrences] => 5
55 | [include_start_date] => 1
56 |
57 | */
58 | }
59 |
--------------------------------------------------------------------------------
/src/Serializer/InternalClasses/DateTimeZoneSerializer.php:
--------------------------------------------------------------------------------
1 |
5 | * Date: 7/3/15
6 | * Time: 6:00 PM.
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace NilPortugues\Serializer\Serializer\InternalClasses;
13 |
14 | use DateTimeZone;
15 | use NilPortugues\Serializer\Serializer;
16 | use ReflectionClass;
17 |
18 | class DateTimeZoneSerializer
19 | {
20 | /**
21 | * @param Serializer $serializer
22 | * @param DateTimeZone $dateTimeZone
23 | *
24 | * @return mixed
25 | */
26 | public static function serialize(Serializer $serializer, DateTimeZone $dateTimeZone)
27 | {
28 | return array(
29 | Serializer::CLASS_IDENTIFIER_KEY => 'DateTimeZone',
30 | 'timezone' => array(
31 | Serializer::SCALAR_TYPE => 'string',
32 | Serializer::SCALAR_VALUE => $dateTimeZone->getName(),
33 | ),
34 | );
35 | }
36 |
37 | /**
38 | * @param Serializer $serializer
39 | * @param string $className
40 | * @param array $value
41 | *
42 | * @return object
43 | */
44 | public static function unserialize(Serializer $serializer, $className, array $value)
45 | {
46 | $ref = new ReflectionClass($className);
47 |
48 | foreach ($value as &$v) {
49 | if (\is_array($v)) {
50 | $v = $serializer->unserialize($v);
51 | }
52 | }
53 |
54 | return $ref->newInstanceArgs($value);
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/Serializer/InternalClasses/SplFixedArraySerializer.php:
--------------------------------------------------------------------------------
1 | get_class($splFixedArray),
21 | Serializer::CLASS_PARENT_KEY => 'SplFixedArray',
22 | Serializer::SCALAR_VALUE => [],
23 | ];
24 | foreach ($splFixedArray->toArray() as $key => $field) {
25 | $toArray[Serializer::SCALAR_VALUE][$key] = $serializer->serialize($field);
26 | }
27 |
28 | return $toArray;
29 | }
30 |
31 | /**
32 | * @param Serializer $serializer
33 | * @param string $className
34 | * @param array $value
35 | *
36 | * @return mixed
37 | */
38 | public static function unserialize(Serializer $serializer, $className, array $value)
39 | {
40 | $data = $serializer->unserialize($value[Serializer::SCALAR_VALUE]);
41 |
42 | /* @var SplFixedArray $instance */
43 | $ref = new ReflectionClass($className);
44 | $instance = $ref->newInstanceWithoutConstructor();
45 |
46 | $instance->setSize(count($data));
47 | foreach ($data as $k => $v) {
48 | $instance[$k] = $v;
49 | }
50 |
51 | return $instance;
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/SerializerException.php:
--------------------------------------------------------------------------------
1 |
5 | * Date: 7/3/15
6 | * Time: 6:11 PM.
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace NilPortugues\Serializer\Strategy;
13 |
14 | /**
15 | * Class JsonStrategy.
16 | */
17 | class JsonStrategy implements StrategyInterface
18 | {
19 | /**
20 | * @param mixed $value
21 | *
22 | * @return string
23 | */
24 | public function serialize($value)
25 | {
26 | return \json_encode($value, JSON_UNESCAPED_UNICODE);
27 | }
28 |
29 | /**
30 | * @param $value
31 | *
32 | * @return array
33 | */
34 | public function unserialize($value)
35 | {
36 | return \json_decode($value, true);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/Strategy/NullStrategy.php:
--------------------------------------------------------------------------------
1 |
5 | * Date: 8/29/15
6 | * Time: 12:44 PM.
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace NilPortugues\Serializer\Strategy;
13 |
14 | /**
15 | * Class NullStrategy.
16 | */
17 | class NullStrategy implements StrategyInterface
18 | {
19 | /**
20 | * @param mixed $value
21 | *
22 | * @return string
23 | */
24 | public function serialize($value)
25 | {
26 | return $value;
27 | }
28 |
29 | /**
30 | * @param string $value
31 | *
32 | * @return array
33 | */
34 | public function unserialize($value)
35 | {
36 | return $value;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/Strategy/StrategyInterface.php:
--------------------------------------------------------------------------------
1 |
5 | * Date: 7/4/15
6 | * Time: 2:56 PM.
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace NilPortugues\Serializer\Strategy;
13 |
14 | interface StrategyInterface
15 | {
16 | /**
17 | * @param mixed $value
18 | *
19 | * @return string
20 | */
21 | public function serialize($value);
22 |
23 | /**
24 | * @param $value
25 | *
26 | * @return array
27 | */
28 | public function unserialize($value);
29 | }
30 |
--------------------------------------------------------------------------------
/src/Strategy/XmlStrategy.php:
--------------------------------------------------------------------------------
1 |
5 | * Date: 8/29/15
6 | * Time: 12:46 PM.
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace NilPortugues\Serializer\Strategy;
13 |
14 | use NilPortugues\Serializer\Serializer;
15 | use SimpleXMLElement;
16 |
17 | class XmlStrategy implements StrategyInterface
18 | {
19 | /**
20 | * @var array
21 | */
22 | private $replacements = [
23 | Serializer::CLASS_IDENTIFIER_KEY => 'np_serializer_type',
24 | Serializer::SCALAR_TYPE => 'np_serializer_scalar',
25 | Serializer::SCALAR_VALUE => 'np_serializer_value',
26 | Serializer::MAP_TYPE => 'np_serializer_map',
27 | ];
28 |
29 | /**
30 | * @param mixed $value
31 | *
32 | * @return string
33 | */
34 | public function serialize($value)
35 | {
36 | $value = self::replaceKeys($this->replacements, $value);
37 | $xml = new SimpleXMLElement('');
38 | $this->arrayToXml($value, $xml);
39 |
40 | return $xml->asXML();
41 | }
42 |
43 | /**
44 | * @param array $replacements
45 | * @param array $input
46 | *
47 | * @return array
48 | */
49 | private static function replaceKeys(array &$replacements, array $input)
50 | {
51 | $return = [];
52 | foreach ($input as $key => $value) {
53 | $key = \str_replace(\array_keys($replacements), \array_values($replacements), $key);
54 |
55 | if (\is_array($value)) {
56 | $value = self::replaceKeys($replacements, $value);
57 | }
58 |
59 | $return[$key] = $value;
60 | }
61 |
62 | return $return;
63 | }
64 |
65 | /**
66 | * Converts an array to XML using SimpleXMLElement.
67 | *
68 | * @param array $data
69 | * @param SimpleXMLElement $xmlData
70 | */
71 | private function arrayToXml(array &$data, SimpleXMLElement $xmlData)
72 | {
73 | foreach ($data as $key => $value) {
74 | if (\is_array($value)) {
75 | if (\is_numeric($key)) {
76 | $key = 'np_serializer_element_'.gettype($key).'_'.$key;
77 | }
78 | $subnode = $xmlData->addChild($key);
79 | $this->arrayToXml($value, $subnode);
80 | } else {
81 | $xmlData->addChild("$key", "$value");
82 | }
83 | }
84 | }
85 |
86 | /**
87 | * @param $value
88 | *
89 | * @return array
90 | */
91 | public function unserialize($value)
92 | {
93 | $array = (array) \simplexml_load_string($value);
94 | self::castToArray($array);
95 | self::recoverArrayNumericKeyValues($array);
96 | $replacements = \array_flip($this->replacements);
97 | $array = self::replaceKeys($replacements, $array);
98 |
99 | return $array;
100 | }
101 |
102 | /**
103 | * @param array $array
104 | */
105 | private static function castToArray(array &$array)
106 | {
107 | foreach ($array as &$value) {
108 | if ($value instanceof SimpleXMLElement) {
109 | $value = (array) $value;
110 | }
111 |
112 | if (\is_array($value)) {
113 | self::castToArray($value);
114 | }
115 | }
116 | }
117 |
118 | /**
119 | * @param array $array
120 | */
121 | private static function recoverArrayNumericKeyValues(array &$array)
122 | {
123 | $newArray = [];
124 | foreach ($array as $key => &$value) {
125 | if (false !== \strpos($key, 'np_serializer_element_')) {
126 | $key = self::getNumericKeyValue($key);
127 | }
128 |
129 | $newArray[$key] = $value;
130 |
131 | if (\is_array($newArray[$key])) {
132 | self::recoverArrayNumericKeyValues($newArray[$key]);
133 | }
134 | }
135 | $array = $newArray;
136 | }
137 |
138 | /**
139 | * @param $key
140 | *
141 | * @return float|int
142 | */
143 | private static function getNumericKeyValue($key)
144 | {
145 | $newKey = \str_replace('np_serializer_element_', '', $key);
146 | list($type, $index) = \explode('_', $newKey);
147 |
148 | if ('integer' === $type) {
149 | $index = (int) $index;
150 | }
151 |
152 | return $index;
153 | }
154 | }
155 |
--------------------------------------------------------------------------------
/src/Strategy/YamlStrategy.php:
--------------------------------------------------------------------------------
1 |
5 | * Date: 8/27/15
6 | * Time: 11:58 PM.
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace NilPortugues\Serializer\Strategy;
13 |
14 | use Symfony\Component\Yaml\Yaml;
15 |
16 | class YamlStrategy implements StrategyInterface
17 | {
18 | /**
19 | * @param mixed $value
20 | *
21 | * @return string
22 | */
23 | public function serialize($value)
24 | {
25 | return Yaml::dump($value);
26 | }
27 |
28 | /**
29 | * @param $value
30 | *
31 | * @return array
32 | */
33 | public function unserialize($value)
34 | {
35 | return Yaml::parse($value);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/Transformer/AbstractTransformer.php:
--------------------------------------------------------------------------------
1 |
5 | * Date: 7/17/15
6 | * Time: 11:40 PM.
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace NilPortugues\Serializer\Transformer;
13 |
14 | use InvalidArgumentException;
15 | use NilPortugues\Serializer\Serializer;
16 | use NilPortugues\Serializer\Strategy\StrategyInterface;
17 |
18 | abstract class AbstractTransformer implements StrategyInterface
19 | {
20 | /**
21 | * @param array $array
22 | * @param array $unwantedKey
23 | */
24 | protected function recursiveUnset(array &$array, array $unwantedKey)
25 | {
26 | foreach ($unwantedKey as $key) {
27 | if (\array_key_exists($key, $array)) {
28 | unset($array[$key]);
29 | }
30 | }
31 |
32 | foreach ($array as &$value) {
33 | if (\is_array($value)) {
34 | $this->recursiveUnset($value, $unwantedKey);
35 | }
36 | }
37 | }
38 |
39 | /**
40 | * @param array $array
41 | */
42 | protected function recursiveSetValues(array &$array)
43 | {
44 | if (\array_key_exists(Serializer::SCALAR_VALUE, $array)) {
45 | $array = $array[Serializer::SCALAR_VALUE];
46 | }
47 |
48 | if (\is_array($array) && !array_key_exists(Serializer::SCALAR_VALUE, $array)) {
49 | foreach ($array as &$value) {
50 | if (\is_array($value)) {
51 | $this->recursiveSetValues($value);
52 | }
53 | }
54 | }
55 | }
56 |
57 | /**
58 | * @param array $array
59 | * @param null $parentKey
60 | * @param null $currentKey
61 | */
62 | protected function recursiveFlattenOneElementObjectsToScalarType(array &$array, $parentKey = null, $currentKey = null)
63 | {
64 | if (1 === \count($array) && \is_scalar(\end($array))) {
65 | if ($parentKey == $currentKey) {
66 | $array = \array_pop($array);
67 | }
68 | }
69 |
70 | if (\is_array($array)) {
71 | foreach ($array as $parentKey => &$value) {
72 |
73 | if (\is_array($value)) {
74 | $key = null;
75 | foreach($value as $key => $v) {
76 | if (is_array($v)) {
77 | $this->recursiveFlattenOneElementObjectsToScalarType($v, $parentKey, $key);
78 | }
79 | }
80 | $this->recursiveFlattenOneElementObjectsToScalarType($value, $parentKey, $key);
81 | }
82 | }
83 | }
84 | }
85 |
86 | /**
87 | * @param $value
88 | *
89 | * @throws \InvalidArgumentException
90 | *
91 | * @return array
92 | */
93 | public function unserialize($value)
94 | {
95 | throw new InvalidArgumentException(\sprintf('%s does not perform unserializations.', __CLASS__));
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/src/Transformer/ArrayTransformer.php:
--------------------------------------------------------------------------------
1 |
5 | * Date: 8/29/15
6 | * Time: 2:48 PM.
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace NilPortugues\Serializer\Transformer;
13 |
14 | use NilPortugues\Serializer\Serializer;
15 |
16 | class ArrayTransformer extends AbstractTransformer
17 | {
18 | public function __construct()
19 | {
20 | //overwriting default constructor.
21 | }
22 |
23 | /**
24 | * @param mixed $value
25 | *
26 | * @return string
27 | */
28 | public function serialize($value)
29 | {
30 | $this->recursiveSetValues($value);
31 | $this->recursiveUnset($value, [Serializer::CLASS_IDENTIFIER_KEY]);
32 | $this->recursiveFlattenOneElementObjectsToScalarType($value);
33 |
34 | return $value;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/Transformer/FlatArrayTransformer.php:
--------------------------------------------------------------------------------
1 |
5 | * Date: 8/29/15
6 | * Time: 2:48 PM.
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace NilPortugues\Serializer\Transformer;
13 |
14 | class FlatArrayTransformer extends ArrayTransformer
15 | {
16 | /**
17 | * @param mixed $value
18 | *
19 | * @return string
20 | */
21 | public function serialize($value)
22 | {
23 | return $this->flatten(parent::serialize($value));
24 | }
25 |
26 | /**
27 | * @param array $array
28 | * @param string $prefix
29 | *
30 | * @return array
31 | */
32 | private function flatten(array $array, $prefix = '')
33 | {
34 | $result = [];
35 | foreach ($array as $key => $value) {
36 | if (\is_array($value)) {
37 | $result = $result + $this->flatten($value, $prefix.$key.'.');
38 | } else {
39 | $result[$prefix.$key] = $value;
40 | }
41 | }
42 |
43 | return $result;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/Transformer/JsonTransformer.php:
--------------------------------------------------------------------------------
1 |
5 | * Date: 8/31/15
6 | * Time: 9:33 PM.
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace NilPortugues\Serializer\Transformer;
13 |
14 | use DOMDocument;
15 | use SimpleXMLElement;
16 |
17 | /**
18 | * Class XmlTransformer.
19 | */
20 | class XmlTransformer extends ArrayTransformer
21 | {
22 | /**
23 | * @param mixed $value
24 | *
25 | * @return string
26 | */
27 | public function serialize($value)
28 | {
29 | $array = parent::serialize($value);
30 |
31 | $xmlData = new SimpleXMLElement('');
32 | $this->arrayToXml($array, $xmlData);
33 | $xml = $xmlData->asXML();
34 |
35 | $xmlDoc = new DOMDocument();
36 | $xmlDoc->loadXML($xml);
37 | $xmlDoc->preserveWhiteSpace = false;
38 | $xmlDoc->formatOutput = true;
39 |
40 | return $xmlDoc->saveXML();
41 | }
42 |
43 | /**
44 | * Converts an array to XML using SimpleXMLElement.
45 | *
46 | * @param array $data
47 | * @param SimpleXMLElement $xmlData
48 | */
49 | private function arrayToXml(array &$data, SimpleXMLElement $xmlData)
50 | {
51 | foreach ($data as $key => $value) {
52 | if (\is_array($value)) {
53 | if (\is_numeric($key)) {
54 | $key = 'sequential-item';
55 | }
56 | $subnode = $xmlData->addChild($key);
57 |
58 | $this->arrayToXml($value, $subnode);
59 | } else {
60 | $subnode = $xmlData->addChild("$key", "$value");
61 |
62 | $type = \gettype($value);
63 | if ('array' !== $type) {
64 | $subnode->addAttribute('type', $type);
65 | }
66 | }
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/Transformer/YamlTransformer.php:
--------------------------------------------------------------------------------
1 |
5 | * Date: 8/31/15
6 | * Time: 9:11 PM.
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace NilPortugues\Serializer\Transformer;
13 |
14 | use Symfony\Component\Yaml\Yaml;
15 |
16 | class YamlTransformer extends ArrayTransformer
17 | {
18 | /**
19 | * @param mixed $value
20 | *
21 | * @return string
22 | */
23 | public function serialize($value)
24 | {
25 | return Yaml::dump(parent::serialize($value));
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/XmlSerializer.php:
--------------------------------------------------------------------------------
1 |
5 | * Date: 8/29/15
6 | * Time: 12:47 PM.
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace NilPortugues\Serializer;
13 |
14 | use NilPortugues\Serializer\Strategy\XmlStrategy;
15 |
16 | class XmlSerializer extends Serializer
17 | {
18 | /**
19 | *
20 | */
21 | public function __construct()
22 | {
23 | parent::__construct(new XmlStrategy());
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/YamlSerializer.php:
--------------------------------------------------------------------------------
1 |
5 | * Date: 8/29/15
6 | * Time: 12:41 PM.
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace NilPortugues\Serializer;
13 |
14 | use NilPortugues\Serializer\Strategy\YamlStrategy;
15 |
16 | class YamlSerializer extends Serializer
17 | {
18 | /**
19 | *
20 | */
21 | public function __construct()
22 | {
23 | parent::__construct(new YamlStrategy());
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/tests/DeepCopySerializerTest.php:
--------------------------------------------------------------------------------
1 |
5 | * Date: 8/30/15
6 | * Time: 12:33 PM.
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace NilPortugues\Test\Serializer;
13 |
14 | use DateTime;
15 | use NilPortugues\Serializer\DeepCopySerializer;
16 | use NilPortugues\Serializer\Strategy\NullStrategy;
17 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\Comment;
18 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\Post;
19 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\User;
20 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\ValueObject\CommentId;
21 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\ValueObject\PostId;
22 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\ValueObject\UserId;
23 | use NilPortugues\Test\Serializer\SupportClasses\ChildOfSplFixedArray;
24 | use SplFixedArray;
25 |
26 | class DeepCopySerializerTest extends \PHPUnit_Framework_TestCase
27 | {
28 | public function testSerialization()
29 | {
30 | $object = $this->getObject();
31 | $serializer = new DeepCopySerializer(new NullStrategy());
32 | $serializedObject = $serializer->serialize($object);
33 |
34 | $this->assertEquals($object, $serializer->unserialize($serializedObject));
35 | }
36 |
37 | private function getObject()
38 | {
39 | return new Post(
40 | new PostId(9),
41 | 'Hello World',
42 | 'Your first post',
43 | new User(
44 | new UserId(1),
45 | 'Post Author'
46 | ),
47 | [
48 | new Comment(
49 | new CommentId(1000),
50 | 'Have no fear, sers, your king is safe.',
51 | new User(new UserId(2), 'Barristan Selmy'),
52 | [
53 | 'created_at' => (new DateTime('2015/07/18 12:13:00'))->format('c'),
54 | 'accepted_at' => (new DateTime('2015/07/19 00:00:00'))->format('c'),
55 | ]
56 | ),
57 | ]
58 | );
59 | }
60 |
61 | public function testArraySerialization()
62 | {
63 | $arrayOfObjects = [$this->getObject(), $this->getObject()];
64 | $serializer = new DeepCopySerializer(new NullStrategy());
65 | $serializedObject = $serializer->serialize($arrayOfObjects);
66 |
67 | $this->assertEquals($arrayOfObjects, $serializer->unserialize($serializedObject));
68 | }
69 |
70 | public function testObjectStorageCopyDuringSerialization()
71 | {
72 | $post = $this->getObject();
73 |
74 | $stdClass = new \stdClass();
75 | $stdClass->first = $post;
76 | $stdClass->second = $post;
77 |
78 | $serializer = new DeepCopySerializer(new NullStrategy());
79 | $serializedObject = $serializer->serialize($stdClass);
80 |
81 | $this->assertEquals($stdClass, $serializer->unserialize($serializedObject));
82 | }
83 |
84 | public function testSplFixedArraySerialization()
85 | {
86 | $splFixedArray = new SplFixedArray(3);
87 | $splFixedArray[0] = 1;
88 | $splFixedArray[1] = 2;
89 | $splFixedArray[2] = 3;
90 |
91 | $serializer = new DeepCopySerializer(new NullStrategy());
92 | $serializedObject = $serializer->serialize($splFixedArray);
93 |
94 | $this->assertEquals($splFixedArray, $serializer->unserialize($serializedObject));
95 | }
96 |
97 | public function testSplFixedArrayChildSerialization()
98 | {
99 | $splFixedArray = new ChildOfSplFixedArray(3);
100 | $splFixedArray[0] = 1;
101 | $splFixedArray[1] = 2;
102 | $splFixedArray[2] = 3;
103 |
104 | $serializer = new DeepCopySerializer(new NullStrategy());
105 | $serializedObject = $serializer->serialize($splFixedArray);
106 |
107 | $this->assertEquals($splFixedArray, $serializer->unserialize($serializedObject));
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/tests/Dummy/ComplexObject/Comment.php:
--------------------------------------------------------------------------------
1 |
5 | * Date: 7/18/15
6 | * Time: 10:42 AM.
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace NilPortugues\Test\Serializer\Dummy\ComplexObject;
13 |
14 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\ValueObject\CommentId;
15 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\ValueObject\UserId;
16 |
17 | class Comment
18 | {
19 | /**
20 | * @var
21 | */
22 | private $commentId;
23 | /**
24 | * @var array
25 | */
26 | private $dates;
27 | /**
28 | * @var string
29 | */
30 | private $comment;
31 |
32 | /**
33 | * @param CommentId $id
34 | * @param $comment
35 | * @param User $user
36 | * @param array $dates
37 | */
38 | public function __construct(CommentId $id, $comment, User $user, array $dates)
39 | {
40 | $this->commentId = $id;
41 | $this->comment = $comment;
42 | $this->user = $user;
43 | $this->dates = $dates;
44 | }
45 |
46 | /**
47 | * @return mixed
48 | */
49 | public function getCommentId()
50 | {
51 | return $this->commentId;
52 | }
53 |
54 | /**
55 | * @return mixed
56 | */
57 | public function getComment()
58 | {
59 | return $this->comment;
60 | }
61 |
62 | /**
63 | * @return UserId
64 | */
65 | public function getUser()
66 | {
67 | return $this->user;
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/tests/Dummy/ComplexObject/Post.php:
--------------------------------------------------------------------------------
1 |
5 | * Date: 7/18/15
6 | * Time: 10:42 AM.
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace NilPortugues\Test\Serializer\Dummy\ComplexObject;
13 |
14 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\ValueObject\PostId;
15 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\ValueObject\UserId;
16 |
17 | class Post
18 | {
19 | /**
20 | * @param PostId $id
21 | * @param $title
22 | * @param $content
23 | * @param User $user
24 | * @param array $comments
25 | */
26 | public function __construct(PostId $id, $title, $content, User $user, array $comments)
27 | {
28 | $this->postId = $id;
29 | $this->title = $title;
30 | $this->content = $content;
31 | $this->author = $user;
32 | $this->comments = $comments;
33 | }
34 |
35 | /**
36 | * @return array
37 | */
38 | public function getComments()
39 | {
40 | return $this->comments;
41 | }
42 |
43 | /**
44 | * @return mixed
45 | */
46 | public function getContent()
47 | {
48 | return $this->content;
49 | }
50 |
51 | /**
52 | * @return PostId
53 | */
54 | public function getPostId()
55 | {
56 | return $this->postId;
57 | }
58 |
59 | /**
60 | * @return mixed
61 | */
62 | public function getTitle()
63 | {
64 | return $this->title;
65 | }
66 |
67 | /**
68 | * @return UserId
69 | */
70 | public function getUserId()
71 | {
72 | return $this->author;
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/tests/Dummy/ComplexObject/User.php:
--------------------------------------------------------------------------------
1 |
5 | * Date: 7/18/15
6 | * Time: 10:41 AM.
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace NilPortugues\Test\Serializer\Dummy\ComplexObject;
13 |
14 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\ValueObject\UserId;
15 |
16 | class User
17 | {
18 | /**
19 | * @var UserId
20 | */
21 | private $userId;
22 | /**
23 | * @var
24 | */
25 | private $name;
26 |
27 | /**
28 | * @param UserId $id
29 | * @param $name
30 | */
31 | public function __construct(UserId $id, $name)
32 | {
33 | $this->userId = $id;
34 | $this->name = $name;
35 | }
36 |
37 | /**
38 | * @return mixed
39 | */
40 | public function getUserId()
41 | {
42 | return $this->userId;
43 | }
44 |
45 | /**
46 | * @return mixed
47 | */
48 | public function getName()
49 | {
50 | return $this->name;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/tests/Dummy/ComplexObject/ValueObject/CommentId.php:
--------------------------------------------------------------------------------
1 |
5 | * Date: 7/18/15
6 | * Time: 10:42 AM.
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace NilPortugues\Test\Serializer\Dummy\ComplexObject\ValueObject;
13 |
14 | class CommentId
15 | {
16 | /**
17 | * @param $id
18 | */
19 | public function __construct($id)
20 | {
21 | $this->commentId = $id;
22 | }
23 |
24 | /**
25 | * @return mixed
26 | */
27 | public function getCommentId()
28 | {
29 | return $this->commentId;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/tests/Dummy/ComplexObject/ValueObject/PostId.php:
--------------------------------------------------------------------------------
1 |
5 | * Date: 7/18/15
6 | * Time: 10:42 AM.
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace NilPortugues\Test\Serializer\Dummy\ComplexObject\ValueObject;
13 |
14 | class PostId
15 | {
16 | /**
17 | * @param $id
18 | */
19 | public function __construct($id)
20 | {
21 | $this->postId = $id;
22 | }
23 |
24 | /**
25 | * @return mixed
26 | */
27 | public function getPostId()
28 | {
29 | return $this->postId;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/tests/Dummy/ComplexObject/ValueObject/UserId.php:
--------------------------------------------------------------------------------
1 |
5 | * Date: 7/18/15
6 | * Time: 10:41 AM.
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace NilPortugues\Test\Serializer\Dummy\ComplexObject\ValueObject;
13 |
14 | class UserId
15 | {
16 | /**
17 | * @param $id
18 | */
19 | public function __construct($id)
20 | {
21 | $this->userId = $id;
22 | }
23 |
24 | /**
25 | * @return mixed
26 | */
27 | public function getUserId()
28 | {
29 | return $this->userId;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/tests/Dummy/SimpleObject/Post.php:
--------------------------------------------------------------------------------
1 |
5 | * Date: 7/18/15
6 | * Time: 11:21 AM.
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace NilPortugues\Test\Serializer\Dummy\SimpleObject;
13 |
14 | class Post
15 | {
16 | /**
17 | * @var
18 | */
19 | private $postId;
20 | /**
21 | * @var
22 | */
23 | private $title;
24 | /**
25 | * @var
26 | */
27 | private $body;
28 | /**
29 | * @var
30 | */
31 | private $authorId;
32 | /**
33 | * @var array
34 | */
35 | private $comments = [];
36 |
37 | /**
38 | * @param $postId
39 | * @param $title
40 | * @param $body
41 | * @param $authorId
42 | */
43 | public function __construct($postId, $title, $body, $authorId)
44 | {
45 | $this->postId = $postId;
46 | $this->title = $title;
47 | $this->body = $body;
48 | $this->authorId = $authorId;
49 | }
50 |
51 | /**
52 | * @param $commentId
53 | * @param $user
54 | * @param $comment
55 | * @param $created_at
56 | */
57 | public function addComment($commentId, $user, $comment, $created_at)
58 | {
59 | $this->comments[] = [
60 | 'comment_id' => $commentId,
61 | 'comment' => $comment,
62 | 'user_id' => $user,
63 | 'created_at' => $created_at,
64 | ];
65 | }
66 |
67 | /**
68 | * @param mixed $authorId
69 | *
70 | * @return $this
71 | */
72 | public function setAuthorId($authorId)
73 | {
74 | $this->authorId = $authorId;
75 |
76 | return $this;
77 | }
78 |
79 | /**
80 | * @return mixed
81 | */
82 | public function getAuthorId()
83 | {
84 | return $this->authorId;
85 | }
86 |
87 | /**
88 | * @param mixed $body
89 | *
90 | * @return $this
91 | */
92 | public function setBody($body)
93 | {
94 | $this->body = $body;
95 |
96 | return $this;
97 | }
98 |
99 | /**
100 | * @return mixed
101 | */
102 | public function getBody()
103 | {
104 | return $this->body;
105 | }
106 |
107 | /**
108 | * @param mixed $commentId
109 | *
110 | * @return $this
111 | */
112 | public function setPostId($commentId)
113 | {
114 | $this->postId = $commentId;
115 |
116 | return $this;
117 | }
118 |
119 | /**
120 | * @return mixed
121 | */
122 | public function getPostId()
123 | {
124 | return $this->postId;
125 | }
126 |
127 | /**
128 | * @param mixed $title
129 | *
130 | * @return $this
131 | */
132 | public function setTitle($title)
133 | {
134 | $this->title = $title;
135 |
136 | return $this;
137 | }
138 |
139 | /**
140 | * @return mixed
141 | */
142 | public function getTitle()
143 | {
144 | return $this->title;
145 | }
146 | }
147 |
--------------------------------------------------------------------------------
/tests/JsonSerializerTest.php:
--------------------------------------------------------------------------------
1 |
5 | * Date: 8/30/15
6 | * Time: 12:33 PM.
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace NilPortugues\Test\Serializer;
13 |
14 | use DateTime;
15 | use NilPortugues\Serializer\JsonSerializer;
16 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\Comment;
17 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\Post;
18 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\User;
19 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\ValueObject\CommentId;
20 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\ValueObject\PostId;
21 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\ValueObject\UserId;
22 |
23 | class JsonSerializerTest extends \PHPUnit_Framework_TestCase
24 | {
25 | public function testSerialization()
26 | {
27 | $object = $this->getObject();
28 | $serializer = new JsonSerializer();
29 | $serializedObject = $serializer->serialize($object);
30 |
31 | $this->assertEquals($object, $serializer->unserialize($serializedObject));
32 | }
33 |
34 | private function getObject()
35 | {
36 | return new Post(
37 | new PostId(9),
38 | 'Hello World',
39 | 'Your first post',
40 | new User(
41 | new UserId(1),
42 | 'Post Author'
43 | ),
44 | [
45 | new Comment(
46 | new CommentId(1000),
47 | 'Have no fear, sers, your king is safe.',
48 | new User(new UserId(2), 'Barristan Selmy'),
49 | [
50 | 'created_at' => (new DateTime('2015/07/18 12:13:00'))->format('c'),
51 | 'accepted_at' => (new DateTime('2015/07/19 00:00:00'))->format('c'),
52 | ]
53 | ),
54 | ]
55 | );
56 | }
57 |
58 | public function testArraySerialization()
59 | {
60 | $arrayOfObjects = [$this->getObject(), $this->getObject()];
61 | $serializer = new JsonSerializer();
62 | $serializedObject = $serializer->serialize($arrayOfObjects);
63 |
64 | $this->assertEquals($arrayOfObjects, $serializer->unserialize($serializedObject));
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/tests/SerializerTest.php:
--------------------------------------------------------------------------------
1 | serializer = new Serializer(new JsonStrategy());
29 | }
30 |
31 | /**
32 | * Test serialization of DateTime classes.
33 | *
34 | * Some interal classes, such as DateTime, cannot be initialized with
35 | * ReflectionClass::newInstanceWithoutConstructor()
36 | */
37 | public function testSerializationOfDateTime()
38 | {
39 | $date = new \DateTime('2014-06-15 12:00:00', new \DateTimeZone('UTC'));
40 |
41 | $obj = $this->serializer->unserialize($this->serializer->serialize($date));
42 | $this->assertSame($date->getTimestamp(), $obj->getTimestamp());
43 | $this->assertEquals($date, $obj);
44 | }
45 |
46 | /**
47 | * Test serialization of scalar values.
48 | *
49 | * @dataProvider scalarDataToJson
50 | *
51 | * @param mixed $scalar
52 | * @param string $jsoned
53 | */
54 | public function testSerializeScalar($scalar, $jsoned)
55 | {
56 | $this->assertSame($jsoned, $this->serializer->serialize($scalar));
57 | }
58 |
59 | /**
60 | * Test unserialization of scalar values.
61 | *
62 | * @dataProvider scalarDataToJson
63 | *
64 | * @param mixed $scalar
65 | * @param string $jsoned
66 | */
67 | public function testUnserializeScalar($scalar, $jsoned)
68 | {
69 | $this->assertSame($scalar, $this->serializer->unserialize($jsoned));
70 | }
71 |
72 | /**
73 | * List of scalar data.
74 | *
75 | * @return array
76 | */
77 | public function scalarDataToJson()
78 | {
79 | return [
80 | ['testing', '{"@scalar":"string","@value":"testing"}'],
81 | [123, '{"@scalar":"integer","@value":123}'],
82 | [0, '{"@scalar":"integer","@value":0}'],
83 | [0.0, '{"@scalar":"float","@value":0}'],
84 | [17.0, '{"@scalar":"float","@value":17}'],
85 | [17e1, '{"@scalar":"float","@value":170}'],
86 | [17.2, '{"@scalar":"float","@value":17.2}'],
87 | [true, '{"@scalar":"boolean","@value":true}'],
88 | [false, '{"@scalar":"boolean","@value":false}'],
89 | [null, '{"@scalar":"NULL","@value":null}'],
90 | // Non UTF8
91 | ['ßåö', '{"@scalar":"string","@value":"ßåö"}'],
92 | ];
93 | }
94 |
95 | /**
96 | * Test the serialization of resources.
97 | */
98 | public function testSerializeResource()
99 | {
100 | $this->setExpectedException(SerializerException::class);
101 | $this->serializer->serialize(\fopen(__FILE__, 'r'));
102 | }
103 |
104 | /**
105 | * Test the serialization of closures.
106 | */
107 | public function testSerializeClosure()
108 | {
109 | $this->setExpectedException(SerializerException::class);
110 | $this->serializer->serialize(['func' => function () {
111 | echo 'whoops';
112 | }]);
113 | }
114 |
115 | /**
116 | * Test serialization of array without objects.
117 | *
118 | * @dataProvider arrayNoObjectData
119 | *
120 | * @param array $array
121 | * @param string $jsoned
122 | */
123 | public function testSerializeArrayNoObject($array, $jsoned)
124 | {
125 | $this->assertSame($jsoned, $this->serializer->serialize($array));
126 | }
127 |
128 | /**
129 | * Test unserialization of array without objects.
130 | *
131 | * @dataProvider arrayNoObjectData
132 | *
133 | * @param array $array
134 | * @param string $jsoned
135 | */
136 | public function testUnserializeArrayNoObject($array, $jsoned)
137 | {
138 | $this->assertSame($array, $this->serializer->unserialize($jsoned));
139 | }
140 |
141 | /**
142 | * List of array data.
143 | *
144 | * @return array
145 | */
146 | public function arrayNoObjectData()
147 | {
148 | return [
149 | [[1, 2, 3], '{"@map":"array","@value":[{"@scalar":"integer","@value":1},{"@scalar":"integer","@value":2},{"@scalar":"integer","@value":3}]}'],
150 | [[1, 'abc', false], '{"@map":"array","@value":[{"@scalar":"integer","@value":1},{"@scalar":"string","@value":"abc"},{"@scalar":"boolean","@value":false}]}'],
151 | [['a' => 1, 'b' => 2, 'c' => 3], '{"@map":"array","@value":{"a":{"@scalar":"integer","@value":1},"b":{"@scalar":"integer","@value":2},"c":{"@scalar":"integer","@value":3}}}'],
152 | [['integer' => 1, 'string' => 'abc', 'bool' => false], '{"@map":"array","@value":{"integer":{"@scalar":"integer","@value":1},"string":{"@scalar":"string","@value":"abc"},"bool":{"@scalar":"boolean","@value":false}}}'],
153 | [[1, ['nested']], '{"@map":"array","@value":[{"@scalar":"integer","@value":1},{"@map":"array","@value":[{"@scalar":"string","@value":"nested"}]}]}'],
154 | [['integer' => 1, 'array' => ['nested']], '{"@map":"array","@value":{"integer":{"@scalar":"integer","@value":1},"array":{"@map":"array","@value":[{"@scalar":"string","@value":"nested"}]}}}'],
155 | [['integer' => 1, 'array' => ['nested' => 'object']], '{"@map":"array","@value":{"integer":{"@scalar":"integer","@value":1},"array":{"@map":"array","@value":{"nested":{"@scalar":"string","@value":"object"}}}}}'],
156 | [[1.0, 2, 3e1], '{"@map":"array","@value":[{"@scalar":"float","@value":1},{"@scalar":"integer","@value":2},{"@scalar":"float","@value":30}]}'],
157 | ];
158 | }
159 |
160 | /**
161 | * Test serialization of objects.
162 | */
163 | public function testSerializeObject()
164 | {
165 | $obj = new stdClass();
166 | $this->assertSame('{"@type":"stdClass"}', $this->serializer->serialize($obj));
167 |
168 | $obj = $empty = new SupportClasses\EmptyClass();
169 | $this->assertSame('{"@type":"NilPortugues\\\\Test\\\\Serializer\\\\SupportClasses\\\\EmptyClass"}', $this->serializer->serialize($obj));
170 |
171 | $obj = new SupportClasses\AllVisibilities();
172 | $expected = '{"@type":"NilPortugues\\\\Test\\\\Serializer\\\\SupportClasses\\\\AllVisibilities","pub":{"@scalar":"string","@value":"this is public"},"prot":{"@scalar":"string","@value":"protected"},"priv":{"@scalar":"string","@value":"dont tell anyone"}}';
173 | $this->assertSame($expected, $this->serializer->serialize($obj));
174 |
175 | $obj->pub = 'new value';
176 | $expected = '{"@type":"NilPortugues\\\\Test\\\\Serializer\\\\SupportClasses\\\\AllVisibilities","pub":{"@scalar":"string","@value":"new value"},"prot":{"@scalar":"string","@value":"protected"},"priv":{"@scalar":"string","@value":"dont tell anyone"}}';
177 | $this->assertSame($expected, $this->serializer->serialize($obj));
178 |
179 | $obj->pub = $empty;
180 | $expected = '{"@type":"NilPortugues\\\\Test\\\\Serializer\\\\SupportClasses\\\\AllVisibilities","pub":{"@type":"NilPortugues\\\\Test\\\\Serializer\\\\SupportClasses\\\\EmptyClass"},"prot":{"@scalar":"string","@value":"protected"},"priv":{"@scalar":"string","@value":"dont tell anyone"}}';
181 | $this->assertSame($expected, $this->serializer->serialize($obj));
182 |
183 | $array = ['instance' => $empty];
184 | $expected = '{"@map":"array","@value":{"instance":{"@type":"NilPortugues\\\\Test\\\\Serializer\\\\SupportClasses\\\\EmptyClass"}}}';
185 | $this->assertSame($expected, $this->serializer->serialize($array));
186 |
187 | $obj = new stdClass();
188 | $obj->total = 10.0;
189 | $obj->discount = 0.0;
190 | $expected = '{"@type":"stdClass","total":{"@scalar":"float","@value":10},"discount":{"@scalar":"float","@value":0}}';
191 | $this->assertSame($expected, $this->serializer->serialize($obj));
192 | }
193 |
194 | /**
195 | * Test unserialization of objects.
196 | */
197 | public function testUnserializeObjects()
198 | {
199 | $serialized = '{"@type":"stdClass"}';
200 | $obj = $this->serializer->unserialize($serialized);
201 | $this->assertInstanceOf('stdClass', $obj);
202 |
203 | $serialized = '{"@type":"NilPortugues\\\\Test\\\\Serializer\\\\SupportClasses\\\\EmptyClass"}';
204 | $obj = $this->serializer->unserialize($serialized);
205 | $this->assertInstanceOf(EmptyClass::class, $obj);
206 |
207 | $serialized = '{"@type":"NilPortugues\\\\Test\\\\Serializer\\\\SupportClasses\\\\AllVisibilities","pub":{"@type":"NilPortugues\\\\Test\\\\Serializer\\\\SupportClasses\\\\EmptyClass"},"prot":"protected","priv":"dont tell anyone"}';
208 | $obj = $this->serializer->unserialize($serialized);
209 | $this->assertInstanceOf(AllVisibilities::class, $obj);
210 | $this->assertInstanceOf(EmptyClass::class, $obj->pub);
211 | $this->assertAttributeSame('protected', 'prot', $obj);
212 | $this->assertAttributeSame('dont tell anyone', 'priv', $obj);
213 |
214 | $serialized = '{"instance":{"@type":"NilPortugues\\\\Test\\\\Serializer\\\\SupportClasses\\\\EmptyClass"}}';
215 | $array = $this->serializer->unserialize($serialized);
216 | $this->assertTrue(\is_array($array));
217 | $this->assertInstanceOf(EmptyClass::class, $array['instance']);
218 | }
219 |
220 | /**
221 | * Test magic serialization methods.
222 | */
223 | public function testSerializationMagicMethods()
224 | {
225 | $obj = new SupportClasses\MagicClass();
226 | $serialized = '{"@type":"NilPortugues\\\\Test\\\\Serializer\\\\SupportClasses\\\\MagicClass","show":{"@scalar":"boolean","@value":true},"hide":{"@scalar":"boolean","@value":true},"woke":{"@scalar":"boolean","@value":false}}';
227 | $this->assertSame($serialized, $this->serializer->serialize($obj));
228 | $this->assertFalse($obj->woke);
229 |
230 | $obj = $this->serializer->unserialize($serialized);
231 | $this->assertTrue($obj->woke);
232 | }
233 |
234 | /**
235 | * TraversableSerializer serialization.
236 |
237 | public function testSerializationOfTraversableClasses()
238 | {
239 | $traversable = new TraversableClass();
240 | $traversable->next();
241 |
242 | $serialized = $this->serializer->serialize($traversable);
243 | $unserializedCollection = $this->serializer->unserialize($serialized);
244 |
245 |
246 | $this->assertEquals($traversable, $unserializedCollection);
247 | }
248 |
249 | /**
250 | * TraversableSerializer serialization.
251 | } */
252 |
253 | /**
254 | * ArrayAccess serialization.
255 | */
256 | public function testSerializationOfArrayAccessClasses()
257 | {
258 | $arrayAccess = new ArrayAccessClass();
259 | $arrayAccess[] = 'Append 1';
260 | $arrayAccess[] = 'Append 2';
261 | $arrayAccess[] = 'Append 3';
262 |
263 | $unserializedCollection = $this->serializer->unserialize($this->serializer->serialize($arrayAccess));
264 |
265 | $this->assertEquals($arrayAccess, $unserializedCollection);
266 | }
267 |
268 | /**
269 | * Test serialization of DateTimeImmutable classes.
270 | *
271 | * Some interal classes, such as DateTimeImmutable, cannot be initialized with
272 | * ReflectionClass::newInstanceWithoutConstructor()
273 | */
274 | public function testSerializationOfDateTimeImmutable()
275 | {
276 | if (\version_compare(PHP_VERSION, '5.5.0', '<')) {
277 | $this->markTestSkipped('Supported for PHP 5.5.0 and above');
278 | }
279 |
280 | $date = new \DateTimeImmutable('2014-06-15 12:00:00', new \DateTimeZone('UTC'));
281 | $obj = $this->serializer->unserialize($this->serializer->serialize($date));
282 |
283 | $this->assertSame($date->getTimestamp(), $obj->getTimestamp());
284 | $this->assertEquals($date, $obj);
285 | }
286 |
287 | /**
288 | * Test serialization of DateTimeZone classes.
289 | *
290 | * Some interal classes, such as DateTimeZone, cannot be initialized with
291 | * ReflectionClass::newInstanceWithoutConstructor()
292 | */
293 | public function testSerializationOfDateTimeZone()
294 | {
295 | $date = new \DateTimeZone('UTC');
296 |
297 | $obj = $this->serializer->unserialize($this->serializer->serialize($date));
298 | $this->assertEquals($date, $obj);
299 | }
300 |
301 | /**
302 | * Test serialization of DateInterval classes.
303 | *
304 | * Some interal classes, such as DateInterval, cannot be initialized with
305 | * ReflectionClass::newInstanceWithoutConstructor()
306 | */
307 | public function testSerializationOfDateInterval()
308 | {
309 | $date = new \DateInterval('P2Y4DT6H8M');
310 | $obj = $this->serializer->unserialize($this->serializer->serialize($date));
311 | $this->assertEquals($date, $obj);
312 | $this->assertSame($date->d, $obj->d);
313 | }
314 |
315 | /**
316 | * Test serialization of DatePeriod classes.
317 | *
318 | * Some interal classes, such as DatePeriod, cannot be initialized with
319 | * ReflectionClass::newInstanceWithoutConstructor()
320 | */
321 | public function testSerializationOfDatePeriodException()
322 | {
323 | $this->setExpectedException(
324 | SerializerException::class,
325 | 'DatePeriod is not supported in Serializer. Loop through it and serialize the output.'
326 | );
327 |
328 | $period = new \DatePeriod(new \DateTime('2012-07-01'), new \DateInterval('P7D'), 4);
329 | $this->serializer->serialize($period);
330 | }
331 |
332 | /**
333 | * Test serialization of DatePeriod output.
334 | */
335 | public function testSerializationOfDatePeriodOutputIsSerializable()
336 | {
337 | $period = new \DatePeriod(new \DateTime('2012-07-01'), new \DateInterval('P7D'), 4);
338 | $dates = [];
339 | foreach ($period as $p) {
340 | $dates[] = $p;
341 | }
342 |
343 | $serialized = $this->serializer->serialize($dates);
344 | $objs = $this->serializer->unserialize($serialized);
345 |
346 | foreach ($objs as $key => $obj) {
347 | $this->assertSame($dates[$key]->getTimestamp(), $obj->getTimestamp());
348 | $this->assertEquals($dates[$key], $obj);
349 | }
350 | }
351 |
352 | /**
353 | * Test unserialize of unknown class.
354 | */
355 | public function testUnserializeUnknownClass()
356 | {
357 | $this->setExpectedException(SerializerException::class);
358 | $serialized = '{"@type":"UnknownClass"}';
359 | $this->serializer->unserialize($serialized);
360 | }
361 |
362 | /**
363 | * Test serialization of undeclared properties.
364 | */
365 | public function testSerializationUndeclaredProperties()
366 | {
367 | $obj = new stdClass();
368 | $obj->param1 = true;
369 | $obj->param2 = 'store me, please';
370 | $serialized = '{"@type":"stdClass","param1":{"@scalar":"boolean","@value":true},"param2":{"@scalar":"string","@value":"store me, please"}}';
371 | $this->assertSame($serialized, $this->serializer->serialize($obj));
372 |
373 | $obj2 = $this->serializer->unserialize($serialized);
374 | $this->assertInstanceOf('stdClass', $obj2);
375 | $this->assertTrue($obj2->param1);
376 | $this->assertSame('store me, please', $obj2->param2);
377 |
378 | $serialized = '{"@type":"stdClass","sub":{"@type":"stdClass","key":"value"}}';
379 | $obj = $this->serializer->unserialize($serialized);
380 | $this->assertInstanceOf('stdClass', $obj->sub);
381 | $this->assertSame('value', $obj->sub->key);
382 | }
383 |
384 | /**
385 | * Test serialize with recursion.
386 | */
387 | public function testSerializeRecursion()
388 | {
389 | $c1 = new stdClass();
390 | $c1->c2 = new stdClass();
391 | $c1->c2->c3 = new stdClass();
392 | $c1->c2->c3->c1 = $c1;
393 | $c1->something = 'ok';
394 | $c1->c2->c3->ok = true;
395 |
396 | $expected = '{"@type":"stdClass","c2":{"@type":"stdClass","c3":{"@type":"stdClass","c1":{"@type":"@0"},"ok":{"@scalar":"boolean","@value":true}}},"something":{"@scalar":"string","@value":"ok"}}';
397 | $this->assertSame($expected, $this->serializer->serialize($c1));
398 |
399 | $c1 = new stdClass();
400 | $c1->mirror = $c1;
401 | $expected = '{"@type":"stdClass","mirror":{"@type":"@0"}}';
402 | $this->assertSame($expected, $this->serializer->serialize($c1));
403 | }
404 |
405 | /**
406 | * Test unserialize with recursion.
407 | */
408 | public function testUnserializeRecursion()
409 | {
410 | $serialized = '{"@type":"stdClass","c2":{"@type":"stdClass","c3":{"@type":"stdClass","c1":{"@type":"@0"},"ok":{"@scalar":"boolean","@value":true}}},"something":{"@scalar":"string","@value":"ok"}}';
411 | $obj = $this->serializer->unserialize($serialized);
412 | $this->assertTrue($obj->c2->c3->ok);
413 | $this->assertSame($obj, $obj->c2->c3->c1);
414 | $this->assertNotSame($obj, $obj->c2);
415 |
416 | $serialized = '{"@type":"stdClass","c2":{"@type":"stdClass","c3":{"@type":"stdClass","c1":{"@type":"@0"},"c2":{"@type":"@1"},"c3":{"@type":"@2"}},"c3_copy":{"@type":"@2"}}}';
417 | $obj = $this->serializer->unserialize($serialized);
418 | $this->assertSame($obj, $obj->c2->c3->c1);
419 | $this->assertSame($obj->c2, $obj->c2->c3->c2);
420 | $this->assertSame($obj->c2->c3, $obj->c2->c3->c3);
421 | $this->assertSame($obj->c2->c3_copy, $obj->c2->c3);
422 | }
423 |
424 | public function testItCanSerializeAndUnserializeTraversableClass()
425 | {
426 | $elements = [new \DateTime('now')];
427 | $collection = new \Doctrine\Common\Collections\ArrayCollection($elements);
428 | $serializer = new Serializer(new \NilPortugues\Serializer\Strategy\JsonStrategy());
429 | $serialized = $serializer->serialize($collection);
430 |
431 | $this->assertEquals($collection, $serializer->unserialize($serialized));
432 | }
433 |
434 | public function testItCanGetTransformer()
435 | {
436 | $strategy = new \NilPortugues\Serializer\Strategy\JsonStrategy();
437 | $serializer = new Serializer($strategy);
438 |
439 | $this->assertSame($strategy, $serializer->getTransformer());
440 | }
441 |
442 | public function testSerializationOfAnArrayOfScalars()
443 | {
444 | $scalar = 'a string';
445 |
446 | $serializer = new Serializer(new \NilPortugues\Serializer\Strategy\JsonStrategy());
447 | $serialized = $serializer->serialize($scalar);
448 |
449 | $this->assertEquals($scalar, $serializer->unserialize($serialized));
450 | }
451 | }
452 |
--------------------------------------------------------------------------------
/tests/SupportClasses/AllVisibilities.php:
--------------------------------------------------------------------------------
1 | container = ['one' => 1, 'two' => 2, 'three' => 3];
18 | }
19 |
20 | /**
21 | * @param mixed $offset
22 | * @param mixed $value
23 | */
24 | public function offsetSet($offset, $value)
25 | {
26 | if (\is_null($offset)) {
27 | $this->container[] = $value;
28 | } else {
29 | $this->container[$offset] = $value;
30 | }
31 | }
32 |
33 | /**
34 | * @param mixed $offset
35 | *
36 | * @return bool
37 | */
38 | public function offsetExists($offset)
39 | {
40 | return isset($this->container[$offset]);
41 | }
42 |
43 | /**
44 | * @param mixed $offset
45 | */
46 | public function offsetUnset($offset)
47 | {
48 | unset($this->container[$offset]);
49 | }
50 |
51 | /**
52 | * @param mixed $offset
53 | *
54 | * @return mixed|null
55 | */
56 | public function offsetGet($offset)
57 | {
58 | return isset($this->container[$offset]) ? $this->container[$offset] : null;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/tests/SupportClasses/ChildOfSplFixedArray.php:
--------------------------------------------------------------------------------
1 | woke = true;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/tests/SupportClasses/TraversableClass.php:
--------------------------------------------------------------------------------
1 | position = 0;
23 | }
24 |
25 | /**
26 | *
27 | */
28 | public function rewind()
29 | {
30 | $this->position = 0;
31 | }
32 |
33 | /**
34 | * @return mixed
35 | */
36 | public function current()
37 | {
38 | return $this->array[$this->position];
39 | }
40 |
41 | /**
42 | * @return int
43 | */
44 | public function key()
45 | {
46 | return $this->position;
47 | }
48 |
49 | /**
50 | *
51 | */
52 | public function next()
53 | {
54 | ++$this->position;
55 | }
56 |
57 | /**
58 | * @return bool
59 | */
60 | public function valid()
61 | {
62 | return isset($this->array[$this->position]);
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/tests/Transformer/ArrayTransformerTest.php:
--------------------------------------------------------------------------------
1 |
5 | * Date: 8/30/15
6 | * Time: 1:24 PM.
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace NilPortugues\Test\Serializer\Transformer;
13 |
14 | use DateTime;
15 | use NilPortugues\Serializer\DeepCopySerializer;
16 | use NilPortugues\Serializer\Transformer\ArrayTransformer;
17 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\Comment;
18 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\Post;
19 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\User;
20 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\ValueObject\CommentId;
21 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\ValueObject\PostId;
22 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\ValueObject\UserId;
23 |
24 | class ArrayTransformerTest extends \PHPUnit_Framework_TestCase
25 | {
26 | public function testSerialization()
27 | {
28 | $object = $this->getObject();
29 | $serializer = new DeepCopySerializer(new ArrayTransformer());
30 |
31 | $expected = array(
32 | 'postId' => 9,
33 | 'title' => 'Hello World',
34 | 'content' => 'Your first post',
35 | 'author' => array(
36 | 'userId' => 1,
37 | 'name' => 'Post Author',
38 | ),
39 | 'comments' => array(
40 | 0 => array(
41 | 'commentId' => 1000,
42 | 'dates' => array(
43 | 'created_at' => '2015-07-18T12:13:00+02:00',
44 | 'accepted_at' => '2015-07-19T00:00:00+02:00',
45 | ),
46 | 'comment' => 'Have no fear, sers, your king is safe.',
47 | 'user' => array(
48 | 'userId' => 2,
49 | 'name' => 'Barristan Selmy',
50 | ),
51 | ),
52 | ),
53 | );
54 |
55 | $this->assertEquals($expected, $serializer->serialize($object));
56 | }
57 |
58 | /**
59 | * @return Post
60 | */
61 | private function getObject()
62 | {
63 | return new Post(
64 | new PostId(9),
65 | 'Hello World',
66 | 'Your first post',
67 | new User(
68 | new UserId(1),
69 | 'Post Author'
70 | ),
71 | [
72 | new Comment(
73 | new CommentId(1000),
74 | 'Have no fear, sers, your king is safe.',
75 | new User(new UserId(2), 'Barristan Selmy'),
76 | [
77 | 'created_at' => (new DateTime('2015/07/18 12:13:00'))->format('c'),
78 | 'accepted_at' => (new DateTime('2015/07/19 00:00:00'))->format('c'),
79 | ]
80 | ),
81 | ]
82 | );
83 | }
84 |
85 | public function testArraySerialization()
86 | {
87 | $arrayOfObjects = [$this->getObject(), $this->getObject()];
88 | $serializer = new DeepCopySerializer(new ArrayTransformer());
89 |
90 | $expected = array(
91 | 0 => array(
92 | 'postId' => 9,
93 | 'title' => 'Hello World',
94 | 'content' => 'Your first post',
95 | 'author' => array(
96 | 'userId' => 1,
97 | 'name' => 'Post Author',
98 | ),
99 | 'comments' => array(
100 | 0 => array(
101 | 'commentId' => 1000,
102 | 'dates' => array(
103 | 'created_at' => '2015-07-18T12:13:00+02:00',
104 | 'accepted_at' => '2015-07-19T00:00:00+02:00',
105 | ),
106 | 'comment' => 'Have no fear, sers, your king is safe.',
107 | 'user' => array(
108 | 'userId' => 2,
109 | 'name' => 'Barristan Selmy',
110 | ),
111 | ),
112 | ),
113 | ),
114 | 1 => array(
115 | 'postId' => 9,
116 | 'title' => 'Hello World',
117 | 'content' => 'Your first post',
118 | 'author' => array(
119 | 'userId' => 1,
120 | 'name' => 'Post Author',
121 | ),
122 | 'comments' => array(
123 | 0 => array(
124 | 'commentId' => 1000,
125 | 'dates' => array(
126 | 'created_at' => '2015-07-18T12:13:00+02:00',
127 | 'accepted_at' => '2015-07-19T00:00:00+02:00',
128 | ),
129 | 'comment' => 'Have no fear, sers, your king is safe.',
130 | 'user' => array(
131 | 'userId' => 2,
132 | 'name' => 'Barristan Selmy',
133 | ),
134 | ),
135 | ),
136 | ),
137 | );
138 |
139 | $this->assertEquals($expected, $serializer->serialize($arrayOfObjects));
140 | }
141 |
142 | public function testUnserializeWillThrowException()
143 | {
144 | $serialize = new DeepCopySerializer(new ArrayTransformer());
145 |
146 | $this->setExpectedException(\InvalidArgumentException::class);
147 | $serialize->unserialize($serialize->serialize($this->getObject()));
148 | }
149 | }
150 |
--------------------------------------------------------------------------------
/tests/Transformer/FlatArrayTransformerTest.php:
--------------------------------------------------------------------------------
1 |
5 | * Date: 8/30/15
6 | * Time: 1:24 PM.
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace NilPortugues\Test\Serializer\Transformer;
13 |
14 | use DateTime;
15 | use NilPortugues\Serializer\DeepCopySerializer;
16 | use NilPortugues\Serializer\Transformer\FlatArrayTransformer;
17 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\Comment;
18 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\Post;
19 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\User;
20 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\ValueObject\CommentId;
21 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\ValueObject\PostId;
22 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\ValueObject\UserId;
23 |
24 | class FlatArrayTransformerTest extends \PHPUnit_Framework_TestCase
25 | {
26 | public function testSerialization()
27 | {
28 | $object = $this->getObject();
29 | $serializer = new DeepCopySerializer(new FlatArrayTransformer());
30 |
31 | $expected = [
32 | 'postId' => 9,
33 | 'title' => 'Hello World',
34 | 'content' => 'Your first post',
35 | 'author.userId' => 1,
36 | 'author.name' => 'Post Author',
37 | 'comments.0.commentId' => 1000,
38 | 'comments.0.dates.created_at' => '2015-07-18T12:13:00+02:00',
39 | 'comments.0.dates.accepted_at' => '2015-07-19T00:00:00+02:00',
40 | 'comments.0.comment' => 'Have no fear, sers, your king is safe.',
41 | 'comments.0.user.userId' => 2,
42 | 'comments.0.user.name' => 'Barristan Selmy',
43 |
44 | ];
45 |
46 | $this->assertEquals($expected, $serializer->serialize($object));
47 | }
48 |
49 | /**
50 | * @return Post
51 | */
52 | private function getObject()
53 | {
54 | return new Post(
55 | new PostId(9),
56 | 'Hello World',
57 | 'Your first post',
58 | new User(
59 | new UserId(1),
60 | 'Post Author'
61 | ),
62 | [
63 | new Comment(
64 | new CommentId(1000),
65 | 'Have no fear, sers, your king is safe.',
66 | new User(new UserId(2), 'Barristan Selmy'),
67 | [
68 | 'created_at' => (new DateTime('2015/07/18 12:13:00'))->format('c'),
69 | 'accepted_at' => (new DateTime('2015/07/19 00:00:00'))->format('c'),
70 | ]
71 | ),
72 | ]
73 | );
74 | }
75 |
76 | public function testArraySerialization()
77 | {
78 | $arrayOfObjects = [$this->getObject(), $this->getObject()];
79 | $serializer = new DeepCopySerializer(new FlatArrayTransformer());
80 |
81 | $expected = [
82 | '0.postId' => 9,
83 | '0.title' => 'Hello World',
84 | '0.content' => 'Your first post',
85 | '0.author.userId' => 1,
86 | '0.author.name' => 'Post Author',
87 | '0.comments.0.commentId' => 1000,
88 | '0.comments.0.dates.created_at' => '2015-07-18T12:13:00+02:00',
89 | '0.comments.0.dates.accepted_at' => '2015-07-19T00:00:00+02:00',
90 | '0.comments.0.comment' => 'Have no fear, sers, your king is safe.',
91 | '0.comments.0.user.userId' => 2,
92 | '0.comments.0.user.name' => 'Barristan Selmy',
93 | '1.postId' => 9,
94 | '1.title' => 'Hello World',
95 | '1.content' => 'Your first post',
96 | '1.author.userId' => 1,
97 | '1.author.name' => 'Post Author',
98 | '1.comments.0.commentId' => 1000,
99 | '1.comments.0.dates.created_at' => '2015-07-18T12:13:00+02:00',
100 | '1.comments.0.dates.accepted_at' => '2015-07-19T00:00:00+02:00',
101 | '1.comments.0.comment' => 'Have no fear, sers, your king is safe.',
102 | '1.comments.0.user.userId' => 2,
103 | '1.comments.0.user.name' => 'Barristan Selmy',
104 | ];
105 |
106 | $this->assertEquals($expected, $serializer->serialize($arrayOfObjects));
107 | }
108 |
109 | public function testUnserializeWillThrowException()
110 | {
111 | $serialize = new DeepCopySerializer(new FlatArrayTransformer());
112 |
113 | $this->setExpectedException(\InvalidArgumentException::class);
114 | $serialize->unserialize($serialize->serialize($this->getObject()));
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/tests/Transformer/JsonTransformerTest.php:
--------------------------------------------------------------------------------
1 |
5 | * Date: 8/30/15
6 | * Time: 1:03 PM.
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace NilPortugues\Test\Serializer\Transformer;
13 |
14 | use DateTime;
15 | use NilPortugues\Serializer\DeepCopySerializer;
16 | use NilPortugues\Serializer\Transformer\JsonTransformer;
17 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\Comment;
18 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\Post;
19 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\User;
20 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\ValueObject\CommentId;
21 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\ValueObject\PostId;
22 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\ValueObject\UserId;
23 |
24 | class JsonTransformerTest extends \PHPUnit_Framework_TestCase
25 | {
26 |
27 | public function testSerializationObjectWithArrayOfOneAttribute()
28 | {
29 | $object = new \stdClass();
30 | $object->payload = ['userId' => 1];
31 |
32 | $serializer = new DeepCopySerializer(new JsonTransformer());
33 |
34 | $expected = <<assertEquals($expected, $serializer->serialize($object));
43 | }
44 |
45 | public function testSerializationObjectWithObjectOfOneAttribute()
46 | {
47 | $internal = new \stdClass();
48 | $internal->userId = 1;
49 |
50 | $object = new \stdClass();
51 | $object->payload = $internal;
52 |
53 | $serializer = new DeepCopySerializer(new JsonTransformer());
54 |
55 | $expected = <<assertEquals($expected, $serializer->serialize($object));
64 | }
65 |
66 | public function testSerialization()
67 | {
68 | $object = $this->getObject();
69 | $serializer = new DeepCopySerializer(new JsonTransformer());
70 |
71 | $expected = <<assertEquals($expected, $serializer->serialize($object));
98 | }
99 |
100 | /**
101 | * @return Post
102 | */
103 | private function getObject()
104 | {
105 | return new Post(
106 | new PostId(9),
107 | 'Hello World',
108 | 'Your first post',
109 | new User(
110 | new UserId(1),
111 | 'Post Author'
112 | ),
113 | [
114 | new Comment(
115 | new CommentId(1000),
116 | 'Have no fear, sers, your king is safe.',
117 | new User(new UserId(2), 'Barristan Selmy'),
118 | [
119 | 'created_at' => (new DateTime('2015/07/18 12:13:00'))->format('c'),
120 | 'accepted_at' => (new DateTime('2015/07/19 00:00:00'))->format('c'),
121 | ]
122 | ),
123 | ]
124 | );
125 | }
126 |
127 | public function testArraySerialization()
128 | {
129 | $arrayOfObjects = [$this->getObject(), $this->getObject()];
130 | $serializer = new DeepCopySerializer(new JsonTransformer());
131 |
132 | $expected = <<assertEquals($expected, $serializer->serialize($arrayOfObjects));
184 | }
185 |
186 | public function testUnserializeWillThrowException()
187 | {
188 | $serialize = new DeepCopySerializer(new JsonTransformer());
189 |
190 | $this->setExpectedException(\InvalidArgumentException::class);
191 | $serialize->unserialize($serialize->serialize($this->getObject()));
192 | }
193 | }
194 |
--------------------------------------------------------------------------------
/tests/Transformer/XmlTransformerTest.php:
--------------------------------------------------------------------------------
1 |
5 | * Date: 8/30/15
6 | * Time: 1:03 PM.
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace NilPortugues\Test\Serializer\Transformer;
13 |
14 | use DateTime;
15 | use NilPortugues\Serializer\DeepCopySerializer;
16 | use NilPortugues\Serializer\Transformer\XmlTransformer;
17 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\Comment;
18 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\Post;
19 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\User;
20 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\ValueObject\CommentId;
21 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\ValueObject\PostId;
22 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\ValueObject\UserId;
23 |
24 | class XmlTransformerTest extends \PHPUnit_Framework_TestCase
25 | {
26 | public function testSerialization()
27 | {
28 | $object = $this->getObject();
29 | $serializer = new DeepCopySerializer(new XmlTransformer());
30 | $xml = $serializer->serialize($object);
31 |
32 | $expected = <<
34 |
35 | 9
36 | Hello World
37 | Your first post
38 |
39 | 1
40 | Post Author
41 |
42 |
43 |
44 | 1000
45 |
46 | 2015-07-18T12:13:00+02:00
47 | 2015-07-19T00:00:00+02:00
48 |
49 | Have no fear, sers, your king is safe.
50 |
51 | 2
52 | Barristan Selmy
53 |
54 |
55 |
56 |
57 |
58 | STRING;
59 |
60 | $this->assertEquals($expected, $xml);
61 | }
62 |
63 | /**
64 | * @return Post
65 | */
66 | private function getObject()
67 | {
68 | return new Post(
69 | new PostId(9),
70 | 'Hello World',
71 | 'Your first post',
72 | new User(
73 | new UserId(1),
74 | 'Post Author'
75 | ),
76 | [
77 | new Comment(
78 | new CommentId(1000),
79 | 'Have no fear, sers, your king is safe.',
80 | new User(new UserId(2), 'Barristan Selmy'),
81 | [
82 | 'created_at' => (new DateTime('2015/07/18 12:13:00'))->format('c'),
83 | 'accepted_at' => (new DateTime('2015/07/19 00:00:00'))->format('c'),
84 | ]
85 | ),
86 | ]
87 | );
88 | }
89 |
90 | public function testArraySerialization()
91 | {
92 | $arrayOfObjects = [$this->getObject(), $this->getObject()];
93 | $serializer = new DeepCopySerializer(new XmlTransformer());
94 |
95 | $expected = <<
97 |
98 |
99 | 9
100 | Hello World
101 | Your first post
102 |
103 | 1
104 | Post Author
105 |
106 |
107 |
108 | 1000
109 |
110 | 2015-07-18T12:13:00+02:00
111 | 2015-07-19T00:00:00+02:00
112 |
113 | Have no fear, sers, your king is safe.
114 |
115 | 2
116 | Barristan Selmy
117 |
118 |
119 |
120 |
121 |
122 | 9
123 | Hello World
124 | Your first post
125 |
126 | 1
127 | Post Author
128 |
129 |
130 |
131 | 1000
132 |
133 | 2015-07-18T12:13:00+02:00
134 | 2015-07-19T00:00:00+02:00
135 |
136 | Have no fear, sers, your king is safe.
137 |
138 | 2
139 | Barristan Selmy
140 |
141 |
142 |
143 |
144 |
145 |
146 | STRING;
147 |
148 | $this->assertEquals($expected, $serializer->serialize($arrayOfObjects));
149 | }
150 |
151 | public function testUnserializeWillThrowException()
152 | {
153 | $serialize = new DeepCopySerializer(new XmlTransformer());
154 |
155 | $this->setExpectedException(\InvalidArgumentException::class);
156 | $serialize->unserialize($serialize->serialize($this->getObject()));
157 | }
158 | }
159 |
--------------------------------------------------------------------------------
/tests/Transformer/YamlTransformerTest.php:
--------------------------------------------------------------------------------
1 |
5 | * Date: 8/30/15
6 | * Time: 1:03 PM.
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace NilPortugues\Test\Serializer\Transformer;
13 |
14 | use DateTime;
15 | use NilPortugues\Serializer\DeepCopySerializer;
16 | use NilPortugues\Serializer\Transformer\YamlTransformer;
17 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\Comment;
18 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\Post;
19 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\User;
20 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\ValueObject\CommentId;
21 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\ValueObject\PostId;
22 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\ValueObject\UserId;
23 |
24 | class YamlTransformerTest extends \PHPUnit_Framework_TestCase
25 | {
26 | public function testSerialization()
27 | {
28 | $object = $this->getObject();
29 | $serializer = new DeepCopySerializer(new YamlTransformer());
30 |
31 | $expected = "postId: 9
32 | title: 'Hello World'
33 | content: 'Your first post'
34 | author:
35 | userId: 1
36 | name: 'Post Author'
37 | comments:
38 | - { commentId: 1000, dates: { created_at: '2015-07-18T12:13:00+02:00', accepted_at: '2015-07-19T00:00:00+02:00' }, comment: 'Have no fear, sers, your king is safe.', user: { userId: 2, name: 'Barristan Selmy' } }
39 | ";
40 |
41 | $this->assertEquals($expected, $serializer->serialize($object));
42 | }
43 |
44 | /**
45 | * @return Post
46 | */
47 | private function getObject()
48 | {
49 | return new Post(
50 | new PostId(9),
51 | 'Hello World',
52 | 'Your first post',
53 | new User(
54 | new UserId(1),
55 | 'Post Author'
56 | ),
57 | [
58 | new Comment(
59 | new CommentId(1000),
60 | 'Have no fear, sers, your king is safe.',
61 | new User(new UserId(2), 'Barristan Selmy'),
62 | [
63 | 'created_at' => (new DateTime('2015/07/18 12:13:00'))->format('c'),
64 | 'accepted_at' => (new DateTime('2015/07/19 00:00:00'))->format('c'),
65 | ]
66 | ),
67 | ]
68 | );
69 | }
70 |
71 | public function testArraySerialization()
72 | {
73 | $arrayOfObjects = [$this->getObject(), $this->getObject()];
74 | $serializer = new DeepCopySerializer(new YamlTransformer());
75 |
76 | $expected = "-
77 | postId: 9
78 | title: 'Hello World'
79 | content: 'Your first post'
80 | author: { userId: 1, name: 'Post Author' }
81 | comments: [{ commentId: 1000, dates: { created_at: '2015-07-18T12:13:00+02:00', accepted_at: '2015-07-19T00:00:00+02:00' }, comment: 'Have no fear, sers, your king is safe.', user: { userId: 2, name: 'Barristan Selmy' } }]
82 | -
83 | postId: 9
84 | title: 'Hello World'
85 | content: 'Your first post'
86 | author: { userId: 1, name: 'Post Author' }
87 | comments: [{ commentId: 1000, dates: { created_at: '2015-07-18T12:13:00+02:00', accepted_at: '2015-07-19T00:00:00+02:00' }, comment: 'Have no fear, sers, your king is safe.', user: { userId: 2, name: 'Barristan Selmy' } }]
88 | ";
89 |
90 | $this->assertEquals($expected, $serializer->serialize($arrayOfObjects));
91 | }
92 |
93 | public function testUnserializeWillThrowException()
94 | {
95 | $serialize = new DeepCopySerializer(new YamlTransformer());
96 |
97 | $this->setExpectedException(\InvalidArgumentException::class);
98 | $serialize->unserialize($serialize->serialize($this->getObject()));
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/tests/XmlSerializerTest.php:
--------------------------------------------------------------------------------
1 |
5 | * Date: 8/30/15
6 | * Time: 12:33 PM.
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace NilPortugues\Test\Serializer;
13 |
14 | use DateTime;
15 | use NilPortugues\Serializer\XmlSerializer;
16 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\Comment;
17 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\Post;
18 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\User;
19 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\ValueObject\CommentId;
20 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\ValueObject\PostId;
21 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\ValueObject\UserId;
22 |
23 | class XmlSerializerTest extends \PHPUnit_Framework_TestCase
24 | {
25 | public function testSerialization()
26 | {
27 | $object = $this->getObject();
28 | $serializer = new XmlSerializer();
29 | $serializedObject = $serializer->serialize($object);
30 |
31 | $this->assertEquals($object, $serializer->unserialize($serializedObject));
32 | }
33 |
34 | private function getObject()
35 | {
36 | return new Post(
37 | new PostId(9),
38 | 'Hello World',
39 | 'Your first post',
40 | new User(
41 | new UserId(1),
42 | 'Post Author'
43 | ),
44 | [
45 | new Comment(
46 | new CommentId(1000),
47 | 'Have no fear, sers, your king is safe.',
48 | new User(new UserId(2), 'Barristan Selmy'),
49 | [
50 | 'created_at' => (new DateTime('2015/07/18 12:13:00'))->format('c'),
51 | 'accepted_at' => (new DateTime('2015/07/19 00:00:00'))->format('c'),
52 | ]
53 | ),
54 | ]
55 | );
56 | }
57 |
58 | public function testArraySerialization()
59 | {
60 | $arrayOfObjects = [$this->getObject(), $this->getObject()];
61 | $serializer = new XmlSerializer();
62 | $serializedObject = $serializer->serialize($arrayOfObjects);
63 |
64 | $this->assertEquals($arrayOfObjects, $serializer->unserialize($serializedObject));
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/tests/YamlSerializerTest.php:
--------------------------------------------------------------------------------
1 |
5 | * Date: 8/30/15
6 | * Time: 12:33 PM.
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace NilPortugues\Test\Serializer;
13 |
14 | use DateTime;
15 | use NilPortugues\Serializer\YamlSerializer;
16 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\Comment;
17 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\Post;
18 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\User;
19 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\ValueObject\CommentId;
20 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\ValueObject\PostId;
21 | use NilPortugues\Test\Serializer\Dummy\ComplexObject\ValueObject\UserId;
22 |
23 | class YamlSerializerTest extends \PHPUnit_Framework_TestCase
24 | {
25 | public function testSerialization()
26 | {
27 | $object = $this->getObject();
28 | $serializer = new YamlSerializer();
29 | $serializedObject = $serializer->serialize($object);
30 |
31 | $this->assertEquals($object, $serializer->unserialize($serializedObject));
32 | }
33 |
34 | private function getObject()
35 | {
36 | return new Post(
37 | new PostId(9),
38 | 'Hello World',
39 | 'Your first post',
40 | new User(
41 | new UserId(1),
42 | 'Post Author'
43 | ),
44 | [
45 | new Comment(
46 | new CommentId(1000),
47 | 'Have no fear, sers, your king is safe.',
48 | new User(new UserId(2), 'Barristan Selmy'),
49 | [
50 | 'created_at' => (new DateTime('2015/07/18 12:13:00'))->format('c'),
51 | 'accepted_at' => (new DateTime('2015/07/19 00:00:00'))->format('c'),
52 | ]
53 | ),
54 | ]
55 | );
56 | }
57 |
58 | public function testArraySerialization()
59 | {
60 | $arrayOfObjects = [$this->getObject(), $this->getObject()];
61 | $serializer = new YamlSerializer();
62 | $serializedObject = $serializer->serialize($arrayOfObjects);
63 |
64 | $this->assertEquals($arrayOfObjects, $serializer->unserialize($serializedObject));
65 | }
66 | }
67 |
--------------------------------------------------------------------------------