Added Laravel project
This commit is contained in:
7
Laravel/vendor/myclabs/deep-copy/.gitattributes
vendored
Executable file
7
Laravel/vendor/myclabs/deep-copy/.gitattributes
vendored
Executable file
@@ -0,0 +1,7 @@
|
||||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
||||
|
||||
*.png binary
|
||||
|
||||
tests/ export-ignore
|
||||
phpunit.xml.dist export-ignore
|
6
Laravel/vendor/myclabs/deep-copy/.gitignore
vendored
Executable file
6
Laravel/vendor/myclabs/deep-copy/.gitignore
vendored
Executable file
@@ -0,0 +1,6 @@
|
||||
.DS_Store
|
||||
.idea/*
|
||||
|
||||
vendor/*
|
||||
composer.phar
|
||||
composer.lock
|
37
Laravel/vendor/myclabs/deep-copy/.travis.yml
vendored
Executable file
37
Laravel/vendor/myclabs/deep-copy/.travis.yml
vendored
Executable file
@@ -0,0 +1,37 @@
|
||||
language: php
|
||||
|
||||
php:
|
||||
- '5.5'
|
||||
- '5.6'
|
||||
- '7.0'
|
||||
- '7.1'
|
||||
- nightly
|
||||
- hhvm
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
include:
|
||||
- php: '5.4'
|
||||
env: COMPOSER_FLAGS="--prefer-lowest"
|
||||
allow_failures:
|
||||
- php: nightly
|
||||
- php: hhvm
|
||||
|
||||
before_install:
|
||||
- |
|
||||
if [ "$TRAVIS_PHP_VERSION" = "nightly" ] || "$TRAVIS_PHP_VERSION" = "7.1" ]; then
|
||||
COMPOSER_FLAGS="$COMPOSER_FLAGS --ignore-platform-reqs"
|
||||
fi;
|
||||
|
||||
install:
|
||||
- composer update -n --prefer-dist $COMPOSER_FLAGS
|
||||
- wget https://github.com/satooshi/php-coveralls/releases/download/v1.0.0/coveralls.phar
|
||||
|
||||
before_script:
|
||||
- mkdir -p build/logs
|
||||
|
||||
script:
|
||||
- vendor/bin/phpunit --coverage-clover build/logs/clover.xml
|
||||
|
||||
after_script:
|
||||
- php coveralls.phar -v
|
20
Laravel/vendor/myclabs/deep-copy/LICENSE
vendored
Normal file
20
Laravel/vendor/myclabs/deep-copy/LICENSE
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013 My C-Sense
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
290
Laravel/vendor/myclabs/deep-copy/README.md
vendored
Normal file
290
Laravel/vendor/myclabs/deep-copy/README.md
vendored
Normal file
@@ -0,0 +1,290 @@
|
||||
# DeepCopy
|
||||
|
||||
DeepCopy helps you create deep copies (clones) of your objects. It is designed to handle cycles in the association graph.
|
||||
|
||||
[](https://travis-ci.org/myclabs/DeepCopy) [](https://coveralls.io/r/myclabs/DeepCopy?branch=master) [](https://scrutinizer-ci.com/g/myclabs/DeepCopy/)
|
||||
[](https://packagist.org/packages/myclabs/deep-copy)
|
||||
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [How](#how)
|
||||
1. [Why](#why)
|
||||
1. [Using simply `clone`](#using-simply-clone)
|
||||
1. [Overridding `__clone()`](#overridding-__clone)
|
||||
1. [With `DeepCopy`](#with-deepcopy)
|
||||
1. [How it works](#how-it-works)
|
||||
1. [Going further](#going-further)
|
||||
1. [Matchers](#matchers)
|
||||
1. [Property name](#property-name)
|
||||
1. [Specific property](#specific-property)
|
||||
1. [Type](#type)
|
||||
1. [Filters](#filters)
|
||||
1. [`SetNullFilter`](#setnullfilter)
|
||||
1. [`KeepFilter`](#keepfilter)
|
||||
1. [`ReplaceFilter`](#replacefilter)
|
||||
1. [`ShallowCopyFilter`](#doctrinecollectionfilter)
|
||||
1. [`DoctrineCollectionFilter`](#doctrinecollectionfilter)
|
||||
1. [`DoctrineEmptyCollectionFilter`](#doctrineemptycollectionfilter)
|
||||
1. [Contributing](#contributing)
|
||||
1. [Tests](#tests)
|
||||
|
||||
## How?
|
||||
|
||||
Install with Composer:
|
||||
|
||||
```json
|
||||
composer require myclabs/deep-copy
|
||||
```
|
||||
|
||||
Use simply:
|
||||
|
||||
```php
|
||||
use DeepCopy\DeepCopy;
|
||||
|
||||
$deepCopy = new DeepCopy();
|
||||
$myCopy = $deepCopy->copy($myObject);
|
||||
```
|
||||
|
||||
|
||||
## Why?
|
||||
|
||||
- How do you create copies of your objects?
|
||||
|
||||
```php
|
||||
$myCopy = clone $myObject;
|
||||
```
|
||||
|
||||
- How do you create **deep** copies of your objects (i.e. copying also all the objects referenced in the properties)?
|
||||
|
||||
You use [`__clone()`](http://www.php.net/manual/en/language.oop5.cloning.php#object.clone) and implement the behavior yourself.
|
||||
|
||||
- But how do you handle **cycles** in the association graph?
|
||||
|
||||
Now you're in for a big mess :(
|
||||
|
||||

|
||||
|
||||
### Using simply `clone`
|
||||
|
||||

|
||||
|
||||
### Overridding `__clone()`
|
||||
|
||||

|
||||
|
||||
### With `DeepCopy`
|
||||
|
||||

|
||||
|
||||
## How it works
|
||||
|
||||
DeepCopy recursively traverses all the object's properties and clones them. To avoid cloning the same object twice it keeps a hash map of all instances and thus preserves the object graph.
|
||||
|
||||
## Going further
|
||||
|
||||
You can add filters to customize the copy process.
|
||||
|
||||
The method to add a filter is `$deepCopy->addFilter($filter, $matcher)`,
|
||||
with `$filter` implementing `DeepCopy\Filter\Filter`
|
||||
and `$matcher` implementing `DeepCopy\Matcher\Matcher`.
|
||||
|
||||
We provide some generic filters and matchers.
|
||||
|
||||
### Matchers
|
||||
|
||||
- `DeepCopy\Matcher` applies on a object attribute.
|
||||
- `DeepCopy\TypeMatcher` applies on any element found in graph, including array elements.
|
||||
|
||||
#### Property name
|
||||
|
||||
The `PropertyNameMatcher` will match a property by its name:
|
||||
|
||||
```php
|
||||
use DeepCopy\Matcher\PropertyNameMatcher;
|
||||
|
||||
$matcher = new PropertyNameMatcher('id');
|
||||
// will apply a filter to any property of any objects named "id"
|
||||
```
|
||||
|
||||
#### Specific property
|
||||
|
||||
The `PropertyMatcher` will match a specific property of a specific class:
|
||||
|
||||
```php
|
||||
use DeepCopy\Matcher\PropertyMatcher;
|
||||
|
||||
$matcher = new PropertyMatcher('MyClass', 'id');
|
||||
// will apply a filter to the property "id" of any objects of the class "MyClass"
|
||||
```
|
||||
|
||||
#### Type
|
||||
|
||||
The `TypeMatcher` will match any element by its type (instance of a class or any value that could be parameter of [gettype()](http://php.net/manual/en/function.gettype.php) function):
|
||||
|
||||
```php
|
||||
use DeepCopy\TypeMatcher\TypeMatcher;
|
||||
|
||||
$matcher = new TypeMatcher('Doctrine\Common\Collections\Collection');
|
||||
// will apply a filter to any object that is an instance of Doctrine\Common\Collections\Collection
|
||||
```
|
||||
|
||||
### Filters
|
||||
|
||||
- `DeepCopy\Filter` applies a transformation to the object attribute matched by `DeepCopy\Matcher`.
|
||||
- `DeepCopy\TypeFilter` applies a transformation to any element matched by `DeepCopy\TypeMatcher`.
|
||||
|
||||
#### `SetNullFilter`
|
||||
|
||||
Let's say for example that you are copying a database record (or a Doctrine entity), so you want the copy not to have any ID:
|
||||
|
||||
```php
|
||||
use DeepCopy\DeepCopy;
|
||||
use DeepCopy\Filter\SetNullFilter;
|
||||
use DeepCopy\Matcher\PropertyNameMatcher;
|
||||
|
||||
$myObject = MyClass::load(123);
|
||||
echo $myObject->id; // 123
|
||||
|
||||
$deepCopy = new DeepCopy();
|
||||
$deepCopy->addFilter(new SetNullFilter(), new PropertyNameMatcher('id'));
|
||||
$myCopy = $deepCopy->copy($myObject);
|
||||
|
||||
echo $myCopy->id; // null
|
||||
```
|
||||
|
||||
#### `KeepFilter`
|
||||
|
||||
If you want a property to remain untouched (for example, an association to an object):
|
||||
|
||||
```php
|
||||
use DeepCopy\DeepCopy;
|
||||
use DeepCopy\Filter\KeepFilter;
|
||||
use DeepCopy\Matcher\PropertyMatcher;
|
||||
|
||||
$deepCopy = new DeepCopy();
|
||||
$deepCopy->addFilter(new KeepFilter(), new PropertyMatcher('MyClass', 'category'));
|
||||
$myCopy = $deepCopy->copy($myObject);
|
||||
|
||||
// $myCopy->category has not been touched
|
||||
```
|
||||
|
||||
#### `ReplaceFilter`
|
||||
|
||||
1. If you want to replace the value of a property:
|
||||
|
||||
```php
|
||||
use DeepCopy\DeepCopy;
|
||||
use DeepCopy\Filter\ReplaceFilter;
|
||||
use DeepCopy\Matcher\PropertyMatcher;
|
||||
|
||||
$deepCopy = new DeepCopy();
|
||||
$callback = function ($currentValue) {
|
||||
return $currentValue . ' (copy)'
|
||||
};
|
||||
$deepCopy->addFilter(new ReplaceFilter($callback), new PropertyMatcher('MyClass', 'title'));
|
||||
$myCopy = $deepCopy->copy($myObject);
|
||||
|
||||
// $myCopy->title will contain the data returned by the callback, e.g. 'The title (copy)'
|
||||
```
|
||||
|
||||
2. If you want to replace whole element:
|
||||
|
||||
```php
|
||||
use DeepCopy\DeepCopy;
|
||||
use DeepCopy\TypeFilter\ReplaceFilter;
|
||||
use DeepCopy\TypeMatcher\TypeMatcher;
|
||||
|
||||
$deepCopy = new DeepCopy();
|
||||
$callback = function (MyClass $myClass) {
|
||||
return get_class($myClass);
|
||||
};
|
||||
$deepCopy->addTypeFilter(new ReplaceFilter($callback), new TypeMatcher('MyClass'));
|
||||
$myCopy = $deepCopy->copy(array(new MyClass, 'some string', new MyClass));
|
||||
|
||||
// $myCopy will contain ['MyClass', 'some string', 'MyClass']
|
||||
```
|
||||
|
||||
|
||||
The `$callback` parameter of the `ReplaceFilter` constructor accepts any PHP callable.
|
||||
|
||||
#### `ShallowCopyFilter`
|
||||
|
||||
Stop *DeepCopy* from recursively copying element, using standard `clone` instead:
|
||||
|
||||
```php
|
||||
use DeepCopy\DeepCopy;
|
||||
use DeepCopy\TypeFilter\ShallowCopyFilter;
|
||||
use DeepCopy\TypeMatcher\TypeMatcher;
|
||||
use Mockery as m;
|
||||
|
||||
$this->deepCopy = new DeepCopy();
|
||||
$this->deepCopy->addTypeFilter(
|
||||
new ShallowCopyFilter,
|
||||
new TypeMatcher(m\MockInterface::class)
|
||||
);
|
||||
|
||||
$myServiceWithMocks = new MyService(m::mock(MyDependency1::class), m::mock(MyDependency2::class));
|
||||
// all mocks will be just cloned, not deep-copied
|
||||
```
|
||||
|
||||
#### `DoctrineCollectionFilter`
|
||||
|
||||
If you use Doctrine and want to copy an entity, you will need to use the `DoctrineCollectionFilter`:
|
||||
|
||||
```php
|
||||
use DeepCopy\DeepCopy;
|
||||
use DeepCopy\Filter\Doctrine\DoctrineCollectionFilter;
|
||||
use DeepCopy\Matcher\PropertyTypeMatcher;
|
||||
|
||||
$deepCopy = new DeepCopy();
|
||||
$deepCopy->addFilter(new DoctrineCollectionFilter(), new PropertyTypeMatcher('Doctrine\Common\Collections\Collection'));
|
||||
$myCopy = $deepCopy->copy($myObject);
|
||||
```
|
||||
|
||||
#### `DoctrineEmptyCollectionFilter`
|
||||
|
||||
If you use Doctrine and want to copy an entity who contains a `Collection` that you want to be reset, you can use the `DoctrineEmptyCollectionFilter`
|
||||
|
||||
```php
|
||||
use DeepCopy\DeepCopy;
|
||||
use DeepCopy\Filter\Doctrine\DoctrineEmptyCollectionFilter;
|
||||
use DeepCopy\Matcher\PropertyMatcher;
|
||||
|
||||
$deepCopy = new DeepCopy();
|
||||
$deepCopy->addFilter(new DoctrineEmptyCollectionFilter(), new PropertyMatcher('MyClass', 'myProperty'));
|
||||
$myCopy = $deepCopy->copy($myObject);
|
||||
|
||||
// $myCopy->myProperty will return an empty collection
|
||||
```
|
||||
|
||||
#### `DoctrineProxyFilter`
|
||||
|
||||
If you use Doctrine and use cloning on lazy loaded entities, you might encounter errors mentioning missing fields on a
|
||||
Doctrine proxy class (...\\\_\_CG\_\_\Proxy).
|
||||
You can use the `DoctrineProxyFilter` to load the actual entity behind the Doctrine proxy class.
|
||||
**Make sure, though, to put this as one of your very first filters in the filter chain so that the entity is loaded before other filters are applied!**
|
||||
|
||||
```php
|
||||
use DeepCopy\DeepCopy;
|
||||
use DeepCopy\Filter\Doctrine\DoctrineProxyFilter;
|
||||
use DeepCopy\Matcher\Doctrine\DoctrineProxyMatcher;
|
||||
|
||||
$deepCopy = new DeepCopy();
|
||||
$deepCopy->addFilter(new DoctrineProxyFilter(), new DoctrineProxyMatcher());
|
||||
$myCopy = $deepCopy->copy($myObject);
|
||||
|
||||
// $myCopy should now contain a clone of all entities, including those that were not yet fully loaded.
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
DeepCopy is distributed under the MIT license.
|
||||
|
||||
### Tests
|
||||
|
||||
Running the tests is simple:
|
||||
|
||||
```php
|
||||
phpunit
|
||||
```
|
21
Laravel/vendor/myclabs/deep-copy/composer.json
vendored
Normal file
21
Laravel/vendor/myclabs/deep-copy/composer.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "myclabs/deep-copy",
|
||||
"type": "library",
|
||||
"description": "Create deep copies (clones) of your objects",
|
||||
"keywords": ["clone", "copy", "duplicate", "object", "object graph"],
|
||||
"homepage": "https://github.com/myclabs/DeepCopy",
|
||||
"license": "MIT",
|
||||
"autoload": {
|
||||
"psr-4": { "DeepCopy\\": "src/DeepCopy/" }
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": { "DeepCopyTest\\": "tests/DeepCopyTest/" }
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/collections": "1.*",
|
||||
"phpunit/phpunit": "~4.1"
|
||||
}
|
||||
}
|
BIN
Laravel/vendor/myclabs/deep-copy/doc/clone.png
vendored
Normal file
BIN
Laravel/vendor/myclabs/deep-copy/doc/clone.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
BIN
Laravel/vendor/myclabs/deep-copy/doc/deep-clone.png
vendored
Normal file
BIN
Laravel/vendor/myclabs/deep-copy/doc/deep-clone.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
BIN
Laravel/vendor/myclabs/deep-copy/doc/deep-copy.png
vendored
Normal file
BIN
Laravel/vendor/myclabs/deep-copy/doc/deep-copy.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
BIN
Laravel/vendor/myclabs/deep-copy/doc/graph.png
vendored
Normal file
BIN
Laravel/vendor/myclabs/deep-copy/doc/graph.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.3 KiB |
246
Laravel/vendor/myclabs/deep-copy/src/DeepCopy/DeepCopy.php
vendored
Normal file
246
Laravel/vendor/myclabs/deep-copy/src/DeepCopy/DeepCopy.php
vendored
Normal file
@@ -0,0 +1,246 @@
|
||||
<?php
|
||||
|
||||
namespace DeepCopy;
|
||||
|
||||
use DeepCopy\Exception\CloneException;
|
||||
use DeepCopy\Filter\Filter;
|
||||
use DeepCopy\Matcher\Matcher;
|
||||
use DeepCopy\TypeFilter\Spl\SplDoublyLinkedList;
|
||||
use DeepCopy\TypeFilter\TypeFilter;
|
||||
use DeepCopy\TypeMatcher\TypeMatcher;
|
||||
use ReflectionProperty;
|
||||
use DeepCopy\Reflection\ReflectionHelper;
|
||||
|
||||
/**
|
||||
* DeepCopy
|
||||
*/
|
||||
class DeepCopy
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $hashMap = [];
|
||||
|
||||
/**
|
||||
* Filters to apply.
|
||||
* @var array
|
||||
*/
|
||||
private $filters = [];
|
||||
|
||||
/**
|
||||
* Type Filters to apply.
|
||||
* @var array
|
||||
*/
|
||||
private $typeFilters = [];
|
||||
|
||||
private $skipUncloneable = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $useCloneMethod;
|
||||
|
||||
/**
|
||||
* @param bool $useCloneMethod If set to true, when an object implements the __clone() function, it will be used
|
||||
* instead of the regular deep cloning.
|
||||
*/
|
||||
public function __construct($useCloneMethod = false)
|
||||
{
|
||||
$this->useCloneMethod = $useCloneMethod;
|
||||
|
||||
$this->addTypeFilter(new SplDoublyLinkedList($this), new TypeMatcher('\SplDoublyLinkedList'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Cloning uncloneable properties won't throw exception.
|
||||
* @param $skipUncloneable
|
||||
* @return $this
|
||||
*/
|
||||
public function skipUncloneable($skipUncloneable = true)
|
||||
{
|
||||
$this->skipUncloneable = $skipUncloneable;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a deep copy of the object.
|
||||
* @param mixed $object
|
||||
* @return mixed
|
||||
*/
|
||||
public function copy($object)
|
||||
{
|
||||
$this->hashMap = [];
|
||||
|
||||
return $this->recursiveCopy($object);
|
||||
}
|
||||
|
||||
public function addFilter(Filter $filter, Matcher $matcher)
|
||||
{
|
||||
$this->filters[] = [
|
||||
'matcher' => $matcher,
|
||||
'filter' => $filter,
|
||||
];
|
||||
}
|
||||
|
||||
public function addTypeFilter(TypeFilter $filter, TypeMatcher $matcher)
|
||||
{
|
||||
$this->typeFilters[] = [
|
||||
'matcher' => $matcher,
|
||||
'filter' => $filter,
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
private function recursiveCopy($var)
|
||||
{
|
||||
// Matches Type Filter
|
||||
if ($filter = $this->getFirstMatchedTypeFilter($this->typeFilters, $var)) {
|
||||
return $filter->apply($var);
|
||||
}
|
||||
|
||||
// Resource
|
||||
if (is_resource($var)) {
|
||||
return $var;
|
||||
}
|
||||
// Array
|
||||
if (is_array($var)) {
|
||||
return $this->copyArray($var);
|
||||
}
|
||||
// Scalar
|
||||
if (! is_object($var)) {
|
||||
return $var;
|
||||
}
|
||||
// Object
|
||||
return $this->copyObject($var);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy an array
|
||||
* @param array $array
|
||||
* @return array
|
||||
*/
|
||||
private function copyArray(array $array)
|
||||
{
|
||||
foreach ($array as $key => $value) {
|
||||
$array[$key] = $this->recursiveCopy($value);
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy an object
|
||||
* @param object $object
|
||||
* @return object
|
||||
*/
|
||||
private function copyObject($object)
|
||||
{
|
||||
$objectHash = spl_object_hash($object);
|
||||
|
||||
if (isset($this->hashMap[$objectHash])) {
|
||||
return $this->hashMap[$objectHash];
|
||||
}
|
||||
|
||||
$reflectedObject = new \ReflectionObject($object);
|
||||
|
||||
if (false === $isCloneable = $reflectedObject->isCloneable() and $this->skipUncloneable) {
|
||||
$this->hashMap[$objectHash] = $object;
|
||||
return $object;
|
||||
}
|
||||
|
||||
if (false === $isCloneable) {
|
||||
throw new CloneException(sprintf(
|
||||
'Class "%s" is not cloneable.',
|
||||
$reflectedObject->getName()
|
||||
));
|
||||
}
|
||||
|
||||
$newObject = clone $object;
|
||||
$this->hashMap[$objectHash] = $newObject;
|
||||
if ($this->useCloneMethod && $reflectedObject->hasMethod('__clone')) {
|
||||
return $object;
|
||||
}
|
||||
|
||||
if ($newObject instanceof \DateTimeInterface) {
|
||||
return $newObject;
|
||||
}
|
||||
foreach (ReflectionHelper::getProperties($reflectedObject) as $property) {
|
||||
$this->copyObjectProperty($newObject, $property);
|
||||
}
|
||||
|
||||
return $newObject;
|
||||
}
|
||||
|
||||
private function copyObjectProperty($object, ReflectionProperty $property)
|
||||
{
|
||||
// Ignore static properties
|
||||
if ($property->isStatic()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Apply the filters
|
||||
foreach ($this->filters as $item) {
|
||||
/** @var Matcher $matcher */
|
||||
$matcher = $item['matcher'];
|
||||
/** @var Filter $filter */
|
||||
$filter = $item['filter'];
|
||||
|
||||
if ($matcher->matches($object, $property->getName())) {
|
||||
$filter->apply(
|
||||
$object,
|
||||
$property->getName(),
|
||||
function ($object) {
|
||||
return $this->recursiveCopy($object);
|
||||
}
|
||||
);
|
||||
// If a filter matches, we stop processing this property
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$property->setAccessible(true);
|
||||
$propertyValue = $property->getValue($object);
|
||||
|
||||
// Copy the property
|
||||
$property->setValue($object, $this->recursiveCopy($propertyValue));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns first filter that matches variable, NULL if no such filter found.
|
||||
* @param array $filterRecords Associative array with 2 members: 'filter' with value of type {@see TypeFilter} and
|
||||
* 'matcher' with value of type {@see TypeMatcher}
|
||||
* @param mixed $var
|
||||
* @return TypeFilter|null
|
||||
*/
|
||||
private function getFirstMatchedTypeFilter(array $filterRecords, $var)
|
||||
{
|
||||
$matched = $this->first(
|
||||
$filterRecords,
|
||||
function (array $record) use ($var) {
|
||||
/* @var TypeMatcher $matcher */
|
||||
$matcher = $record['matcher'];
|
||||
|
||||
return $matcher->matches($var);
|
||||
}
|
||||
);
|
||||
|
||||
return isset($matched) ? $matched['filter'] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns first element that matches predicate, NULL if no such element found.
|
||||
* @param array $elements
|
||||
* @param callable $predicate Predicate arguments are: element.
|
||||
* @return mixed|null
|
||||
*/
|
||||
private function first(array $elements, callable $predicate)
|
||||
{
|
||||
foreach ($elements as $element) {
|
||||
if (call_user_func($predicate, $element)) {
|
||||
return $element;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
6
Laravel/vendor/myclabs/deep-copy/src/DeepCopy/Exception/CloneException.php
vendored
Normal file
6
Laravel/vendor/myclabs/deep-copy/src/DeepCopy/Exception/CloneException.php
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
namespace DeepCopy\Exception;
|
||||
|
||||
class CloneException extends \UnexpectedValueException
|
||||
{
|
||||
}
|
31
Laravel/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineCollectionFilter.php
vendored
Normal file
31
Laravel/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineCollectionFilter.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace DeepCopy\Filter\Doctrine;
|
||||
|
||||
use DeepCopy\Filter\Filter;
|
||||
use ReflectionProperty;
|
||||
|
||||
/**
|
||||
* Set a null value for a property
|
||||
*/
|
||||
class DoctrineCollectionFilter implements Filter
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function apply($object, $property, $objectCopier)
|
||||
{
|
||||
$reflectionProperty = new ReflectionProperty($object, $property);
|
||||
|
||||
$reflectionProperty->setAccessible(true);
|
||||
$oldCollection = $reflectionProperty->getValue($object);
|
||||
|
||||
$newCollection = $oldCollection->map(
|
||||
function ($item) use ($objectCopier) {
|
||||
return $objectCopier($item);
|
||||
}
|
||||
);
|
||||
|
||||
$reflectionProperty->setValue($object, $newCollection);
|
||||
}
|
||||
}
|
24
Laravel/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineEmptyCollectionFilter.php
vendored
Normal file
24
Laravel/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineEmptyCollectionFilter.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace DeepCopy\Filter\Doctrine;
|
||||
|
||||
use DeepCopy\Filter\Filter;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
|
||||
class DoctrineEmptyCollectionFilter implements Filter
|
||||
{
|
||||
/**
|
||||
* Apply the filter to the object.
|
||||
*
|
||||
* @param object $object
|
||||
* @param string $property
|
||||
* @param callable $objectCopier
|
||||
*/
|
||||
public function apply($object, $property, $objectCopier)
|
||||
{
|
||||
$reflectionProperty = new \ReflectionProperty($object, $property);
|
||||
$reflectionProperty->setAccessible(true);
|
||||
|
||||
$reflectionProperty->setValue($object, new ArrayCollection());
|
||||
}
|
||||
}
|
20
Laravel/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineProxyFilter.php
vendored
Normal file
20
Laravel/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineProxyFilter.php
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace DeepCopy\Filter\Doctrine;
|
||||
|
||||
use DeepCopy\Filter\Filter;
|
||||
|
||||
/**
|
||||
* Trigger the magic method __load() on a Doctrine Proxy class to load the
|
||||
* actual entity from the database.
|
||||
*/
|
||||
class DoctrineProxyFilter implements Filter
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function apply($object, $property, $objectCopier)
|
||||
{
|
||||
$object->__load();
|
||||
}
|
||||
}
|
17
Laravel/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Filter.php
vendored
Normal file
17
Laravel/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Filter.php
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace DeepCopy\Filter;
|
||||
|
||||
/**
|
||||
* Filter to apply to a property while copying an object
|
||||
*/
|
||||
interface Filter
|
||||
{
|
||||
/**
|
||||
* Apply the filter to the object.
|
||||
* @param object $object
|
||||
* @param string $property
|
||||
* @param callable $objectCopier
|
||||
*/
|
||||
public function apply($object, $property, $objectCopier);
|
||||
}
|
17
Laravel/vendor/myclabs/deep-copy/src/DeepCopy/Filter/KeepFilter.php
vendored
Normal file
17
Laravel/vendor/myclabs/deep-copy/src/DeepCopy/Filter/KeepFilter.php
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace DeepCopy\Filter;
|
||||
|
||||
/**
|
||||
* Keep the value of a property
|
||||
*/
|
||||
class KeepFilter implements Filter
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function apply($object, $property, $objectCopier)
|
||||
{
|
||||
// Nothing to do
|
||||
}
|
||||
}
|
35
Laravel/vendor/myclabs/deep-copy/src/DeepCopy/Filter/ReplaceFilter.php
vendored
Normal file
35
Laravel/vendor/myclabs/deep-copy/src/DeepCopy/Filter/ReplaceFilter.php
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace DeepCopy\Filter;
|
||||
|
||||
/**
|
||||
* Replace the value of a property
|
||||
*/
|
||||
class ReplaceFilter implements Filter
|
||||
{
|
||||
/**
|
||||
* @var callable
|
||||
*/
|
||||
protected $callback;
|
||||
|
||||
/**
|
||||
* @param callable $callable Will be called to get the new value for each property to replace
|
||||
*/
|
||||
public function __construct(callable $callable)
|
||||
{
|
||||
$this->callback = $callable;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function apply($object, $property, $objectCopier)
|
||||
{
|
||||
$reflectionProperty = new \ReflectionProperty($object, $property);
|
||||
$reflectionProperty->setAccessible(true);
|
||||
|
||||
$value = call_user_func($this->callback, $reflectionProperty->getValue($object));
|
||||
|
||||
$reflectionProperty->setValue($object, $value);
|
||||
}
|
||||
}
|
22
Laravel/vendor/myclabs/deep-copy/src/DeepCopy/Filter/SetNullFilter.php
vendored
Normal file
22
Laravel/vendor/myclabs/deep-copy/src/DeepCopy/Filter/SetNullFilter.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace DeepCopy\Filter;
|
||||
|
||||
use ReflectionProperty;
|
||||
|
||||
/**
|
||||
* Set a null value for a property
|
||||
*/
|
||||
class SetNullFilter implements Filter
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function apply($object, $property, $objectCopier)
|
||||
{
|
||||
$reflectionProperty = new ReflectionProperty($object, $property);
|
||||
|
||||
$reflectionProperty->setAccessible(true);
|
||||
$reflectionProperty->setValue($object, null);
|
||||
}
|
||||
}
|
20
Laravel/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/Doctrine/DoctrineProxyMatcher.php
vendored
Normal file
20
Laravel/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/Doctrine/DoctrineProxyMatcher.php
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace DeepCopy\Matcher\Doctrine;
|
||||
|
||||
use DeepCopy\Matcher\Matcher;
|
||||
use Doctrine\Common\Persistence\Proxy;
|
||||
|
||||
/**
|
||||
* Match a Doctrine Proxy class.
|
||||
*/
|
||||
class DoctrineProxyMatcher implements Matcher
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function matches($object, $property)
|
||||
{
|
||||
return $object instanceof Proxy;
|
||||
}
|
||||
}
|
16
Laravel/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/Matcher.php
vendored
Normal file
16
Laravel/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/Matcher.php
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace DeepCopy\Matcher;
|
||||
|
||||
/**
|
||||
* Matcher interface
|
||||
*/
|
||||
interface Matcher
|
||||
{
|
||||
/**
|
||||
* @param object $object
|
||||
* @param string $property
|
||||
* @return boolean
|
||||
*/
|
||||
public function matches($object, $property);
|
||||
}
|
37
Laravel/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyMatcher.php
vendored
Normal file
37
Laravel/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyMatcher.php
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace DeepCopy\Matcher;
|
||||
|
||||
/**
|
||||
* Match a specific property of a specific class
|
||||
*/
|
||||
class PropertyMatcher implements Matcher
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $class;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $property;
|
||||
|
||||
/**
|
||||
* @param string $class Class name
|
||||
* @param string $property Property name
|
||||
*/
|
||||
public function __construct($class, $property)
|
||||
{
|
||||
$this->class = $class;
|
||||
$this->property = $property;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function matches($object, $property)
|
||||
{
|
||||
return ($object instanceof $this->class) && ($property == $this->property);
|
||||
}
|
||||
}
|
30
Laravel/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyNameMatcher.php
vendored
Normal file
30
Laravel/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyNameMatcher.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace DeepCopy\Matcher;
|
||||
|
||||
/**
|
||||
* Match a property by its name
|
||||
*/
|
||||
class PropertyNameMatcher implements Matcher
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $property;
|
||||
|
||||
/**
|
||||
* @param string $property Property name
|
||||
*/
|
||||
public function __construct($property)
|
||||
{
|
||||
$this->property = $property;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function matches($object, $property)
|
||||
{
|
||||
return $property == $this->property;
|
||||
}
|
||||
}
|
38
Laravel/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyTypeMatcher.php
vendored
Normal file
38
Laravel/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyTypeMatcher.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace DeepCopy\Matcher;
|
||||
|
||||
use ReflectionProperty;
|
||||
|
||||
/**
|
||||
* Match a property by its type
|
||||
*
|
||||
* It is recommended to use {@see DeepCopy\TypeFilter\TypeFilter} instead, as it applies on all occurrences
|
||||
* of given type in copied context (eg. array elements), not just on object properties.
|
||||
*/
|
||||
class PropertyTypeMatcher implements Matcher
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $propertyType;
|
||||
|
||||
/**
|
||||
* @param string $propertyType Property type
|
||||
*/
|
||||
public function __construct($propertyType)
|
||||
{
|
||||
$this->propertyType = $propertyType;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function matches($object, $property)
|
||||
{
|
||||
$reflectionProperty = new ReflectionProperty($object, $property);
|
||||
$reflectionProperty->setAccessible(true);
|
||||
|
||||
return $reflectionProperty->getValue($object) instanceof $this->propertyType;
|
||||
}
|
||||
}
|
39
Laravel/vendor/myclabs/deep-copy/src/DeepCopy/Reflection/ReflectionHelper.php
vendored
Normal file
39
Laravel/vendor/myclabs/deep-copy/src/DeepCopy/Reflection/ReflectionHelper.php
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace DeepCopy\Reflection;
|
||||
|
||||
class ReflectionHelper
|
||||
{
|
||||
/**
|
||||
* Retrieves all properties (including private ones), from object and all its ancestors.
|
||||
*
|
||||
* Standard \ReflectionClass->getProperties() does not return private properties from ancestor classes.
|
||||
*
|
||||
* @author muratyaman@gmail.com
|
||||
* @see http://php.net/manual/en/reflectionclass.getproperties.php
|
||||
*
|
||||
* @param \ReflectionClass $ref
|
||||
* @return \ReflectionProperty[]
|
||||
*/
|
||||
public static function getProperties(\ReflectionClass $ref)
|
||||
{
|
||||
$props = $ref->getProperties();
|
||||
$propsArr = array();
|
||||
|
||||
foreach ($props as $prop) {
|
||||
$propertyName = $prop->getName();
|
||||
$propsArr[$propertyName] = $prop;
|
||||
}
|
||||
|
||||
if ($parentClass = $ref->getParentClass()) {
|
||||
$parentPropsArr = self::getProperties($parentClass);
|
||||
foreach ($propsArr as $key => $property) {
|
||||
$parentPropsArr[$key] = $property;
|
||||
}
|
||||
|
||||
return $parentPropsArr;
|
||||
}
|
||||
|
||||
return $propsArr;
|
||||
}
|
||||
}
|
27
Laravel/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/ReplaceFilter.php
vendored
Normal file
27
Laravel/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/ReplaceFilter.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace DeepCopy\TypeFilter;
|
||||
|
||||
class ReplaceFilter implements TypeFilter
|
||||
{
|
||||
/**
|
||||
* @var callable
|
||||
*/
|
||||
protected $callback;
|
||||
|
||||
/**
|
||||
* @param callable $callable Will be called to get the new value for each element to replace
|
||||
*/
|
||||
public function __construct(callable $callable)
|
||||
{
|
||||
$this->callback = $callable;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function apply($element)
|
||||
{
|
||||
return call_user_func($this->callback, $element);
|
||||
}
|
||||
}
|
14
Laravel/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/ShallowCopyFilter.php
vendored
Normal file
14
Laravel/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/ShallowCopyFilter.php
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace DeepCopy\TypeFilter;
|
||||
|
||||
class ShallowCopyFilter implements TypeFilter
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function apply($element)
|
||||
{
|
||||
return clone $element;
|
||||
}
|
||||
}
|
37
Laravel/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/Spl/SplDoublyLinkedList.php
vendored
Normal file
37
Laravel/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/Spl/SplDoublyLinkedList.php
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace DeepCopy\TypeFilter\Spl;
|
||||
|
||||
use DeepCopy\DeepCopy;
|
||||
use DeepCopy\TypeFilter\TypeFilter;
|
||||
|
||||
class SplDoublyLinkedList implements TypeFilter
|
||||
{
|
||||
/**
|
||||
* @var DeepCopy
|
||||
*/
|
||||
private $deepCopy;
|
||||
|
||||
public function __construct(DeepCopy $deepCopy)
|
||||
{
|
||||
$this->deepCopy = $deepCopy;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function apply($element)
|
||||
{
|
||||
$newElement = clone $element;
|
||||
|
||||
if ($element instanceof \SplDoublyLinkedList) {
|
||||
// Replace each element in the list with a deep copy of itself
|
||||
for ($i = 1; $i <= $newElement->count(); $i++) {
|
||||
$newElement->push($this->deepCopy->copy($newElement->shift()));
|
||||
}
|
||||
}
|
||||
|
||||
return $newElement;
|
||||
|
||||
}
|
||||
}
|
12
Laravel/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/TypeFilter.php
vendored
Normal file
12
Laravel/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/TypeFilter.php
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace DeepCopy\TypeFilter;
|
||||
|
||||
interface TypeFilter
|
||||
{
|
||||
/**
|
||||
* Apply the filter to the object.
|
||||
* @param mixed $element
|
||||
*/
|
||||
public function apply($element);
|
||||
}
|
31
Laravel/vendor/myclabs/deep-copy/src/DeepCopy/TypeMatcher/TypeMatcher.php
vendored
Normal file
31
Laravel/vendor/myclabs/deep-copy/src/DeepCopy/TypeMatcher/TypeMatcher.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace DeepCopy\TypeMatcher;
|
||||
|
||||
/**
|
||||
* TypeMatcher class
|
||||
*/
|
||||
class TypeMatcher
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $type;
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
*/
|
||||
public function __construct($type)
|
||||
{
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $element
|
||||
* @return boolean
|
||||
*/
|
||||
public function matches($element)
|
||||
{
|
||||
return is_object($element) ? is_a($element, $this->type) : gettype($element) === $this->type;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user