221 lines
6.1 KiB
PHP

<?php
namespace Infinito\Domain\DomManagement;
use Infinito\Entity\EntityInterface;
use Infinito\Domain\RightManagement\RightTransformerService;
use Doctrine\Common\Collections\Collection;
use Infinito\Domain\RequestManagement\Entity\RequestedEntityServiceInterface;
use Infinito\Exception\NotCorrectInstanceException;
use Infinito\DBAL\Types\Meta\Right\LayerType;
use Infinito\Domain\LayerManagement\LayerInterfaceMap;
use FOS\UserBundle\Model\UserInterface;
/**
* This class is not ready and not tested!
*
* @todo Implement tests!
* @todo finish class!
* @todo refactor class!
*
* @author kevinfrantz
*/
final class EntityDomService implements EntityDomServiceInterface
{
/**
* @var string
*/
const GET_METHOD = RightTransformerService::GET_PREFIX;
/**
* @var string
*/
const HAS_METHOD = RightTransformerService::HAS_PREFIX;
/**
* @var RequestedEntityServiceInterface
*/
private $requestedEntity;
/**
* @var EntityInterface
*/
private $entity;
/**
* @var \ReflectionClass
*/
private $entityReflectionClass;
/**
* @var array[]|\ReflectionProperty[]
*/
private $properties = [];
/**
* @var \DOMDocument
*/
private $domDocument;
/**
* @param RequestedEntityServiceInterface $requestedEntity
*/
public function __construct(RequestedEntityServiceInterface $requestedEntity)
{
$this->requestedEntity = $requestedEntity;
}
private function createProperties(): void
{
$this->properties = $this->entityReflectionClass->getProperties();
}
private function createDomDocument(): void
{
$this->domDocument = new \DOMDocument();
}
/**
* @param string $method
*
* @return bool
*/
private function methodExist(string $method): bool
{
return $this->entityReflectionClass->hasMethod($method);
}
/**
* @param string $method
*
* @return mixed
*/
private function getMethodResult(string $method)
{
return $this->entity->{$method}();
}
/**
* @param string $propertyName
*
* @return mixed
*/
private function getPropertyValue(string $propertyName)
{
$hasMethod = $this->getMethodName(self::HAS_METHOD, $propertyName);
if ($this->methodExist($hasMethod) && !$this->getMethodResult($hasMethod)) {
return null;
}
$getMethod = $this->getMethodName(self::GET_METHOD, $propertyName);
$result = $this->getMethodResult($getMethod);
return $result;
}
/**
* @param mixed|EntityInterface $value
* @param \DOMElement $domElement
*/
private function mappValue($value, \DOMElement $domElement): void
{
foreach (LayerInterfaceMap::getAllInterfaces() as $layer => $interface) {
if ($value instanceof $interface) {
$this->setLayerDomElement($domElement, $layer, $value);
return;
}
if ($value instanceof UserInterface) {
$this->setUserDomElement($domElement, $value);
return;
}
}
if (is_object($value)) {
throw new NotCorrectInstanceException('The instance '.get_class($value).' is not supported!');
}
$domElement->setAttribute('type', gettype($value));
$domElement->setAttribute('value', $value);
return;
}
/**
* @param \DOMElement $domElement
* @param string $layer
* @param EntityInterface $entity
*/
private function setLayerDomElement(\DOMElement $domElement, string $layer, EntityInterface $entity): void
{
$domElement->setAttribute('layer', $layer);
$domElement->setAttribute('id', $entity->getId());
$domElement->setAttribute('name', LayerType::getReadableValue($layer));
}
/**
* @param \DomElement $domElement
*/
private function setUserDomElement(\DomElement $domElement, \Infinito\Entity\UserInterface $user): void
{
$domElement->setAttribute('value', $user->getId());
$domElement->setAttribute('name', 'user');
}
/**
* @param string $method
* @param string $propertyName
*
* @return string
*/
private function getMethodName(string $method, string $propertyName): string
{
return $method.ucfirst($propertyName);
}
/**
* @param string $propertyName
*
* @return bool
*/
private function isPropertyAccessible(string $propertyName): bool
{
$getMethod = $this->getMethodName(self::GET_METHOD, $propertyName);
return $this->entityReflectionClass->hasMethod($getMethod);
}
/**
* {@inheritdoc}
*
* @see \Infinito\Domain\DomManagement\EntityDomServiceInterface::getDomDocument()
*/
public function getDomDocument(): \DOMDocument
{
$this->entity = $this->requestedEntity->getEntity();
$this->entityReflectionClass = new \ReflectionClass($this->entity);
$this->createProperties();
$this->createDomDocument();
foreach ($this->properties as $property) {
$propertyName = $property->getName();
if ($this->isPropertyAccessible($propertyName)) {
$domElement = $this->domDocument->createElement('attribut');
$domElement->setAttribute('name', $propertyName);
$value = $this->getPropertyValue($propertyName);
if ($value instanceof Collection) {
foreach ($value as $valueElement) {
$domSubElement = $this->domDocument->createElement('list-element');
$domElement->setAttribute('name', $propertyName);
$this->mappValue($valueElement, $domSubElement);
$domElement->appendChild($domSubElement);
}
} else {
$this->mappValue($value, $domElement);
}
$this->domDocument->appendChild($domElement);
}
}
$this->domDocument->saveXML();
return $this->domDocument;
}
}