entityResolver->fieldList(EntityResolver::KEY_ENTITY_NAME, true) as $key => $field) { $attribute = $this->entityResolver->searchFieldAnnotation($key,[ Field::class ]); if ( $entity->__isset($key) ) { yield $attribute->name ?? $key => $entity->$key; } elseif ( $field->allowsNull() ) { yield $attribute->name ?? $key => null; } } } public function push(iterable $dataset) : Generator|array { $unmatched = []; foreach($dataset as $key => $value) { $field = $this->entityResolver->field(strtolower($key), EntityResolver::KEY_COLUMN_NAME, false) ?? $this->entityResolver->field(strtolower($key), EntityResolver::KEY_LC_ENTITY_NAME, false); if ( $field === null ) { if ($this->entityStrictFieldsDeclaration ) { throw new \Exception("Field `$key` can not be found within your entity ".static::class); } else { $unmatched[$key] = $value; } continue; } $type = $field->getTypes()[0]; if ( is_null($value) ) { yield $field->name => null; } elseif ( $field->expectType('array') ) { if ( is_string($value)) { if (substr($value, 0, 1) === "a") { yield $field->name => unserialize($value); } else { $data = json_decode($value, true); if (json_last_error() !== \JSON_ERROR_NONE) { throw new \Exception(sprintf("JSON error while decoding in EntityTrait : '%s' given %s", json_last_error_msg(), $value)); } yield $field->name => $data; } } elseif ( is_array($value) ) { yield $field->name => $value; } } elseif ( EntityField::isScalarType($type->type) ) { if ( $type->type === 'string' ) { $attribute = $this->entityResolver->searchFieldAnnotation($field->name, [ Field::class ] ); if ( $attribute->length ?? null ) { $value = mb_substr($value, 0, $attribute->length); } } elseif ( $type->type === 'bool' ) { $value = (bool) $value; } yield $field->name => $value; } elseif ( $value instanceof \UnitEnum ) { yield $field->name => $value; } elseif (enum_exists($type->type)) { yield $field->name => $type->type::from($value); } elseif ( ! $type->builtIn ) { try { yield $field->name => Ulmus::instanciateObject($type->type, [ $value ]); } catch(\Error $e) { throw new \Error(sprintf("%s for class '%s' on field '%s'", $e->getMessage(), get_class($this), $field->name)); } } } return $unmatched; } public function pullRelation(object $entity) : Generator { foreach($this->entityResolver->reflectedClass->getProperties(true) as $name => $field){ $relation = $this->entityResolver->searchFieldAnnotation($name, [ Relation::class ] ); if ($relation) { $ignore = $this->entityResolver->searchFieldAnnotation($name, [ Relation\Ignore::class ] ); if ($ignore && $ignore->ignoreExport) { if ( $relation->isOneToOne() ) { # @TODO TO INCLUDED INTO getTypes() RETURNED CLASS WHEN DONE ! yield $name => ( new \ReflectionClass($field->getTypes()[0]) )->newInstanceWithoutConstructor(); } else { # empty collection yield $name => []; } continue; } # @TODO Must fix recursive bug.. this last check is way too basic to work if ( $entity->__isset($name) && ($relation->entity ?? $relation->bridge) !== static::class ) { if ( null !== $value = $entity->__isset($name) ?? null ) { if ( is_iterable($value) ) { $list = []; foreach($value as $entityObj) { $list[] = $entityObj->entityGetDataset(false); } yield $name => $list; } elseif ( is_object($value) ) { yield $name => $value->entityGetDataset(false); } } } } } } }