Augmentation vers version 3.3.0
This commit is contained in:
375
vendor/ocramius/proxy-manager/CHANGELOG.md
vendored
Normal file
375
vendor/ocramius/proxy-manager/CHANGELOG.md
vendored
Normal file
@@ -0,0 +1,375 @@
|
||||
---
|
||||
title: Changelog
|
||||
---
|
||||
|
||||
This is a list of changes/improvements that were introduced in ProxyManager
|
||||
|
||||
## 2.1.1
|
||||
|
||||
This release provides aggressive improvements in static introspection via
|
||||
[phpstan/phpstan](https://github.com/phpstan/phpstan). No functional
|
||||
changes, just removed possible bugs due to excessive parameter count
|
||||
in method calls, as well as test type hint fixes.
|
||||
|
||||
Total issues resolved: **3**
|
||||
|
||||
- [351: Travis already has xdebug pre-installed for PHP 7.1](https://github.com/Ocramius/ProxyManager/pull/351)
|
||||
- [358: Fix #351 - travis has xdebug pre-installed for PHP 7.1](https://github.com/Ocramius/ProxyManager/pull/358)
|
||||
- [361: PHPStan inspection fixes](https://github.com/Ocramius/ProxyManager/pull/361)
|
||||
|
||||
## 2.1.0
|
||||
|
||||
### Improved
|
||||
|
||||
- Introduced support for PHP 7.1, `void` and nullable (`?`)
|
||||
types [#314](https://github.com/Ocramius/ProxyManager/issues/314)
|
||||
[#327](https://github.com/Ocramius/ProxyManager/pull/327)
|
||||
- The test suite is now fully CI-covered by mutation testing [#348](https://github.com/Ocramius/ProxyManager/pull/348)
|
||||
- Moved all performance testing to PHPBench [#326](https://github.com/Ocramius/ProxyManager/pull/326)
|
||||
- PHP 7.0 support dropped [#327](https://github.com/Ocramius/ProxyManager/pull/327)
|
||||
|
||||
Total issues resolved: **9**
|
||||
|
||||
- [290: Branch-alias version bump: master bump to 3.0.x](https://github.com/Ocramius/ProxyManager/pull/290)
|
||||
- [314: Nullable params type](https://github.com/Ocramius/ProxyManager/issues/314)
|
||||
- [326: Moved performance tests to phpbench-based suite](https://github.com/Ocramius/ProxyManager/pull/326)
|
||||
- [327: PHP 7.1 support](https://github.com/Ocramius/ProxyManager/pull/327)
|
||||
- [336: Hotfix tests for php 7 support](https://github.com/Ocramius/ProxyManager/pull/336)
|
||||
- [339: Provided type ?... is invalid](https://github.com/Ocramius/ProxyManager/issues/339)
|
||||
- [343: Fix typo in ghost objects lazy loading code example](https://github.com/Ocramius/ProxyManager/pull/343)
|
||||
- [348: Introduced full mutation testing](https://github.com/Ocramius/ProxyManager/pull/348)
|
||||
- [349: install xdebug manually for php 7.1](https://github.com/Ocramius/ProxyManager/pull/349)
|
||||
|
||||
## 2.0.4
|
||||
|
||||
### Fixed
|
||||
|
||||
- Remove deprecated `getMock` usage from tests [#325](https://github.com/Ocramius/ProxyManager/pull/325)
|
||||
- Fix incorrect type in docs example [#329](https://github.com/Ocramius/ProxyManager/pull/329)
|
||||
- Bug when proxy `__get` magic method [#344](https://github.com/Ocramius/ProxyManager/pull/344)
|
||||
- Fix lazy loading value holder magic method support [#345](https://github.com/Ocramius/ProxyManager/pull/345)
|
||||
|
||||
## 2.0.3
|
||||
|
||||
### Fixed
|
||||
|
||||
- Various test suite cleanups, mostly because of
|
||||
[new PHPUnit 5.4.0 deprecations being introduced](https://github.com/sebastianbergmann/phpunit/wiki/Release-Announcement-for-PHPUnit-5.4.0)
|
||||
[#318](https://github.com/Ocramius/ProxyManager/issues/318)
|
||||
- Removed `zendframework/zend-code:3.0.3` from installable dependencies, since
|
||||
a critical bug was introduced in it [#321](https://github.com/Ocramius/ProxyManager/issues/321)
|
||||
[#323](https://github.com/Ocramius/ProxyManager/issues/323)
|
||||
[#324](https://github.com/Ocramius/ProxyManager/issues/324). Please upgrade to
|
||||
`zendframework/zend-code:3.0.4` or newer.
|
||||
|
||||
## 2.0.2
|
||||
|
||||
### Fixed
|
||||
|
||||
- Various optimizations were performed in the [`ocramius/package-versions`](https://github.com/Ocramius/PackageVersions)
|
||||
integration in order to prevent "class not found" fatals. [#294](https://github.com/Ocramius/ProxyManager/issues/294)
|
||||
- Null objects produced via a given class name were not extending from the given class name, causing obvious LSP
|
||||
compliance and type-compatibility issues. [#300](https://github.com/Ocramius/ProxyManager/issues/300)
|
||||
[#301](https://github.com/Ocramius/ProxyManager/issues/301)
|
||||
- Specific installation versions were removed from the [README.md](README.md) install instructions, since composer
|
||||
is installing the latest available version by default. [#305](https://github.com/Ocramius/ProxyManager/issues/305)
|
||||
- PHP 7.0.6 support was dropped. PHP 7.0.6 includes some nasty reflection bugs that caused `__isset` to be called when
|
||||
`ReflectionProperty#getValue()` is used (https://bugs.php.net/72174).
|
||||
[#306](https://github.com/Ocramius/ProxyManager/issues/306)
|
||||
[#308](https://github.com/Ocramius/ProxyManager/issues/308)
|
||||
- PHP 7.0.7 contains additional limitations as to when `$this` can be used. Specifically, `$this` cannot be used as a
|
||||
parameter name for closures that have an already assigned `$this`. Due to `$this` being incorrectly used as parameter
|
||||
name within this library, running ProxyManager on PHP 7.0.7 would have caused a fatal error.
|
||||
[#306](https://github.com/Ocramius/ProxyManager/issues/306)
|
||||
[#308](https://github.com/Ocramius/ProxyManager/issues/308)
|
||||
[#316](https://github.com/Ocramius/ProxyManager/issues/316)
|
||||
- PHP 7.1.0-DEV includes type-checks for incompatible arithmetic operations: some of those operations were erroneously
|
||||
performed in the library internals. [#308](https://github.com/Ocramius/ProxyManager/issues/308)
|
||||
|
||||
## 2.0.1
|
||||
|
||||
### Fixed
|
||||
|
||||
- Travis-CI environment was fixed to test the library using the minimum dependencies version.
|
||||
|
||||
### Added
|
||||
|
||||
- Added unit test to make sure that properties skipped should be preserved even being cloned.
|
||||
|
||||
## 2.0.0
|
||||
|
||||
### BC Breaks
|
||||
|
||||
Please refer to [the upgrade documentation](UPGRADE.md) to see which backwards-incompatible
|
||||
changes were applied to this release.
|
||||
|
||||
### New features
|
||||
|
||||
#### PHP 7 support
|
||||
|
||||
ProxyManager will now correctly operate in PHP 7 environments.
|
||||
|
||||
#### PHP 7 Return type hints
|
||||
|
||||
ProxyManager will now correctly mimic signatures of methods with return type hints:
|
||||
|
||||
```php
|
||||
class SayHello
|
||||
{
|
||||
public function hello() : string
|
||||
{
|
||||
return 'hello!';
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### PHP 7 Scalar type hints
|
||||
|
||||
ProxyManager will now correctly mimic signatures of methods with scalar type hints
|
||||
|
||||
```php
|
||||
class SayHello
|
||||
{
|
||||
public function hello(string $name) : string
|
||||
{
|
||||
return 'hello, ' . $name;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### PHP 5.6 Variadics support
|
||||
|
||||
ProxyManager will now correctly mimic behavior of methods with variadic parameters:
|
||||
|
||||
```php
|
||||
class SayHello
|
||||
{
|
||||
public function hello(string ...$names) : string
|
||||
{
|
||||
return 'hello, ' . implode(', ', $names);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
By-ref variadic arguments are also supported:
|
||||
|
||||
```php
|
||||
class SayHello
|
||||
{
|
||||
public function hello(string ... & $names)
|
||||
{
|
||||
foreach ($names as & $name) {
|
||||
$name = 'hello, ' . $name;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Constructors in proxies are not replaced anymore
|
||||
|
||||
In ProxyManager v1.x, the constructor of a proxy was completely replaced with a method
|
||||
accepting proxy-specific parameters.
|
||||
|
||||
This is no longer true, and you will be able to use the constructor of your objects as
|
||||
if the class wasn't proxied at all:
|
||||
|
||||
```php
|
||||
class SayHello
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
echo 'Hello!';
|
||||
}
|
||||
}
|
||||
|
||||
/* @var $proxyGenerator \ProxyManager\ProxyGenerator\ProxyGeneratorInterface */
|
||||
$proxyClass = $proxyGenerator->generateProxy(
|
||||
new ReflectionClass(SayHello::class),
|
||||
new ClassGenerator('ProxyClassName')
|
||||
);
|
||||
|
||||
eval('<?php ' . $proxyClass->generate());
|
||||
|
||||
$proxyName = $proxyClass->getName();
|
||||
$object = new ProxyClassName(); // echoes "Hello!"
|
||||
|
||||
var_dump($object); // a proxy object
|
||||
```
|
||||
|
||||
If you still want to manually build a proxy (without factories), a
|
||||
`public static staticProxyConstructor` method is added to the generated proxy classes.
|
||||
|
||||
#### Friend classes support
|
||||
|
||||
You can now access state of "friend objects" at any time.
|
||||
|
||||
```php
|
||||
class EmailAddress
|
||||
{
|
||||
private $address;
|
||||
|
||||
public function __construct(string $address)
|
||||
{
|
||||
assertEmail($address);
|
||||
|
||||
$this->address = $address;
|
||||
}
|
||||
|
||||
public function equalsTo(EmailAddress $other)
|
||||
{
|
||||
return $this->address === $other->address;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
When using lazy-loading or access-interceptors, the `equalsTo` method will
|
||||
properly work, as even `protected` and `private` access are now correctly proxied.
|
||||
|
||||
#### Ghost objects now only lazy-load on state-access
|
||||
|
||||
Lazy loading ghost objects now trigger lazy-loading only when their state is accessed.
|
||||
This also implies that lazy loading ghost objects cannot be used with interfaces anymore.
|
||||
|
||||
```php
|
||||
class AccessPolicy
|
||||
{
|
||||
private $policyName;
|
||||
|
||||
/**
|
||||
* Calling this method WILL cause lazy-loading, when using a ghost object,
|
||||
* as the method is accessing the object's state
|
||||
*/
|
||||
public function getPolicyName() : string
|
||||
{
|
||||
return $this->policyName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calling this method WILL NOT cause lazy-loading, when using a ghost object,
|
||||
* as the method is not reading any from the object.
|
||||
*/
|
||||
public function allowAccess() : bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Faster ghost object state initialization
|
||||
|
||||
Lazy loading ghost objects can now be initialized in a more efficient way, by avoiding
|
||||
reflection or setters:
|
||||
|
||||
```php
|
||||
class Foo
|
||||
{
|
||||
private $a;
|
||||
protected $b;
|
||||
public $c;
|
||||
}
|
||||
|
||||
$factory = new \ProxyManager\Factory\LazyLoadingGhostFactory();
|
||||
|
||||
$proxy = $factory-createProxy(
|
||||
Foo::class,
|
||||
function (
|
||||
GhostObjectInterface $proxy,
|
||||
string $method,
|
||||
array $parameters,
|
||||
& $initializer,
|
||||
array $properties
|
||||
) {
|
||||
$initializer = null;
|
||||
|
||||
$properties["\0Foo\0a"] = 'abc';
|
||||
$properties["\0*\0b"] = 'def';
|
||||
$properties['c'] = 'ghi';
|
||||
|
||||
return true;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
$reflectionA = new ReflectionProperty(Foo::class, 'a');
|
||||
$reflectionA->setAccessible(true);
|
||||
|
||||
var_dump($reflectionA->getValue($proxy)); // dumps "abc"
|
||||
|
||||
$reflectionB = new ReflectionProperty(Foo::class, 'b');
|
||||
$reflectionB->setAccessible(true);
|
||||
|
||||
var_dump($reflectionB->getValue($proxy)); // dumps "def"
|
||||
|
||||
var_dump($proxy->c); // dumps "ghi"
|
||||
```
|
||||
|
||||
#### Skipping lazy-loaded properties in generated proxies
|
||||
|
||||
Lazy loading ghost objects can now skip lazy-loading for certain properties.
|
||||
This is especially useful when you have properties that are always available,
|
||||
such as identifiers of entities:
|
||||
|
||||
```php
|
||||
class User
|
||||
{
|
||||
private $id;
|
||||
private $username;
|
||||
|
||||
public function getId() : int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getUsername() : string
|
||||
{
|
||||
return $this->username;
|
||||
}
|
||||
}
|
||||
|
||||
/* @var $proxy User */
|
||||
$proxy = (new \ProxyManager\Factory\LazyLoadingGhostFactory())->createProxy(
|
||||
User::class,
|
||||
function (
|
||||
GhostObjectInterface $proxy,
|
||||
string $method,
|
||||
array $parameters,
|
||||
& $initializer,
|
||||
array $properties
|
||||
) {
|
||||
$initializer = null;
|
||||
|
||||
var_dump('Triggered lazy-loading!');
|
||||
|
||||
$properties["\0User\0username"] = 'Ocramius';
|
||||
|
||||
return true;
|
||||
},
|
||||
[
|
||||
'skippedProperties' => [
|
||||
"\0User\0id",
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$idReflection = new \ReflectionProperty(User::class, 'id');
|
||||
|
||||
$idReflection->setAccessible(true);
|
||||
$idReflection->setValue($proxy, 123);
|
||||
|
||||
var_dump($proxy->getId()); // 123
|
||||
var_dump($proxy->getUsername()); // "Triggered lazy-loading!", then "Ocramius"
|
||||
```
|
||||
|
||||
#### Proxies are now always generated on-the-fly by default
|
||||
|
||||
Proxies are now automatically generated any time you require them: no configuration
|
||||
needed. If you want to gain better performance, you may still want to read
|
||||
the [tuning for production docs](docs/tuning-for-production.md).
|
||||
|
||||
#### Proxy names are now hashed, simplified signature is attached to them
|
||||
|
||||
Proxy classes now have shorter names, as the parameters used to generate them are
|
||||
hashed into their name. A signature is attached to proxy classes (as a private static
|
||||
property) so that proxy classes aren't re-used across library updates.
|
||||
Upgrading ProxyManager will now cause all proxies to be re-generated automatically,
|
||||
while the old proxy files are going to be ignored.
|
||||
17
vendor/ocramius/proxy-manager/README.md
vendored
17
vendor/ocramius/proxy-manager/README.md
vendored
@@ -1,8 +1,8 @@
|
||||
# Proxy Manager
|
||||
|
||||
This library aims at providing abstraction for generating various kinds of [proxy classes](http://marco-pivetta.com/proxy-pattern-in-php/).
|
||||
This library aims at providing abstraction for generating various kinds of [proxy classes](http://ocramius.github.io/presentations/proxy-pattern-in-php/).
|
||||
|
||||

|
||||

|
||||
|
||||
[](https://travis-ci.org/Ocramius/ProxyManager)
|
||||
[](https://scrutinizer-ci.com/g/Ocramius/ProxyManager/)
|
||||
@@ -19,14 +19,19 @@ This library aims at providing abstraction for generating various kinds of [prox
|
||||
|
||||
## Documentation
|
||||
|
||||
You can learn about the proxy pattern and how to use the **ProxyManager** on the [online documentation](http://ocramius.github.io/ProxyManager).
|
||||
You can learn about the proxy pattern and how to use the **ProxyManager** in the [docs](docs), which are also
|
||||
[compiled to HTML](http://ocramius.github.io/ProxyManager).
|
||||
|
||||
## Help/Support
|
||||
|
||||
[](https://gitter.im/Ocramius/ProxyManager?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||
|
||||
## Installation
|
||||
|
||||
The suggested installation method is via [composer](https://getcomposer.org/):
|
||||
|
||||
```sh
|
||||
php composer.phar require ocramius/proxy-manager:1.0.*
|
||||
php composer.phar require ocramius/proxy-manager
|
||||
```
|
||||
|
||||
## Proxy example
|
||||
@@ -37,9 +42,9 @@ Here's how you build a lazy loadable object with ProxyManager using a *Virtual P
|
||||
$factory = new \ProxyManager\Factory\LazyLoadingValueHolderFactory();
|
||||
|
||||
$proxy = $factory->createProxy(
|
||||
'MyApp\HeavyComplexObject',
|
||||
\MyApp\HeavyComplexObject::class,
|
||||
function (& $wrappedObject, $proxy, $method, $parameters, & $initializer) {
|
||||
$wrappedObject = new HeavyComplexObject(); // instantiation logic here
|
||||
$wrappedObject = new \MyApp\HeavyComplexObject(); // instantiation logic here
|
||||
$initializer = null; // turning off further lazy initialization
|
||||
}
|
||||
);
|
||||
|
||||
20
vendor/ocramius/proxy-manager/STABILITY.md
vendored
20
vendor/ocramius/proxy-manager/STABILITY.md
vendored
@@ -1,10 +1,14 @@
|
||||
---
|
||||
title: Stability
|
||||
---
|
||||
|
||||
This is a list of supported versions, with their expected release/support time-frames:
|
||||
|
||||
# 0.5.x
|
||||
# 2.0.x
|
||||
|
||||
* Release date: 2013-12-01
|
||||
* Bug fixes: till 2015-03-11
|
||||
* Security fixes: till 2015-12-11
|
||||
* Release date: 2016-01-30
|
||||
* Bug fixes: till 2017-12-31
|
||||
* Security fixes: till 2018-12-31
|
||||
|
||||
# 1.0.x
|
||||
|
||||
@@ -12,8 +16,8 @@ This is a list of supported versions, with their expected release/support time-f
|
||||
* Bug fixes: till 2015-12-11
|
||||
* Security fixes: till 2016-12-11
|
||||
|
||||
# 2.0.x
|
||||
# 0.5.x
|
||||
|
||||
* Release date: TBA
|
||||
* Bug fixes: TBA
|
||||
* Security fixes: TBA
|
||||
* Release date: 2013-12-01
|
||||
* Bug fixes: till 2015-03-11
|
||||
* Security fixes: till 2015-12-11
|
||||
|
||||
33
vendor/ocramius/proxy-manager/UPGRADE.md
vendored
33
vendor/ocramius/proxy-manager/UPGRADE.md
vendored
@@ -1,5 +1,38 @@
|
||||
---
|
||||
title: Upgrade
|
||||
---
|
||||
|
||||
This is a list of backwards compatibility (BC) breaks introduced in ProxyManager:
|
||||
|
||||
# 2.0.0
|
||||
|
||||
* PHP `~7.0` is now required to use ProxyManager
|
||||
* HHVM compatibility is not guaranteed, as HHVM is not yet PHP 7 compliant
|
||||
* All classes and interfaces now use [strict scalar type hints](http://php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration).
|
||||
If you extended or implemented anything from the `ProxyManager\` namespace, you probably need to change
|
||||
that code to adapt it to the new signature.
|
||||
* All classes and interfaces now use [return type declarations](http://php.net/manual/en/functions.returning-values.php#functions.returning-values.type-declaration).
|
||||
If you extended or implemented anything from the `ProxyManager\` namespace, you probably need to change
|
||||
that code to adapt it to the new signature.
|
||||
* ProxyManager will no longer write proxies to disk by default:
|
||||
the [`EvaluatingGeneratorStrategy`](src/GeneratorStrategy/EvaluatingGeneratorStrategy.php) is used instead.
|
||||
If you still want ProxyManager to write files to disk, please refer to the [tuning for production docs](docs/tuning-for-production.md)
|
||||
* Ghost objects were entirely rewritten, for better support and improved performance. Lazy-loading is not
|
||||
triggered by public API access, but by property access (private and public). While this is not really a BC
|
||||
break, you are encouraged to check your applications if you rely on [ghost objects](docs/lazy-loading-ghost-object.md).
|
||||
* If ProxyManager can't find a proxy, it will now automatically attempt to auto-generate it, regardless of
|
||||
the settings passed to it.
|
||||
* `ProxyManager\Configuration#setAutoGenerateProxies()` was removed. Please look for calls to this method and
|
||||
remove them.
|
||||
* Private properties are now also correctly handled by ProxyManager: accessing proxy state via friend classes
|
||||
(protected or private scope) does not require any particular workarounds anymore.
|
||||
* `ProxyManager\Version::VERSION` was removed. Please use `ProxyManager\Version::getVersion()` instead.
|
||||
* PHP 4 style constructors are no longer supported
|
||||
|
||||
# 1.0.0
|
||||
|
||||
`1.0.0` is be fully compatible with `0.5.0`.
|
||||
|
||||
# 0.5.0
|
||||
|
||||
* The Generated Hydrator has been removed - it is now available as a separate project
|
||||
|
||||
29
vendor/ocramius/proxy-manager/composer.json
vendored
29
vendor/ocramius/proxy-manager/composer.json
vendored
@@ -15,24 +15,30 @@
|
||||
{
|
||||
"name": "Marco Pivetta",
|
||||
"email": "ocramius@gmail.com",
|
||||
"homepage": "http://ocramius.github.com/"
|
||||
"homepage": "http://ocramius.github.io/"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.3.3",
|
||||
"zendframework/zend-code": ">2.2.5,<3.0"
|
||||
"php": "^7.1.0",
|
||||
"zendframework/zend-code": "^3.1.0",
|
||||
"ocramius/package-versions": "^1.1.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-phar": "*",
|
||||
"phpunit/phpunit": "~4.0",
|
||||
"squizlabs/php_codesniffer": "1.5.*"
|
||||
"ext-phar": "*",
|
||||
"phpunit/phpunit": "^5.6.4",
|
||||
"phpunit/phpunit-mock-objects": "^3.4.1",
|
||||
"squizlabs/php_codesniffer": "^2.7.0",
|
||||
"couscous/couscous": "^1.5.2",
|
||||
"phpbench/phpbench": "^0.12.2",
|
||||
"phpstan/phpstan": "^0.6.4",
|
||||
"nikic/php-parser": "^3.0.4",
|
||||
"humbug/humbug": "dev-master@DEV"
|
||||
},
|
||||
"suggest": {
|
||||
"zendframework/zend-stdlib": "To use the hydrator proxy",
|
||||
"ocramius/generated-hydrator": "To have very fast object to array to object conversion for ghost objects",
|
||||
"zendframework/zend-xmlrpc": "To have the XmlRpc adapter (Remote Object feature)",
|
||||
"zendframework/zend-json": "To have the JsonRpc adapter (Remote Object feature)",
|
||||
"zendframework/zend-soap": "To have the Soap adapter (Remote Object feature)"
|
||||
"zendframework/zend-xmlrpc": "To have the XmlRpc adapter (Remote Object feature)",
|
||||
"zendframework/zend-json": "To have the JsonRpc adapter (Remote Object feature)",
|
||||
"zendframework/zend-soap": "To have the Soap adapter (Remote Object feature)"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
@@ -41,13 +47,14 @@
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-0": {
|
||||
"ProxyManagerBench\\": "tests",
|
||||
"ProxyManagerTest\\": "tests",
|
||||
"ProxyManagerTestAsset\\": "tests"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.0.x-dev"
|
||||
"dev-master": "3.0.x-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
125
vendor/ocramius/proxy-manager/doc-template/css/highlight.dark.css
vendored
Normal file
125
vendor/ocramius/proxy-manager/doc-template/css/highlight.dark.css
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
Copyright (c) 2006, Ivan Sagalaev
|
||||
All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of highlight.js nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
background: #444;
|
||||
-webkit-text-size-adjust: none;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-literal,
|
||||
.hljs-change,
|
||||
.hljs-winutils,
|
||||
.hljs-flow,
|
||||
.nginx .hljs-title,
|
||||
.tex .hljs-special {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.hljs,
|
||||
.hljs-subst {
|
||||
color: #ddd;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-title,
|
||||
.hljs-type,
|
||||
.ini .hljs-title,
|
||||
.hljs-tag .hljs-value,
|
||||
.css .hljs-rules .hljs-value,
|
||||
.hljs-preprocessor,
|
||||
.hljs-pragma,
|
||||
.ruby .hljs-symbol,
|
||||
.ruby .hljs-symbol .hljs-string,
|
||||
.ruby .hljs-class .hljs-parent,
|
||||
.hljs-built_in,
|
||||
.django .hljs-template_tag,
|
||||
.django .hljs-variable,
|
||||
.smalltalk .hljs-class,
|
||||
.hljs-javadoc,
|
||||
.ruby .hljs-string,
|
||||
.django .hljs-filter .hljs-argument,
|
||||
.smalltalk .hljs-localvars,
|
||||
.smalltalk .hljs-array,
|
||||
.hljs-attr_selector,
|
||||
.hljs-pseudo,
|
||||
.hljs-addition,
|
||||
.hljs-stream,
|
||||
.hljs-envvar,
|
||||
.apache .hljs-tag,
|
||||
.apache .hljs-cbracket,
|
||||
.tex .hljs-command,
|
||||
.hljs-prompt,
|
||||
.coffeescript .hljs-attribute {
|
||||
color: #d88;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-annotation,
|
||||
.hljs-decorator,
|
||||
.hljs-pi,
|
||||
.hljs-doctype,
|
||||
.hljs-deletion,
|
||||
.hljs-shebang,
|
||||
.apache .hljs-sqbracket,
|
||||
.tex .hljs-formula {
|
||||
color: #777;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-literal,
|
||||
.hljs-title,
|
||||
.css .hljs-id,
|
||||
.hljs-phpdoc,
|
||||
.hljs-dartdoc,
|
||||
.hljs-type,
|
||||
.vbscript .hljs-built_in,
|
||||
.rsl .hljs-built_in,
|
||||
.smalltalk .hljs-class,
|
||||
.diff .hljs-header,
|
||||
.hljs-chunk,
|
||||
.hljs-winutils,
|
||||
.bash .hljs-variable,
|
||||
.apache .hljs-tag,
|
||||
.tex .hljs-special,
|
||||
.hljs-request,
|
||||
.hljs-status {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.coffeescript .javascript,
|
||||
.javascript .xml,
|
||||
.tex .hljs-formula,
|
||||
.xml .javascript,
|
||||
.xml .vbscript,
|
||||
.xml .css,
|
||||
.xml .hljs-cdata {
|
||||
opacity: 0.5;
|
||||
}
|
||||
179
vendor/ocramius/proxy-manager/doc-template/css/main.css
vendored
Normal file
179
vendor/ocramius/proxy-manager/doc-template/css/main.css
vendored
Normal file
@@ -0,0 +1,179 @@
|
||||
html { font-family: sans-serif; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; }
|
||||
body { margin: 0; }
|
||||
[hidden], template { display: none; }
|
||||
a { background: transparent; }
|
||||
a:active, a:hover { outline: 0; }
|
||||
h1 { font-size: 2em; margin: 0.67em 0; }
|
||||
img { border: 0; }
|
||||
svg:not(:root) { overflow: hidden; }
|
||||
figure { margin: 1em 40px; }
|
||||
hr { -moz-box-sizing: content-box; box-sizing: content-box; height: 0; }
|
||||
pre { overflow: auto; }
|
||||
code, kbd, pre, samp { font-family: 'Menlo', 'Monaco', monospace; font-size: 1em; }
|
||||
button, input, optgroup, select, textarea { color: inherit; font: inherit; margin: 0; }
|
||||
button { overflow: visible; }
|
||||
button, select { text-transform: none; }
|
||||
button, html input[type="button"], input[type="reset"], input[type="submit"] { -webkit-appearance: button; cursor: pointer; }
|
||||
h1, h2, h3, h4, h5, h6, p, ul, ol, li { margin: 0; padding: 0; line-height: normal; }
|
||||
a { color: #31811D; text-decoration: none; }
|
||||
a:hover { color: #2F611C; text-decoration: none; }
|
||||
h3 { margin-bottom: 1em; color: #17324f; font-weight: 400; font-size: 3em; }
|
||||
h4 { margin-bottom: 1em; font-weight: 400; font-size: 1.375em; }
|
||||
p { margin-bottom: 1.5em; font-size: 1.125em; }
|
||||
hr { margin: 2.5em 0; padding: 0; width: 100%; height: 3px; border: 0; background: #e6eaef; }
|
||||
pre code { border-radius: 4px; font-size: 15px; padding: 20px; border: 1px solid #EBEBEB; }
|
||||
.content h1 { padding-bottom: 12px; border-bottom: 1px solid #EFEFEF; margin-bottom: 20px; }
|
||||
.main-nav ul li{ position: relative;}
|
||||
.main-nav ul li{ position: relative;}
|
||||
.main-nav ul li:hover { background: #2F611C;}
|
||||
.main-nav ul li:hover > ul { display:block }
|
||||
.main-nav ul li > ul { display:none; position: absolute; list-style: none; width: 100%; z-index: 9;}
|
||||
.main-nav ul li > ul li a { color: #BFE5F1; display: block; background: #2F611C; padding: 20px;}
|
||||
.main-nav ul li > ul li a:hover { background: #1C440C;}
|
||||
|
||||
/* Menu Sidebar*/
|
||||
.button-block { padding-top: 15px; }
|
||||
.button-block .btn-1 { margin-right: 6px; }
|
||||
.btn, .spy-nav a { position: relative; display: inline-block; margin: 0; padding: 0 20px; height: 57px; border: 0; vertical-align: top; text-align: center; text-transform: uppercase; font-weight: 400; font-size: 1.125em; transitionP: all .2s; line-height: 57px; }
|
||||
.btn.btn-action, .spy-nav a.btn-action { background: #ee2d4d; color: #fff; }
|
||||
.btn.btn-action:hover, .spy-nav a.btn-action:hover { background: #bf0f2d; }
|
||||
.btn.btn-default, .spy-nav a { background: #31811D; color: #fff; }
|
||||
.btn.btn-default:hover, .spy-nav a:hover { background: #2F611C; color: #fff; }
|
||||
.btn.btn-text, .spy-nav a.btn-text { color: #18324f; font-weight: 600; }
|
||||
.btn.btn-full, .spy-nav a { display: block; }
|
||||
@media only screen and (max-width: 480px) {
|
||||
.site-header{ position: fixed !important; top: 0; z-index: 999999}
|
||||
.page-title-wrapper{ margin-top: 70px;}
|
||||
.main-wrapper iframe{ width: 42% !important; float: left; margin-left: 8%;}
|
||||
.content iframe{width: 100%; height: 100%;}
|
||||
}
|
||||
|
||||
.btn-top { position: relative; display: inline-block; float: right; margin: 20px 0 0; padding: 0 30px 0 50px; height: 57px; border: 2px solid #31811D; color: #31811D; vertical-align: top; text-align: center; text-transform: uppercase; font-weight: 600; font-size: 1.125em; line-height: 53px; transition: all .2s; }
|
||||
.btn-top:before { background-position: 0 -140px; width: 52px; height: 52px; position: absolute; top: 0; left: 0; content: ''; }
|
||||
@media only screen and (min-resolution: 2dppx), (-webkit-min-device-pixel-ratio: 2) { .btn-top:before { background-position: 0 -140px; background-size: 152px auto; width: 52px; height: 52px; } }
|
||||
.btn-top:hover { border-color: #2F611C; color: #2F611C; }
|
||||
@media only screen and (max-width: 768px) { .btn-top { float: none; margin-top: 0; margin-bottom: 30px; white-space: nowrap; } }
|
||||
@media only screen and (max-width: 480px) { .btn-top { font-size: 0.9em; line-height: 46px; height: 48px; padding-right: 22px; padding-left: 47px; } }
|
||||
|
||||
.btn-download { float: right; padding-left: 50px; }
|
||||
.btn-download:before { background-position: -18px -116px; width: 16px; height: 16px; position: absolute; top: 50%; left: 20px; margin-top: -7px; content: ''; }
|
||||
@media only screen and (min-resolution: 2dppx), (-webkit-min-device-pixel-ratio: 2) { .btn-download:before { background-position: -18px -116px; background-size: 152px auto; width: 16px; height: 16px; } }
|
||||
|
||||
.btn-done { float: right; padding-left: 50px; }
|
||||
.btn-done:before { background-position: 0 -116px; width: 18px; height: 14px; position: absolute; top: 50%; margin-top: -7px; left: 20px; content: ''; }
|
||||
@media only screen and (min-resolution: 2dppx), (-webkit-min-device-pixel-ratio: 2) { .btn-done:before { background-position: 0 -116px; background-size: 152px auto; width: 18px; height: 13.5px; margin-top: -6.75px; } }
|
||||
|
||||
.btn-cancel { float: right; }
|
||||
|
||||
*, *:before, *:after { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; }
|
||||
|
||||
html { -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; min-width: 280px; }
|
||||
@media only screen and (min-width: 64.063em) and (max-width: 90em) { html { min-width: 960px; } }
|
||||
|
||||
body { font-size: 16px; font-family: 'Source Sans Pro', sans-serif; min-width: 290px; }
|
||||
@media only screen and (max-width: 480px) { body.page-home { background-image: none; } }
|
||||
|
||||
img { max-width: 100%; height: auto !important; }
|
||||
|
||||
input { -webkit-appearance: none; -webkit-border-radius: 0; border-radius: 0; }
|
||||
|
||||
main { overflow: hidden; }
|
||||
|
||||
.clearfix:after { content: ""; display: table; clear: both; }
|
||||
|
||||
.container { width: 60em; margin-left: auto; margin-right: auto; }
|
||||
.container:after { content: " "; display: block; clear: both; }
|
||||
@media only screen and (max-width: 1024px) { .container { margin-left: 15px; margin-right: 15px; width: auto; } }
|
||||
|
||||
.content ul { padding-left: 19px; list-style-type: square; margin-top: 15px; }
|
||||
|
||||
/* Menu top */
|
||||
.main-nav { float: right; }
|
||||
.fixed-wrapper .main-nav { display: none; }
|
||||
.active .main-nav { display: block; }
|
||||
.main-nav > ul { list-style: none; }
|
||||
.main-nav > ul > li { float: left; }
|
||||
.main-nav > ul > li > a { display: block; padding: 22px 30px; color: #fff; text-decoration: none; text-transform: uppercase; font-weight: 600; font-size: 1.375em; line-height: 29px; transition: all .2s; }
|
||||
.main-nav > ul > li > a:hover { color: #bfe5f1; background-color: #2F611C; }
|
||||
.main-nav > ul > li > a.active { background-color: #2F611C; color: #fff; }
|
||||
.main-nav > ul > li > a.opened { background-color: #18324f; }
|
||||
@media only screen and (max-width: 600px) { .main-nav { font-size: 0.86em; }
|
||||
.main-nav > ul > li > a { padding-left: 18px; padding-right: 18px; } }
|
||||
@media only screen and (max-width: 480px) { .main-nav > ul > li > a { font-size: 0.95em; padding: 22px 6px; } }
|
||||
|
||||
.site-header { position: relative; width: 100%; background: #31811D; }
|
||||
.site-header h1 { float: left; margin: 15px 0; }
|
||||
.site-header h1 a { display: block; }
|
||||
.site-header h1 img { display: block; max-height: 42px; }
|
||||
@media only screen and (max-width: 480px) { .site-header h1 img { max-height: 42px; } }
|
||||
|
||||
.page-title-wrapper { position: relative; padding: 26px 0 55px; text-align: center; }
|
||||
.page-title-wrapper .page-title { margin-top: 44px; color: #17324f; font-weight: 400; font-size: 3.75em; }
|
||||
.page-title-wrapper .linguistics { padding: 0 2em 13px; border-bottom: 1px solid #D4DBE3; color: #18324f; text-transform: uppercase; font-weight: 400; font-size: 1.25em; }
|
||||
@media only screen and (max-width: 768px) { .page-title-wrapper { font-size: 0.8em; } }
|
||||
@media only screen and (max-width: 480px) { .page-title-wrapper { font-size: 0.65em; } }
|
||||
|
||||
.site-footer { margin-top: 20px; padding-top: 50px; padding-bottom: 50px; background: #18324f; color: #7c8ea3; text-align: center; }
|
||||
.site-footer .container { position: relative; }
|
||||
.footer-logos ul li{ list-style: none; display: inline-block;}
|
||||
.footer-logos ul li a{ padding-left: 10px; padding-right: 10px}
|
||||
.site-footer a{ color: white !important;}
|
||||
.site-footer p { text-align: left; display: block; margin-bottom: 1.5em; font-size: 1.125em; }
|
||||
@media only screen and (max-width: 1024px) { .site-footer p { margin-left: 0; } }
|
||||
@media only screen and (max-width: 768px) { .site-footer p { text-align: center; margin-left: auto; } }
|
||||
@media only screen and (max-width: 600px) { .site-footer { font-size: 0.9em; } }
|
||||
|
||||
.main-logo { display: block; float: left; margin: 30px 0; }
|
||||
.fixed-wrapper .main-logo { display: none; }
|
||||
.main-logo img { display: block; }
|
||||
.main-logo figure { position: relative; margin: 0; max-width: 56px; }
|
||||
.main-logo figcaption { position: absolute; width: 160px; top: 20px; left: 68px; }
|
||||
.active .main-logo { display: block; margin: 0; }
|
||||
.active .main-logo figure { max-width: 42px; }
|
||||
.active .main-logo figcaption { width: 120px; top: 15px; left: 55px; }
|
||||
@media only screen and (max-width: 480px) { .main-logo figcaption { display: none; } }
|
||||
|
||||
.container { width: 60em; margin-left: auto; margin-right: auto; }
|
||||
.container:after { content: " "; display: block; clear: both; }
|
||||
@media only screen and (max-width: 1024px) { .container { margin-left: 15px; margin-right: 15px; width: auto; } }
|
||||
|
||||
.component-demo { position: relative; padding: 1px 0 0; background: #e6eaef; }
|
||||
.component-demo:before { background-image: url("../img/enf.png"); }
|
||||
@media only screen and (max-width: 480px) { .component-demo { padding: 40px 0 0; } }
|
||||
|
||||
.component-info .container { position: relative; }
|
||||
.component-info .sidebar { width: 220px; float: left; margin-top: 75px; }
|
||||
.component-info .sidebar .component-meta { margin-top: 10px; font-size: 1.125em; }
|
||||
.component-info .sidebar .component-meta span { white-space: nowrap; margin-bottom: 10px; padding-left: 25px; color: #18324f; }
|
||||
.component-info .sidebar.sticky { position: fixed; margin-top: 38px; }
|
||||
.component-info .content { width: 64.58333333%; float: right; margin-top: 60px; margin-bottom: 75px; }
|
||||
.component-info .content h3 { margin-bottom: .75em; font-size: 2.75em; }
|
||||
.component-info .content p { margin-bottom: 1.75em; line-height: 1.45; }
|
||||
@media only screen and (max-width: 480px) { .component-info .content .section-title { font-size: 2.1em; } }
|
||||
@media only screen and (max-width: 768px) { .component-info .sidebar { float: none; margin-left: auto; margin-right: auto; }
|
||||
.component-info .sidebar .component-meta { margin-top: 30px; text-align: center; }
|
||||
.component-info .sidebar.sticky { position: relative; margin-top: 75px; }
|
||||
.component-info .content { float: none; width: 100%; } }
|
||||
@media only screen and (max-width: 480px) { .component-info .content { margin-bottom: 0; } }
|
||||
|
||||
.spy-nav { margin-bottom: 10px; }
|
||||
.spy-nav ul { list-style: none; }
|
||||
.spy-nav a { padding-top: 9px; padding-bottom: 10px; height: auto; border-bottom: 1px solid #4B8B20; text-align: left; text-transform: none; font-size: 1.375em; line-height: normal; }
|
||||
.spy-nav .active a { border-bottom-color: #fff; background: #fff; color: #17324f; }
|
||||
.spy-nav select{ width: 100%; margin-bottom: 10px}
|
||||
|
||||
.main-wrapper { margin: 44px auto 44px; max-width: 600px; }
|
||||
.main-wrapper label { display: block; margin-bottom: .75em; color: #3f4e5e; font-size: 1.25em; }
|
||||
.main-wrapper .text-field { padding: 0 15px; width: 100%; height: 40px; border: 1px solid #CBD3DD; font-size: 1.125em; }
|
||||
.main-wrapper ::-webkit-input-placeholder { color: #CBD3DD; font-style: italic; font-size: 18px; }
|
||||
.main-wrapper :-moz-placeholder { color: #CBD3DD; font-style: italic; font-size: 18px; }
|
||||
.main-wrapper ::-moz-placeholder { color: #CBD3DD; font-style: italic; font-size: 18px; }
|
||||
.main-wrapper :-ms-input-placeholder { color: #CBD3DD; font-style: italic; font-size: 18px; }
|
||||
|
||||
.page-icon-wrapper:before, .page-icon-wrapper .logo-asp:before, .page-icon-wrapper .logo-hibernate:before, .page-icon-wrapper .logo-angularjs:before, .page-icon-wrapper .logo-requirejs:before, .page-icon-wrapper .logo-reward:before, .component-demo:before {background-repeat: no-repeat; background-size: 100%; width: 92px; height: 108px; position: absolute; left: 50%; margin-left: -46px; top: 0; bottom: auto; margin-top: -28px; content: ''; }
|
||||
|
||||
.container { width: 60em; margin-left: auto; margin-right: auto; }
|
||||
.container:after { content: " "; display: block; clear: both; }
|
||||
@media only screen and (max-width: 1024px) { .container { margin-left: 15px; margin-right: 15px; width: auto; } }
|
||||
|
||||
.bcms-clearfix:after {content: ""; visibility: hidden; display: block; height: 0; clear: both; }
|
||||
117
vendor/ocramius/proxy-manager/doc-template/default.twig
vendored
Normal file
117
vendor/ocramius/proxy-manager/doc-template/default.twig
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="no-js" id="top">
|
||||
<head>
|
||||
<title>ProxyManager Documentation{% if title is defined %} - {{ title }}{% endif %}</title>
|
||||
|
||||
<meta name="description" content="A proxyManager write in php" />
|
||||
<meta name="keywords" content="ProxyManager, proxy, manager, ocramius, Marco Pivetta, php" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
|
||||
<link href='http://fonts.googleapis.com/css?family=Source+Sans+Pro:200,300,400,600' rel='stylesheet' type='text/css'>
|
||||
<link href="{{ baseUrl }}/css/main.css" rel="stylesheet" />
|
||||
<link href="{{ baseUrl }}/css/highlight.dark.css" rel="stylesheet" />
|
||||
<script src="//code.jquery.com/jquery-2.1.3.min.js"></script>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/8.3/highlight.min.js"></script>
|
||||
<script>hljs.initHighlightingOnLoad();</script>
|
||||
<link rel="shortcut icon" href="favicon.ico">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header class="site-header">
|
||||
<div class="container">
|
||||
<h1><a href="{{ baseUrl }}"><img alt="ProxyManager" src="{{ baseUrl }}/img/block.png" /></a></h1>
|
||||
|
||||
<nav class="main-nav" role="navigation">
|
||||
<ul>
|
||||
<li><a href="https://github.com/Ocramius/ProxyManager" target="_blank">Github</a></li>
|
||||
|
||||
{% if versions is defined %}
|
||||
<li>
|
||||
<a href="#">Version</a>
|
||||
|
||||
<ul>
|
||||
{% for key, version in versions.items %}
|
||||
<li><a href="{{ version.link|e }}">{{ version.name|e }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
<div class="bcms-clearfix"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
<main role="main">
|
||||
<section class="component-content"><div class="page-title-wrapper">
|
||||
<div class="container">
|
||||
<img src="https://github.com/Ocramius/ProxyManager/raw/master/proxy-manager.png">
|
||||
<h2 class="page-title">Proxy Manager</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="component-demo" id="live-demo">
|
||||
<div class="container">
|
||||
<div class="main-wrapper" style="text-align: right">
|
||||
<iframe src="http://ghbtns.com/github-btn.html?user=ocramius&repo=ProxyManager&type=fork&count=true&size=large"
|
||||
allowtransparency="true" frameborder="0" scrolling="0" width="310" height="40"></iframe>
|
||||
|
||||
<iframe src="http://ghbtns.com/github-btn.html?user=ocramius&repo=ProxyManager&type=watch&count=true&size=large"
|
||||
allowtransparency="true" frameborder="0" scrolling="0" width="200" height="40"></iframe>
|
||||
|
||||
</div>
|
||||
<div class="bcms-clearfix bcms-clearfix"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="component-info">
|
||||
<div class="container">
|
||||
|
||||
<aside class="sidebar">
|
||||
<nav class="spy-nav">
|
||||
<ul>
|
||||
<li><a href="{{ baseUrl }}/index.html">Intro</a></li>
|
||||
<li><a href="{{ baseUrl }}/docs/lazy-loading-value-holder.html">Virtual Proxy</a></li>
|
||||
<li><a href="{{ baseUrl }}/docs/lazy-loading-ghost-object.html">Ghost Object</a></li>
|
||||
<li><a href="{{ baseUrl }}/docs/access-interceptor-value-holder.html">Smart Reference</a></li>
|
||||
<li><a href="{{ baseUrl }}/docs/access-interceptor-scope-localizer.html">Smart Reference<br/>(fluent safe)</a></li>
|
||||
<li><a href="{{ baseUrl }}/docs/null-object.html">Null Objects</a></li>
|
||||
<li><a href="{{ baseUrl }}/docs/remote-object.html">Remote Object</a></li>
|
||||
<li><a href="{{ baseUrl }}/docs/generator-strategies.html">Code Evaluators</a></li>
|
||||
<li><a href="{{ baseUrl }}/docs/tuning-for-production.html">Tuning for Production</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<div class="bcms-clearfix bcms-clearfix"></div>
|
||||
<a class="btn btn-action btn-full download-component"
|
||||
href="{{ baseUrl }}/docs/download.html">Download</a>
|
||||
<div class="bcms-clearfix"></div>
|
||||
</aside>
|
||||
|
||||
<div class="content">
|
||||
{% block content %}
|
||||
|
||||
{{ content|raw }}
|
||||
|
||||
{% endblock %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer class="site-footer" role="contentinfo">
|
||||
<div class="container">
|
||||
<div class="footer-logos">
|
||||
<ul>
|
||||
<li><a href="{{ baseUrl }}/stability.html">Stability</a> | </li>
|
||||
<li><a href="{{ baseUrl }}/upgrade.html">Upgrade Notes</a> | </li>
|
||||
<li><a href="{{ baseUrl }}/changelog.html">Changelog</a> | </li>
|
||||
<li><a href="{{ baseUrl }}/contributing.html">Contributing</a> | </li>
|
||||
<li><a href="{{ baseUrl }}/docs/credits.html">Credits</a> | </li>
|
||||
<li><a href="{{ baseUrl }}/docs/copyright.html">Copyright</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bcms-clearfix"></div>
|
||||
</footer>
|
||||
<div class="bcms-clearfix"></div>
|
||||
</body>
|
||||
</html>
|
||||
BIN
vendor/ocramius/proxy-manager/doc-template/favicon.ico
vendored
Normal file
BIN
vendor/ocramius/proxy-manager/doc-template/favicon.ico
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 169 KiB |
BIN
vendor/ocramius/proxy-manager/doc-template/img/block.png
vendored
Normal file
BIN
vendor/ocramius/proxy-manager/doc-template/img/block.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.3 KiB |
BIN
vendor/ocramius/proxy-manager/doc-template/img/enf.png
vendored
Normal file
BIN
vendor/ocramius/proxy-manager/doc-template/img/enf.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.7 KiB |
@@ -1,3 +1,7 @@
|
||||
---
|
||||
title: Access Interceptor Scope Localizer Proxy
|
||||
---
|
||||
|
||||
# Access Interceptor Scope Localizer Proxy
|
||||
|
||||
An access interceptor scope localizer is a smart reference proxy that allows you to dynamically
|
||||
@@ -60,8 +64,10 @@ would break an [access interceptor value holder](access-interceptor-value-holder
|
||||
will cause the two objects to be un-synchronized, with possible unexpected behaviour.
|
||||
* serializing or un-serializing an access interceptor scope localizer (or the real instance)
|
||||
will not cause the real instance (or the proxy) to be serialized or un-serialized
|
||||
* if a proxied object contains private properties, then an exception will be thrown if you use
|
||||
PHP `< 5.4.0`.
|
||||
* methods using `func_get_args()`, `func_get_arg()` and `func_num_arg()` will not function properly
|
||||
for parameters that are not part of the proxied object interface: use
|
||||
[variadic arguments](http://php.net/manual/en/functions.arguments.php#functions.variable-arg-list)
|
||||
instead.
|
||||
|
||||
## Example
|
||||
|
||||
@@ -86,8 +92,8 @@ $factory = new Factory();
|
||||
|
||||
$proxy = $factory->createProxy(
|
||||
new Foo(),
|
||||
array('doFoo' => function () { echo "PreFoo!\n"; }),
|
||||
array('doFoo' => function () { echo "PostFoo!\n"; })
|
||||
['doFoo' => function () { echo "PreFoo!\n"; }],
|
||||
['doFoo' => function () { echo "PostFoo!\n"; }]
|
||||
);
|
||||
|
||||
$proxy->doFoo();
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
---
|
||||
title: Access Interceptor Value Holder Proxy
|
||||
---
|
||||
|
||||
# Access Interceptor Value Holder Proxy
|
||||
|
||||
An access interceptor value holder is a smart reference proxy that allows you to dynamically
|
||||
@@ -35,8 +39,8 @@ $factory = new Factory();
|
||||
|
||||
$proxy = $factory->createProxy(
|
||||
new Foo(),
|
||||
array('doFoo' => function () { echo "PreFoo!\n"; }),
|
||||
array('doFoo' => function () { echo "PostFoo!\n"; })
|
||||
['doFoo' => function () { echo "PreFoo!\n"; }],
|
||||
['doFoo' => function () { echo "PostFoo!\n"; }]
|
||||
);
|
||||
|
||||
$proxy->doFoo();
|
||||
@@ -54,10 +58,8 @@ PostFoo!
|
||||
|
||||
A proxy produced by the
|
||||
[`ProxyManager\Factory\AccessInterceptorValueHolderFactory`](https://github.com/Ocramius/ProxyManager/blob/master/src/ProxyManager/Factory/AccessInterceptorValueHolderFactory.php)
|
||||
implements both the
|
||||
[`ProxyManager\Proxy\ValueHolderInterface`](https://github.com/Ocramius/ProxyManager/blob/master/src/ProxyManager/Proxy/ValueHolderInterface.php)
|
||||
and the
|
||||
[`ProxyManager\Proxy\AccessInterceptorInterface`](https://github.com/Ocramius/ProxyManager/blob/master/src/ProxyManager/Proxy/ValueHolderInterface.php).
|
||||
implements the
|
||||
[`ProxyManager\Proxy\AccessInterceptorValueHolderInterface`](https://github.com/Ocramius/ProxyManager/blob/master/src/ProxyManager/Proxy/AccessInterceptorValueHolderInterface.php).
|
||||
|
||||
Therefore, you can set an access interceptor callback by calling:
|
||||
|
||||
@@ -68,7 +70,7 @@ $proxy->setMethodSuffixInterceptor('methodName', function () { echo 'post'; });
|
||||
|
||||
You can also listen to public properties access by attaching interceptors to `__get`, `__set`, `__isset` and `__unset`.
|
||||
|
||||
A prefix interceptor (executed before method logic) should have following signature:
|
||||
A prefix interceptor (executed before method logic) should have the following signature:
|
||||
|
||||
```php
|
||||
/**
|
||||
@@ -85,7 +87,7 @@ A prefix interceptor (executed before method logic) should have following signat
|
||||
$prefixInterceptor = function ($proxy, $instance, $method, $params, & $returnEarly) {};
|
||||
```
|
||||
|
||||
A suffix interceptor (executed after method logic) should have following signature:
|
||||
A suffix interceptor (executed after method logic) should have the following signature:
|
||||
|
||||
```php
|
||||
/**
|
||||
@@ -103,6 +105,13 @@ A suffix interceptor (executed after method logic) should have following signatu
|
||||
$suffixInterceptor = function ($proxy, $instance, $method, $params, $returnValue, & $returnEarly) {};
|
||||
```
|
||||
|
||||
## Known limitations
|
||||
|
||||
* methods using `func_get_args()`, `func_get_arg()` and `func_num_arg()` will not function properly
|
||||
for parameters that are not part of the proxied object interface: use
|
||||
[variadic arguments](http://php.net/manual/en/functions.arguments.php#functions.variable-arg-list)
|
||||
instead.
|
||||
|
||||
## Tuning performance for production
|
||||
|
||||
See [Tuning ProxyManager for Production](https://github.com/Ocramius/ProxyManager/blob/master/docs/tuning-for-production.md).
|
||||
See [Tuning ProxyManager for Production](https://github.com/Ocramius/ProxyManager/blob/master/docs/tuning-for-production.md).
|
||||
|
||||
15
vendor/ocramius/proxy-manager/docs/copyright.md
vendored
Normal file
15
vendor/ocramius/proxy-manager/docs/copyright.md
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
---
|
||||
title: License
|
||||
---
|
||||
|
||||
# License
|
||||
|
||||
Copyright (c) 2013 Marco Pivetta
|
||||
|
||||
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.
|
||||
|
||||
---
|
||||
26
vendor/ocramius/proxy-manager/docs/credits.md
vendored
Normal file
26
vendor/ocramius/proxy-manager/docs/credits.md
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
---
|
||||
title: Credits
|
||||
---
|
||||
|
||||
# Credits
|
||||
|
||||
The idea was originated by a [talk about Proxies in PHP OOP](http://marco-pivetta.com/proxy-pattern-in-php/) that I gave at the [@phpugffm](https://twitter.com/phpugffm) in January 2013.
|
||||
|
||||
---
|
||||
|
||||
### Contributors
|
||||
|
||||
- [Marco Pivetta](https://github.com/Ocramius)
|
||||
- [Jefersson Nathan](https://github.com/malukenho)
|
||||
- [Blanchon Vincent](https://github.com/blanchonvincent)
|
||||
- [Markus Staab](https://github.com/staabm)
|
||||
- [Gordon Stratton](https://github.com/gws)
|
||||
- [Prolic](https://github.com/prolic)
|
||||
- [Guillaume Royer](https://github.com/guilro)
|
||||
- [Robert Reiz](https://github.com/reiz)
|
||||
- [Lee Davis](https://github.com/leedavis81)
|
||||
- [flip111](https://github.com/flip111)
|
||||
- [Krzysztof Menzyk](https://github.com/krymen)
|
||||
- [Aleksey Khudyakov](https://github.com/Xerkus)
|
||||
- [Alexander](https://github.com/asm89)
|
||||
- [Raul Fraile](https://github.com/raulfraile)
|
||||
11
vendor/ocramius/proxy-manager/docs/download.md
vendored
Normal file
11
vendor/ocramius/proxy-manager/docs/download.md
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
title: Download / Installation
|
||||
---
|
||||
|
||||
## Download / Installation
|
||||
|
||||
The suggested installation method is via [composer](https://getcomposer.org/).
|
||||
|
||||
```sh
|
||||
php composer.phar require ocramius/proxy-manager:1.0.*
|
||||
```
|
||||
@@ -1,3 +1,7 @@
|
||||
---
|
||||
title: Generator strategies
|
||||
---
|
||||
|
||||
# Generator strategies
|
||||
|
||||
ProxyManager allows you to generate classes based on generator strategies and a
|
||||
@@ -13,4 +17,4 @@ Currently, 3 generator strategies are shipped with ProxyManager:
|
||||
where you want to generate multiple classes at runtime
|
||||
* [`ProxyManager\GeneratorStrategy\FileWriterGeneratorStrategy`](https://github.com/Ocramius/ProxyManager/blob/master/src/ProxyManager/GeneratorStrategy/FileWriterGeneratorStrategy.php),
|
||||
which accepts a [`ProxyManager\FileLocator\FileLocatorInterface`](https://github.com/Ocramius/ProxyManager/blob/master/src/ProxyManager/FileLocator/FileLocatorInterface.php)
|
||||
instance as constructor parameter, and based on it, writes the generated class to a file before returning its code.
|
||||
instance as constructor parameter, and based on it, writes the generated class to a file before returning its code.
|
||||
|
||||
@@ -1,7 +1,17 @@
|
||||
---
|
||||
title: Lazy Loading Ghost Object Proxies
|
||||
---
|
||||
|
||||
# Lazy Loading Ghost Object Proxies
|
||||
|
||||
A lazy loading ghost object proxy is a ghost proxy that looks exactly like the real instance of the proxied subject,
|
||||
but which has all properties nulled before initialization.
|
||||
A Lazy Loading Ghost is a type of proxy object.
|
||||
|
||||
More specifically, it is a fake object that looks exactly like an object
|
||||
that you want to interact with, but is actually just an empty instance
|
||||
that gets all properties populated as soon as they are needed.
|
||||
|
||||
Those properties do not really exist until the ghost object is actually
|
||||
initialized.
|
||||
|
||||
## Lazy loading with the Ghost Object
|
||||
|
||||
@@ -41,20 +51,20 @@ subject, they are better suited for representing dataset rows.
|
||||
|
||||
## When do I use a ghost object?
|
||||
|
||||
You usually need a ghost object in cases where following applies
|
||||
You usually need a ghost object in cases where following applies:
|
||||
|
||||
* you are building a small data-mapper and want to lazily load data across associations in your object graph
|
||||
* you want to initialize objects representing rows in a large dataset
|
||||
* you want to compare instances of lazily initialized objects without the risk of comparing a proxy with a real subject
|
||||
* you are building a small data-mapper and want to lazily load data across associations in your object graph;
|
||||
* you want to initialize objects representing rows in a large dataset;
|
||||
* you want to compare instances of lazily initialized objects without the risk of comparing a proxy with a real subject;
|
||||
* you are aware of the internal state of the object and are confident in working with its internals via reflection
|
||||
or direct property access
|
||||
or direct property access.
|
||||
|
||||
## Usage examples
|
||||
|
||||
[ProxyManager](https://github.com/Ocramius/ProxyManager) provides a factory that creates lazy loading ghost objects.
|
||||
To use it, follow these steps:
|
||||
|
||||
First of all, define your object's logic without taking care of lazy loading:
|
||||
First, define your object's logic without taking care of lazy loading:
|
||||
|
||||
```php
|
||||
namespace MyApp;
|
||||
@@ -74,88 +84,186 @@ class Customer
|
||||
}
|
||||
```
|
||||
|
||||
Then use the proxy manager to create a ghost object of it.
|
||||
You will be responsible of setting its state during lazy loading:
|
||||
Then, use the proxy manager to create a ghost object of it.
|
||||
You will be responsible for setting its state during lazy loading:
|
||||
|
||||
```php
|
||||
namespace MyApp;
|
||||
|
||||
use ProxyManager\Factory\LazyLoadingGhostFactory;
|
||||
use ProxyManager\Proxy\LazyLoadingInterface;
|
||||
use ProxyManager\Proxy\GhostObjectInterface;
|
||||
|
||||
require_once __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
$factory = new LazyLoadingGhostFactory();
|
||||
$initializer = function (LazyLoadingInterface $proxy, $method, array $parameters, & $initializer) {
|
||||
$initializer = function (
|
||||
GhostObjectInterface $ghostObject,
|
||||
string $method,
|
||||
array $parameters,
|
||||
& $initializer,
|
||||
array $properties
|
||||
) {
|
||||
$initializer = null; // disable initialization
|
||||
|
||||
// load data and modify the object here
|
||||
$proxy->setName('Agent');
|
||||
$proxy->setSurname('Smith');
|
||||
$properties["\0MyApp\\Customer\0name"] = 'Agent';
|
||||
$properties["\0MyApp\\Customer\0surname"] = 'Smith';
|
||||
|
||||
// you may also call methods on the object, but remember that
|
||||
// the constructor was not called yet:
|
||||
$ghostObject->setSurname('Smith');
|
||||
|
||||
return true; // confirm that initialization occurred correctly
|
||||
};
|
||||
|
||||
$instance = $factory->createProxy('MyApp\Customer', $initializer);
|
||||
$ghostObject = $factory->createProxy(\MyApp\Customer::class, $initializer);
|
||||
```
|
||||
|
||||
You can now simply use your object as before:
|
||||
You can now use your object as before:
|
||||
|
||||
```php
|
||||
// this will just work as before
|
||||
echo $proxy->getName() . ' ' . $proxy->getSurname(); // Agent Smith
|
||||
// this will work as before
|
||||
echo $ghostObject->getName() . ' ' . $ghostObject->getSurname(); // Agent Smith
|
||||
```
|
||||
|
||||
## Lazy Initialization
|
||||
|
||||
As you can see, we use a closure to handle lazy initialization of the proxy instance at runtime.
|
||||
The initializer closure signature for ghost objects should be as following:
|
||||
We use a closure to handle lazy initialization of the proxy instance at runtime.
|
||||
The initializer closure signature for ghost objects is:
|
||||
|
||||
```php
|
||||
/**
|
||||
* @var object $proxy the instance the ghost object proxy that is being initialized
|
||||
* @var string $method the name of the method that triggered lazy initialization
|
||||
* @var array $parameters an ordered list of parameters passed to the method that
|
||||
* triggered initialization, indexed by parameter name
|
||||
* @var Closure $initializer a reference to the property that is the initializer for the
|
||||
* proxy. Set it to null to disable further initialization
|
||||
* @var object $ghostObject The instance of the ghost object proxy that is being initialized.
|
||||
* @var string $method The name of the method that triggered lazy initialization.
|
||||
* @var array $parameters An ordered list of parameters passed to the method that
|
||||
* triggered initialization, indexed by parameter name.
|
||||
* @var Closure $initializer A reference to the property that is the initializer for the
|
||||
* proxy. Set it to null to disable further initialization.
|
||||
* @var array $properties By-ref array with the properties defined in the object, with their
|
||||
* default values pre-assigned. Keys are in the same format that
|
||||
* an (array) cast of an object would provide:
|
||||
* - `"\0Ns\\ClassName\0propertyName"` for `private $propertyName`
|
||||
* defined on `Ns\ClassName`
|
||||
* - `"\0Ns\\ClassName\0propertyName"` for `protected $propertyName`
|
||||
* defined in any level of the hierarchy
|
||||
* - `"propertyName"` for `public $propertyName`
|
||||
* defined in any level of the hierarchy
|
||||
*
|
||||
* @return bool true on success
|
||||
*/
|
||||
$initializer = function ($proxy, $method, $parameters, & $initializer) {};
|
||||
$initializer = function (
|
||||
\ProxyManager\Proxy\GhostObjectInterface $ghostObject,
|
||||
string $method,
|
||||
array $parameters,
|
||||
& $initializer,
|
||||
array $properties
|
||||
) {};
|
||||
```
|
||||
|
||||
The initializer closure should usually be coded like following:
|
||||
|
||||
```php
|
||||
$initializer = function ($proxy, $method, $parameters, & $initializer) {
|
||||
$initializer = function (
|
||||
\ProxyManager\Proxy\GhostObjectInterface $ghostObject,
|
||||
string $method,
|
||||
array $parameters,
|
||||
& $initializer,
|
||||
array $properties
|
||||
) {
|
||||
$initializer = null; // disable initializer for this proxy instance
|
||||
|
||||
// modify the object with loaded data
|
||||
$proxy->setFoo(/* ... */);
|
||||
$proxy->setBar(/* ... */);
|
||||
// initialize properties (please read further on)
|
||||
$properties["\0ClassName\0foo"] = 'foo';
|
||||
$properties["\0ClassName\0bar"] = 'bar';
|
||||
|
||||
return true; // report success
|
||||
};
|
||||
```
|
||||
|
||||
### Lazy initialization `$properties` explained
|
||||
|
||||
The assignments to properties in this closure use unusual `"\0"` sequences.
|
||||
This is to be consistent with how PHP represents private and protected properties when
|
||||
casting an object to an array.
|
||||
`ProxyManager` simply copies a reference to the properties into the `$properties` array passed to the
|
||||
initializer, which allows you to set the state of the object without accessing any of its public
|
||||
API. (This is a very important detail for mapper implementations!)
|
||||
|
||||
Specifically:
|
||||
|
||||
* `"\0Ns\\ClassName\0propertyName"` means `private $propertyName` defined in `Ns\ClassName`;
|
||||
* `"\0*\0propertyName"` means `protected $propertyName` defined in any level of the class
|
||||
hierarchy;
|
||||
* `"propertyName"` means `public $propertyName` defined in any level of the class hierarchy.
|
||||
|
||||
Therefore, given this class:
|
||||
|
||||
```php
|
||||
namespace MyNamespace;
|
||||
|
||||
class MyClass
|
||||
{
|
||||
private $property1;
|
||||
protected $property2;
|
||||
public $property3;
|
||||
}
|
||||
```
|
||||
|
||||
Its appropriate initialization code would be:
|
||||
|
||||
```php
|
||||
namespace MyApp;
|
||||
|
||||
use ProxyManager\Factory\LazyLoadingGhostFactory;
|
||||
use ProxyManager\Proxy\GhostObjectInterface;
|
||||
|
||||
require_once __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
$factory = new LazyLoadingGhostFactory();
|
||||
$initializer = function (
|
||||
GhostObjectInterface $ghostObject,
|
||||
string $method,
|
||||
array $parameters,
|
||||
& $initializer,
|
||||
array $properties
|
||||
) {
|
||||
$initializer = null;
|
||||
|
||||
$properties["\0MyNamespace\\MyClass\0property1"] = 'foo'; //private property of MyNamespace\MyClass
|
||||
$properties["\0*\0property2"] = 'bar'; //protected property in MyClass's hierarchy
|
||||
$properties["property3"] = 'baz'; //public property in MyClass's hierarchy
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
$instance = $factory->createProxy(\MyNamespace\MyClass::class, $initializer);
|
||||
```
|
||||
|
||||
This code would initialize `$property1`, `$property2` and `$property3`
|
||||
respectively to `"foo"`, `"bar"` and `"baz"`.
|
||||
|
||||
You may read the default values for those properties by reading the respective array keys.
|
||||
|
||||
Although it is possible to initialize the object by interacting with its public API, it is
|
||||
not safe to do so, because the object only contains default property values since its constructor was not called.
|
||||
|
||||
## Proxy implementation
|
||||
|
||||
The
|
||||
[`ProxyManager\Factory\LazyLoadingGhostFactory`](https://github.com/Ocramius/ProxyManager/blob/master/src/ProxyManager/Factory/LazyLoadingGhostFactory.php)
|
||||
produces proxies that implement both the
|
||||
[`ProxyManager\Proxy\GhostObjectInterface`](https://github.com/Ocramius/ProxyManager/blob/master/src/ProxyManager/Proxy/GhostObjectInterface.php)
|
||||
and the
|
||||
[`ProxyManager\Proxy\LazyLoadingInterface`](https://github.com/Ocramius/ProxyManager/blob/master/src/ProxyManager/Proxy/LazyLoadingInterface.php).
|
||||
produces proxies that implement the
|
||||
[`ProxyManager\Proxy\GhostObjectInterface`](https://github.com/Ocramius/ProxyManager/blob/master/src/ProxyManager/Proxy/GhostObjectInterface.php).
|
||||
|
||||
At any point in time, you can set a new initializer for the proxy:
|
||||
|
||||
```php
|
||||
$proxy->setProxyInitializer($initializer);
|
||||
$ghostObject->setProxyInitializer($initializer);
|
||||
```
|
||||
|
||||
In your initializer, you **MUST** turn off any further initialization:
|
||||
|
||||
```php
|
||||
$proxy->setProxyInitializer(null);
|
||||
$ghostObject->setProxyInitializer(null);
|
||||
```
|
||||
|
||||
or
|
||||
@@ -164,43 +272,137 @@ or
|
||||
$initializer = null; // if you use the initializer passed by reference to the closure
|
||||
```
|
||||
|
||||
Remember to call `$ghostObject->setProxyInitializer(null);`, or to set `$initializer = null` inside your
|
||||
initializer closure to disable initialization of your proxy, or else initialization will trigger
|
||||
more than once.
|
||||
|
||||
## Triggering Initialization
|
||||
|
||||
A lazy loading ghost object is initialized whenever you access any property or method of it.
|
||||
A lazy loading ghost object is initialized whenever you access any of its properties.
|
||||
Any of the following interactions would trigger lazy initialization:
|
||||
|
||||
```php
|
||||
// calling a method
|
||||
$proxy->someMethod();
|
||||
// calling a method (only if the method accesses internal state)
|
||||
$ghostObject->someMethod();
|
||||
|
||||
// reading a property
|
||||
echo $proxy->someProperty;
|
||||
echo $ghostObject->someProperty;
|
||||
|
||||
// writing a property
|
||||
$proxy->someProperty = 'foo';
|
||||
$ghostObject->someProperty = 'foo';
|
||||
|
||||
// checking for existence of a property
|
||||
isset($proxy->someProperty);
|
||||
isset($ghostObject->someProperty);
|
||||
|
||||
// removing a property
|
||||
unset($proxy->someProperty);
|
||||
unset($ghostObject->someProperty);
|
||||
|
||||
// accessing a property via reflection
|
||||
$reflection = new \ReflectionProperty($ghostObject, 'someProperty');
|
||||
$reflection->setAccessible(true);
|
||||
$reflection->getValue($ghostObject);
|
||||
|
||||
// cloning the entire proxy
|
||||
clone $proxy;
|
||||
clone $ghostObject;
|
||||
|
||||
// serializing the proxy
|
||||
$unserialized = unserialize(serialize($proxy));
|
||||
$unserialized = unserialize(serialize($ghostObject));
|
||||
```
|
||||
|
||||
Remember to call `$proxy->setProxyInitializer(null);` to disable initialization of your proxy, or it will happen more
|
||||
than once.
|
||||
A method like following would never trigger lazy loading, in the context of a ghost object:
|
||||
|
||||
```php
|
||||
public function sayHello() : string
|
||||
{
|
||||
return 'Look ma! No property accessed!';
|
||||
}
|
||||
```
|
||||
|
||||
## Skipping properties (properties that should not be initialized)
|
||||
|
||||
In some contexts, you may want some properties to be completely ignored by the lazy-loading
|
||||
system.
|
||||
|
||||
An example for that (in data mappers) is entities with identifiers: an identifier is usually
|
||||
|
||||
* lightweight
|
||||
* known at all times
|
||||
|
||||
This means that it can be set in our object at all times, and we never need to lazy-load
|
||||
it. Here is a typical example:
|
||||
|
||||
```php
|
||||
namespace MyApp;
|
||||
|
||||
class User
|
||||
{
|
||||
private $id;
|
||||
private $username;
|
||||
private $passwordHash;
|
||||
private $email;
|
||||
private $address;
|
||||
// ...
|
||||
|
||||
public function getId() : int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If we want to skip the property `$id` from lazy-loading, we might want to tell that to
|
||||
the `LazyLoadingGhostFactory`. Here is a longer example, with a more near-real-world
|
||||
scenario:
|
||||
|
||||
```php
|
||||
namespace MyApp;
|
||||
|
||||
use ProxyManager\Factory\LazyLoadingGhostFactory;
|
||||
use ProxyManager\Proxy\GhostObjectInterface;
|
||||
|
||||
require_once __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
$factory = new LazyLoadingGhostFactory();
|
||||
$initializer = function (
|
||||
GhostObjectInterface $ghostObject,
|
||||
string $method,
|
||||
array $parameters,
|
||||
& $initializer,
|
||||
array $properties
|
||||
) {
|
||||
$initializer = null;
|
||||
|
||||
// note that `getId` won't initialize our proxy here
|
||||
$properties["\0MyApp\\User\0username"] = $db->fetchField('users', 'username', $ghostObject->getId();
|
||||
$properties["\0MyApp\\User\0passwordHash"] = $db->fetchField('users', 'passwordHash', $ghostObject->getId();
|
||||
$properties["\0MyApp\\User\0email"] = $db->fetchField('users', 'email', $ghostObject->getId();
|
||||
$properties["\0MyApp\\User\0address"] = $db->fetchField('users', 'address', $ghostObject->getId();
|
||||
|
||||
return true;
|
||||
};
|
||||
$proxyOptions = [
|
||||
'skippedProperties' => [
|
||||
"\0MyApp\\User\0id",
|
||||
],
|
||||
];
|
||||
|
||||
$instance = $factory->createProxy(User::class, $initializer, $proxyOptions);
|
||||
|
||||
$idReflection = new \ReflectionProperty(User::class, 'id');
|
||||
|
||||
$idReflection->setAccessible(true);
|
||||
|
||||
// write the identifier into our ghost object (assuming `setId` doesn't exist)
|
||||
$idReflection->setValue($instance, 1234);
|
||||
```
|
||||
|
||||
In this example, we pass a `skippedProperties` array to our proxy factory. Note the use of the `"\0"` parameter syntax as described above.
|
||||
|
||||
## Proxying interfaces
|
||||
|
||||
You can also generate proxies from an interface FQCN. By proxying an interface, you will only be able to access the
|
||||
methods defined by the interface itself, even if the `wrappedObject` implements more methods. This will anyway save
|
||||
some memory since the proxy won't contain any properties.
|
||||
A lazy loading ghost object cannot proxy an interface directly, as it operates directly around
|
||||
the state of an object. Use a [Virtual Proxy](lazy-loading-value-holder.md) for that instead.
|
||||
|
||||
## Tuning performance for production
|
||||
|
||||
See [Tuning ProxyManager for Production](https://github.com/Ocramius/ProxyManager/blob/master/docs/tuning-for-production.md).
|
||||
See [Tuning ProxyManager for Production](tuning-for-production.md).
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
---
|
||||
title: Lazy Loading Value Holder Proxy
|
||||
---
|
||||
|
||||
# Lazy Loading Value Holder Proxy
|
||||
|
||||
A lazy loading value holder proxy is a virtual proxy that wraps and lazily initializes a "real" instance of the proxied
|
||||
@@ -66,7 +70,7 @@ class HeavyComplexObject
|
||||
}
|
||||
|
||||
public function doFoo() {
|
||||
echo "OK!"
|
||||
echo 'OK!';
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -89,7 +93,7 @@ $initializer = function (& $wrappedObject, LazyLoadingInterface $proxy, $method,
|
||||
return true; // confirm that initialization occurred correctly
|
||||
};
|
||||
|
||||
$instance = $factory->createProxy('MyApp\HeavyComplexObject', $initializer);
|
||||
$proxy = $factory->createProxy('MyApp\HeavyComplexObject', $initializer);
|
||||
```
|
||||
|
||||
You can now simply use your object as before:
|
||||
@@ -110,20 +114,20 @@ The initializer closure signature should be as following:
|
||||
* set it to your real object
|
||||
* @var object $proxy the instance proxy that is being initialized
|
||||
* @var string $method the name of the method that triggered lazy initialization
|
||||
* @var string $parameters an ordered list of parameters passed to the method that
|
||||
* @var array $parameters an ordered list of parameters passed to the method that
|
||||
* triggered initialization, indexed by parameter name
|
||||
* @var Closure $initializer a reference to the property that is the initializer for the
|
||||
* proxy. Set it to null to disable further initialization
|
||||
*
|
||||
* @return bool true on success
|
||||
*/
|
||||
$initializer = function (& $wrappedObject, $proxy, $method, $parameters, & $initializer) {};
|
||||
$initializer = function (& $wrappedObject, $proxy, $method, array $parameters, & $initializer) {};
|
||||
```
|
||||
|
||||
The initializer closure should usually be coded like following:
|
||||
|
||||
```php
|
||||
$initializer = function (& $wrappedObject, $proxy, $method, $parameters, & $initializer) {
|
||||
$initializer = function (& $wrappedObject, $proxy, $method, array $parameters, & $initializer) {
|
||||
$newlyCreatedObject = new Foo(); // instantiation logic
|
||||
$newlyCreatedObject->setBar('baz') // instantiation logic
|
||||
$newlyCreatedObject->setBat('bam') // instantiation logic
|
||||
@@ -197,6 +201,13 @@ You can also generate proxies from an interface FQCN. By proxying an interface,
|
||||
methods defined by the interface itself, even if the `wrappedObject` implements more methods. This will anyway save
|
||||
some memory since the proxy won't contain useless inherited properties.
|
||||
|
||||
## Known limitations
|
||||
|
||||
* methods using `func_get_args()`, `func_get_arg()` and `func_num_arg()` will not function properly
|
||||
for parameters that are not part of the proxied object interface: use
|
||||
[variadic arguments](http://php.net/manual/en/functions.arguments.php#functions.variable-arg-list)
|
||||
instead.
|
||||
|
||||
## Tuning performance for production
|
||||
|
||||
See [Tuning ProxyManager for Production](https://github.com/Ocramius/ProxyManager/blob/master/docs/tuning-for-production.md).
|
||||
See [Tuning ProxyManager for Production](tuning-for-production.md).
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
---
|
||||
title: Null Object Proxy
|
||||
---
|
||||
|
||||
# Null Object Proxy
|
||||
|
||||
A Null Object proxy is a [null object pattern](http://en.wikipedia.org/wiki/Null_Object_pattern) implementation.
|
||||
@@ -9,7 +13,7 @@ In your application, when you can't return the object related to the request, th
|
||||
for the return value and handle the failing condition gracefully, thus generating an explosion of conditionals throughout your code.
|
||||
Fortunately, this seemingly-tangled situation can be sorted out simply by creating a polymorphic implementation of the
|
||||
domain object, which would implement the same interface as the one of the object in question, only that its methods
|
||||
wouldn’t do anything, therefore offloading client code from doing repetitive checks for ugly null values when the operation
|
||||
wouldn't do anything, therefore offloading client code from doing repetitive checks for ugly null values when the operation
|
||||
is executed.
|
||||
|
||||
## Usage examples
|
||||
@@ -24,16 +28,20 @@ class UserMapper
|
||||
}
|
||||
|
||||
public function fetchById($id) {
|
||||
$this->adapter->select("users", array("id" => $id));
|
||||
$this->adapter->select('users', ['id' => $id]);
|
||||
|
||||
if (!$row = $this->adapter->fetch()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->createUser($row);
|
||||
}
|
||||
|
||||
private function createUser(array $row) {
|
||||
$user = new Entity\User($row["name"], $row["email"]);
|
||||
$user->setId($row["id"]);
|
||||
$user = new Entity\User($row['name'], $row['email']);
|
||||
|
||||
$user->setId($row['id']);
|
||||
|
||||
return $user;
|
||||
}
|
||||
}
|
||||
@@ -62,7 +70,8 @@ class UserMapper
|
||||
}
|
||||
|
||||
public function fetchById($id) {
|
||||
$this->adapter->select("users", array("id" => $id));
|
||||
$this->adapter->select('users', ['id' => $id]);
|
||||
|
||||
return $this->createUser($this->adapter->fetch());
|
||||
}
|
||||
|
||||
@@ -72,8 +81,11 @@ class UserMapper
|
||||
|
||||
return $factory->createProxy('Entity\User');
|
||||
}
|
||||
$user = new Entity\User($row["name"], $row["email"]);
|
||||
$user->setId($row["id"]);
|
||||
|
||||
$user = new Entity\User($row['name'], $row['email']);
|
||||
|
||||
$user->setId($row['id']);
|
||||
|
||||
return $user;
|
||||
}
|
||||
}
|
||||
@@ -86,4 +98,4 @@ methods defined by the interface itself, and like with the object, the methods a
|
||||
|
||||
## Tuning performance for production
|
||||
|
||||
See [Tuning ProxyManager for Production](https://github.com/Ocramius/ProxyManager/blob/master/docs/tuning-for-production.md).
|
||||
See [Tuning ProxyManager for Production](tuning-for-production.md).
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
---
|
||||
title: Remote Object Proxy
|
||||
---
|
||||
|
||||
# Remote Object Proxy
|
||||
|
||||
The remote object implementation is a mechanism that enables an local object to control an other object on an other server.
|
||||
@@ -88,13 +92,20 @@ interface AdapterInterface
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function call($wrappedClass, $method, array $params = array());
|
||||
public function call($wrappedClass, $method, array $params = []);
|
||||
}
|
||||
```
|
||||
|
||||
It is very easy to create your own implementation (for RESTful web services, for example). Simply pass
|
||||
your own adapter instance to your factory at construction time
|
||||
|
||||
## Known limitations
|
||||
|
||||
* methods using `func_get_args()`, `func_get_arg()` and `func_num_arg()` will not function properly
|
||||
for parameters that are not part of the proxied object interface: use
|
||||
[variadic arguments](http://php.net/manual/en/functions.arguments.php#functions.variable-arg-list)
|
||||
instead.
|
||||
|
||||
## Tuning performance for production
|
||||
|
||||
See [Tuning ProxyManager for Production](https://github.com/Ocramius/ProxyManager/blob/master/docs/tuning-for-production.md).
|
||||
See [Tuning ProxyManager for Production](tuning-for-production.md).
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
---
|
||||
title: Tuning the ProxyManager for production
|
||||
---
|
||||
|
||||
## Tuning the ProxyManager for production
|
||||
|
||||
By default, all proxy factories generate the required proxy classes at runtime.
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Autoloader;
|
||||
|
||||
use ProxyManager\FileLocator\FileLocatorInterface;
|
||||
@@ -52,7 +54,7 @@ class Autoloader implements AutoloaderInterface
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function __invoke($className)
|
||||
public function __invoke(string $className) : bool
|
||||
{
|
||||
if (class_exists($className, false) || ! $this->classNameInflector->isProxyClassName($className)) {
|
||||
return false;
|
||||
@@ -64,6 +66,8 @@ class Autoloader implements AutoloaderInterface
|
||||
return false;
|
||||
}
|
||||
|
||||
/* @noinspection PhpIncludeInspection */
|
||||
/* @noinspection UsingInclusionOnceReturnValueInspection */
|
||||
return (bool) require_once $file;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Autoloader;
|
||||
|
||||
/**
|
||||
@@ -33,5 +35,5 @@ interface AutoloaderInterface
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function __invoke($className);
|
||||
public function __invoke(string $className) : bool;
|
||||
}
|
||||
|
||||
@@ -16,12 +16,14 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager;
|
||||
|
||||
use ProxyManager\Autoloader\Autoloader;
|
||||
use ProxyManager\Autoloader\AutoloaderInterface;
|
||||
use ProxyManager\FileLocator\FileLocator;
|
||||
use ProxyManager\GeneratorStrategy\FileWriterGeneratorStrategy;
|
||||
use ProxyManager\GeneratorStrategy\EvaluatingGeneratorStrategy;
|
||||
use ProxyManager\GeneratorStrategy\GeneratorStrategyInterface;
|
||||
use ProxyManager\Inflector\ClassNameInflector;
|
||||
use ProxyManager\Inflector\ClassNameInflectorInterface;
|
||||
@@ -82,37 +84,12 @@ class Configuration
|
||||
*/
|
||||
protected $classSignatureGenerator;
|
||||
|
||||
/**
|
||||
* @deprecated deprecated since version 0.5
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function setAutoGenerateProxies()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*
|
||||
* @deprecated deprecated since version 0.5
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function doesAutoGenerateProxies()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AutoloaderInterface $proxyAutoloader
|
||||
*/
|
||||
public function setProxyAutoloader(AutoloaderInterface $proxyAutoloader)
|
||||
public function setProxyAutoloader(AutoloaderInterface $proxyAutoloader) : void
|
||||
{
|
||||
$this->proxyAutoloader = $proxyAutoloader;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AutoloaderInterface
|
||||
*/
|
||||
public function getProxyAutoloader()
|
||||
public function getProxyAutoloader() : AutoloaderInterface
|
||||
{
|
||||
return $this->proxyAutoloader
|
||||
?: $this->proxyAutoloader = new Autoloader(
|
||||
@@ -121,119 +98,75 @@ class Configuration
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $proxiesNamespace
|
||||
*/
|
||||
public function setProxiesNamespace($proxiesNamespace)
|
||||
public function setProxiesNamespace(string $proxiesNamespace) : void
|
||||
{
|
||||
$this->proxiesNamespace = $proxiesNamespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getProxiesNamespace()
|
||||
public function getProxiesNamespace() : string
|
||||
{
|
||||
return $this->proxiesNamespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $proxiesTargetDir
|
||||
*/
|
||||
public function setProxiesTargetDir($proxiesTargetDir)
|
||||
public function setProxiesTargetDir(string $proxiesTargetDir) : void
|
||||
{
|
||||
$this->proxiesTargetDir = (string) $proxiesTargetDir;
|
||||
$this->proxiesTargetDir = $proxiesTargetDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getProxiesTargetDir()
|
||||
public function getProxiesTargetDir() : string
|
||||
{
|
||||
return $this->proxiesTargetDir ?: $this->proxiesTargetDir = sys_get_temp_dir();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param GeneratorStrategyInterface $generatorStrategy
|
||||
*/
|
||||
public function setGeneratorStrategy(GeneratorStrategyInterface $generatorStrategy)
|
||||
public function setGeneratorStrategy(GeneratorStrategyInterface $generatorStrategy) : void
|
||||
{
|
||||
$this->generatorStrategy = $generatorStrategy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return GeneratorStrategyInterface
|
||||
*/
|
||||
public function getGeneratorStrategy()
|
||||
public function getGeneratorStrategy() : GeneratorStrategyInterface
|
||||
{
|
||||
return $this->generatorStrategy
|
||||
?: $this->generatorStrategy = new FileWriterGeneratorStrategy(
|
||||
new FileLocator($this->getProxiesTargetDir())
|
||||
);
|
||||
?: $this->generatorStrategy = new EvaluatingGeneratorStrategy();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ClassNameInflectorInterface $classNameInflector
|
||||
*/
|
||||
public function setClassNameInflector(ClassNameInflectorInterface $classNameInflector)
|
||||
public function setClassNameInflector(ClassNameInflectorInterface $classNameInflector) : void
|
||||
{
|
||||
$this->classNameInflector = $classNameInflector;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ClassNameInflectorInterface
|
||||
*/
|
||||
public function getClassNameInflector()
|
||||
public function getClassNameInflector() : ClassNameInflectorInterface
|
||||
{
|
||||
return $this->classNameInflector
|
||||
?: $this->classNameInflector = new ClassNameInflector($this->getProxiesNamespace());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SignatureGeneratorInterface $signatureGenerator
|
||||
*/
|
||||
public function setSignatureGenerator(SignatureGeneratorInterface $signatureGenerator)
|
||||
public function setSignatureGenerator(SignatureGeneratorInterface $signatureGenerator) : void
|
||||
{
|
||||
$this->signatureGenerator = $signatureGenerator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return SignatureGeneratorInterface
|
||||
*/
|
||||
public function getSignatureGenerator()
|
||||
public function getSignatureGenerator() : SignatureGeneratorInterface
|
||||
{
|
||||
return $this->signatureGenerator ?: $this->signatureGenerator = new SignatureGenerator();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SignatureCheckerInterface $signatureChecker
|
||||
*/
|
||||
public function setSignatureChecker(SignatureCheckerInterface $signatureChecker)
|
||||
public function setSignatureChecker(SignatureCheckerInterface $signatureChecker) : void
|
||||
{
|
||||
$this->signatureChecker = $signatureChecker;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return SignatureCheckerInterface
|
||||
*/
|
||||
public function getSignatureChecker()
|
||||
public function getSignatureChecker() : SignatureCheckerInterface
|
||||
{
|
||||
return $this->signatureChecker
|
||||
?: $this->signatureChecker = new SignatureChecker($this->getSignatureGenerator());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ClassSignatureGeneratorInterface $classSignatureGenerator
|
||||
*/
|
||||
public function setClassSignatureGenerator(ClassSignatureGeneratorInterface $classSignatureGenerator)
|
||||
public function setClassSignatureGenerator(ClassSignatureGeneratorInterface $classSignatureGenerator) : void
|
||||
{
|
||||
$this->classSignatureGenerator = $classSignatureGenerator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ClassSignatureGeneratorInterface
|
||||
*/
|
||||
public function getClassSignatureGenerator()
|
||||
public function getClassSignatureGenerator() : ClassSignatureGeneratorInterface
|
||||
{
|
||||
return $this->classSignatureGenerator
|
||||
?: new ClassSignatureGenerator($this->getSignatureGenerator());
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Exception;
|
||||
|
||||
use BadMethodCallException;
|
||||
@@ -30,13 +32,8 @@ class DisabledMethodException extends BadMethodCallException implements Exceptio
|
||||
{
|
||||
const NAME = __CLASS__;
|
||||
|
||||
/**
|
||||
* @param string $method
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function disabledMethod($method)
|
||||
public static function disabledMethod(string $method) : self
|
||||
{
|
||||
return new self(sprintf('Method "%s" is forcefully disabled', (string) $method));
|
||||
return new self(sprintf('Method "%s" is forcefully disabled', $method));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Exception;
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,11 +16,10 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Exception;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use ReflectionClass;
|
||||
use ReflectionMethod;
|
||||
use UnexpectedValueException;
|
||||
|
||||
/**
|
||||
@@ -31,13 +30,7 @@ use UnexpectedValueException;
|
||||
*/
|
||||
class FileNotWritableException extends UnexpectedValueException implements ExceptionInterface
|
||||
{
|
||||
/**
|
||||
* @param string $fromPath
|
||||
* @param string $toPath
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function fromInvalidMoveOperation($fromPath, $toPath)
|
||||
public static function fromInvalidMoveOperation(string $fromPath, string $toPath) : self
|
||||
{
|
||||
return new self(sprintf(
|
||||
'Could not move file "%s" to location "%s": '
|
||||
@@ -48,19 +41,26 @@ class FileNotWritableException extends UnexpectedValueException implements Excep
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated this method is unused, and will be removed in ProxyManager 3.0.0
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function fromNonWritableLocation($path)
|
||||
public static function fromNonWritableLocation($path) : self
|
||||
{
|
||||
$messages = array();
|
||||
$messages = [];
|
||||
$destination = realpath($path);
|
||||
|
||||
if (($destination = realpath($path)) && ! is_file($destination)) {
|
||||
if (! $destination) {
|
||||
$messages[] = 'path does not exist';
|
||||
}
|
||||
|
||||
if ($destination && ! is_file($destination)) {
|
||||
$messages[] = 'exists and is not a file';
|
||||
}
|
||||
|
||||
if (! is_writable($destination)) {
|
||||
if ($destination && ! is_writable($destination)) {
|
||||
$messages[] = 'is not writable';
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Exception;
|
||||
|
||||
use InvalidArgumentException;
|
||||
@@ -30,32 +32,17 @@ use ReflectionMethod;
|
||||
*/
|
||||
class InvalidProxiedClassException extends InvalidArgumentException implements ExceptionInterface
|
||||
{
|
||||
/**
|
||||
* @param ReflectionClass $reflection
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function interfaceNotSupported(ReflectionClass $reflection)
|
||||
public static function interfaceNotSupported(ReflectionClass $reflection) : self
|
||||
{
|
||||
return new self(sprintf('Provided interface "%s" cannot be proxied', $reflection->getName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ReflectionClass $reflection
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function finalClassNotSupported(ReflectionClass $reflection)
|
||||
public static function finalClassNotSupported(ReflectionClass $reflection) : self
|
||||
{
|
||||
return new self(sprintf('Provided class "%s" is final and cannot be proxied', $reflection->getName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ReflectionClass $reflection
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function abstractProtectedMethodsNotSupported(ReflectionClass $reflection)
|
||||
public static function abstractProtectedMethodsNotSupported(ReflectionClass $reflection) : self
|
||||
{
|
||||
return new self(sprintf(
|
||||
'Provided class "%s" has following protected abstract methods, and therefore cannot be proxied:' . "\n%s",
|
||||
@@ -63,12 +50,12 @@ class InvalidProxiedClassException extends InvalidArgumentException implements E
|
||||
implode(
|
||||
"\n",
|
||||
array_map(
|
||||
function (ReflectionMethod $reflectionMethod) {
|
||||
function (ReflectionMethod $reflectionMethod) : string {
|
||||
return $reflectionMethod->getDeclaringClass()->getName() . '::' . $reflectionMethod->getName();
|
||||
},
|
||||
array_filter(
|
||||
$reflection->getMethods(),
|
||||
function (ReflectionMethod $method) {
|
||||
function (ReflectionMethod $method) : bool {
|
||||
return $method->isAbstract() && $method->isProtected();
|
||||
}
|
||||
)
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Exception;
|
||||
|
||||
use InvalidArgumentException;
|
||||
@@ -28,13 +30,8 @@ use InvalidArgumentException;
|
||||
*/
|
||||
class InvalidProxyDirectoryException extends InvalidArgumentException implements ExceptionInterface
|
||||
{
|
||||
/**
|
||||
* @param string $directory
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function proxyDirectoryNotFound($directory)
|
||||
public static function proxyDirectoryNotFound(string $directory) : self
|
||||
{
|
||||
return new self(sprintf('Provided directory "%s" does not exist', (string) $directory));
|
||||
return new self(sprintf('Provided directory "%s" does not exist', $directory));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Exception;
|
||||
|
||||
use LogicException;
|
||||
@@ -29,12 +31,7 @@ use ReflectionProperty;
|
||||
*/
|
||||
class UnsupportedProxiedClassException extends LogicException implements ExceptionInterface
|
||||
{
|
||||
/**
|
||||
* @param ReflectionProperty $property
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function unsupportedLocalizedReflectionProperty(ReflectionProperty $property)
|
||||
public static function unsupportedLocalizedReflectionProperty(ReflectionProperty $property) : self
|
||||
{
|
||||
return new self(
|
||||
sprintf(
|
||||
|
||||
@@ -16,10 +16,15 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Factory;
|
||||
|
||||
use ProxyManager\Configuration;
|
||||
use ProxyManager\Generator\ClassGenerator;
|
||||
use ProxyManager\ProxyGenerator\ProxyGeneratorInterface;
|
||||
use ProxyManager\Signature\Exception\InvalidSignatureException;
|
||||
use ProxyManager\Signature\Exception\MissingSignatureException;
|
||||
use ProxyManager\Version;
|
||||
use ReflectionClass;
|
||||
|
||||
@@ -41,7 +46,7 @@ abstract class AbstractBaseFactory
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
private $checkedClasses = array();
|
||||
private $checkedClasses = [];
|
||||
|
||||
/**
|
||||
* @param \ProxyManager\Configuration $configuration
|
||||
@@ -53,27 +58,39 @@ abstract class AbstractBaseFactory
|
||||
|
||||
/**
|
||||
* Generate a proxy from a class name
|
||||
* @param string $className
|
||||
*
|
||||
* @param string $className
|
||||
* @param mixed[] $proxyOptions
|
||||
*
|
||||
* @return string proxy class name
|
||||
*
|
||||
* @throws InvalidSignatureException
|
||||
* @throws MissingSignatureException
|
||||
* @throws \OutOfBoundsException
|
||||
*/
|
||||
protected function generateProxy($className)
|
||||
protected function generateProxy(string $className, array $proxyOptions = []) : string
|
||||
{
|
||||
if (isset($this->checkedClasses[$className])) {
|
||||
if (\array_key_exists($className, $this->checkedClasses)) {
|
||||
return $this->checkedClasses[$className];
|
||||
}
|
||||
|
||||
$proxyParameters = array(
|
||||
$proxyParameters = [
|
||||
'className' => $className,
|
||||
'factory' => get_class($this),
|
||||
'proxyManagerVersion' => Version::VERSION
|
||||
);
|
||||
'proxyManagerVersion' => Version::getVersion(),
|
||||
];
|
||||
$proxyClassName = $this
|
||||
->configuration
|
||||
->getClassNameInflector()
|
||||
->getProxyClassName($className, $proxyParameters);
|
||||
|
||||
if (! class_exists($proxyClassName)) {
|
||||
$this->generateProxyClass($proxyClassName, $className, $proxyParameters);
|
||||
$this->generateProxyClass(
|
||||
$proxyClassName,
|
||||
$className,
|
||||
$proxyParameters,
|
||||
$proxyOptions
|
||||
);
|
||||
}
|
||||
|
||||
$this
|
||||
@@ -84,29 +101,33 @@ abstract class AbstractBaseFactory
|
||||
return $this->checkedClasses[$className] = $proxyClassName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \ProxyManager\ProxyGenerator\ProxyGeneratorInterface
|
||||
*/
|
||||
abstract protected function getGenerator();
|
||||
abstract protected function getGenerator() : ProxyGeneratorInterface;
|
||||
|
||||
/**
|
||||
* Generates the provided `$proxyClassName` from the given `$className` and `$proxyParameters`
|
||||
* @param string $proxyClassName
|
||||
* @param string $className
|
||||
* @param array $proxyParameters
|
||||
*
|
||||
* @return void
|
||||
* @param string $proxyClassName
|
||||
* @param string $className
|
||||
* @param array $proxyParameters
|
||||
* @param mixed[] $proxyOptions
|
||||
*/
|
||||
private function generateProxyClass($proxyClassName, $className, array $proxyParameters)
|
||||
{
|
||||
private function generateProxyClass(
|
||||
string $proxyClassName,
|
||||
string $className,
|
||||
array $proxyParameters,
|
||||
array $proxyOptions = []
|
||||
) : void {
|
||||
$className = $this->configuration->getClassNameInflector()->getUserClassName($className);
|
||||
$phpClass = new ClassGenerator($proxyClassName);
|
||||
|
||||
$this->getGenerator()->generate(new ReflectionClass($className), $phpClass);
|
||||
$this->getGenerator()->generate(new ReflectionClass($className), $phpClass, $proxyOptions);
|
||||
|
||||
$phpClass = $this->configuration->getClassSignatureGenerator()->addSignature($phpClass, $proxyParameters);
|
||||
|
||||
$this->configuration->getGeneratorStrategy()->generate($phpClass);
|
||||
$this->configuration->getProxyAutoloader()->__invoke($proxyClassName);
|
||||
$this->configuration->getGeneratorStrategy()->generate($phpClass, $proxyOptions);
|
||||
|
||||
$autoloader = $this->configuration->getProxyAutoloader();
|
||||
|
||||
$autoloader($proxyClassName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,9 +16,15 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Factory;
|
||||
|
||||
use ProxyManager\Proxy\AccessInterceptorInterface;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizerGenerator;
|
||||
use ProxyManager\ProxyGenerator\ProxyGeneratorInterface;
|
||||
use ProxyManager\Signature\Exception\InvalidSignatureException;
|
||||
use ProxyManager\Signature\Exception\MissingSignatureException;
|
||||
|
||||
/**
|
||||
* Factory responsible of producing proxy objects
|
||||
@@ -40,19 +46,26 @@ class AccessInterceptorScopeLocalizerFactory extends AbstractBaseFactory
|
||||
* @param \Closure[] $suffixInterceptors an array (indexed by method name) of interceptor closures to be called
|
||||
* after method logic is executed
|
||||
*
|
||||
* @return \ProxyManager\Proxy\AccessInterceptorInterface
|
||||
* @return AccessInterceptorInterface
|
||||
*
|
||||
* @throws InvalidSignatureException
|
||||
* @throws MissingSignatureException
|
||||
* @throws \OutOfBoundsException
|
||||
*/
|
||||
public function createProxy($instance, array $prefixInterceptors = array(), array $suffixInterceptors = array())
|
||||
{
|
||||
public function createProxy(
|
||||
$instance,
|
||||
array $prefixInterceptors = [],
|
||||
array $suffixInterceptors = []
|
||||
) : AccessInterceptorInterface {
|
||||
$proxyClassName = $this->generateProxy(get_class($instance));
|
||||
|
||||
return new $proxyClassName($instance, $prefixInterceptors, $suffixInterceptors);
|
||||
return $proxyClassName::staticProxyConstructor($instance, $prefixInterceptors, $suffixInterceptors);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function getGenerator()
|
||||
protected function getGenerator() : ProxyGeneratorInterface
|
||||
{
|
||||
return $this->generator ?: $this->generator = new AccessInterceptorScopeLocalizerGenerator();
|
||||
}
|
||||
|
||||
@@ -16,9 +16,15 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Factory;
|
||||
|
||||
use ProxyManager\Proxy\AccessInterceptorValueHolderInterface;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorValueHolderGenerator;
|
||||
use ProxyManager\ProxyGenerator\ProxyGeneratorInterface;
|
||||
use ProxyManager\Signature\Exception\InvalidSignatureException;
|
||||
use ProxyManager\Signature\Exception\MissingSignatureException;
|
||||
|
||||
/**
|
||||
* Factory responsible of producing proxy objects
|
||||
@@ -40,19 +46,26 @@ class AccessInterceptorValueHolderFactory extends AbstractBaseFactory
|
||||
* @param \Closure[] $suffixInterceptors an array (indexed by method name) of interceptor closures to be called
|
||||
* after method logic is executed
|
||||
*
|
||||
* @return \ProxyManager\Proxy\AccessInterceptorInterface|\ProxyManager\Proxy\ValueHolderInterface
|
||||
* @return AccessInterceptorValueHolderInterface
|
||||
*
|
||||
* @throws InvalidSignatureException
|
||||
* @throws MissingSignatureException
|
||||
* @throws \OutOfBoundsException
|
||||
*/
|
||||
public function createProxy($instance, array $prefixInterceptors = array(), array $suffixInterceptors = array())
|
||||
{
|
||||
public function createProxy(
|
||||
$instance,
|
||||
array $prefixInterceptors = [],
|
||||
array $suffixInterceptors = []
|
||||
) : AccessInterceptorValueHolderInterface {
|
||||
$proxyClassName = $this->generateProxy(get_class($instance));
|
||||
|
||||
return new $proxyClassName($instance, $prefixInterceptors, $suffixInterceptors);
|
||||
return $proxyClassName::staticProxyConstructor($instance, $prefixInterceptors, $suffixInterceptors);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function getGenerator()
|
||||
protected function getGenerator() : ProxyGeneratorInterface
|
||||
{
|
||||
return $this->generator ?: $this->generator = new AccessInterceptorValueHolderGenerator();
|
||||
}
|
||||
|
||||
@@ -16,19 +16,24 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Factory;
|
||||
|
||||
use Closure;
|
||||
use ProxyManager\Proxy\GhostObjectInterface;
|
||||
use ProxyManager\ProxyGenerator\LazyLoadingGhostGenerator;
|
||||
use ProxyManager\ProxyGenerator\ProxyGeneratorInterface;
|
||||
use ProxyManager\Signature\Exception\InvalidSignatureException;
|
||||
use ProxyManager\Signature\Exception\MissingSignatureException;
|
||||
|
||||
/**
|
||||
* Factory responsible of producing ghost instances
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
* @license MIT
|
||||
*
|
||||
* @method \ProxyManager\Proxy\GhostObjectInterface createProxy($className, \Closure $initializer)
|
||||
*/
|
||||
class LazyLoadingGhostFactory extends AbstractLazyFactory
|
||||
class LazyLoadingGhostFactory extends AbstractBaseFactory
|
||||
{
|
||||
/**
|
||||
* @var \ProxyManager\ProxyGenerator\LazyLoadingGhostGenerator|null
|
||||
@@ -38,8 +43,60 @@ class LazyLoadingGhostFactory extends AbstractLazyFactory
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function getGenerator()
|
||||
protected function getGenerator() : ProxyGeneratorInterface
|
||||
{
|
||||
return $this->generator ?: $this->generator = new LazyLoadingGhostGenerator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new lazy proxy instance of the given class with
|
||||
* the given initializer
|
||||
*
|
||||
* Please refer to the following documentation when using this method:
|
||||
*
|
||||
* @link https://github.com/Ocramius/ProxyManager/blob/master/docs/lazy-loading-ghost-object.md
|
||||
*
|
||||
* @param string $className name of the class to be proxied
|
||||
* @param Closure $initializer initializer to be passed to the proxy. The initializer closure should have following
|
||||
* signature:
|
||||
*
|
||||
* <code>
|
||||
* $initializer = function (
|
||||
* GhostObjectInterface $proxy,
|
||||
* string $method,
|
||||
* array $parameters,
|
||||
* & $initializer,
|
||||
* array $properties
|
||||
* ) {};
|
||||
* </code>
|
||||
*
|
||||
* Where:
|
||||
* - $proxy is the proxy instance on which the initializer is acting
|
||||
* - $method is the name of the method that triggered the lazy initialization
|
||||
* - $parameters are the parameters that were passed to $method
|
||||
* - $initializer by-ref initializer - should be assigned null in the initializer body
|
||||
* - $properties a by-ref map of the properties of the object, indexed by PHP
|
||||
* internal property name. Assign values to it to initialize the
|
||||
* object state
|
||||
*
|
||||
* @param mixed[] $proxyOptions a set of options to be used when generating the proxy. Currently supports only
|
||||
* key "skippedProperties", which allows to skip lazy-loading of some properties.
|
||||
* "skippedProperties" is a string[], containing a list of properties referenced
|
||||
* via PHP's internal property name (i.e. "\0ClassName\0propertyName")
|
||||
*
|
||||
* @return GhostObjectInterface
|
||||
*
|
||||
* @throws MissingSignatureException
|
||||
* @throws InvalidSignatureException
|
||||
* @throws \OutOfBoundsException
|
||||
*/
|
||||
public function createProxy(
|
||||
string $className,
|
||||
Closure $initializer,
|
||||
array $proxyOptions = []
|
||||
) : GhostObjectInterface {
|
||||
$proxyClassName = $this->generateProxy($className, $proxyOptions);
|
||||
|
||||
return $proxyClassName::staticProxyConstructor($initializer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,29 +16,41 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Factory;
|
||||
|
||||
use ProxyManager\Proxy\VirtualProxyInterface;
|
||||
use ProxyManager\ProxyGenerator\LazyLoadingValueHolderGenerator;
|
||||
use ProxyManager\ProxyGenerator\ProxyGeneratorInterface;
|
||||
|
||||
/**
|
||||
* Factory responsible of producing virtual proxy instances
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
* @license MIT
|
||||
*
|
||||
* @method \ProxyManager\Proxy\VirtualProxyInterface createProxy($className, \Closure $initializer)
|
||||
*/
|
||||
class LazyLoadingValueHolderFactory extends AbstractLazyFactory
|
||||
class LazyLoadingValueHolderFactory extends AbstractBaseFactory
|
||||
{
|
||||
/**
|
||||
* @var \ProxyManager\ProxyGenerator\LazyLoadingValueHolderGenerator|null
|
||||
*/
|
||||
private $generator;
|
||||
|
||||
public function createProxy(
|
||||
string $className,
|
||||
\Closure $initializer,
|
||||
array $proxyOptions = []
|
||||
) : VirtualProxyInterface {
|
||||
$proxyClassName = $this->generateProxy($className, $proxyOptions);
|
||||
|
||||
return $proxyClassName::staticProxyConstructor($initializer);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function getGenerator()
|
||||
protected function getGenerator() : ProxyGeneratorInterface
|
||||
{
|
||||
return $this->generator ?: $this->generator = new LazyLoadingValueHolderGenerator();
|
||||
}
|
||||
|
||||
@@ -16,9 +16,15 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Factory;
|
||||
|
||||
use ProxyManager\Proxy\NullObjectInterface;
|
||||
use ProxyManager\ProxyGenerator\NullObjectGenerator;
|
||||
use ProxyManager\ProxyGenerator\ProxyGeneratorInterface;
|
||||
use ProxyManager\Signature\Exception\InvalidSignatureException;
|
||||
use ProxyManager\Signature\Exception\MissingSignatureException;
|
||||
|
||||
/**
|
||||
* Factory responsible of producing proxy objects
|
||||
@@ -36,20 +42,24 @@ class NullObjectFactory extends AbstractBaseFactory
|
||||
/**
|
||||
* @param object $instanceOrClassName the object to be wrapped or interface to transform to null object
|
||||
*
|
||||
* @return \ProxyManager\Proxy\NullobjectInterface
|
||||
* @return NullObjectInterface
|
||||
*
|
||||
* @throws InvalidSignatureException
|
||||
* @throws MissingSignatureException
|
||||
* @throws \OutOfBoundsException
|
||||
*/
|
||||
public function createProxy($instanceOrClassName)
|
||||
public function createProxy($instanceOrClassName) : NullObjectInterface
|
||||
{
|
||||
$className = is_object($instanceOrClassName) ? get_class($instanceOrClassName) : $instanceOrClassName;
|
||||
$proxyClassName = $this->generateProxy($className);
|
||||
|
||||
return new $proxyClassName();
|
||||
return $proxyClassName::staticProxyConstructor();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function getGenerator()
|
||||
protected function getGenerator() : ProxyGeneratorInterface
|
||||
{
|
||||
return $this->generator ?: $this->generator = new NullObjectGenerator();
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Factory\RemoteObject\Adapter;
|
||||
|
||||
use ProxyManager\Factory\RemoteObject\AdapterInterface;
|
||||
@@ -41,7 +43,7 @@ abstract class BaseAdapter implements AdapterInterface
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $map = array();
|
||||
protected $map = [];
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
@@ -49,7 +51,7 @@ abstract class BaseAdapter implements AdapterInterface
|
||||
* @param Client $client
|
||||
* @param array $map map of service names to their aliases
|
||||
*/
|
||||
public function __construct(Client $client, array $map = array())
|
||||
public function __construct(Client $client, array $map = [])
|
||||
{
|
||||
$this->client = $client;
|
||||
$this->map = $map;
|
||||
@@ -58,11 +60,11 @@ abstract class BaseAdapter implements AdapterInterface
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function call($wrappedClass, $method, array $params = array())
|
||||
public function call(string $wrappedClass, string $method, array $params = [])
|
||||
{
|
||||
$serviceName = $this->getServiceName($wrappedClass, $method);
|
||||
|
||||
if (isset($this->map[$serviceName])) {
|
||||
if (\array_key_exists($serviceName, $this->map)) {
|
||||
$serviceName = $this->map[$serviceName];
|
||||
}
|
||||
|
||||
@@ -77,5 +79,5 @@ abstract class BaseAdapter implements AdapterInterface
|
||||
*
|
||||
* @return string Service name
|
||||
*/
|
||||
abstract protected function getServiceName($wrappedClass, $method);
|
||||
abstract protected function getServiceName(string $wrappedClass, string $method) : string;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Factory\RemoteObject\Adapter;
|
||||
|
||||
/**
|
||||
@@ -29,7 +31,7 @@ class JsonRpc extends BaseAdapter
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function getServiceName($wrappedClass, $method)
|
||||
protected function getServiceName(string $wrappedClass, string $method) : string
|
||||
{
|
||||
return $wrappedClass . '.' . $method;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Factory\RemoteObject\Adapter;
|
||||
|
||||
/**
|
||||
@@ -29,8 +31,8 @@ class Soap extends BaseAdapter
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function getServiceName($wrappedClass, $method)
|
||||
protected function getServiceName(string $wrappedClass, string $method) : string
|
||||
{
|
||||
return (string) $method;
|
||||
return $method;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Factory\RemoteObject\Adapter;
|
||||
|
||||
/**
|
||||
@@ -29,7 +31,7 @@ class XmlRpc extends BaseAdapter
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function getServiceName($wrappedClass, $method)
|
||||
protected function getServiceName(string $wrappedClass, string $method) : string
|
||||
{
|
||||
return $wrappedClass . '.' . $method;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Factory\RemoteObject;
|
||||
|
||||
/**
|
||||
@@ -33,5 +35,5 @@ interface AdapterInterface
|
||||
* @param string $method
|
||||
* @param array $params
|
||||
*/
|
||||
public function call($wrappedClass, $method, array $params = array());
|
||||
public function call(string $wrappedClass, string $method, array $params = []);
|
||||
}
|
||||
|
||||
@@ -16,11 +16,17 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Factory;
|
||||
|
||||
use ProxyManager\Configuration;
|
||||
use ProxyManager\Factory\RemoteObject\AdapterInterface;
|
||||
use ProxyManager\Proxy\RemoteObjectInterface;
|
||||
use ProxyManager\ProxyGenerator\ProxyGeneratorInterface;
|
||||
use ProxyManager\ProxyGenerator\RemoteObjectGenerator;
|
||||
use ProxyManager\Signature\Exception\InvalidSignatureException;
|
||||
use ProxyManager\Signature\Exception\MissingSignatureException;
|
||||
|
||||
/**
|
||||
* Factory responsible of producing remote proxy objects
|
||||
@@ -56,20 +62,25 @@ class RemoteObjectFactory extends AbstractBaseFactory
|
||||
/**
|
||||
* @param string|object $instanceOrClassName
|
||||
*
|
||||
* @return \ProxyManager\Proxy\RemoteObjectInterface
|
||||
* @return RemoteObjectInterface
|
||||
*
|
||||
* @throws InvalidSignatureException
|
||||
* @throws MissingSignatureException
|
||||
* @throws \OutOfBoundsException
|
||||
*/
|
||||
public function createProxy($instanceOrClassName)
|
||||
public function createProxy($instanceOrClassName) : RemoteObjectInterface
|
||||
{
|
||||
$className = is_object($instanceOrClassName) ? get_class($instanceOrClassName) : $instanceOrClassName;
|
||||
$proxyClassName = $this->generateProxy($className);
|
||||
$proxyClassName = $this->generateProxy(
|
||||
is_object($instanceOrClassName) ? get_class($instanceOrClassName) : $instanceOrClassName
|
||||
);
|
||||
|
||||
return new $proxyClassName($this->adapter);
|
||||
return $proxyClassName::staticProxyConstructor($this->adapter);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function getGenerator()
|
||||
protected function getGenerator() : ProxyGeneratorInterface
|
||||
{
|
||||
return $this->generator ?: $this->generator = new RemoteObjectGenerator();
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\FileLocator;
|
||||
|
||||
use ProxyManager\Exception\InvalidProxyDirectoryException;
|
||||
@@ -38,19 +40,21 @@ class FileLocator implements FileLocatorInterface
|
||||
*
|
||||
* @throws \ProxyManager\Exception\InvalidProxyDirectoryException
|
||||
*/
|
||||
public function __construct($proxiesDirectory)
|
||||
public function __construct(string $proxiesDirectory)
|
||||
{
|
||||
$this->proxiesDirectory = realpath($proxiesDirectory);
|
||||
$absolutePath = realpath($proxiesDirectory);
|
||||
|
||||
if (false === $this->proxiesDirectory) {
|
||||
if (false === $absolutePath) {
|
||||
throw InvalidProxyDirectoryException::proxyDirectoryNotFound($proxiesDirectory);
|
||||
}
|
||||
|
||||
$this->proxiesDirectory = $absolutePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getProxyFileName($className)
|
||||
public function getProxyFileName(string $className) : string
|
||||
{
|
||||
return $this->proxiesDirectory . DIRECTORY_SEPARATOR . str_replace('\\', '', $className) . '.php';
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\FileLocator;
|
||||
|
||||
/**
|
||||
@@ -33,5 +35,5 @@ interface FileLocatorInterface
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getProxyFileName($className);
|
||||
public function getProxyFileName(string $className) : string;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Generator;
|
||||
|
||||
use Zend\Code\Generator\ClassGenerator as ZendClassGenerator;
|
||||
@@ -31,7 +33,7 @@ class ClassGenerator extends ZendClassGenerator
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function setExtendedClass($extendedClass)
|
||||
public function setExtendedClass($extendedClass) : parent
|
||||
{
|
||||
if ($extendedClass) {
|
||||
$extendedClass = '\\' . trim($extendedClass, '\\');
|
||||
@@ -43,7 +45,7 @@ class ClassGenerator extends ZendClassGenerator
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function setImplementedInterfaces(array $interfaces)
|
||||
public function setImplementedInterfaces(array $interfaces) : parent
|
||||
{
|
||||
foreach ($interfaces as & $interface) {
|
||||
$interface = '\\' . trim($interface, '\\');
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Generator;
|
||||
|
||||
use ReflectionClass;
|
||||
@@ -33,7 +35,7 @@ class MagicMethodGenerator extends MethodGenerator
|
||||
* @param string $name
|
||||
* @param array $parameters
|
||||
*/
|
||||
public function __construct(ReflectionClass $originalClass, $name, array $parameters = array())
|
||||
public function __construct(ReflectionClass $originalClass, string $name, array $parameters = [])
|
||||
{
|
||||
parent::__construct(
|
||||
$name,
|
||||
|
||||
@@ -16,9 +16,10 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Generator;
|
||||
|
||||
use Zend\Code\Generator\DocBlockGenerator;
|
||||
use Zend\Code\Generator\MethodGenerator as ZendMethodGenerator;
|
||||
use Zend\Code\Reflection\MethodReflection;
|
||||
|
||||
@@ -31,131 +32,15 @@ use Zend\Code\Reflection\MethodReflection;
|
||||
class MethodGenerator extends ZendMethodGenerator
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $returnsReference = false;
|
||||
|
||||
/**
|
||||
* @param boolean $returnsReference
|
||||
*/
|
||||
public function setReturnsReference($returnsReference)
|
||||
{
|
||||
$this->returnsReference = (bool) $returnsReference;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
public function returnsReference()
|
||||
{
|
||||
return $this->returnsReference;
|
||||
}
|
||||
|
||||
/**
|
||||
* @override enforces generation of \ProxyManager\Generator\MethodGenerator
|
||||
*
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public static function fromReflection(MethodReflection $reflectionMethod)
|
||||
public static function fromReflection(MethodReflection $reflectionMethod) : self
|
||||
{
|
||||
/* @var $method self */
|
||||
$method = new static();
|
||||
$method = parent::fromReflection($reflectionMethod);
|
||||
|
||||
$method->setSourceContent($reflectionMethod->getContents(false));
|
||||
$method->setSourceDirty(false);
|
||||
|
||||
if ($reflectionMethod->getDocComment() != '') {
|
||||
$method->setDocBlock(DocBlockGenerator::fromReflection($reflectionMethod->getDocBlock()));
|
||||
}
|
||||
|
||||
$method->setFinal($reflectionMethod->isFinal());
|
||||
$method->setVisibility(self::extractVisibility($reflectionMethod));
|
||||
|
||||
foreach ($reflectionMethod->getParameters() as $reflectionParameter) {
|
||||
$method->setParameter(ParameterGenerator::fromReflection($reflectionParameter));
|
||||
}
|
||||
|
||||
$method->setStatic($reflectionMethod->isStatic());
|
||||
$method->setName($reflectionMethod->getName());
|
||||
$method->setBody($reflectionMethod->getBody());
|
||||
$method->setReturnsReference($reflectionMethod->returnsReference());
|
||||
$method->setInterface(false);
|
||||
|
||||
return $method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the visibility for the given method reflection
|
||||
*
|
||||
* @param MethodReflection $reflectionMethod
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function extractVisibility(MethodReflection $reflectionMethod)
|
||||
{
|
||||
if ($reflectionMethod->isPrivate()) {
|
||||
return static::VISIBILITY_PRIVATE;
|
||||
}
|
||||
|
||||
if ($reflectionMethod->isProtected()) {
|
||||
return static::VISIBILITY_PROTECTED;
|
||||
}
|
||||
|
||||
return static::VISIBILITY_PUBLIC;
|
||||
}
|
||||
|
||||
/**
|
||||
* @override fixes by-reference return value in zf2's method generator
|
||||
*
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function generate()
|
||||
{
|
||||
$output = '';
|
||||
$indent = $this->getIndentation();
|
||||
|
||||
if (null !== ($docBlock = $this->getDocBlock())) {
|
||||
$docBlock->setIndentation($indent);
|
||||
|
||||
$output .= $docBlock->generate();
|
||||
}
|
||||
|
||||
$output .= $indent . $this->generateMethodDeclaration() . self::LINE_FEED . $indent . '{' . self::LINE_FEED;
|
||||
|
||||
if ($this->body) {
|
||||
$output .= preg_replace('#^(.+?)$#m', $indent . $indent . '$1', trim($this->body))
|
||||
. self::LINE_FEED;
|
||||
}
|
||||
|
||||
$output .= $indent . '}' . self::LINE_FEED;
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function generateMethodDeclaration()
|
||||
{
|
||||
$output = $this->generateVisibility()
|
||||
. ' function '
|
||||
. (($this->returnsReference()) ? '& ' : '')
|
||||
. $this->getName() . '(';
|
||||
|
||||
$parameterOutput = array();
|
||||
|
||||
foreach ($this->getParameters() as $parameter) {
|
||||
$parameterOutput[] = $parameter->generate();
|
||||
}
|
||||
|
||||
return $output . implode(', ', $parameterOutput) . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function generateVisibility()
|
||||
{
|
||||
return $this->isAbstract() ? 'abstract ' : (($this->isFinal()) ? 'final ' : '')
|
||||
. ($this->getVisibility() . (($this->isStatic()) ? ' static' : ''));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Generator\Util;
|
||||
|
||||
use ReflectionClass;
|
||||
@@ -30,18 +32,11 @@ use Zend\Code\Generator\MethodGenerator;
|
||||
*/
|
||||
final class ClassGeneratorUtils
|
||||
{
|
||||
/**
|
||||
* @param ReflectionClass $originalClass
|
||||
* @param ClassGenerator $classGenerator
|
||||
* @param MethodGenerator $generatedMethod
|
||||
*
|
||||
* @return void|false
|
||||
*/
|
||||
public static function addMethodIfNotFinal(
|
||||
ReflectionClass $originalClass,
|
||||
ClassGenerator $classGenerator,
|
||||
MethodGenerator $generatedMethod
|
||||
) {
|
||||
) : bool {
|
||||
$methodName = $generatedMethod->getName();
|
||||
|
||||
if ($originalClass->hasMethod($methodName) && $originalClass->getMethod($methodName)->isFinal()) {
|
||||
@@ -49,5 +44,7 @@ final class ClassGeneratorUtils
|
||||
}
|
||||
|
||||
$classGenerator->addMethodFromGenerator($generatedMethod);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
41
vendor/ocramius/proxy-manager/src/ProxyManager/Generator/Util/ProxiedMethodReturnExpression.php
vendored
Normal file
41
vendor/ocramius/proxy-manager/src/ProxyManager/Generator/Util/ProxiedMethodReturnExpression.php
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Generator\Util;
|
||||
|
||||
/**
|
||||
* Utility class to generate return expressions in method, given a method signature.
|
||||
*
|
||||
* This is required since return expressions may be forbidden by the method signature (void).
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
* @license MIT
|
||||
*/
|
||||
final class ProxiedMethodReturnExpression
|
||||
{
|
||||
public static function generate(string $returnedValueExpression, ?\ReflectionMethod $originalMethod) : string
|
||||
{
|
||||
if ($originalMethod && 'void' === (string) $originalMethod->getReturnType()) {
|
||||
return $returnedValueExpression . ";\nreturn;";
|
||||
}
|
||||
|
||||
return 'return ' . $returnedValueExpression . ';';
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Generator\Util;
|
||||
|
||||
/**
|
||||
@@ -37,7 +39,7 @@ abstract class UniqueIdentifierGenerator
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getIdentifier($name)
|
||||
public static function getIdentifier(string $name) : string
|
||||
{
|
||||
return str_replace(
|
||||
'.',
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\GeneratorStrategy;
|
||||
|
||||
use Zend\Code\Generator\ClassGenerator;
|
||||
@@ -31,7 +33,7 @@ class BaseGeneratorStrategy implements GeneratorStrategyInterface
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function generate(ClassGenerator $classGenerator)
|
||||
public function generate(ClassGenerator $classGenerator) : string
|
||||
{
|
||||
return $classGenerator->generate();
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\GeneratorStrategy;
|
||||
|
||||
use Zend\Code\Generator\ClassGenerator;
|
||||
@@ -38,7 +40,9 @@ class EvaluatingGeneratorStrategy implements GeneratorStrategyInterface
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
// @codeCoverageIgnoreStart
|
||||
$this->canEval = ! ini_get('suhosin.executor.disable_eval');
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -46,21 +50,22 @@ class EvaluatingGeneratorStrategy implements GeneratorStrategyInterface
|
||||
*
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function generate(ClassGenerator $classGenerator)
|
||||
public function generate(ClassGenerator $classGenerator) : string
|
||||
{
|
||||
$code = $classGenerator->generate();
|
||||
|
||||
// @codeCoverageIgnoreStart
|
||||
if (! $this->canEval) {
|
||||
// @codeCoverageIgnoreStart
|
||||
$fileName = sys_get_temp_dir() . '/EvaluatingGeneratorStrategy.php.tmp.' . uniqid('', true);
|
||||
$fileName = tempnam(sys_get_temp_dir(), 'EvaluatingGeneratorStrategy.php.tmp.');
|
||||
|
||||
file_put_contents($fileName, "<?php\n" . $code);
|
||||
/* @noinspection PhpIncludeInspection */
|
||||
require $fileName;
|
||||
unlink($fileName);
|
||||
|
||||
return $code;
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
eval($code);
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\GeneratorStrategy;
|
||||
|
||||
use ProxyManager\Exception\FileNotWritableException;
|
||||
@@ -56,8 +58,10 @@ class FileWriterGeneratorStrategy implements GeneratorStrategyInterface
|
||||
* Write generated code to disk and return the class code
|
||||
*
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @throws FileNotWritableException
|
||||
*/
|
||||
public function generate(ClassGenerator $classGenerator)
|
||||
public function generate(ClassGenerator $classGenerator) : string
|
||||
{
|
||||
$className = trim($classGenerator->getNamespaceName(), '\\')
|
||||
. '\\' . trim($classGenerator->getName(), '\\');
|
||||
@@ -68,15 +72,11 @@ class FileWriterGeneratorStrategy implements GeneratorStrategyInterface
|
||||
|
||||
try {
|
||||
$this->writeFile("<?php\n\n" . $generatedCode, $fileName);
|
||||
} catch (FileNotWritableException $fileNotWritable) {
|
||||
|
||||
return $generatedCode;
|
||||
} finally {
|
||||
restore_error_handler();
|
||||
|
||||
throw $fileNotWritable;
|
||||
}
|
||||
|
||||
restore_error_handler();
|
||||
|
||||
return $generatedCode;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -88,13 +88,11 @@ class FileWriterGeneratorStrategy implements GeneratorStrategyInterface
|
||||
*
|
||||
* @throws FileNotWritableException
|
||||
*/
|
||||
private function writeFile($source, $location)
|
||||
private function writeFile(string $source, string $location) : void
|
||||
{
|
||||
$tmpFileName = $location . '.' . uniqid('', true);
|
||||
$tmpFileName = tempnam($location, 'temporaryProxyManagerFile');
|
||||
|
||||
if (! file_put_contents($tmpFileName, $source)) {
|
||||
throw FileNotWritableException::fromNonWritableLocation($tmpFileName);
|
||||
}
|
||||
file_put_contents($tmpFileName, $source);
|
||||
|
||||
if (! rename($tmpFileName, $location)) {
|
||||
unlink($tmpFileName);
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\GeneratorStrategy;
|
||||
|
||||
use Zend\Code\Generator\ClassGenerator;
|
||||
@@ -35,5 +37,5 @@ interface GeneratorStrategyInterface
|
||||
*
|
||||
* @return string the class body
|
||||
*/
|
||||
public function generate(ClassGenerator $classGenerator);
|
||||
public function generate(ClassGenerator $classGenerator) : string;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Inflector;
|
||||
|
||||
use ProxyManager\Inflector\Util\ParameterHasher;
|
||||
@@ -51,9 +53,9 @@ final class ClassNameInflector implements ClassNameInflectorInterface
|
||||
/**
|
||||
* @param string $proxyNamespace
|
||||
*/
|
||||
public function __construct($proxyNamespace)
|
||||
public function __construct(string $proxyNamespace)
|
||||
{
|
||||
$this->proxyNamespace = (string) $proxyNamespace;
|
||||
$this->proxyNamespace = $proxyNamespace;
|
||||
$this->proxyMarker = '\\' . static::PROXY_MARKER . '\\';
|
||||
$this->proxyMarkerLength = strlen($this->proxyMarker);
|
||||
$this->parameterHasher = new ParameterHasher();
|
||||
@@ -62,7 +64,7 @@ final class ClassNameInflector implements ClassNameInflectorInterface
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getUserClassName($className)
|
||||
public function getUserClassName(string $className) : string
|
||||
{
|
||||
$className = ltrim($className, '\\');
|
||||
|
||||
@@ -80,7 +82,7 @@ final class ClassNameInflector implements ClassNameInflectorInterface
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getProxyClassName($className, array $options = array())
|
||||
public function getProxyClassName(string $className, array $options = []) : string
|
||||
{
|
||||
return $this->proxyNamespace
|
||||
. $this->proxyMarker
|
||||
@@ -91,7 +93,7 @@ final class ClassNameInflector implements ClassNameInflectorInterface
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function isProxyClassName($className)
|
||||
public function isProxyClassName(string $className) : bool
|
||||
{
|
||||
return false !== strrpos($className, $this->proxyMarker);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Inflector;
|
||||
|
||||
/**
|
||||
@@ -38,7 +40,7 @@ interface ClassNameInflectorInterface
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getUserClassName($className);
|
||||
public function getUserClassName(string $className) : string;
|
||||
|
||||
/**
|
||||
* Retrieve the class name of the proxy for the given user-defined class name
|
||||
@@ -48,7 +50,7 @@ interface ClassNameInflectorInterface
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getProxyClassName($className, array $options = array());
|
||||
public function getProxyClassName(string $className, array $options = []) : string;
|
||||
|
||||
/**
|
||||
* Retrieve whether the provided class name is a proxy
|
||||
@@ -57,5 +59,5 @@ interface ClassNameInflectorInterface
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isProxyClassName($className);
|
||||
public function isProxyClassName(string $className) : bool;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Inflector\Util;
|
||||
|
||||
/**
|
||||
@@ -34,7 +36,7 @@ class ParameterEncoder
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function encodeParameters(array $parameters)
|
||||
public function encodeParameters(array $parameters) : string
|
||||
{
|
||||
return base64_encode(serialize($parameters));
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Inflector\Util;
|
||||
|
||||
/**
|
||||
@@ -33,7 +35,7 @@ class ParameterHasher
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function hashParameters(array $parameters)
|
||||
public function hashParameters(array $parameters) : string
|
||||
{
|
||||
return md5(serialize($parameters));
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Proxy;
|
||||
|
||||
/**
|
||||
@@ -34,7 +36,7 @@ interface AccessInterceptorInterface extends ProxyInterface
|
||||
* A prefix interceptor should have a signature like following:
|
||||
*
|
||||
* <code>
|
||||
* $prefixInterceptor = function ($proxy, $instance, $method, $params, & $returnEarly) {};
|
||||
* $interceptor = function ($proxy, $instance, string $method, array $params, & $returnEarly) {};
|
||||
* </code>
|
||||
*
|
||||
* @param string $methodName name of the intercepted method
|
||||
@@ -42,7 +44,7 @@ interface AccessInterceptorInterface extends ProxyInterface
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setMethodPrefixInterceptor($methodName, \Closure $prefixInterceptor = null);
|
||||
public function setMethodPrefixInterceptor(string $methodName, \Closure $prefixInterceptor = null);
|
||||
|
||||
/**
|
||||
* Set or remove the suffix interceptor for a method
|
||||
@@ -52,7 +54,7 @@ interface AccessInterceptorInterface extends ProxyInterface
|
||||
* A prefix interceptor should have a signature like following:
|
||||
*
|
||||
* <code>
|
||||
* $suffixInterceptor = function ($proxy, $instance, $method, $params, $returnValue, & $returnEarly) {};
|
||||
* $interceptor = function ($proxy, $instance, string $method, array $params, $returnValue, & $returnEarly) {};
|
||||
* </code>
|
||||
*
|
||||
* @param string $methodName name of the intercepted method
|
||||
@@ -60,5 +62,5 @@ interface AccessInterceptorInterface extends ProxyInterface
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setMethodSuffixInterceptor($methodName, \Closure $suffixInterceptor = null);
|
||||
public function setMethodSuffixInterceptor(string $methodName, \Closure $suffixInterceptor = null);
|
||||
}
|
||||
|
||||
31
vendor/ocramius/proxy-manager/src/ProxyManager/Proxy/AccessInterceptorValueHolderInterface.php
vendored
Normal file
31
vendor/ocramius/proxy-manager/src/ProxyManager/Proxy/AccessInterceptorValueHolderInterface.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Proxy;
|
||||
|
||||
/**
|
||||
* Aggregates AccessInterceptor and ValueHolderInterface, mostly for return type hinting
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
* @license MIT
|
||||
*/
|
||||
interface AccessInterceptorValueHolderInterface extends AccessInterceptorInterface, ValueHolderInterface
|
||||
{
|
||||
}
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Proxy\Exception;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Proxy;
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Proxy;
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Proxy;
|
||||
|
||||
/**
|
||||
@@ -34,7 +36,7 @@ interface LazyLoadingInterface extends ProxyInterface
|
||||
* An initializer should have a signature like following:
|
||||
*
|
||||
* <code>
|
||||
* $initializer = function (& $wrappedObject, $proxy, $method, $parameters, & $initializer) {};
|
||||
* $initializer = function (& $wrappedObject, $proxy, string $method, array $parameters, & $initializer) {};
|
||||
* </code>
|
||||
*
|
||||
* @param \Closure|null $initializer
|
||||
@@ -53,12 +55,12 @@ interface LazyLoadingInterface extends ProxyInterface
|
||||
*
|
||||
* @return bool true if the proxy could be initialized
|
||||
*/
|
||||
public function initializeProxy();
|
||||
public function initializeProxy() : bool;
|
||||
|
||||
/**
|
||||
* Retrieves current initialization status of the proxy
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isProxyInitialized();
|
||||
public function isProxyInitialized() : bool;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Proxy;
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Proxy;
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Proxy;
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Proxy;
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Proxy;
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\Proxy;
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,11 +16,14 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\AccessInterceptor\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MagicMethodGenerator;
|
||||
use ProxyManager\ProxyGenerator\Util\Properties;
|
||||
use ProxyManager\ProxyGenerator\Util\UnsetPropertiesGenerator;
|
||||
use ReflectionClass;
|
||||
use ReflectionProperty;
|
||||
|
||||
/**
|
||||
* Magic `__wakeup` for lazy loading value holder objects
|
||||
@@ -32,19 +35,16 @@ class MagicWakeup extends MagicMethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param ReflectionClass $originalClass
|
||||
*/
|
||||
public function __construct(ReflectionClass $originalClass)
|
||||
{
|
||||
parent::__construct($originalClass, '__wakeup');
|
||||
|
||||
/* @var $publicProperties \ReflectionProperty[] */
|
||||
$publicProperties = $originalClass->getProperties(ReflectionProperty::IS_PUBLIC);
|
||||
$unsetProperties = array();
|
||||
|
||||
foreach ($publicProperties as $publicProperty) {
|
||||
$unsetProperties[] = '$this->' . $publicProperty->getName();
|
||||
}
|
||||
|
||||
$this->setBody($unsetProperties ? 'unset(' . implode(', ', $unsetProperties) . ");" : '');
|
||||
$this->setBody(UnsetPropertiesGenerator::generateSnippet(
|
||||
Properties::fromReflectionClass($originalClass),
|
||||
'this'
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,13 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\AccessInterceptor\MethodGenerator;
|
||||
|
||||
use Closure;
|
||||
use ProxyManager\Generator\MethodGenerator;
|
||||
use ProxyManager\Generator\ParameterGenerator;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use Zend\Code\Generator\PropertyGenerator;
|
||||
|
||||
/**
|
||||
@@ -33,6 +36,10 @@ class SetMethodPrefixInterceptor extends MethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param PropertyGenerator $prefixInterceptor
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct(PropertyGenerator $prefixInterceptor)
|
||||
{
|
||||
@@ -40,11 +47,11 @@ class SetMethodPrefixInterceptor extends MethodGenerator
|
||||
|
||||
$interceptor = new ParameterGenerator('prefixInterceptor');
|
||||
|
||||
$interceptor->setType('Closure');
|
||||
$interceptor->setType(Closure::class);
|
||||
$interceptor->setDefaultValue(null);
|
||||
$this->setParameter(new ParameterGenerator('methodName'));
|
||||
$this->setParameter(new ParameterGenerator('methodName', 'string'));
|
||||
$this->setParameter($interceptor);
|
||||
$this->setDocblock('{@inheritDoc}');
|
||||
$this->setDocBlock('{@inheritDoc}');
|
||||
$this->setBody('$this->' . $prefixInterceptor->getName() . '[$methodName] = $prefixInterceptor;');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,13 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\AccessInterceptor\MethodGenerator;
|
||||
|
||||
use Closure;
|
||||
use ProxyManager\Generator\MethodGenerator;
|
||||
use ProxyManager\Generator\ParameterGenerator;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use Zend\Code\Generator\PropertyGenerator;
|
||||
|
||||
/**
|
||||
@@ -33,6 +36,10 @@ class SetMethodSuffixInterceptor extends MethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param PropertyGenerator $suffixInterceptor
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct(PropertyGenerator $suffixInterceptor)
|
||||
{
|
||||
@@ -40,11 +47,11 @@ class SetMethodSuffixInterceptor extends MethodGenerator
|
||||
|
||||
$interceptor = new ParameterGenerator('suffixInterceptor');
|
||||
|
||||
$interceptor->setType('Closure');
|
||||
$interceptor->setType(Closure::class);
|
||||
$interceptor->setDefaultValue(null);
|
||||
$this->setParameter(new ParameterGenerator('methodName'));
|
||||
$this->setParameter(new ParameterGenerator('methodName', 'string'));
|
||||
$this->setParameter($interceptor);
|
||||
$this->setDocblock('{@inheritDoc}');
|
||||
$this->setDocBlock('{@inheritDoc}');
|
||||
$this->setBody('$this->' . $suffixInterceptor->getName() . '[$methodName] = $suffixInterceptor;');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\AccessInterceptor\PropertyGenerator;
|
||||
|
||||
use ProxyManager\Generator\Util\UniqueIdentifierGenerator;
|
||||
@@ -31,13 +33,15 @@ class MethodPrefixInterceptors extends PropertyGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(UniqueIdentifierGenerator::getIdentifier('methodPrefixInterceptors'));
|
||||
|
||||
$this->setDefaultValue(array());
|
||||
$this->setDefaultValue([]);
|
||||
$this->setVisibility(self::VISIBILITY_PRIVATE);
|
||||
$this->setDocblock('@var \\Closure[] map of interceptors to be called per-method before execution');
|
||||
$this->setDocBlock('@var \\Closure[] map of interceptors to be called per-method before execution');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\AccessInterceptor\PropertyGenerator;
|
||||
|
||||
use ProxyManager\Generator\Util\UniqueIdentifierGenerator;
|
||||
@@ -31,13 +33,15 @@ class MethodSuffixInterceptors extends PropertyGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(UniqueIdentifierGenerator::getIdentifier('methodSuffixInterceptors'));
|
||||
|
||||
$this->setDefaultValue(array());
|
||||
$this->setDefaultValue([]);
|
||||
$this->setVisibility(self::VISIBILITY_PRIVATE);
|
||||
$this->setDocblock('@var \\Closure[] map of interceptors to be called per-method after execution');
|
||||
$this->setDocBlock('@var \\Closure[] map of interceptors to be called per-method after execution');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MethodGenerator;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use ProxyManager\ProxyGenerator\Util\Properties;
|
||||
use ReflectionClass;
|
||||
use Zend\Code\Generator\PropertyGenerator;
|
||||
|
||||
/**
|
||||
* The `bindProxyProperties` method implementation for access interceptor scope localizers
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
* @license MIT
|
||||
*/
|
||||
class BindProxyProperties extends MethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param ReflectionClass $originalClass
|
||||
* @param PropertyGenerator $prefixInterceptors
|
||||
* @param PropertyGenerator $suffixInterceptors
|
||||
*/
|
||||
public function __construct(
|
||||
ReflectionClass $originalClass,
|
||||
PropertyGenerator $prefixInterceptors,
|
||||
PropertyGenerator $suffixInterceptors
|
||||
) {
|
||||
parent::__construct(
|
||||
'bindProxyProperties',
|
||||
[
|
||||
new ParameterGenerator('localizedObject', $originalClass->getName()),
|
||||
new ParameterGenerator('prefixInterceptors', 'array', []),
|
||||
new ParameterGenerator('suffixInterceptors', 'array', []),
|
||||
],
|
||||
static::FLAG_PRIVATE,
|
||||
null,
|
||||
"@override constructor to setup interceptors\n\n"
|
||||
. "@param \\" . $originalClass->getName() . " \$localizedObject\n"
|
||||
. "@param \\Closure[] \$prefixInterceptors method interceptors to be used before method logic\n"
|
||||
. "@param \\Closure[] \$suffixInterceptors method interceptors to be used before method logic"
|
||||
);
|
||||
|
||||
$localizedProperties = [];
|
||||
|
||||
$properties = Properties::fromReflectionClass($originalClass);
|
||||
|
||||
foreach ($properties->getAccessibleProperties() as $property) {
|
||||
$propertyName = $property->getName();
|
||||
|
||||
$localizedProperties[] = '$this->' . $propertyName . ' = & $localizedObject->' . $propertyName . ';';
|
||||
}
|
||||
|
||||
foreach ($properties->getPrivateProperties() as $property) {
|
||||
$propertyName = $property->getName();
|
||||
|
||||
$localizedProperties[] = "\\Closure::bind(function () use (\$localizedObject) {\n "
|
||||
. '$this->' . $propertyName . ' = & $localizedObject->' . $propertyName . ";\n"
|
||||
. '}, $this, ' . var_export($property->getDeclaringClass()->getName(), true)
|
||||
. ')->__invoke();';
|
||||
}
|
||||
|
||||
$this->setBody(
|
||||
($localizedProperties ? implode("\n\n", $localizedProperties) . "\n\n" : '')
|
||||
. '$this->' . $prefixInterceptors->getName() . " = \$prefixInterceptors;\n"
|
||||
. '$this->' . $suffixInterceptors->getName() . " = \$suffixInterceptors;"
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MethodGenerator;
|
||||
@@ -37,30 +39,31 @@ class InterceptedMethod extends MethodGenerator
|
||||
* @param \Zend\Code\Generator\PropertyGenerator $suffixInterceptors
|
||||
*
|
||||
* @return self
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public static function generateMethod(
|
||||
MethodReflection $originalMethod,
|
||||
PropertyGenerator $prefixInterceptors,
|
||||
PropertyGenerator $suffixInterceptors
|
||||
) {
|
||||
) : self {
|
||||
/* @var $method self */
|
||||
$method = static::fromReflection($originalMethod);
|
||||
$forwardedParams = array();
|
||||
$forwardedParams = [];
|
||||
|
||||
foreach ($originalMethod->getParameters() as $parameter) {
|
||||
$forwardedParams[] = '$' . $parameter->getName();
|
||||
$forwardedParams[] = ($parameter->isVariadic() ? '...' : '') . '$' . $parameter->getName();
|
||||
}
|
||||
|
||||
$method->setDocblock('{@inheritDoc}');
|
||||
$method->setBody(
|
||||
InterceptorGenerator::createInterceptedMethodBody(
|
||||
'$returnValue = parent::'
|
||||
. $originalMethod->getName() . '(' . implode(', ', $forwardedParams) . ');',
|
||||
$method,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors
|
||||
)
|
||||
);
|
||||
$method->setDocBlock('{@inheritDoc}');
|
||||
$method->setBody(InterceptorGenerator::createInterceptedMethodBody(
|
||||
'$returnValue = parent::'
|
||||
. $originalMethod->getName() . '(' . implode(', ', $forwardedParams) . ');',
|
||||
$method,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors,
|
||||
$originalMethod
|
||||
));
|
||||
|
||||
return $method;
|
||||
}
|
||||
|
||||
@@ -16,10 +16,13 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MagicMethodGenerator;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator\Util\InterceptorGenerator;
|
||||
use ProxyManager\ProxyGenerator\Util\GetMethodIfExists;
|
||||
use ReflectionClass;
|
||||
use Zend\Code\Generator\PropertyGenerator;
|
||||
|
||||
@@ -33,6 +36,10 @@ class MagicClone extends MagicMethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param ReflectionClass $originalClass
|
||||
* @param PropertyGenerator $prefixInterceptors
|
||||
* @param PropertyGenerator $suffixInterceptors
|
||||
*/
|
||||
public function __construct(
|
||||
ReflectionClass $originalClass,
|
||||
@@ -41,13 +48,14 @@ class MagicClone extends MagicMethodGenerator
|
||||
) {
|
||||
parent::__construct($originalClass, '__clone');
|
||||
|
||||
$this->setBody(
|
||||
InterceptorGenerator::createInterceptedMethodBody(
|
||||
$originalClass->hasMethod('__clone') ? '$returnValue = parent::__clone();' : '$returnValue = null;',
|
||||
$this,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors
|
||||
)
|
||||
);
|
||||
$parent = GetMethodIfExists::get($originalClass, '__clone');
|
||||
|
||||
$this->setBody(InterceptorGenerator::createInterceptedMethodBody(
|
||||
$parent ? '$returnValue = parent::__clone();' : '$returnValue = null;',
|
||||
$this,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors,
|
||||
$parent
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,13 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MagicMethodGenerator;
|
||||
use ProxyManager\Generator\ParameterGenerator;
|
||||
use ProxyManager\ProxyGenerator\Util\GetMethodIfExists;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator\Util\InterceptorGenerator;
|
||||
use ProxyManager\ProxyGenerator\Util\PublicScopeSimulator;
|
||||
use ReflectionClass;
|
||||
@@ -37,21 +40,24 @@ class MagicGet extends MagicMethodGenerator
|
||||
* @param ReflectionClass $originalClass
|
||||
* @param PropertyGenerator $prefixInterceptors
|
||||
* @param PropertyGenerator $suffixInterceptors
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(
|
||||
ReflectionClass $originalClass,
|
||||
PropertyGenerator $prefixInterceptors,
|
||||
PropertyGenerator $suffixInterceptors
|
||||
) {
|
||||
parent::__construct($originalClass, '__get', array(new ParameterGenerator('name')));
|
||||
parent::__construct($originalClass, '__get', [new ParameterGenerator('name')]);
|
||||
|
||||
$override = $originalClass->hasMethod('__get');
|
||||
$parent = GetMethodIfExists::get($originalClass, '__get');
|
||||
|
||||
$this->setDocblock(($override ? "{@inheritDoc}\n" : '') . '@param string $name');
|
||||
$this->setDocBlock(($parent ? "{@inheritDoc}\n" : '') . '@param string $name');
|
||||
|
||||
if ($override) {
|
||||
$callParent = '$returnValue = & parent::__get($name);';
|
||||
} else {
|
||||
$callParent = '$returnValue = & parent::__get($name);';
|
||||
|
||||
if (! $parent) {
|
||||
$callParent = PublicScopeSimulator::getPublicAccessSimulationCode(
|
||||
PublicScopeSimulator::OPERATION_GET,
|
||||
'name',
|
||||
@@ -61,13 +67,12 @@ class MagicGet extends MagicMethodGenerator
|
||||
);
|
||||
}
|
||||
|
||||
$this->setBody(
|
||||
InterceptorGenerator::createInterceptedMethodBody(
|
||||
$callParent,
|
||||
$this,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors
|
||||
)
|
||||
);
|
||||
$this->setBody(InterceptorGenerator::createInterceptedMethodBody(
|
||||
$callParent,
|
||||
$this,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors,
|
||||
$parent
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,13 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MagicMethodGenerator;
|
||||
use ProxyManager\Generator\ParameterGenerator;
|
||||
use ProxyManager\ProxyGenerator\Util\GetMethodIfExists;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator\Util\InterceptorGenerator;
|
||||
use ProxyManager\ProxyGenerator\Util\PublicScopeSimulator;
|
||||
use ReflectionClass;
|
||||
@@ -37,21 +40,24 @@ class MagicIsset extends MagicMethodGenerator
|
||||
* @param ReflectionClass $originalClass
|
||||
* @param PropertyGenerator $prefixInterceptors
|
||||
* @param PropertyGenerator $suffixInterceptors
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(
|
||||
ReflectionClass $originalClass,
|
||||
PropertyGenerator $prefixInterceptors,
|
||||
PropertyGenerator $suffixInterceptors
|
||||
) {
|
||||
parent::__construct($originalClass, '__isset', array(new ParameterGenerator('name')));
|
||||
parent::__construct($originalClass, '__isset', [new ParameterGenerator('name')]);
|
||||
|
||||
$override = $originalClass->hasMethod('__isset');
|
||||
$parent = GetMethodIfExists::get($originalClass, '__isset');
|
||||
|
||||
$this->setDocblock(($override ? "{@inheritDoc}\n" : '') . '@param string $name');
|
||||
$this->setDocBlock(($parent ? "{@inheritDoc}\n" : '') . '@param string $name');
|
||||
|
||||
if ($override) {
|
||||
$callParent = '$returnValue = & parent::__isset($name);';
|
||||
} else {
|
||||
$callParent = '$returnValue = & parent::__isset($name);';
|
||||
|
||||
if (! $parent) {
|
||||
$callParent = PublicScopeSimulator::getPublicAccessSimulationCode(
|
||||
PublicScopeSimulator::OPERATION_ISSET,
|
||||
'name',
|
||||
@@ -61,13 +67,12 @@ class MagicIsset extends MagicMethodGenerator
|
||||
);
|
||||
}
|
||||
|
||||
$this->setBody(
|
||||
InterceptorGenerator::createInterceptedMethodBody(
|
||||
$callParent,
|
||||
$this,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors
|
||||
)
|
||||
);
|
||||
$this->setBody(InterceptorGenerator::createInterceptedMethodBody(
|
||||
$callParent,
|
||||
$this,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors,
|
||||
$parent
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,13 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MagicMethodGenerator;
|
||||
use ProxyManager\Generator\ParameterGenerator;
|
||||
use ProxyManager\ProxyGenerator\Util\GetMethodIfExists;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator\Util\InterceptorGenerator;
|
||||
use ProxyManager\ProxyGenerator\Util\PublicScopeSimulator;
|
||||
use ReflectionClass;
|
||||
@@ -37,6 +40,9 @@ class MagicSet extends MagicMethodGenerator
|
||||
* @param \ReflectionClass $originalClass
|
||||
* @param \Zend\Code\Generator\PropertyGenerator $prefixInterceptors
|
||||
* @param \Zend\Code\Generator\PropertyGenerator $suffixInterceptors
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(
|
||||
ReflectionClass $originalClass,
|
||||
@@ -46,16 +52,16 @@ class MagicSet extends MagicMethodGenerator
|
||||
parent::__construct(
|
||||
$originalClass,
|
||||
'__set',
|
||||
array(new ParameterGenerator('name'), new ParameterGenerator('value'))
|
||||
[new ParameterGenerator('name'), new ParameterGenerator('value')]
|
||||
);
|
||||
|
||||
$override = $originalClass->hasMethod('__set');
|
||||
$parent = GetMethodIfExists::get($originalClass, '__set');
|
||||
|
||||
$this->setDocblock(($override ? "{@inheritDoc}\n" : '') . '@param string $name');
|
||||
$this->setDocBlock(($parent ? "{@inheritDoc}\n" : '') . '@param string $name');
|
||||
|
||||
if ($override) {
|
||||
$callParent = '$returnValue = & parent::__set($name, $value);';
|
||||
} else {
|
||||
$callParent = '$returnValue = & parent::__set($name, $value);';
|
||||
|
||||
if (! $parent) {
|
||||
$callParent = PublicScopeSimulator::getPublicAccessSimulationCode(
|
||||
PublicScopeSimulator::OPERATION_SET,
|
||||
'name',
|
||||
@@ -65,13 +71,12 @@ class MagicSet extends MagicMethodGenerator
|
||||
);
|
||||
}
|
||||
|
||||
$this->setBody(
|
||||
InterceptorGenerator::createInterceptedMethodBody(
|
||||
$callParent,
|
||||
$this,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors
|
||||
)
|
||||
);
|
||||
$this->setBody(InterceptorGenerator::createInterceptedMethodBody(
|
||||
$callParent,
|
||||
$this,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors,
|
||||
$parent
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,13 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MagicMethodGenerator;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator\Util\InterceptorGenerator;
|
||||
use ProxyManager\ProxyGenerator\Util\GetMethodIfExists;
|
||||
use ReflectionClass;
|
||||
use Zend\Code\Generator\PropertyGenerator;
|
||||
|
||||
@@ -33,6 +36,10 @@ class MagicSleep extends MagicMethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param ReflectionClass $originalClass
|
||||
* @param PropertyGenerator $prefixInterceptors
|
||||
* @param PropertyGenerator $suffixInterceptors
|
||||
*/
|
||||
public function __construct(
|
||||
ReflectionClass $originalClass,
|
||||
@@ -41,17 +48,16 @@ class MagicSleep extends MagicMethodGenerator
|
||||
) {
|
||||
parent::__construct($originalClass, '__sleep');
|
||||
|
||||
$callParent = $originalClass->hasMethod('__sleep')
|
||||
? '$returnValue = & parent::__sleep();'
|
||||
: '$returnValue = array_keys((array) $this);';
|
||||
$parent = GetMethodIfExists::get($originalClass, '__sleep');
|
||||
|
||||
$this->setBody(
|
||||
InterceptorGenerator::createInterceptedMethodBody(
|
||||
$callParent,
|
||||
$this,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors
|
||||
)
|
||||
);
|
||||
$callParent = $parent ? '$returnValue = & parent::__sleep();' : '$returnValue = array_keys((array) $this);';
|
||||
|
||||
$this->setBody(InterceptorGenerator::createInterceptedMethodBody(
|
||||
$callParent,
|
||||
$this,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors,
|
||||
$parent
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,13 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MagicMethodGenerator;
|
||||
use ProxyManager\Generator\ParameterGenerator;
|
||||
use ProxyManager\ProxyGenerator\Util\GetMethodIfExists;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator\Util\InterceptorGenerator;
|
||||
use ProxyManager\ProxyGenerator\Util\PublicScopeSimulator;
|
||||
use ReflectionClass;
|
||||
@@ -37,21 +40,24 @@ class MagicUnset extends MagicMethodGenerator
|
||||
* @param ReflectionClass $originalClass
|
||||
* @param PropertyGenerator $prefixInterceptors
|
||||
* @param PropertyGenerator $suffixInterceptors
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(
|
||||
ReflectionClass $originalClass,
|
||||
PropertyGenerator $prefixInterceptors,
|
||||
PropertyGenerator $suffixInterceptors
|
||||
) {
|
||||
parent::__construct($originalClass, '__unset', array(new ParameterGenerator('name')));
|
||||
parent::__construct($originalClass, '__unset', [new ParameterGenerator('name')]);
|
||||
|
||||
$override = $originalClass->hasMethod('__unset');
|
||||
$parent = GetMethodIfExists::get($originalClass, '__unset');
|
||||
|
||||
$this->setDocblock(($override ? "{@inheritDoc}\n" : '') . '@param string $name');
|
||||
$this->setDocBlock(($parent ? "{@inheritDoc}\n" : '') . '@param string $name');
|
||||
|
||||
if ($override) {
|
||||
$callParent = '$returnValue = & parent::__unset($name);';
|
||||
} else {
|
||||
$callParent = '$returnValue = & parent::__unset($name);';
|
||||
|
||||
if (! $parent) {
|
||||
$callParent = PublicScopeSimulator::getPublicAccessSimulationCode(
|
||||
PublicScopeSimulator::OPERATION_UNSET,
|
||||
'name',
|
||||
@@ -61,13 +67,12 @@ class MagicUnset extends MagicMethodGenerator
|
||||
);
|
||||
}
|
||||
|
||||
$this->setBody(
|
||||
InterceptorGenerator::createInterceptedMethodBody(
|
||||
$callParent,
|
||||
$this,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors
|
||||
)
|
||||
);
|
||||
$this->setBody(InterceptorGenerator::createInterceptedMethodBody(
|
||||
$callParent,
|
||||
$this,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors,
|
||||
$parent
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MethodGenerator;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use ReflectionClass;
|
||||
|
||||
/**
|
||||
* The `staticProxyConstructor` implementation for an access interceptor scope localizer proxy
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
* @license MIT
|
||||
*/
|
||||
class StaticProxyConstructor extends MethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param ReflectionClass $originalClass
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct(ReflectionClass $originalClass)
|
||||
{
|
||||
parent::__construct('staticProxyConstructor', [], static::FLAG_PUBLIC | static::FLAG_STATIC);
|
||||
|
||||
$localizedObject = new ParameterGenerator('localizedObject');
|
||||
$prefix = new ParameterGenerator('prefixInterceptors');
|
||||
$suffix = new ParameterGenerator('suffixInterceptors');
|
||||
|
||||
$localizedObject->setType($originalClass->getName());
|
||||
$prefix->setDefaultValue([]);
|
||||
$suffix->setDefaultValue([]);
|
||||
$prefix->setType('array');
|
||||
$suffix->setType('array');
|
||||
|
||||
$this->setParameter($localizedObject);
|
||||
$this->setParameter($prefix);
|
||||
$this->setParameter($suffix);
|
||||
$this->setReturnType($originalClass->getName());
|
||||
|
||||
$this->setDocBlock(
|
||||
"Constructor to setup interceptors\n\n"
|
||||
. "@param \\" . $originalClass->getName() . " \$localizedObject\n"
|
||||
. "@param \\Closure[] \$prefixInterceptors method interceptors to be used before method logic\n"
|
||||
. "@param \\Closure[] \$suffixInterceptors method interceptors to be used before method logic\n\n"
|
||||
. '@return self'
|
||||
);
|
||||
$this->setBody(
|
||||
'static $reflection;' . "\n\n"
|
||||
. '$reflection = $reflection ?: $reflection = new \ReflectionClass(__CLASS__);' . "\n"
|
||||
. '$instance = $reflection->newInstanceWithoutConstructor();' . "\n\n"
|
||||
. '$instance->bindProxyProperties($localizedObject, $prefixInterceptors, $suffixInterceptors);' . "\n\n"
|
||||
. 'return $instance;'
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -16,9 +16,12 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator\Util;
|
||||
|
||||
use ProxyManager\Generator\MethodGenerator;
|
||||
use ProxyManager\Generator\Util\ProxiedMethodReturnExpression;
|
||||
use Zend\Code\Generator\PropertyGenerator;
|
||||
|
||||
/**
|
||||
@@ -27,8 +30,7 @@ use Zend\Code\Generator\PropertyGenerator;
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
* @license MIT
|
||||
*
|
||||
* @internal - this class is just here as a small utility for this component,
|
||||
* don't use it in your own code
|
||||
* @private - this class is just here as a small utility for this component, don't use it in your own code
|
||||
*/
|
||||
class InterceptorGenerator
|
||||
{
|
||||
@@ -39,19 +41,21 @@ class InterceptorGenerator
|
||||
* @param \ProxyManager\Generator\MethodGenerator $method
|
||||
* @param \Zend\Code\Generator\PropertyGenerator $prefixInterceptors
|
||||
* @param \Zend\Code\Generator\PropertyGenerator $suffixInterceptors
|
||||
* @param \ReflectionMethod|null $originalMethod
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function createInterceptedMethodBody(
|
||||
$methodBody,
|
||||
string $methodBody,
|
||||
MethodGenerator $method,
|
||||
PropertyGenerator $prefixInterceptors,
|
||||
PropertyGenerator $suffixInterceptors
|
||||
) {
|
||||
$name = var_export($method->getName(), true);
|
||||
$prefixInterceptors = $prefixInterceptors->getName();
|
||||
$suffixInterceptors = $suffixInterceptors->getName();
|
||||
$params = array();
|
||||
PropertyGenerator $suffixInterceptors,
|
||||
?\ReflectionMethod $originalMethod
|
||||
) : string {
|
||||
$name = var_export($method->getName(), true);
|
||||
$prefixInterceptorsName = $prefixInterceptors->getName();
|
||||
$suffixInterceptorsName = $suffixInterceptors->getName();
|
||||
$params = [];
|
||||
|
||||
foreach ($method->getParameters() as $parameter) {
|
||||
$parameterName = $parameter->getName();
|
||||
@@ -60,23 +64,23 @@ class InterceptorGenerator
|
||||
|
||||
$paramsString = 'array(' . implode(', ', $params) . ')';
|
||||
|
||||
return "if (isset(\$this->$prefixInterceptors" . "[$name])) {\n"
|
||||
return "if (isset(\$this->$prefixInterceptorsName" . "[$name])) {\n"
|
||||
. " \$returnEarly = false;\n"
|
||||
. " \$prefixReturnValue = \$this->$prefixInterceptors" . "[$name]->__invoke("
|
||||
. " \$prefixReturnValue = \$this->$prefixInterceptorsName" . "[$name]->__invoke("
|
||||
. "\$this, \$this, $name, $paramsString, \$returnEarly);\n\n"
|
||||
. " if (\$returnEarly) {\n"
|
||||
. " return \$prefixReturnValue;\n"
|
||||
. ' ' . ProxiedMethodReturnExpression::generate('$prefixReturnValue', $originalMethod) . "\n"
|
||||
. " }\n"
|
||||
. "}\n\n"
|
||||
. $methodBody . "\n\n"
|
||||
. "if (isset(\$this->$suffixInterceptors" . "[$name])) {\n"
|
||||
. "if (isset(\$this->$suffixInterceptorsName" . "[$name])) {\n"
|
||||
. " \$returnEarly = false;\n"
|
||||
. " \$suffixReturnValue = \$this->$suffixInterceptors" . "[$name]->__invoke("
|
||||
. " \$suffixReturnValue = \$this->$suffixInterceptorsName" . "[$name]->__invoke("
|
||||
. "\$this, \$this, $name, $paramsString, \$returnValue, \$returnEarly);\n\n"
|
||||
. " if (\$returnEarly) {\n"
|
||||
. " return \$suffixReturnValue;\n"
|
||||
. ' ' . ProxiedMethodReturnExpression::generate('$suffixReturnValue', $originalMethod) . "\n"
|
||||
. " }\n"
|
||||
. "}\n\n"
|
||||
. "return \$returnValue;";
|
||||
. ProxiedMethodReturnExpression::generate('$returnValue', $originalMethod);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,13 +16,18 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator;
|
||||
|
||||
use ProxyManager\Exception\InvalidProxiedClassException;
|
||||
use ProxyManager\Generator\Util\ClassGeneratorUtils;
|
||||
use ProxyManager\Proxy\AccessInterceptorInterface;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptor\MethodGenerator\SetMethodPrefixInterceptor;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptor\MethodGenerator\SetMethodSuffixInterceptor;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptor\PropertyGenerator\MethodPrefixInterceptors;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator\Constructor;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptor\PropertyGenerator\MethodSuffixInterceptors;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator\BindProxyProperties;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator\InterceptedMethod;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator\MagicClone;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator\MagicGet;
|
||||
@@ -30,6 +35,7 @@ use ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator\
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator\MagicSet;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator\MagicSleep;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator\MagicUnset;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator\StaticProxyConstructor;
|
||||
use ProxyManager\ProxyGenerator\Assertion\CanProxyAssertion;
|
||||
use ProxyManager\ProxyGenerator\Util\ProxiedMethodsFilter;
|
||||
use ReflectionClass;
|
||||
@@ -51,15 +57,19 @@ class AccessInterceptorScopeLocalizerGenerator implements ProxyGeneratorInterfac
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
* @throws InvalidProxiedClassException
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function generate(ReflectionClass $originalClass, ClassGenerator $classGenerator)
|
||||
{
|
||||
CanProxyAssertion::assertClassCanBeProxied($originalClass, false);
|
||||
|
||||
$classGenerator->setExtendedClass($originalClass->getName());
|
||||
$classGenerator->setImplementedInterfaces(array('ProxyManager\\Proxy\\AccessInterceptorInterface'));
|
||||
$classGenerator->setImplementedInterfaces([AccessInterceptorInterface::class]);
|
||||
$classGenerator->addPropertyFromGenerator($prefixInterceptors = new MethodPrefixInterceptors());
|
||||
$classGenerator->addPropertyFromGenerator($suffixInterceptors = new MethodPrefixInterceptors());
|
||||
$classGenerator->addPropertyFromGenerator($suffixInterceptors = new MethodSuffixInterceptors());
|
||||
|
||||
array_map(
|
||||
function (MethodGenerator $generatedMethod) use ($originalClass, $classGenerator) {
|
||||
@@ -67,20 +77,15 @@ class AccessInterceptorScopeLocalizerGenerator implements ProxyGeneratorInterfac
|
||||
},
|
||||
array_merge(
|
||||
array_map(
|
||||
function (ReflectionMethod $method) use ($prefixInterceptors, $suffixInterceptors) {
|
||||
return InterceptedMethod::generateMethod(
|
||||
new MethodReflection($method->getDeclaringClass()->getName(), $method->getName()),
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors
|
||||
);
|
||||
},
|
||||
$this->buildMethodInterceptor($prefixInterceptors, $suffixInterceptors),
|
||||
ProxiedMethodsFilter::getProxiedMethods(
|
||||
$originalClass,
|
||||
array('__get', '__set', '__isset', '__unset', '__clone', '__sleep')
|
||||
['__get', '__set', '__isset', '__unset', '__clone', '__sleep']
|
||||
)
|
||||
),
|
||||
array(
|
||||
new Constructor($originalClass, $prefixInterceptors, $suffixInterceptors),
|
||||
[
|
||||
new StaticProxyConstructor($originalClass),
|
||||
new BindProxyProperties($originalClass, $prefixInterceptors, $suffixInterceptors),
|
||||
new SetMethodPrefixInterceptor($prefixInterceptors),
|
||||
new SetMethodSuffixInterceptor($suffixInterceptors),
|
||||
new MagicGet($originalClass, $prefixInterceptors, $suffixInterceptors),
|
||||
@@ -89,8 +94,21 @@ class AccessInterceptorScopeLocalizerGenerator implements ProxyGeneratorInterfac
|
||||
new MagicUnset($originalClass, $prefixInterceptors, $suffixInterceptors),
|
||||
new MagicSleep($originalClass, $prefixInterceptors, $suffixInterceptors),
|
||||
new MagicClone($originalClass, $prefixInterceptors, $suffixInterceptors),
|
||||
)
|
||||
]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private function buildMethodInterceptor(
|
||||
MethodPrefixInterceptors $prefixInterceptors,
|
||||
MethodSuffixInterceptors $suffixInterceptors
|
||||
) : callable {
|
||||
return function (ReflectionMethod $method) use ($prefixInterceptors, $suffixInterceptors) : InterceptedMethod {
|
||||
return InterceptedMethod::generateMethod(
|
||||
new MethodReflection($method->getDeclaringClass()->getName(), $method->getName()),
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors
|
||||
);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\AccessInterceptorValueHolder\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MethodGenerator;
|
||||
@@ -38,32 +40,33 @@ class InterceptedMethod extends MethodGenerator
|
||||
* @param \Zend\Code\Generator\PropertyGenerator $suffixInterceptors
|
||||
*
|
||||
* @return self
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public static function generateMethod(
|
||||
MethodReflection $originalMethod,
|
||||
PropertyGenerator $valueHolderProperty,
|
||||
PropertyGenerator $prefixInterceptors,
|
||||
PropertyGenerator $suffixInterceptors
|
||||
) {
|
||||
) : self {
|
||||
/* @var $method self */
|
||||
$method = static::fromReflection($originalMethod);
|
||||
$forwardedParams = array();
|
||||
$forwardedParams = [];
|
||||
|
||||
foreach ($originalMethod->getParameters() as $parameter) {
|
||||
$forwardedParams[] = '$' . $parameter->getName();
|
||||
$forwardedParams[] = ($parameter->isVariadic() ? '...' : '') . '$' . $parameter->getName();
|
||||
}
|
||||
|
||||
$method->setDocblock('{@inheritDoc}');
|
||||
$method->setBody(
|
||||
InterceptorGenerator::createInterceptedMethodBody(
|
||||
'$returnValue = $this->' . $valueHolderProperty->getName() . '->'
|
||||
. $originalMethod->getName() . '(' . implode(', ', $forwardedParams) . ');',
|
||||
$method,
|
||||
$valueHolderProperty,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors
|
||||
)
|
||||
);
|
||||
$method->setDocBlock('{@inheritDoc}');
|
||||
$method->setBody(InterceptorGenerator::createInterceptedMethodBody(
|
||||
'$returnValue = $this->' . $valueHolderProperty->getName() . '->'
|
||||
. $originalMethod->getName() . '(' . implode(', ', $forwardedParams) . ');',
|
||||
$method,
|
||||
$valueHolderProperty,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors,
|
||||
$originalMethod
|
||||
));
|
||||
|
||||
return $method;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\AccessInterceptorValueHolder\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MagicMethodGenerator;
|
||||
@@ -32,6 +34,11 @@ class MagicClone extends MagicMethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param ReflectionClass $originalClass
|
||||
* @param PropertyGenerator $valueHolderProperty
|
||||
* @param PropertyGenerator $prefixInterceptors
|
||||
* @param PropertyGenerator $suffixInterceptors
|
||||
*/
|
||||
public function __construct(
|
||||
ReflectionClass $originalClass,
|
||||
@@ -52,7 +59,7 @@ class MagicClone extends MagicMethodGenerator
|
||||
. "}\n\n"
|
||||
. "foreach (\$this->$suffix as \$key => \$value) {\n"
|
||||
. " \$this->$suffix" . "[\$key] = clone \$value;\n"
|
||||
. "}"
|
||||
. '}'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,13 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\AccessInterceptorValueHolder\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MagicMethodGenerator;
|
||||
use ProxyManager\Generator\ParameterGenerator;
|
||||
use ProxyManager\ProxyGenerator\Util\GetMethodIfExists;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorValueHolder\MethodGenerator\Util\InterceptorGenerator;
|
||||
use ProxyManager\ProxyGenerator\PropertyGenerator\PublicPropertiesMap;
|
||||
use ProxyManager\ProxyGenerator\Util\PublicScopeSimulator;
|
||||
@@ -36,6 +39,15 @@ class MagicGet extends MagicMethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param ReflectionClass $originalClass
|
||||
* @param PropertyGenerator $valueHolder
|
||||
* @param PropertyGenerator $prefixInterceptors
|
||||
* @param PropertyGenerator $suffixInterceptors
|
||||
* @param PublicPropertiesMap $publicProperties
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(
|
||||
ReflectionClass $originalClass,
|
||||
@@ -44,12 +56,12 @@ class MagicGet extends MagicMethodGenerator
|
||||
PropertyGenerator $suffixInterceptors,
|
||||
PublicPropertiesMap $publicProperties
|
||||
) {
|
||||
parent::__construct($originalClass, '__get', array(new ParameterGenerator('name')));
|
||||
parent::__construct($originalClass, '__get', [new ParameterGenerator('name')]);
|
||||
|
||||
$override = $originalClass->hasMethod('__get');
|
||||
$parent = GetMethodIfExists::get($originalClass, '__get');
|
||||
$valueHolderName = $valueHolder->getName();
|
||||
|
||||
$this->setDocblock(($override ? "{@inheritDoc}\n" : '') . '@param string $name');
|
||||
$this->setDocBlock(($parent ? "{@inheritDoc}\n" : '') . '@param string $name');
|
||||
|
||||
$callParent = PublicScopeSimulator::getPublicAccessSimulationCode(
|
||||
PublicScopeSimulator::OPERATION_GET,
|
||||
@@ -65,14 +77,13 @@ class MagicGet extends MagicMethodGenerator
|
||||
. "\n} else {\n $callParent\n}\n\n";
|
||||
}
|
||||
|
||||
$this->setBody(
|
||||
InterceptorGenerator::createInterceptedMethodBody(
|
||||
$callParent,
|
||||
$this,
|
||||
$valueHolder,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors
|
||||
)
|
||||
);
|
||||
$this->setBody(InterceptorGenerator::createInterceptedMethodBody(
|
||||
$callParent,
|
||||
$this,
|
||||
$valueHolder,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors,
|
||||
$parent
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,13 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\AccessInterceptorValueHolder\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MagicMethodGenerator;
|
||||
use ProxyManager\Generator\ParameterGenerator;
|
||||
use ProxyManager\ProxyGenerator\Util\GetMethodIfExists;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorValueHolder\MethodGenerator\Util\InterceptorGenerator;
|
||||
use ProxyManager\ProxyGenerator\PropertyGenerator\PublicPropertiesMap;
|
||||
use ProxyManager\ProxyGenerator\Util\PublicScopeSimulator;
|
||||
@@ -36,6 +39,14 @@ class MagicIsset extends MagicMethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
* @param ReflectionClass $originalClass
|
||||
* @param PropertyGenerator $valueHolder
|
||||
* @param PropertyGenerator $prefixInterceptors
|
||||
* @param PropertyGenerator $suffixInterceptors
|
||||
* @param PublicPropertiesMap $publicProperties
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(
|
||||
ReflectionClass $originalClass,
|
||||
@@ -44,12 +55,12 @@ class MagicIsset extends MagicMethodGenerator
|
||||
PropertyGenerator $suffixInterceptors,
|
||||
PublicPropertiesMap $publicProperties
|
||||
) {
|
||||
parent::__construct($originalClass, '__isset', array(new ParameterGenerator('name')));
|
||||
parent::__construct($originalClass, '__isset', [new ParameterGenerator('name')]);
|
||||
|
||||
$override = $originalClass->hasMethod('__isset');
|
||||
$parent = GetMethodIfExists::get($originalClass, '__isset');
|
||||
$valueHolderName = $valueHolder->getName();
|
||||
|
||||
$this->setDocblock(($override ? "{@inheritDoc}\n" : '') . '@param string $name');
|
||||
$this->setDocBlock(($parent ? "{@inheritDoc}\n" : '') . '@param string $name');
|
||||
|
||||
$callParent = PublicScopeSimulator::getPublicAccessSimulationCode(
|
||||
PublicScopeSimulator::OPERATION_ISSET,
|
||||
@@ -65,14 +76,13 @@ class MagicIsset extends MagicMethodGenerator
|
||||
. "\n} else {\n $callParent\n}\n\n";
|
||||
}
|
||||
|
||||
$this->setBody(
|
||||
InterceptorGenerator::createInterceptedMethodBody(
|
||||
$callParent,
|
||||
$this,
|
||||
$valueHolder,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors
|
||||
)
|
||||
);
|
||||
$this->setBody(InterceptorGenerator::createInterceptedMethodBody(
|
||||
$callParent,
|
||||
$this,
|
||||
$valueHolder,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors,
|
||||
$parent
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,13 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\AccessInterceptorValueHolder\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MagicMethodGenerator;
|
||||
use ProxyManager\Generator\ParameterGenerator;
|
||||
use ProxyManager\ProxyGenerator\Util\GetMethodIfExists;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorValueHolder\MethodGenerator\Util\InterceptorGenerator;
|
||||
use ProxyManager\ProxyGenerator\PropertyGenerator\PublicPropertiesMap;
|
||||
use ProxyManager\ProxyGenerator\Util\PublicScopeSimulator;
|
||||
@@ -36,6 +39,14 @@ class MagicSet extends MagicMethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
* @param ReflectionClass $originalClass
|
||||
* @param PropertyGenerator $valueHolder
|
||||
* @param PropertyGenerator $prefixInterceptors
|
||||
* @param PropertyGenerator $suffixInterceptors
|
||||
* @param PublicPropertiesMap $publicProperties
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(
|
||||
ReflectionClass $originalClass,
|
||||
@@ -47,13 +58,13 @@ class MagicSet extends MagicMethodGenerator
|
||||
parent::__construct(
|
||||
$originalClass,
|
||||
'__set',
|
||||
array(new ParameterGenerator('name'), new ParameterGenerator('value'))
|
||||
[new ParameterGenerator('name'), new ParameterGenerator('value')]
|
||||
);
|
||||
|
||||
$override = $originalClass->hasMethod('__set');
|
||||
$parent = GetMethodIfExists::get($originalClass, '__set');
|
||||
$valueHolderName = $valueHolder->getName();
|
||||
|
||||
$this->setDocblock(($override ? "{@inheritDoc}\n" : '') . '@param string $name');
|
||||
$this->setDocBlock(($parent ? "{@inheritDoc}\n" : '') . '@param string $name');
|
||||
|
||||
$callParent = PublicScopeSimulator::getPublicAccessSimulationCode(
|
||||
PublicScopeSimulator::OPERATION_SET,
|
||||
@@ -69,14 +80,13 @@ class MagicSet extends MagicMethodGenerator
|
||||
. "\n} else {\n $callParent\n}\n\n";
|
||||
}
|
||||
|
||||
$this->setBody(
|
||||
InterceptorGenerator::createInterceptedMethodBody(
|
||||
$callParent,
|
||||
$this,
|
||||
$valueHolder,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors
|
||||
)
|
||||
);
|
||||
$this->setBody(InterceptorGenerator::createInterceptedMethodBody(
|
||||
$callParent,
|
||||
$this,
|
||||
$valueHolder,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors,
|
||||
$parent
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,13 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\AccessInterceptorValueHolder\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MagicMethodGenerator;
|
||||
use ProxyManager\Generator\ParameterGenerator;
|
||||
use ProxyManager\ProxyGenerator\Util\GetMethodIfExists;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorValueHolder\MethodGenerator\Util\InterceptorGenerator;
|
||||
use ProxyManager\ProxyGenerator\PropertyGenerator\PublicPropertiesMap;
|
||||
use ProxyManager\ProxyGenerator\Util\PublicScopeSimulator;
|
||||
@@ -36,6 +39,14 @@ class MagicUnset extends MagicMethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
* @param ReflectionClass $originalClass
|
||||
* @param PropertyGenerator $valueHolder
|
||||
* @param PropertyGenerator $prefixInterceptors
|
||||
* @param PropertyGenerator $suffixInterceptors
|
||||
* @param PublicPropertiesMap $publicProperties
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(
|
||||
ReflectionClass $originalClass,
|
||||
@@ -44,12 +55,12 @@ class MagicUnset extends MagicMethodGenerator
|
||||
PropertyGenerator $suffixInterceptors,
|
||||
PublicPropertiesMap $publicProperties
|
||||
) {
|
||||
parent::__construct($originalClass, '__unset', array(new ParameterGenerator('name')));
|
||||
parent::__construct($originalClass, '__unset', [new ParameterGenerator('name')]);
|
||||
|
||||
$override = $originalClass->hasMethod('__unset');
|
||||
$parent = GetMethodIfExists::get($originalClass, '__unset');
|
||||
$valueHolderName = $valueHolder->getName();
|
||||
|
||||
$this->setDocblock(($override ? "{@inheritDoc}\n" : '') . '@param string $name');
|
||||
$this->setDocBlock(($parent ? "{@inheritDoc}\n" : '') . '@param string $name');
|
||||
|
||||
$callParent = PublicScopeSimulator::getPublicAccessSimulationCode(
|
||||
PublicScopeSimulator::OPERATION_UNSET,
|
||||
@@ -67,14 +78,13 @@ class MagicUnset extends MagicMethodGenerator
|
||||
|
||||
$callParent .= '$returnValue = false;';
|
||||
|
||||
$this->setBody(
|
||||
InterceptorGenerator::createInterceptedMethodBody(
|
||||
$callParent,
|
||||
$this,
|
||||
$valueHolder,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors
|
||||
)
|
||||
);
|
||||
$this->setBody(InterceptorGenerator::createInterceptedMethodBody(
|
||||
$callParent,
|
||||
$this,
|
||||
$valueHolder,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors,
|
||||
$parent
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\AccessInterceptorValueHolder\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MethodGenerator;
|
||||
use ProxyManager\ProxyGenerator\Util\Properties;
|
||||
use ProxyManager\ProxyGenerator\Util\UnsetPropertiesGenerator;
|
||||
use ReflectionClass;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use Zend\Code\Generator\PropertyGenerator;
|
||||
|
||||
/**
|
||||
* The `staticProxyConstructor` implementation for access interceptor value holders
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
* @license MIT
|
||||
*/
|
||||
class StaticProxyConstructor extends MethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param ReflectionClass $originalClass
|
||||
* @param PropertyGenerator $valueHolder
|
||||
* @param PropertyGenerator $prefixInterceptors
|
||||
* @param PropertyGenerator $suffixInterceptors
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct(
|
||||
ReflectionClass $originalClass,
|
||||
PropertyGenerator $valueHolder,
|
||||
PropertyGenerator $prefixInterceptors,
|
||||
PropertyGenerator $suffixInterceptors
|
||||
) {
|
||||
parent::__construct('staticProxyConstructor', [], static::FLAG_PUBLIC | static::FLAG_STATIC);
|
||||
|
||||
$prefix = new ParameterGenerator('prefixInterceptors');
|
||||
$suffix = new ParameterGenerator('suffixInterceptors');
|
||||
|
||||
$prefix->setDefaultValue([]);
|
||||
$suffix->setDefaultValue([]);
|
||||
$prefix->setType('array');
|
||||
$suffix->setType('array');
|
||||
|
||||
$this->setParameter(new ParameterGenerator('wrappedObject'));
|
||||
$this->setParameter($prefix);
|
||||
$this->setParameter($suffix);
|
||||
$this->setReturnType($originalClass->getName());
|
||||
|
||||
$this->setDocBlock(
|
||||
"Constructor to setup interceptors\n\n"
|
||||
. "@param \\" . $originalClass->getName() . " \$wrappedObject\n"
|
||||
. "@param \\Closure[] \$prefixInterceptors method interceptors to be used before method logic\n"
|
||||
. "@param \\Closure[] \$suffixInterceptors method interceptors to be used before method logic\n\n"
|
||||
. '@return self'
|
||||
);
|
||||
|
||||
$this->setBody(
|
||||
'static $reflection;' . "\n\n"
|
||||
. '$reflection = $reflection ?: $reflection = new \ReflectionClass(__CLASS__);' . "\n"
|
||||
. '$instance = (new \ReflectionClass(get_class()))->newInstanceWithoutConstructor();' . "\n\n"
|
||||
. UnsetPropertiesGenerator::generateSnippet(Properties::fromReflectionClass($originalClass), 'instance')
|
||||
. '$instance->' . $valueHolder->getName() . " = \$wrappedObject;\n"
|
||||
. '$instance->' . $prefixInterceptors->getName() . " = \$prefixInterceptors;\n"
|
||||
. '$instance->' . $suffixInterceptors->getName() . " = \$suffixInterceptors;\n\n"
|
||||
. 'return $instance;'
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -16,9 +16,12 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\AccessInterceptorValueHolder\MethodGenerator\Util;
|
||||
|
||||
use ProxyManager\Generator\MethodGenerator;
|
||||
use ProxyManager\Generator\Util\ProxiedMethodReturnExpression;
|
||||
use Zend\Code\Generator\PropertyGenerator;
|
||||
|
||||
/**
|
||||
@@ -27,8 +30,7 @@ use Zend\Code\Generator\PropertyGenerator;
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
* @license MIT
|
||||
*
|
||||
* @internal - this class is just here as a small utility for this component,
|
||||
* don't use it in your own code
|
||||
* @private - this class is just here as a small utility for this component, don't use it in your own code
|
||||
*/
|
||||
class InterceptorGenerator
|
||||
{
|
||||
@@ -40,21 +42,23 @@ class InterceptorGenerator
|
||||
* @param \Zend\Code\Generator\PropertyGenerator $valueHolder
|
||||
* @param \Zend\Code\Generator\PropertyGenerator $prefixInterceptors
|
||||
* @param \Zend\Code\Generator\PropertyGenerator $suffixInterceptors
|
||||
* @param \ReflectionMethod|null $originalMethod
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function createInterceptedMethodBody(
|
||||
$methodBody,
|
||||
string $methodBody,
|
||||
MethodGenerator $method,
|
||||
PropertyGenerator $valueHolder,
|
||||
PropertyGenerator $prefixInterceptors,
|
||||
PropertyGenerator $suffixInterceptors
|
||||
) {
|
||||
$name = var_export($method->getName(), true);
|
||||
$valueHolder = $valueHolder->getName();
|
||||
$prefixInterceptors = $prefixInterceptors->getName();
|
||||
$suffixInterceptors = $suffixInterceptors->getName();
|
||||
$params = array();
|
||||
PropertyGenerator $suffixInterceptors,
|
||||
?\ReflectionMethod $originalMethod
|
||||
) : string {
|
||||
$name = var_export($method->getName(), true);
|
||||
$valueHolderName = $valueHolder->getName();
|
||||
$prefixInterceptorsName = $prefixInterceptors->getName();
|
||||
$suffixInterceptorsName = $suffixInterceptors->getName();
|
||||
$params = [];
|
||||
|
||||
foreach ($method->getParameters() as $parameter) {
|
||||
$parameterName = $parameter->getName();
|
||||
@@ -63,23 +67,23 @@ class InterceptorGenerator
|
||||
|
||||
$paramsString = 'array(' . implode(', ', $params) . ')';
|
||||
|
||||
return "if (isset(\$this->$prefixInterceptors" . "[$name])) {\n"
|
||||
return "if (isset(\$this->$prefixInterceptorsName" . "[$name])) {\n"
|
||||
. " \$returnEarly = false;\n"
|
||||
. " \$prefixReturnValue = \$this->$prefixInterceptors" . "[$name]->__invoke("
|
||||
. "\$this, \$this->$valueHolder, $name, $paramsString, \$returnEarly);\n\n"
|
||||
. " \$prefixReturnValue = \$this->$prefixInterceptorsName" . "[$name]->__invoke("
|
||||
. "\$this, \$this->$valueHolderName, $name, $paramsString, \$returnEarly);\n\n"
|
||||
. " if (\$returnEarly) {\n"
|
||||
. " return \$prefixReturnValue;\n"
|
||||
. ' ' . ProxiedMethodReturnExpression::generate('$prefixReturnValue', $originalMethod) . "\n"
|
||||
. " }\n"
|
||||
. "}\n\n"
|
||||
. $methodBody . "\n\n"
|
||||
. "if (isset(\$this->$suffixInterceptors" . "[$name])) {\n"
|
||||
. "if (isset(\$this->$suffixInterceptorsName" . "[$name])) {\n"
|
||||
. " \$returnEarly = false;\n"
|
||||
. " \$suffixReturnValue = \$this->$suffixInterceptors" . "[$name]->__invoke("
|
||||
. "\$this, \$this->$valueHolder, $name, $paramsString, \$returnValue, \$returnEarly);\n\n"
|
||||
. " \$suffixReturnValue = \$this->$suffixInterceptorsName" . "[$name]->__invoke("
|
||||
. "\$this, \$this->$valueHolderName, $name, $paramsString, \$returnValue, \$returnEarly);\n\n"
|
||||
. " if (\$returnEarly) {\n"
|
||||
. " return \$suffixReturnValue;\n"
|
||||
. ' ' . ProxiedMethodReturnExpression::generate('$suffixReturnValue', $originalMethod) . "\n"
|
||||
. " }\n"
|
||||
. "}\n\n"
|
||||
. "return \$returnValue;";
|
||||
. ProxiedMethodReturnExpression::generate('$returnValue', $originalMethod);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,25 +16,31 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator;
|
||||
|
||||
use ProxyManager\Exception\InvalidProxiedClassException;
|
||||
use ProxyManager\Generator\Util\ClassGeneratorUtils;
|
||||
use ProxyManager\Proxy\AccessInterceptorValueHolderInterface;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptor\MethodGenerator\MagicWakeup;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptor\MethodGenerator\SetMethodPrefixInterceptor;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptor\MethodGenerator\SetMethodSuffixInterceptor;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptor\PropertyGenerator\MethodPrefixInterceptors;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptor\PropertyGenerator\MethodSuffixInterceptors;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorValueHolder\MethodGenerator\Constructor;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorValueHolder\MethodGenerator\InterceptedMethod;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorValueHolder\MethodGenerator\MagicClone;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorValueHolder\MethodGenerator\MagicGet;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorValueHolder\MethodGenerator\MagicIsset;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorValueHolder\MethodGenerator\MagicSet;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorValueHolder\MethodGenerator\MagicUnset;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorValueHolder\MethodGenerator\StaticProxyConstructor;
|
||||
use ProxyManager\ProxyGenerator\Assertion\CanProxyAssertion;
|
||||
use ProxyManager\ProxyGenerator\LazyLoadingValueHolder\PropertyGenerator\ValueHolderProperty;
|
||||
use ProxyManager\ProxyGenerator\PropertyGenerator\PublicPropertiesMap;
|
||||
use ProxyManager\ProxyGenerator\Util\Properties;
|
||||
use ProxyManager\ProxyGenerator\Util\ProxiedMethodsFilter;
|
||||
use ProxyManager\ProxyGenerator\ValueHolder\MethodGenerator\Constructor;
|
||||
use ProxyManager\ProxyGenerator\ValueHolder\MethodGenerator\GetWrappedValueHolderValue;
|
||||
use ProxyManager\ProxyGenerator\ValueHolder\MethodGenerator\MagicSleep;
|
||||
use ReflectionClass;
|
||||
@@ -56,16 +62,17 @@ class AccessInterceptorValueHolderGenerator implements ProxyGeneratorInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
* @throws InvalidProxiedClassException
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function generate(ReflectionClass $originalClass, ClassGenerator $classGenerator)
|
||||
{
|
||||
CanProxyAssertion::assertClassCanBeProxied($originalClass);
|
||||
|
||||
$publicProperties = new PublicPropertiesMap($originalClass);
|
||||
$interfaces = array(
|
||||
'ProxyManager\\Proxy\\AccessInterceptorInterface',
|
||||
'ProxyManager\\Proxy\\ValueHolderInterface',
|
||||
);
|
||||
$publicProperties = new PublicPropertiesMap(Properties::fromReflectionClass($originalClass));
|
||||
$interfaces = [AccessInterceptorValueHolderInterface::class];
|
||||
|
||||
if ($originalClass->isInterface()) {
|
||||
$interfaces[] = $originalClass->getName();
|
||||
@@ -85,18 +92,12 @@ class AccessInterceptorValueHolderGenerator implements ProxyGeneratorInterface
|
||||
},
|
||||
array_merge(
|
||||
array_map(
|
||||
function (ReflectionMethod $method) use ($prefixInterceptors, $suffixInterceptors, $valueHolder) {
|
||||
return InterceptedMethod::generateMethod(
|
||||
new MethodReflection($method->getDeclaringClass()->getName(), $method->getName()),
|
||||
$valueHolder,
|
||||
$prefixInterceptors,
|
||||
$suffixInterceptors
|
||||
);
|
||||
},
|
||||
$this->buildMethodInterceptor($prefixInterceptors, $suffixInterceptors, $valueHolder),
|
||||
ProxiedMethodsFilter::getProxiedMethods($originalClass)
|
||||
),
|
||||
array(
|
||||
new Constructor($originalClass, $valueHolder, $prefixInterceptors, $suffixInterceptors),
|
||||
[
|
||||
Constructor::generateMethod($originalClass, $valueHolder),
|
||||
new StaticProxyConstructor($originalClass, $valueHolder, $prefixInterceptors, $suffixInterceptors),
|
||||
new GetWrappedValueHolderValue($valueHolder),
|
||||
new SetMethodPrefixInterceptor($prefixInterceptors),
|
||||
new SetMethodSuffixInterceptor($suffixInterceptors),
|
||||
@@ -130,9 +131,24 @@ class AccessInterceptorValueHolderGenerator implements ProxyGeneratorInterface
|
||||
),
|
||||
new MagicClone($originalClass, $valueHolder, $prefixInterceptors, $suffixInterceptors),
|
||||
new MagicSleep($originalClass, $valueHolder),
|
||||
new MagicWakeup($originalClass, $valueHolder),
|
||||
)
|
||||
new MagicWakeup($originalClass),
|
||||
]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private function buildMethodInterceptor(
|
||||
MethodPrefixInterceptors $prefixes,
|
||||
MethodSuffixInterceptors $suffixes,
|
||||
ValueHolderProperty $valueHolder
|
||||
) : callable {
|
||||
return function (ReflectionMethod $method) use ($prefixes, $suffixes, $valueHolder) : InterceptedMethod {
|
||||
return InterceptedMethod::generateMethod(
|
||||
new MethodReflection($method->getDeclaringClass()->getName(), $method->getName()),
|
||||
$valueHolder,
|
||||
$prefixes,
|
||||
$suffixes
|
||||
);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\Assertion;
|
||||
|
||||
use BadMethodCallException;
|
||||
@@ -47,7 +49,7 @@ final class CanProxyAssertion
|
||||
*
|
||||
* @throws InvalidProxiedClassException
|
||||
*/
|
||||
public static function assertClassCanBeProxied(ReflectionClass $originalClass, $allowInterfaces = true)
|
||||
public static function assertClassCanBeProxied(ReflectionClass $originalClass, bool $allowInterfaces = true) : void
|
||||
{
|
||||
self::isNotFinal($originalClass);
|
||||
self::hasNoAbstractProtectedMethods($originalClass);
|
||||
@@ -62,7 +64,7 @@ final class CanProxyAssertion
|
||||
*
|
||||
* @throws InvalidProxiedClassException
|
||||
*/
|
||||
private static function isNotFinal(ReflectionClass $originalClass)
|
||||
private static function isNotFinal(ReflectionClass $originalClass) : void
|
||||
{
|
||||
if ($originalClass->isFinal()) {
|
||||
throw InvalidProxiedClassException::finalClassNotSupported($originalClass);
|
||||
@@ -74,11 +76,11 @@ final class CanProxyAssertion
|
||||
*
|
||||
* @throws InvalidProxiedClassException
|
||||
*/
|
||||
private static function hasNoAbstractProtectedMethods(ReflectionClass $originalClass)
|
||||
private static function hasNoAbstractProtectedMethods(ReflectionClass $originalClass) : void
|
||||
{
|
||||
$protectedAbstract = array_filter(
|
||||
$originalClass->getMethods(),
|
||||
function (ReflectionMethod $method) {
|
||||
function (ReflectionMethod $method) : bool {
|
||||
return $method->isAbstract() && $method->isProtected();
|
||||
}
|
||||
);
|
||||
@@ -93,7 +95,7 @@ final class CanProxyAssertion
|
||||
*
|
||||
* @throws InvalidProxiedClassException
|
||||
*/
|
||||
private static function isNotInterface(ReflectionClass $originalClass)
|
||||
private static function isNotInterface(ReflectionClass $originalClass) : void
|
||||
{
|
||||
if ($originalClass->isInterface()) {
|
||||
throw InvalidProxiedClassException::interfaceNotSupported($originalClass);
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\LazyLoading\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MethodGenerator;
|
||||
use ProxyManager\ProxyGenerator\Util\Properties;
|
||||
use ProxyManager\ProxyGenerator\Util\UnsetPropertiesGenerator;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use Zend\Code\Generator\PropertyGenerator;
|
||||
|
||||
/**
|
||||
* The `staticProxyConstructor` implementation for lazy loading proxies
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
* @license MIT
|
||||
*/
|
||||
class StaticProxyConstructor extends MethodGenerator
|
||||
{
|
||||
/**
|
||||
* Static constructor
|
||||
*
|
||||
* @param PropertyGenerator $initializerProperty
|
||||
* @param Properties $properties
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct(PropertyGenerator $initializerProperty, Properties $properties)
|
||||
{
|
||||
parent::__construct('staticProxyConstructor', [], static::FLAG_PUBLIC | static::FLAG_STATIC);
|
||||
|
||||
$this->setParameter(new ParameterGenerator('initializer'));
|
||||
|
||||
$this->setDocBlock("Constructor for lazy initialization\n\n@param \\Closure|null \$initializer");
|
||||
$this->setBody(
|
||||
'static $reflection;' . "\n\n"
|
||||
. '$reflection = $reflection ?: $reflection = new \ReflectionClass(__CLASS__);' . "\n"
|
||||
. '$instance = (new \ReflectionClass(get_class()))->newInstanceWithoutConstructor();' . "\n\n"
|
||||
. UnsetPropertiesGenerator::generateSnippet($properties, 'instance')
|
||||
. '$instance->' . $initializerProperty->getName() . ' = $initializer;' . "\n\n"
|
||||
. 'return $instance;'
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -16,11 +16,15 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\LazyLoadingGhost\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MethodGenerator;
|
||||
use ProxyManager\Generator\ParameterGenerator;
|
||||
use Zend\Code\Generator\ParameterGenerator;
|
||||
use ProxyManager\Generator\Util\UniqueIdentifierGenerator;
|
||||
use ProxyManager\ProxyGenerator\Util\Properties;
|
||||
use ReflectionProperty;
|
||||
use Zend\Code\Generator\PropertyGenerator;
|
||||
|
||||
/**
|
||||
@@ -34,34 +38,160 @@ class CallInitializer extends MethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param PropertyGenerator $initializerProperty
|
||||
* @param PropertyGenerator $initTracker
|
||||
* @param Properties $properties
|
||||
*/
|
||||
public function __construct(
|
||||
PropertyGenerator $initializerProperty,
|
||||
PropertyGenerator $publicPropsDefaults,
|
||||
PropertyGenerator $initTracker
|
||||
PropertyGenerator $initTracker,
|
||||
Properties $properties
|
||||
) {
|
||||
parent::__construct(UniqueIdentifierGenerator::getIdentifier('callInitializer'));
|
||||
$this->setDocblock("Triggers initialization logic for this ghost object");
|
||||
$docBlock = <<<'DOCBLOCK'
|
||||
Triggers initialization logic for this ghost object
|
||||
|
||||
$this->setParameters(array(
|
||||
new ParameterGenerator('methodName'),
|
||||
new ParameterGenerator('parameters', 'array'),
|
||||
));
|
||||
@param string $methodName
|
||||
@param mixed[] $parameters
|
||||
|
||||
$this->setVisibility(static::VISIBILITY_PRIVATE);
|
||||
@return mixed
|
||||
DOCBLOCK;
|
||||
|
||||
parent::__construct(
|
||||
UniqueIdentifierGenerator::getIdentifier('callInitializer'),
|
||||
[
|
||||
new ParameterGenerator('methodName'),
|
||||
new ParameterGenerator('parameters', 'array'),
|
||||
],
|
||||
static::FLAG_PRIVATE,
|
||||
null,
|
||||
$docBlock
|
||||
);
|
||||
|
||||
$initializer = $initializerProperty->getName();
|
||||
$initialization = $initTracker->getName();
|
||||
|
||||
$this->setBody(
|
||||
'if ($this->' . $initialization . ' || ! $this->' . $initializer . ') {' . "\n return;\n}\n\n"
|
||||
. "\$this->" . $initialization . " = true;\n\n"
|
||||
. "foreach (self::\$" . $publicPropsDefaults->getName() . " as \$key => \$default) {\n"
|
||||
. " \$this->\$key = \$default;\n"
|
||||
. "}\n\n"
|
||||
. '$this->' . $initializer . '->__invoke'
|
||||
. '($this, $methodName, $parameters, $this->' . $initializer . ');' . "\n\n"
|
||||
. "\$this->" . $initialization . " = false;"
|
||||
$bodyTemplate = <<<'PHP'
|
||||
if ($this->%s || ! $this->%s) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->%s = true;
|
||||
|
||||
%s
|
||||
%s
|
||||
|
||||
$result = $this->%s->__invoke($this, $methodName, $parameters, $this->%s, $properties);
|
||||
$this->%s = false;
|
||||
|
||||
return $result;
|
||||
PHP;
|
||||
|
||||
$this->setBody(sprintf(
|
||||
$bodyTemplate,
|
||||
$initialization,
|
||||
$initializer,
|
||||
$initialization,
|
||||
$this->propertiesInitializationCode($properties),
|
||||
$this->propertiesReferenceArrayCode($properties),
|
||||
$initializer,
|
||||
$initializer,
|
||||
$initialization
|
||||
));
|
||||
}
|
||||
|
||||
private function propertiesInitializationCode(Properties $properties) : string
|
||||
{
|
||||
$assignments = [];
|
||||
|
||||
foreach ($properties->getAccessibleProperties() as $property) {
|
||||
$assignments[] = '$this->'
|
||||
. $property->getName()
|
||||
. ' = ' . $this->getExportedPropertyDefaultValue($property)
|
||||
. ';';
|
||||
}
|
||||
|
||||
foreach ($properties->getGroupedPrivateProperties() as $className => $privateProperties) {
|
||||
$cacheKey = 'cache' . str_replace('\\', '_', $className);
|
||||
$assignments[] = 'static $' . $cacheKey . ";\n\n"
|
||||
. '$' . $cacheKey . ' ?: $' . $cacheKey . " = \\Closure::bind(function (\$instance) {\n"
|
||||
. $this->getPropertyDefaultsAssignments($privateProperties) . "\n"
|
||||
. '}, null, ' . var_export($className, true) . ");\n\n"
|
||||
. '$' . $cacheKey . "(\$this);\n\n";
|
||||
}
|
||||
|
||||
return implode("\n", $assignments) . "\n\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ReflectionProperty[] $properties
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getPropertyDefaultsAssignments(array $properties) : string
|
||||
{
|
||||
return implode(
|
||||
"\n",
|
||||
array_map(
|
||||
function (ReflectionProperty $property) : string {
|
||||
return ' $instance->' . $property->getName()
|
||||
. ' = ' . $this->getExportedPropertyDefaultValue($property) . ';';
|
||||
},
|
||||
$properties
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private function propertiesReferenceArrayCode(Properties $properties) : string
|
||||
{
|
||||
$assignments = [];
|
||||
|
||||
foreach ($properties->getAccessibleProperties() as $propertyInternalName => $property) {
|
||||
$assignments[] = ' '
|
||||
. var_export($propertyInternalName, true) . ' => & $this->' . $property->getName()
|
||||
. ',';
|
||||
}
|
||||
|
||||
$code = "\$properties = [\n" . implode("\n", $assignments) . "\n];\n\n";
|
||||
|
||||
// must use assignments, as direct reference during array definition causes a fatal error (not sure why)
|
||||
foreach ($properties->getGroupedPrivateProperties() as $className => $classPrivateProperties) {
|
||||
$cacheKey = 'cacheFetch' . str_replace('\\', '_', $className);
|
||||
|
||||
$code .= 'static $' . $cacheKey . ";\n\n"
|
||||
. '$' . $cacheKey . ' ?: $' . $cacheKey
|
||||
. " = \\Closure::bind(function (\$instance, array & \$properties) {\n"
|
||||
. $this->generatePrivatePropertiesAssignmentsCode($classPrivateProperties)
|
||||
. "}, \$this, " . var_export($className, true) . ");\n\n"
|
||||
. '$' . $cacheKey . "(\$this, \$properties);";
|
||||
}
|
||||
|
||||
return $code;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ReflectionProperty[] $properties indexed by internal name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function generatePrivatePropertiesAssignmentsCode(array $properties) : string
|
||||
{
|
||||
$code = '';
|
||||
|
||||
foreach ($properties as $property) {
|
||||
$key = "\0" . $property->getDeclaringClass()->getName() . "\0" . $property->getName();
|
||||
$code .= ' $properties[' . var_export($key, true) . '] = '
|
||||
. '& $instance->' . $property->getName() . ";\n";
|
||||
}
|
||||
|
||||
return $code;
|
||||
}
|
||||
|
||||
private function getExportedPropertyDefaultValue(ReflectionProperty $property) : string
|
||||
{
|
||||
$name = $property->getName();
|
||||
$defaults = $property->getDeclaringClass()->getDefaultProperties();
|
||||
|
||||
return var_export($defaults[$name] ?? null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ProxyManager\ProxyGenerator\LazyLoadingGhost\MethodGenerator;
|
||||
|
||||
use ProxyManager\Generator\MethodGenerator;
|
||||
@@ -32,11 +34,15 @@ class GetProxyInitializer extends MethodGenerator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param PropertyGenerator $initializerProperty
|
||||
*
|
||||
* @throws \Zend\Code\Generator\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct(PropertyGenerator $initializerProperty)
|
||||
{
|
||||
parent::__construct('getProxyInitializer');
|
||||
$this->setDocblock('{@inheritDoc}');
|
||||
$this->setDocBlock('{@inheritDoc}');
|
||||
$this->setBody('return $this->' . $initializerProperty->getName() . ';');
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user