refactoring

This commit is contained in:
Yuri Kuznetsov
2021-02-16 21:22:33 +02:00
parent 18537b9cdb
commit 2e7bc894f1
5 changed files with 265 additions and 123 deletions
+33 -25
View File
@@ -56,7 +56,7 @@ class Entity extends BaseEntity
$this->hasRelation($field);
}
public function loadParentNameField(string $field)
public function loadParentNameField(string $field) : void
{
if (!$this->hasAttribute($field. 'Id') || !$this->hasAttribute($field . 'Type')) {
throw new LogicException("There's no link-parent field '{$field}'.");
@@ -81,12 +81,16 @@ class Entity extends BaseEntity
if ($foreignEntity) {
$this->set($field . 'Name', $foreignEntity->get('name'));
} else {
$this->set($field . 'Name', null);
return;
}
} else {
$this->set($field . 'Name', null);
return;
}
$this->set($field . 'Name', null);
}
protected function getRelationOrderParams(string $link) : ?array
@@ -141,7 +145,7 @@ class Entity extends BaseEntity
];
}
public function loadLinkMultipleField(string $field, $columns = null)
public function loadLinkMultipleField(string $field, $columns = null) : void
{
if (!$this->hasRelation($field) || !$this->hasAttribute($field . 'Ids')) {
return;
@@ -158,7 +162,7 @@ class Entity extends BaseEntity
}
if (!empty($columns)) {
foreach ($columns as $key => $item) {
foreach ($columns as $item) {
$select[] = $item;
}
}
@@ -186,7 +190,9 @@ class Entity extends BaseEntity
foreach ($collection as $e) {
$id = $e->id;
$ids[] = $id;
$names->$id = $e->get('name');
if ($hasType) {
@@ -221,7 +227,7 @@ class Entity extends BaseEntity
}
}
public function loadLinkField(string $field)
public function loadLinkField(string $field) : void
{
if (!$this->hasRelation($field) || !$this->hasAttribute($field . 'Id')) {
throw new LogicException("There's no link field '{$field}'.");
@@ -254,9 +260,13 @@ class Entity extends BaseEntity
}
$this->set($idAttribute, $entityId);
$this->set($field . 'Name', $entityName);
}
/**
* @return ?mixed
*/
public function getLinkMultipleName(string $field, string $id)
{
$namesAttribute = $field . 'Names';
@@ -267,18 +277,14 @@ class Entity extends BaseEntity
$names = $this->get($namesAttribute);
if ($names instanceof StdClass) {
if (isset($names->$id)) {
if (isset($names->$id)) {
return $names->$id;
}
}
if ($names instanceof StdClass && isset($names->$id) && isset($names->$id)) {
return $names->$id;
}
return null;
}
public function setLinkMultipleName(string $field, string $id, ?string $value)
public function setLinkMultipleName(string $field, string $id, ?string $value) : void
{
$namesAttribute = $field . 'Names';
@@ -293,9 +299,13 @@ class Entity extends BaseEntity
}
$object->$id = $value;
$this->set($namesAttribute, $object);
}
/**
* @return ?mixed
*/
public function getLinkMultipleColumn(string $field, string $column, string $id)
{
$columnsAttribute = $field . 'Columns';
@@ -306,18 +316,14 @@ class Entity extends BaseEntity
$columns = $this->get($columnsAttribute);
if ($columns instanceof StdClass) {
if (isset($columns->$id)) {
if (isset($columns->$id->$column)) {
return $columns->$id->$column;
}
}
if ($columns instanceof StdClass && isset($columns->$id) && isset($columns->$id->$column)) {
return $columns->$id->$column;
}
return null;
}
public function setLinkMultipleColumn(string $field, string $column, string $id, $value)
public function setLinkMultipleColumn(string $field, string $column, string $id, $value) : void
{
$columnsAttribute = $field . 'Columns';
@@ -344,14 +350,14 @@ class Entity extends BaseEntity
$this->set($columnsAttribute, $object);
}
public function setLinkMultipleIdList(string $field, array $idList)
public function setLinkMultipleIdList(string $field, array $idList) : void
{
$idsAttribute = $field . 'Ids';
$this->set($idsAttribute, $idList);
}
public function addLinkMultipleId(string $field, string $id)
public function addLinkMultipleId(string $field, string $id) : void
{
$idsAttribute = $field . 'Ids';
@@ -379,7 +385,7 @@ class Entity extends BaseEntity
}
}
public function removeLinkMultipleId(string $field, string $id)
public function removeLinkMultipleId(string $field, string $id) : void
{
if ($this->hasLinkMultipleId($field, $id)) {
$list = $this->getLinkMultipleIdList($field);
@@ -421,7 +427,9 @@ class Entity extends BaseEntity
{
$idsAttribute = $field . 'Ids';
if (!$this->hasAttribute($idsAttribute)) return false;
if (!$this->hasAttribute($idsAttribute)) {
return false;
}
if (!$this->has($idsAttribute)) {
if (!$this->isNew()) {
+19 -1
View File
@@ -122,6 +122,10 @@ class Integration extends \Espo\Core\ORM\Entity
return parent::isAttributeChanged($name);
}
/**
* @deprecated
* @todo Make protected.
*/
public function populateFromArray(array $array, bool $onlyAccessible = true, bool $reset = false) : void
{
if ($reset) {
@@ -141,29 +145,43 @@ class Integration extends \Espo\Core\ORM\Entity
if (!is_null($value)) {
switch ($defs['type']) {
case self::VARCHAR:
break;
case self::BOOL:
$value = ($value === 'true' || $value === '1' || $value === true);
break;
case self::INT:
$value = intval($value);
break;
case self::FLOAT:
$value = floatval($value);
break;
case self::JSON_ARRAY:
$value = is_string($value) ? json_decode($value) : $value;
if (!is_array($value)) {
$value = null;
}
break;
case self::JSON_OBJECT:
$value = is_string($value) ? json_decode($value) : $value;
if (!($value instanceof \StdClass) && !is_array($value)) {
if (!($value instanceof StdClass) && !is_array($value)) {
$value = null;
}
break;
default:
break;
}
}
+151 -90
View File
@@ -29,21 +29,24 @@
namespace Espo\ORM;
use StdClass;
use const E_USER_DEPRECATED;
use StdClass;
use InvalidArgumentException;
class BaseEntity implements Entity
{
public $id = null;
protected $entityType;
private $isNew = false;
private $isSaved = false;
protected $entityType;
protected $isFetched = false;
protected $isBeingSaved = false;
/**
* @todo Make protected. Rename to `attributes`.
@@ -54,21 +57,20 @@ class BaseEntity implements Entity
protected $relations = [];
/**
* @var array Field-Value pairs.
* A field-value map.
*/
protected $valuesContainer = [];
/**
* @var array Field-Value pairs of initial values (fetched from DB).
* A field-value map of values fetched from DB (before changed).
*/
protected $fetchedValuesContainer = [];
/**
* @var ?EntityManager
*/
protected $entityManager;
protected $isFetched = false;
protected $isBeingSaved = false;
public function __construct(string $entityType, array $defs = [], ?EntityManager $entityManager = null)
{
$this->entityType = $entityType ?? null;
@@ -79,6 +81,11 @@ class BaseEntity implements Entity
$this->relations = $defs['relations'] ?? $this->relations;
}
public function getId() : ?string
{
return $this->get('id');
}
public function clear(string $name) : void
{
unset($this->valuesContainer[$name]);
@@ -125,16 +132,22 @@ class BaseEntity implements Entity
$this->id = $value;
}
if ($this->hasAttribute($name)) {
$method = '_set' . ucfirst($name);
if (method_exists($this, $method)) {
$this->$method($value);
} else {
$this->valuesContainer[$name] = $value;
}
if (!$this->hasAttribute($name)) {
return;
}
$method = '_set' . ucfirst($name);
if (method_exists($this, $method)) {
$this->$method($value);
return;
}
$this->populateFromArray([
$name => $value,
]);
return;
}
@@ -148,7 +161,7 @@ class BaseEntity implements Entity
*/
public function get(string $name, $params = [])
{
if ($name == 'id') {
if ($name === 'id') {
return $this->id;
}
@@ -172,7 +185,8 @@ class BaseEntity implements Entity
// @todo Remove this.
if ($this->hasRelation($name) && $this->id && $this->entityManager) {
trigger_error(
"Accessing related records with Entity::get is deprecated. Use \$repository->getRelation(...)->find()",
"Accessing related records with Entity::get is deprecated. " .
"Use \$repository->getRelation(...)->find()",
E_USER_DEPRECATED
);
@@ -203,13 +217,17 @@ class BaseEntity implements Entity
return false;
}
/**
* @deprecated
* @todo Make protected.
*/
public function populateFromArray(array $data, bool $onlyAccessible = true, bool $reset = false) : void
{
if ($reset) {
$this->reset();
}
foreach ($this->getAttributes() as $attribute => $defs) {
foreach ($this->getAttributeList() as $attribute) {
if (!array_key_exists($attribute, $data)) {
continue;
}
@@ -226,79 +244,122 @@ class BaseEntity implements Entity
$value = $data[$attribute];
if (!is_null($value)) {
$valueType = $this->getAttributeType($attribute);
if ($valueType === self::FOREIGN) {
$relation = $this->getAttributeParam($attribute, 'relation');
$foreign = $this->getAttributeParam($attribute, 'foreign');
if (is_string($foreign)) {
$foreignEntityType = $this->getRelationParam($relation, 'entity');
if ($foreignEntityType && $this->entityManager) {
$valueType = $this->entityManager->getMetadata()->get(
$foreignEntityType, ['fields', $foreign, 'type']
);
}
}
}
switch ($valueType) {
case self::VARCHAR:
break;
case self::BOOL:
$value = ($value === 'true' || $value === '1' || $value === true);
break;
case self::INT:
$value = intval($value);
break;
case self::FLOAT:
$value = floatval($value);
break;
case self::JSON_ARRAY:
$value = is_string($value) ? json_decode($value) : $value;
if (!is_array($value)) {
$value = null;
}
break;
case self::JSON_OBJECT:
$value = is_string($value) ? json_decode($value) : $value;
if (!($value instanceof StdClass) && !is_array($value)) {
$value = null;
}
break;
default:
break;
}
}
$method = '_set' . ucfirst($attribute);
if (method_exists($this, $method)) {
$this->$method($value);
continue;
}
$this->valuesContainer[$attribute] = $value;
$this->populateFromArrayItem($attribute, $value);
}
}
protected function populateFromArrayItem(string $attribute, $value) : void
{
$preparedValue = $this->preparePopulateFromArrayItemValue($attribute, $value);
$method = '_set' . ucfirst($attribute);
if (method_exists($this, $method)) {
$this->$method($preparedValue);
return;
}
$this->valuesContainer[$attribute] = $preparedValue;
}
/**
* @return ?mixed
*/
protected function preparePopulateFromArrayItemValue(string $attribute, $value)
{
if (is_null($value)) {
return $value;
}
$attributeType = $this->getAttributeType($attribute);
if ($attributeType === self::FOREIGN) {
$attributeType = $this->getForeignAttributeType($attribute) ?? $attributeType;
}
switch ($attributeType) {
case self::VARCHAR:
break;
case self::BOOL:
return ($value === true || $value === 'true' || $value === '1');
case self::INT:
return intval($value);
case self::FLOAT:
return floatval($value);
case self::JSON_ARRAY:
$preparedValue = is_string($value) ? json_decode($value) : $value;
if (!is_array($preparedValue)) {
$value = null;
}
return $preparedValue;
case self::JSON_OBJECT:
$preparedValue = is_string($value) ? json_decode($value) : $value;
if (!($preparedValue instanceof StdClass) && !is_array($preparedValue)) {
$preparedValue = null;
}
return $preparedValue;
default:
break;
}
return $value;
}
private function getForeignAttributeType(string $attribute) : ?string
{
if (!$this->entityManager) {
return null;
}
$defs = $this->entityManager->getDefs();
$entityDefs = $defs->getEntity($this->entityType);
$relation = $entityDefs->getAttribute($attribute)->getParam('relation');
$foreign = $entityDefs->getAttribute($attribute)->getParam('foreign');
if (!$relation) {
return null;
}
if (!$foreign) {
return null;
}
if (!is_string($foreign)) {
return self::VARCHAR;
}
if (!$entityDefs->getRelation($relation)->hasForeignEntityType()) {
return null;
}
$entityType = $entityDefs->getRelation($relation)->getForeignEntityType();
if (!$defs->hasEntity($entityType)) {
return null;
}
$foreignEntityDefs = $defs->getEntity($entityType);
if (!$foreignEntityDefs->hasAttribute($foreign)) {
return null;
}
return $foreignEntityDefs->getAttribute($foreign)->getType();
}
/**
* Is an entity new.
*/
+5
View File
@@ -56,6 +56,11 @@ interface Entity
const BELONGS_TO_PARENT = 'belongsToParent';
const HAS_CHILDREN = 'hasChildren';
/**
* Get an entity ID.
*/
public function getId() : ?string;
/**
* Reset all attributes (empty an entity).
*/
+57 -7
View File
@@ -30,11 +30,11 @@
namespace tests\unit\Espo\ORM;
use Espo\ORM\{
DB\MysqlMapper,
DB\Query\Mysql as Query,
EntityFactory,
Metadata,
MetadataDataProvider,
Defs\Defs,
Defs\DefsData,
BaseEntity,
};
use tests\unit\testData\DB\Job;
@@ -57,19 +57,30 @@ class EntityTest extends \PHPUnit\Framework\TestCase
->willReturn($ormMetadata);
$this->metadata = new Metadata($metadataDataProvider);
$defsData = new DefsData($this->metadata);
$defs = new Defs($defsData);
$this->entityManager = $this->createMock(EntityManager::class);
$this->entityManager
->expects($this->any())
->method('getDefs')
->willReturn($defs);
}
protected function tearDown() : void
{
}
protected function createEntity(string $entityType, string $className)
protected function createEntity(string $entityType, ?string $className = null)
{
$em = $this->getMockBuilder(EntityManager::class)->disableOriginalConstructor()->getMock();
$defs = $this->metadata->get($entityType);
$entity = new $className($entityType, $defs, $em);
$classNameToUse = $className ?? BaseEntity::class;
$entity = new $classNameToUse($entityType, $defs, $this->entityManager);
return $entity;
}
@@ -236,4 +247,43 @@ class EntityTest extends \PHPUnit\Framework\TestCase
]);
$this->assertTrue($job->isAttributeChanged('object'));
}
public function testSetForeign()
{
$entity = $this->createEntity('Comment');
$entity->set([
'postName' => 'test',
]);
$this->assertEquals('test', $entity->get('postName'));
}
public function testSetJsonObject()
{
$entity = $this->createEntity('Test');
$value = '{"test": "1"}';
$entity->set([
'object' => '{"test": "1"}',
]);
$this->assertEquals(json_decode($value), $entity->get('object'));
}
public function testSetWrongType()
{
$entity = $this->createEntity('Test');
$entity->set([
'int' => '1',
]);
$this->assertEquals(1, $entity->get('int'));
$entity->set('int', '1');
$this->assertEquals(1, $entity->get('int'));
}
}