Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
Total | |
100.00% |
1 / 1 |
|
100.00% |
20 / 20 |
CRAP | |
100.00% |
133 / 133 |
ArrayConverterPlugin | |
100.00% |
1 / 1 |
|
100.00% |
21 / 21 |
38 | |
100.00% |
133 / 133 |
getUseClassNameList | |
100.00% |
1 / 1 |
3 | |
100.00% |
7 / 7 |
|||
getDependantPluginList | |
100.00% |
1 / 1 |
1 | |
100.00% |
0 / 0 |
|||
getInterfaceList | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
generate | |
100.00% |
1 / 1 |
1 | |
100.00% |
4 / 4 |
|||
generateFromArray | |
100.00% |
1 / 1 |
1 | |
100.00% |
10 / 10 |
|||
generateAttributeListFromArray | |
100.00% |
1 / 1 |
2 | |
100.00% |
4 / 4 |
|||
generateAttributeFromArray | |
100.00% |
1 / 1 |
2 | |
100.00% |
6 / 6 |
|||
generateObjectAttributeFromArray | |
100.00% |
1 / 1 |
3 | |
100.00% |
11 / 11 |
|||
generateReferenceListFromArray | |
100.00% |
1 / 1 |
2 | |
100.00% |
3 / 3 |
|||
generateReferenceFromArray | |
100.00% |
1 / 1 |
1 | |
100.00% |
9 / 9 |
|||
generateCollectionListFromArray | |
100.00% |
1 / 1 |
2 | |
100.00% |
3 / 3 |
|||
generateCollectionFromArray | |
100.00% |
1 / 1 |
1 | |
100.00% |
11 / 11 |
|||
addCheckExisting | |
100.00% |
1 / 1 |
3 | |
100.00% |
8 / 8 |
|||
generateToArray | |
100.00% |
1 / 1 |
1 | |
100.00% |
10 / 10 |
|||
generateCycleDetection | |
100.00% |
1 / 1 |
1 | |
100.00% |
9 / 9 |
|||
generateAttributeListToArray | |
100.00% |
1 / 1 |
3 | |
100.00% |
10 / 10 |
|||
generateAttributeToArray | |
100.00% |
1 / 1 |
4 | |
100.00% |
8 / 8 |
|||
generateReferenceListToArray | |
100.00% |
1 / 1 |
2 | |
100.00% |
3 / 3 |
|||
generateReferenceToArray | |
100.00% |
1 / 1 |
1 | |
100.00% |
5 / 5 |
|||
generateCollectionListToArray | |
100.00% |
1 / 1 |
2 | |
100.00% |
3 / 3 |
|||
generateCollectionToArray | |
100.00% |
1 / 1 |
1 | |
100.00% |
8 / 8 |
<?php | |
declare(strict_types = 1); | |
namespace Siesta\GeneratorPlugin\Entity; | |
use Siesta\CodeGenerator\CodeGenerator; | |
use Siesta\CodeGenerator\MethodGenerator; | |
use Siesta\GeneratorPlugin\BasePlugin; | |
use Siesta\GeneratorPlugin\ServiceClass\NewInstancePlugin; | |
use Siesta\Model\Attribute; | |
use Siesta\Model\Collection; | |
use Siesta\Model\Entity; | |
use Siesta\Model\PHPType; | |
use Siesta\Model\Reference; | |
use Siesta\Util\ArrayUtil; | |
/** | |
* @author Gregor Müller | |
*/ | |
class ArrayConverterPlugin extends BasePlugin | |
{ | |
const METHOD_TO_ARRAY = "toArray"; | |
const METHOD_FROM_ARRAY = "fromArray"; | |
const TYPE_ARRAY_ACCESSOR_MAPPING = [ | |
PHPType::BOOL => "getBooleanValue", | |
PHPType::INT => "getIntegerValue", | |
PHPType::FLOAT => "getFloatValue", | |
PHPType::STRING => "getStringValue", | |
PHPType::SIESTA_DATE_TIME => "getDateTime", | |
PHPType::ARRAY => "getArray" | |
]; | |
/** | |
* @param Entity $entity | |
* | |
* @return string[] | |
*/ | |
public function getUseClassNameList(Entity $entity) : array | |
{ | |
$useClassList = [ | |
'Siesta\Util\ArrayAccessor', | |
'Siesta\Contract\ArraySerializable', | |
'Siesta\Util\DefaultCycleDetector', | |
'Siesta\Contract\CycleDetector' | |
]; | |
foreach ($entity->getReferenceList() as $reference) { | |
$foreignEntity = $reference->getForeignEntity(); | |
$serviceFactory = $foreignEntity->getServiceFactoryClass(); | |
if ($serviceFactory !== null) { | |
$useClassList[] = $serviceFactory; | |
} | |
} | |
return $useClassList; | |
} | |
/** | |
* @return string[] | |
*/ | |
public function getDependantPluginList() : array | |
{ | |
return []; | |
} | |
/** | |
* @return string[] | |
*/ | |
public function getInterfaceList() : array | |
{ | |
return ['ArraySerializable']; | |
} | |
/** | |
* @param Entity $entity | |
* @param CodeGenerator $codeGenerator | |
*/ | |
public function generate(Entity $entity, CodeGenerator $codeGenerator) | |
{ | |
$this->setup($entity, $codeGenerator); | |
$this->generateFromArray(); | |
$this->generateToArray(); | |
} | |
/** | |
* | |
*/ | |
protected function generateFromArray() | |
{ | |
$method = $this->codeGenerator->newPublicMethod(self::METHOD_FROM_ARRAY); | |
$method->addParameter("array", "data"); | |
// store raw data | |
$method->addLine('$this->_rawJSON = $data;'); | |
$method->addLine('$arrayAccessor = new ArrayAccessor($data);'); | |
$this->generateAttributeListFromArray($method); | |
$this->addCheckExisting($method); | |
$this->generateReferenceListFromArray($method); | |
$this->generateCollectionListFromArray($method); | |
$method->end(); | |
} | |
/** | |
* | |
*/ | |
protected function generateAttributeListFromArray(MethodGenerator $method) | |
{ | |
foreach ($this->entity->getAttributeList() as $attribute) { | |
$this->generateAttributeFromArray($method, $attribute); | |
$this->generateObjectAttributeFromArray($method, $attribute); | |
} | |
} | |
/** | |
* @param MethodGenerator $method | |
* @param Attribute $attribute | |
*/ | |
protected function generateAttributeFromArray(MethodGenerator $method, Attribute $attribute) | |
{ | |
$name = $attribute->getPhpName(); | |
$accessorMethod = ArrayUtil::getFromArray(self::TYPE_ARRAY_ACCESSOR_MAPPING, $attribute->getPhpType()); | |
if ($accessorMethod === null) { | |
return; | |
} | |
$method->addLine('$this->set' . $attribute->getMethodName() . '($arrayAccessor->' . $accessorMethod . '("' . $name . '"));'); | |
} | |
/** | |
* @param MethodGenerator $method | |
* @param Attribute $attribute | |
*/ | |
protected function generateObjectAttributeFromArray(MethodGenerator $method, Attribute $attribute) | |
{ | |
if (!$attribute->getIsObject() || !$attribute->implementsArraySerializable()) { | |
return; | |
} | |
$name = $attribute->getPhpName(); | |
$type = $attribute->getPhpType(); | |
// access array raw data and make sure it is not null | |
$method->addLine('$' . $name . 'Array = $arrayAccessor->getArray("' . $name . '");'); | |
$method->addIfStart('$' . $name . 'Array !== null'); | |
// instantiate new object and initialize it from array | |
$method->addLine('$' . $name . ' = new ' . $type . '();'); | |
$method->addLine('$' . $name . '->fromArray($' . $name . 'Array);'); | |
// invoke setter to store object | |
$method->addLine('$this->set' . $attribute->getMethodName() . '($' . $name . ');'); | |
// done | |
$method->addIfEnd(); | |
} | |
/** | |
* @param MethodGenerator $method | |
*/ | |
protected function generateReferenceListFromArray(MethodGenerator $method) | |
{ | |
foreach ($this->entity->getReferenceList() as $reference) { | |
$this->generateReferenceFromArray($method, $reference); | |
} | |
} | |
/** | |
* @param MethodGenerator $method | |
* @param Reference $reference | |
*/ | |
protected function generateReferenceFromArray(MethodGenerator $method, Reference $reference) | |
{ | |
$foreignEntity = $reference->getForeignEntity(); | |
$name = $reference->getName(); | |
// get data from array and make sure it is not null | |
$method->addLine('$' . $name . 'Array = $arrayAccessor->getArray("' . $name . '");'); | |
$method->addIfStart('$' . $name . 'Array !== null'); | |
// instantiate new object and initialize it from array | |
$method->addLine('$' . $name . ' = ' . $foreignEntity->getServiceAccess() . '->' . NewInstancePlugin::METHOD_NEW_INSTANCE . '();'); | |
$method->addLine('$' . $name . '->' . self::METHOD_FROM_ARRAY . '($' . $name . 'Array);'); | |
// invoke setter to store attribute | |
$method->addLine('$this->set' . $reference->getMethodName() . '($' . $name . ');'); | |
$method->addIfEnd(); | |
} | |
/** | |
* @param MethodGenerator $method | |
*/ | |
protected function generateCollectionListFromArray(MethodGenerator $method) | |
{ | |
foreach ($this->entity->getCollectionList() as $collection) { | |
$this->generateCollectionFromArray($method, $collection); | |
} | |
} | |
/** | |
* @param MethodGenerator $method | |
* @param Collection $collection | |
*/ | |
protected function generateCollectionFromArray(MethodGenerator $method, Collection $collection) | |
{ | |
$foreignEntity = $collection->getForeignEntity(); | |
$name = $collection->getName(); | |
// get collection data and make sure it exists | |
$method->addLine('$' . $name . 'Array = $arrayAccessor->getArray("' . $name . '");'); | |
$method->addIfStart('$' . $name . 'Array !== null'); | |
// iterate array data | |
$method->addForeachStart('$' . $name . 'Array as $entityArray'); | |
// instantiate new foreign entity initialize it and add it to the collection | |
$method->addLine('$' . $name . ' = ' . $foreignEntity->getServiceAccess() . '->' . NewInstancePlugin::METHOD_NEW_INSTANCE . '();'); | |
$method->addLine('$' . $name . '->' . self::METHOD_FROM_ARRAY . '($entityArray);'); | |
$method->addLine('$this->' . CollectorGetterSetter::METHOD_ADD_TO_PREFIX . $collection->getMethodName() . '($' . $name . ');'); | |
$method->addForeachEnd(); | |
$method->addIfEnd(); | |
} | |
/** | |
* @param MethodGenerator $method | |
*/ | |
protected function addCheckExisting(MethodGenerator $method) | |
{ | |
if (!$this->entity->hasPrimaryKey()) { | |
return; | |
} | |
$pkCheckList = []; | |
foreach ($this->entity->getPrimaryKeyAttributeList() as $attribute) { | |
$pkCheckList[] = '($this->' . $attribute->getPhpName() . ' !== null)'; | |
} | |
$pkCheck = implode(" && ", $pkCheckList); | |
$method->addLine('$this->_existing = ' . $pkCheck . ';'); | |
} | |
/** | |
* | |
*/ | |
protected function generateToArray() | |
{ | |
$method = $this->codeGenerator->newPublicMethod(self::METHOD_TO_ARRAY); | |
$method->addParameter('CycleDetector', 'cycleDetector', 'null'); | |
$method->setReturnType('array', true); | |
$this->generateCycleDetection($method); | |
$this->generateAttributeListToArray($method); | |
$this->generateReferenceListToArray($method); | |
$this->generateCollectionListToArray($method); | |
$method->addLine('return $result;'); | |
$method->end(); | |
} | |
/** | |
* @param MethodGenerator $method | |
*/ | |
protected function generateCycleDetection(MethodGenerator $method) | |
{ | |
$method->addIfStart('$cycleDetector === null'); | |
$method->addLine('$cycleDetector = new DefaultCycleDetector();'); | |
$method->addIfEnd(); | |
$method->newLine(); | |
// canProceed | |
$method->addIfStart('!$cycleDetector->canProceed(self::TABLE_NAME, $this)'); | |
$method->addLine('return null;'); | |
$method->addIfEnd(); | |
$method->newLine(); | |
} | |
/** | |
* @param MethodGenerator $method | |
*/ | |
protected function generateAttributeListToArray(MethodGenerator $method) | |
{ | |
$method->addLine('$result = ['); | |
$method->incrementIndent(); | |
foreach ($this->entity->getAttributeList() as $index => $attribute) { | |
$line = $this->generateAttributeToArray($method, $attribute); | |
if (($index + 1) !== sizeof($this->entity->getAttributeList())) { | |
$line .= ","; | |
} | |
$method->addLine($line); | |
} | |
$method->decrementIndex(); | |
$method->addLine('];'); | |
} | |
/** | |
* @param MethodGenerator $method | |
* @param Attribute $attribute | |
* | |
* @return string | |
*/ | |
protected function generateAttributeToArray(MethodGenerator $method, Attribute $attribute) | |
{ | |
$name = $attribute->getPhpName(); | |
$type = $attribute->getPhpType(); | |
$methodName = 'get' . $attribute->getMethodName(); | |
if ($attribute->getIsObject() && $attribute->implementsArraySerializable()) { | |
return '"' . $name . '" => ($this->' . $methodName . '() !== null) ? $this->' . $methodName . '()->toArray() : null'; | |
} | |
if ($type === PHPType::SIESTA_DATE_TIME) { | |
return '"' . $name . '" => ($this->' . $methodName . '() !== null) ? $this->' . $methodName . '()->getJSONDateTime() : null'; | |
} | |
return '"' . $name . '" => $this->' . $methodName . '()'; | |
} | |
/** | |
* @param MethodGenerator $method | |
*/ | |
protected function generateReferenceListToArray(MethodGenerator $method) | |
{ | |
foreach ($this->entity->getReferenceList() as $reference) { | |
$this->generateReferenceToArray($method, $reference); | |
} | |
} | |
/** | |
* @param MethodGenerator $method | |
* @param Reference $reference | |
*/ | |
protected function generateReferenceToArray(MethodGenerator $method, Reference $reference) | |
{ | |
$name = $reference->getName(); | |
$method->addIfStart('$this->' . $name . ' !== null'); | |
$method->addLine('$result["' . $name . '"] = $this->' . $name . '->' . self::METHOD_TO_ARRAY . '($cycleDetector);'); | |
$method->addIfEnd(); | |
} | |
/** | |
* @param MethodGenerator $method | |
*/ | |
protected function generateCollectionListToArray(MethodGenerator $method) | |
{ | |
foreach ($this->entity->getCollectionList() as $collection) { | |
$this->generateCollectionToArray($method, $collection); | |
} | |
} | |
/** | |
* @param MethodGenerator $method | |
* @param Collection $collection | |
*/ | |
protected function generateCollectionToArray(MethodGenerator $method, Collection $collection) | |
{ | |
$name = $collection->getName(); | |
$method->addLine('$result["' . $name . '"] = [];'); | |
$method->addIfStart('$this->' . $name . ' !== null'); | |
$method->addForeachStart('$this->' . $name . ' as $entity'); | |
$method->addLine('$result["' . $name . '"][] = $entity->' . self::METHOD_TO_ARRAY . '($cycleDetector);'); | |
$method->addForeachEnd(); | |
$method->addIfEnd(); | |
} | |
} |