| Current Path : /var/www/clients/client3/web2/web/vendor/magento/framework/ObjectManager/Code/Generator/ |
| Current File : /var/www/clients/client3/web2/web/vendor/magento/framework/ObjectManager/Code/Generator/Proxy.php |
<?php
/**
* Proxy generator
*
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);
namespace Magento\Framework\ObjectManager\Code\Generator;
/**
* Class Proxy
*
* @package Magento\Framework\ObjectManager\Code\Generator
*/
class Proxy extends \Magento\Framework\Code\Generator\EntityAbstract
{
/**
* Entity type
*/
const ENTITY_TYPE = 'proxy';
/**
* Marker interface
*/
const NON_INTERCEPTABLE_INTERFACE = \Magento\Framework\ObjectManager\NoninterceptableInterface::class;
/**
* Returns default result class name
*
* @param string $modelClassName
* @return string
*/
protected function _getDefaultResultClassName($modelClassName)
{
return $modelClassName . '_' . ucfirst(static::ENTITY_TYPE);
}
/**
* Retrieve class properties
*
* @return array
*/
protected function _getClassProperties()
{
$properties = parent::_getClassProperties();
// protected $_instanceName = null;
$properties[] = [
'name' => '_instanceName',
'visibility' => 'protected',
'docblock' => [
'shortDescription' => 'Proxied instance name',
'tags' => [['name' => 'var', 'description' => 'string']],
],
];
$properties[] = [
'name' => '_subject',
'visibility' => 'protected',
'docblock' => [
'shortDescription' => 'Proxied instance',
'tags' => [['name' => 'var', 'description' => $this->getSourceClassName()]],
],
];
// protected $_shared = null;
$properties[] = [
'name' => '_isShared',
'visibility' => 'protected',
'docblock' => [
'shortDescription' => 'Instance shareability flag',
'tags' => [['name' => 'var', 'description' => 'bool']],
],
];
return $properties;
}
/**
* Returns list of methods for class generator
*
* @return array
*/
protected function _getClassMethods()
{
$construct = $this->_getDefaultConstructorDefinition();
// create proxy methods for all non-static and non-final public methods (excluding constructor)
$methods = [$construct];
$methods[] = [
'name' => '__sleep',
'body' => 'return [\'_subject\', \'_isShared\', \'_instanceName\'];',
'docblock' => ['tags' => [['name' => 'return', 'description' => 'array']]],
];
$methods[] = [
'name' => '__wakeup',
'body' => '$this->_objectManager = \Magento\Framework\App\ObjectManager::getInstance();',
'docblock' => ['shortDescription' => 'Retrieve ObjectManager from global scope'],
];
$methods[] = [
'name' => '__clone',
'body' => "\$this->_subject = clone \$this->_getSubject();",
'docblock' => ['shortDescription' => 'Clone proxied instance'],
];
$methods[] = [
'name' => '_getSubject',
'visibility' => 'protected',
'body' => "if (!\$this->_subject) {\n" .
" \$this->_subject = true === \$this->_isShared\n" .
" ? \$this->_objectManager->get(\$this->_instanceName)\n" .
" : \$this->_objectManager->create(\$this->_instanceName);\n" .
"}\n" .
"return \$this->_subject;",
'docblock' => [
'shortDescription' => 'Get proxied instance',
'tags' => [['name' => 'return', 'description' => $this->getSourceClassName()]],
],
];
$reflectionClass = new \ReflectionClass($this->getSourceClassName());
$publicMethods = $reflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC);
foreach ($publicMethods as $method) {
if (!(
$method->isConstructor() ||
$method->isFinal() ||
$method->isStatic() ||
$method->isDestructor()
)
&& !in_array(
$method->getName(),
['__sleep', '__wakeup', '__clone']
)
) {
$methods[] = $this->_getMethodInfo($method);
}
}
return $methods;
}
/**
* Generates code
*
* @return string
*/
protected function _generateCode()
{
$typeName = $this->getSourceClassName();
$reflection = new \ReflectionClass($typeName);
if ($reflection->isInterface()) {
$this->_classGenerator->setImplementedInterfaces([$typeName, '\\' . self::NON_INTERCEPTABLE_INTERFACE]);
} else {
$this->_classGenerator->setExtendedClass($typeName);
$this->_classGenerator->setImplementedInterfaces(['\\' . self::NON_INTERCEPTABLE_INTERFACE]);
}
return parent::_generateCode();
}
/**
* Collect method info
*
* @param \ReflectionMethod $method
* @return array
*/
protected function _getMethodInfo(\ReflectionMethod $method)
{
$parameterNames = [];
$parameters = [];
foreach ($method->getParameters() as $parameter) {
$name = $parameter->isVariadic() ? '... $' . $parameter->getName() : '$' . $parameter->getName();
$parameterNames[] = $name;
$parameters[] = $this->_getMethodParameterInfo($parameter);
}
$returnTypeValue = $this->getReturnTypeValue($method);
$methodInfo = [
'name' => $method->getName(),
'parameters' => $parameters,
'body' => $this->_getMethodBody(
$method->getName(),
$parameterNames,
$returnTypeValue === 'void'
),
'docblock' => ['shortDescription' => '{@inheritdoc}'],
'returntype' => $returnTypeValue,
];
return $methodInfo;
}
/**
* Get default constructor definition for generated class
*
* @return array
*/
protected function _getDefaultConstructorDefinition()
{
/*
* public function __construct(
* \Magento\Framework\ObjectManagerInterface $objectManager,
* $instanceName,
* $shared = false
* )
*/
return [
'name' => '__construct',
'parameters' => [
['name' => 'objectManager', 'type' => '\\' . \Magento\Framework\ObjectManagerInterface::class],
['name' => 'instanceName', 'defaultValue' => $this->getSourceClassName()],
['name' => 'shared', 'defaultValue' => true],
],
'body' => "\$this->_objectManager = \$objectManager;" .
"\n\$this->_instanceName = \$instanceName;" .
"\n\$this->_isShared = \$shared;",
'docblock' => [
'shortDescription' => ucfirst(static::ENTITY_TYPE) . ' constructor',
'tags' => [
[
'name' => 'param',
'description' => '\Magento\Framework\ObjectManagerInterface $objectManager',
],
['name' => 'param', 'description' => 'string $instanceName'],
['name' => 'param', 'description' => 'bool $shared'],
],
]
];
}
/**
* Build proxy method body
*
* @param string $name
* @param array $parameters
* @param bool $withoutReturn
* @return string
*/
protected function _getMethodBody(
$name,
array $parameters = [],
bool $withoutReturn = false
) {
if (count($parameters) == 0) {
$methodCall = sprintf('%s()', $name);
} else {
$methodCall = sprintf('%s(%s)', $name, implode(', ', $parameters));
}
return ($withoutReturn ? '' : 'return ')
. '$this->_getSubject()->' . $methodCall . ';';
}
/**
* Validates data
*
* @return bool
*/
protected function _validateData()
{
$result = parent::_validateData();
if ($result) {
$sourceClassName = $this->getSourceClassName();
$resultClassName = $this->_getResultClassName();
if ($resultClassName !== $sourceClassName . '\\Proxy') {
$this->_addError(
'Invalid Proxy class name [' . $resultClassName . ']. Use ' . $sourceClassName . '\\Proxy'
);
$result = false;
}
}
return $result;
}
/**
* Returns return type
*
* @param \ReflectionMethod $method
* @return null|string
*/
private function getReturnTypeValue(\ReflectionMethod $method): ?string
{
$returnTypeValue = null;
$returnType = $method->getReturnType();
if ($returnType) {
$returnTypeValue = ($returnType->allowsNull() ? '?' : '');
$returnTypeValue .= ($returnType->getName() === 'self')
? $this->_getFullyQualifiedClassName($method->getDeclaringClass()->getName())
: $returnType->getName();
}
return $returnTypeValue;
}
}