Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
RemoteServiceGenerator.php
Go to the documentation of this file.
1 <?php
7 
9 use Magento\Framework\Code\Generator\Io;
11 use Magento\Framework\Communication\ConfigInterface as CommunicationConfig;
13 use Magento\Framework\Reflection\MethodsMap as ServiceMethodsMap;
14 use Zend\Code\Reflection\MethodReflection;
15 
21 class RemoteServiceGenerator extends \Magento\Framework\Code\Generator\EntityAbstract
22 {
23  const ENTITY_TYPE = 'remote';
24  const REMOTE_SERVICE_SUFFIX = 'Remote';
25 
30 
34  private $serviceMethodsMap;
35 
39  private $reflectionGenerator;
40 
55  public function __construct(
56  CommunicationConfig $communicationConfig,
57  ServiceMethodsMap $serviceMethodsMap,
58  RemoteServiceReader $communicationRemoteServiceReader,
59  $sourceClassName = null,
60  $resultClassName = null,
61  Io $ioObject = null,
62  \Magento\Framework\Code\Generator\CodeGeneratorInterface $classGenerator = null,
63  DefinedClasses $definedClasses = null
64  ) {
65  $this->communicationConfig = $communicationConfig;
66  $this->serviceMethodsMap = $serviceMethodsMap;
67  parent::__construct(
68  $sourceClassName,
69  $resultClassName,
70  $ioObject,
71  $classGenerator,
72  $definedClasses
73  );
74  }
75 
79  protected function _getDefaultConstructorDefinition()
80  {
81  return [
82  'name' => '__construct',
83  'parameters' => [
84  ['name' => 'publisher', 'type' => '\\' . \Magento\Framework\MessageQueue\PublisherInterface::class],
85  ],
86  'body' => "\$this->publisher = \$publisher;",
87  'docblock' => [
88  'shortDescription' => 'Initialize dependencies.',
89  'tags' => [
90  [
91  'name' => 'param',
92  'description' => '\Magento\Framework\MessageQueue\PublisherInterface $publisher',
93  ],
94  ],
95  ],
96  ];
97  }
98 
102  protected function _getClassProperties()
103  {
104  return [
105  [
106  'name' => 'publisher',
107  'visibility' => 'protected',
108  'docblock' => [
109  'shortDescription' => 'Publisher',
110  'tags' => [
111  [
112  'name' => 'var',
113  'description' => '\\' . \Magento\Framework\MessageQueue\PublisherInterface::class,
114  ],
115  ],
116  ],
117  ],
118  ];
119  }
120 
124  protected function _getClassMethods()
125  {
127  $interfaceMethodsMap = $this->serviceMethodsMap->getMethodsMap($this->getSourceClassName());
128  foreach (array_keys($interfaceMethodsMap) as $methodName) {
129  // Uses Zend Reflection instead MethodsMap service, because second does not support features of PHP 7.x
130  $methodReflection = new MethodReflection($this->getSourceClassName(), $methodName);
131  $sourceMethodParameters = $methodReflection->getParameters();
132  $methodParameters = [];
133  $topicParameters = [];
135  foreach ($sourceMethodParameters as $methodParameter) {
136  $parameterName = $methodParameter->getName();
137  $parameter = [
138  'name' => $parameterName,
139  'type' => $methodParameter->getType(),
140  ];
141  if ($methodParameter->isDefaultValueAvailable()) {
142  $parameter['defaultValue'] = $methodParameter->getDefaultValue() !== null
143  ? $methodParameter->getDefaultValue() : $this->_getNullDefaultValue();
144  }
145  $methodParameters[] = $parameter;
146  $topicParameters[] = "'{$parameterName}' => \${$parameterName}";
147  }
148  $topicName = $this->getReflectionGenerator()->generateTopicName($this->getSourceClassName(), $methodName);
149  $topicConfig = $this->communicationConfig->getTopic($topicName);
150  $methodBody = $topicConfig[CommunicationConfig::TOPIC_IS_SYNCHRONOUS] ? 'return ' : '';
151  $methodBody .= "\$this->publisher->publish(\n"
152  . " '{$topicName}',\n"
153  . " [" . implode(', ', $topicParameters) . "]\n"
154  . ");";
155  $annotations = [['name' => 'inheritdoc']];
156  $method = [
157  'name' => $methodName,
158  'returnType' => $methodReflection->getReturnType(),
159  'parameters' => $methodParameters,
160  'body' => $methodBody,
161  'docblock' => ['tags' => $annotations],
162  ];
163  $methods[] = $method;
164  }
165  return $methods;
166  }
167 
171  protected function _validateData()
172  {
173  $classNameValidationResults = $this->validateResultClassName();
174  return parent::_validateData() && $classNameValidationResults;
175  }
176 
180  protected function _generateCode()
181  {
182  $this->_classGenerator->setImplementedInterfaces([$this->getSourceClassName()]);
183  return parent::_generateCode();
184  }
185 
191  protected function validateResultClassName()
192  {
193  $result = true;
194  $sourceClassName = $this->getSourceClassName();
195  $resultClassName = $this->_getResultClassName();
196  $interfaceSuffix = 'Interface';
197  if (substr($sourceClassName, -strlen($interfaceSuffix)) !== $interfaceSuffix) {
198  $this->_addError(
199  sprintf(
200  'Remote service class "%s" should be set as preference for an interface, "%s" given',
201  $resultClassName,
202  $sourceClassName
203  )
204  );
205  }
206  $expectedResultClassName = $sourceClassName . self::REMOTE_SERVICE_SUFFIX;
207  if ($resultClassName !== $expectedResultClassName) {
208  $this->_addError(
209  'Invalid remote service class name [' . $resultClassName . ']. Use ' . $expectedResultClassName
210  );
211  $result = false;
212  }
213  return $result;
214  }
215 
223  private function getReflectionGenerator()
224  {
225  if ($this->reflectionGenerator === null) {
226  $this->reflectionGenerator = \Magento\Framework\App\ObjectManager::getInstance()
227  ->get(ReflectionGenerator::class);
228  }
229  return $this->reflectionGenerator;
230  }
231 }
$methods
Definition: billing.phtml:71
$method
Definition: info.phtml:13
__construct(CommunicationConfig $communicationConfig, ServiceMethodsMap $serviceMethodsMap, RemoteServiceReader $communicationRemoteServiceReader, $sourceClassName=null, $resultClassName=null, Io $ioObject=null, \Magento\Framework\Code\Generator\CodeGeneratorInterface $classGenerator=null, DefinedClasses $definedClasses=null)