123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292 |
- <?php
- /**
- * Proxy generator
- *
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
- 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->getReturnType());
- $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 mixed $returnType
- * @return null|string
- */
- private function getReturnTypeValue($returnType): ?string
- {
- $returnTypeValue = null;
- if ($returnType) {
- $returnTypeValue = ($returnType->allowsNull() ? '?' : '');
- $returnTypeValue .= ($returnType->getName() === 'self')
- ? $this->getSourceClassName()
- : $returnType->getName();
- }
- return $returnTypeValue;
- }
- }
|