| Current Path : /home/rtorresani/www/vendor/magento/framework/Api/Code/Generator/ |
| Current File : //home/rtorresani/www/vendor/magento/framework/Api/Code/Generator/ExtensionAttributesGenerator.php |
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\Framework\Api\Code\Generator;
use Magento\Framework\Code\Generator\DefinedClasses;
use Magento\Framework\Code\Generator\Io;
use Magento\Framework\Api\SimpleDataObjectConverter;
use Magento\Framework\Api\ExtensionAttribute\Config\Converter;
/**
* Code generator for data object extensions.
*/
class ExtensionAttributesGenerator extends \Magento\Framework\Code\Generator\EntityAbstract
{
public const ENTITY_TYPE = 'extension';
public const EXTENSION_SUFFIX = 'Extension';
/**
* @var \Magento\Framework\Api\ExtensionAttribute\Config
*/
protected $config;
/**
* @var \Magento\Framework\Reflection\TypeProcessor
*/
private $typeProcessor;
/**
* @var array
*/
protected $allCustomAttributes;
/**
* Initialize dependencies.
*
* @param \Magento\Framework\Api\ExtensionAttribute\Config $config
* @param string|null $sourceClassName
* @param string|null $resultClassName
* @param Io $ioObject
* @param \Magento\Framework\Code\Generator\CodeGeneratorInterface $classGenerator
* @param DefinedClasses $definedClasses
*/
public function __construct(
\Magento\Framework\Api\ExtensionAttribute\Config $config,
$sourceClassName = null,
$resultClassName = null,
Io $ioObject = null,
\Magento\Framework\Code\Generator\CodeGeneratorInterface $classGenerator = null,
DefinedClasses $definedClasses = null
) {
$sourceClassName .= 'Interface';
$this->config = $config;
parent::__construct(
$sourceClassName,
$resultClassName,
$ioObject,
$classGenerator,
$definedClasses
);
}
/**
* Get type processor
*
* @return \Magento\Framework\Reflection\TypeProcessor
* @deprecated 100.1.0
*/
private function getTypeProcessor()
{
if ($this->typeProcessor === null) {
$this->typeProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get(
\Magento\Framework\Reflection\TypeProcessor::class
);
}
return $this->typeProcessor;
}
/**
* @inheritdoc
*/
protected function _getDefaultConstructorDefinition()
{
return [];
}
/**
* @inheritdoc
*/
protected function _getClassProperties()
{
return [];
}
/**
* @inheritdoc
*/
protected function _getClassMethods()
{
$methods = [];
foreach ($this->getCustomAttributes() as $attributeName => $attributeMetadata) {
$attributeType = $attributeMetadata[Converter::DATA_TYPE];
$propertyName = SimpleDataObjectConverter::snakeCaseToCamelCase($attributeName);
$getterName = 'get' . ucfirst($propertyName);
$setterName = 'set' . ucfirst($propertyName);
$methods[] = [
'name' => $getterName,
'body' => "return \$this->_get('{$attributeName}');",
'docblock' => ['tags' => [['name' => 'return', 'description' => $attributeType . '|null']]],
];
$parameters = ['name' => $propertyName];
// If the attribute type is a valid type declaration (e.g., interface, class, array) then use it to enforce
// constraints on the generated setter methods
if ($this->getTypeProcessor()->isValidTypeDeclaration($attributeType)) {
$parameters['type'] = $attributeType;
}
$methods[] = [
'name' => $setterName,
'parameters' => [$parameters],
'body' => "\$this->setData('{$attributeName}', \${$propertyName});" . PHP_EOL . "return \$this;",
'docblock' => [
'tags' => [
[
'name' => 'param',
'description' => "{$attributeType} \${$propertyName}"
],
[
'name' => 'return',
'description' => '$this'
]
]
],
];
}
return $methods;
}
/**
* @inheritdoc
*/
protected function _validateData()
{
$classNameValidationResults = $this->validateResultClassName();
return parent::_validateData() && $classNameValidationResults;
}
/**
* @inheritdoc
*/
protected function _generateCode()
{
$this->_classGenerator->setImplementedInterfaces([$this->_getResultClassName() . 'Interface']);
$this->_classGenerator->setExtendedClass($this->getExtendedClass());
return parent::_generateCode();
}
/**
* Get class, which should be used as a parent for generated class.
*
* @return string
*/
protected function getExtendedClass()
{
return '\\' . \Magento\Framework\Api\AbstractSimpleObject::class;
}
/**
* Retrieve a list of attributes associated with current source class.
*
* @return array
*/
protected function getCustomAttributes()
{
if (!isset($this->allCustomAttributes)) {
$this->allCustomAttributes = $this->config->get();
}
$dataInterface = $this->getSourceClassName() !== null ? ltrim($this->getSourceClassName(), '\\') : '';
if (isset($this->allCustomAttributes[$dataInterface])) {
foreach ($this->allCustomAttributes[$dataInterface] as $attributeName => $attributeMetadata) {
$attributeType = $attributeMetadata[Converter::DATA_TYPE];
if ($attributeType !== null && strpos($attributeType, '\\') !== false) {
/** Add preceding slash to class names, while leaving primitive types as is */
$attributeType = $this->_getFullyQualifiedClassName($attributeType);
$this->allCustomAttributes[$dataInterface][$attributeName][Converter::DATA_TYPE] =
$this->_getFullyQualifiedClassName($attributeType);
}
}
return $this->allCustomAttributes[$dataInterface];
} else {
return [];
}
}
/**
* Ensure that result class name corresponds to the source class name.
*
* @return bool
*/
protected function validateResultClassName()
{
$result = true;
$sourceClassName = $this->getSourceClassName() ?? '';
$resultClassName = $this->_getResultClassName();
$interfaceSuffix = 'Interface';
$expectedResultClassName = substr($sourceClassName, 0, -strlen($interfaceSuffix)) . self::EXTENSION_SUFFIX;
if ($resultClassName !== $expectedResultClassName) {
$this->_addError(
'Invalid extension name [' . $resultClassName . ']. Use ' . $expectedResultClassName
);
$result = false;
}
return $result;
}
}