- WIP on notes 2.x

This commit is contained in:
mcndave committed 2024-05-28 08:59:12 -04:00
1 parent 2de3139c80
commit f3be11a590
42 files changed
+270 -820

No files matched your search

+61 -152
View File
@@ -4,7 +4,15 @@ namespace Ulmus;
use Notes\Attribute\Ignore;
use Psr\Http\Message\ServerRequestInterface;
use Ulmus\{Common\EntityResolver, Common\EntityField, Entity\EntityInterface, QueryBuilder\QueryBuilderInterface};
use Ulmus\{Attribute\Property\Join,
Attribute\Property\Relation,
Attribute\Property\ResettablePropertyInterface,
Attribute\Property\Virtual,
Common\EntityResolver,
Common\EntityField,
Entity\DatasetHandler,
Entity\EntityInterface,
QueryBuilder\QueryBuilderInterface};
use Ulmus\SearchRequest\{Attribute\SearchParameter,
SearchMethodEnum,
SearchRequestInterface,
@@ -14,6 +22,9 @@ use Ulmus\SearchRequest\{Attribute\SearchParameter,
trait EntityTrait {
use EventTrait;
#[Ignore]
public array $entityLoadedDataset = [];
#[Ignore]
protected bool $entityStrictFieldsDeclaration = false;
@@ -21,14 +32,23 @@ trait EntityTrait {
protected array $entityDatasetUnmatchedFields = [];
#[Ignore]
public array $entityLoadedDataset = [];
protected DatasetHandler $datasetHandler;
#[Ignore]
public function __construct(array $dataset = null) {
public function __construct(iterable|null $dataset = null)
{
$this->initializeEntity($dataset);
}
#[Ignore]
public function initializeEntity(iterable|null $dataset = null) : void
{
if ($dataset) {
$this->entityFillFromDataset($dataset);
$this->fromArray($dataset);
}
$this->datasetHandler = new DatasetHandler(static::resolveEntity(), $this->entityStrictFieldsDeclaration);
$this->resetVirtualProperties();
}
@@ -37,98 +57,55 @@ trait EntityTrait {
{
$loaded = $this->isLoaded();
$entityResolver = $this->resolveEntity();
$handler = $this->datasetHandler->push($dataset);
foreach($dataset as $key => $value) {
$field = $entityResolver->field(strtolower($key), EntityResolver::KEY_COLUMN_NAME, false) ?? $entityResolver->field(strtolower($key), EntityResolver::KEY_LC_ENTITY_NAME, false);
foreach($handler as $field => $value) {
$this->$field = $value;
}
# Temp. fix, incoming patch soon
$type = $field->getTypes()[0];
$this->entityDatasetUnmatchedFields = $handler->getReturn();
if ( $field === null ) {
if ($this->entityStrictFieldsDeclaration ) {
throw new \Exception("Field `$key` can not be found within your entity ".static::class);
}
else {
$this->entityDatasetUnmatchedFields[$key] = $value;
}
}
elseif ( is_null($value) ) {
$this->{$field->name} = null;
}
elseif ( $field->expectType('array') ) {
if ( is_string($value)) {
if (substr($value, 0, 1) === "a") {
$this->{$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));
}
$this->{$field->name} = $data;
}
}
elseif ( is_array($value) ) {
$this->{$field->name} = $value;
}
}
elseif ( EntityField::isScalarType($type->type) ) {
if ( $type->type === 'string' ) {
$annotation = $entityResolver->searchFieldAnnotation($field->name, [ Attribute\Property\Field::class ] );
if ( $annotation->length ?? null ) {
$value = mb_substr($value, 0, $annotation->length);
}
}
elseif ( $type->type === 'bool' ) {
$value = (bool) $value;
}
$this->{$field->name} = $value;
}
elseif ( $value instanceof \UnitEnum ) {
$this->{$field->name} = $value;
}
elseif (enum_exists($type->type)) {
$this->{$field->name} = $type->type::from($value);
}
elseif ( ! $type->builtIn ) {
try {
$this->{$field->name} = Ulmus::instanciateObject($type->type, [ $value ]);
}
catch(\Error $e) {
$f = $type->type;
throw new \Error(sprintf("%s for class '%s' on field '%s'", $e->getMessage(), get_class($this), $field->name));
}
}
# Keeping original data to diff on UPDATE query
if ( ! $loaded /* || $isLoadedDataset */ ) {
#if ( $field !== null ) {
# $annotation = $entityResolver->searchFieldAnnotation($field['name'], new Field() );
# $this->entityLoadedDataset[$annotation ? $annotation->name : $field['name']] = $dataset; # <--------- THIS TO FIX !!!!!!
#}
$this->entityLoadedDataset = array_change_key_case($dataset, \CASE_LOWER);
}
elseif ($overwriteDataset) {
$this->entityLoadedDataset = iterator_to_array(array_change_key_case($dataset, \CASE_LOWER)) + $this->entityLoadedDataset;
}
# Keeping original data to diff on UPDATE query
if ( ! $loaded ) {
$this->entityLoadedDataset = array_change_key_case(is_array($dataset) ? $dataset : iterator_to_array($dataset), \CASE_LOWER);
}
elseif ($overwriteDataset) {
$this->entityLoadedDataset = array_change_key_case(is_array($dataset) ? $dataset : iterator_to_array($dataset), \CASE_LOWER) + $this->entityLoadedDataset;
}
return $this;
}
#[Ignore]
public function entityGetDataset(bool $includeRelations = false, bool $returnSource = false, bool $rewriteValue = true) : array
{
if ( $returnSource ) {
return $this->entityLoadedDataset;
}
$dataset = [];
foreach($this->datasetHandler->pull($this) as $field => $value) {
$dataset[$field] = $rewriteValue ? static::repository()->adapter->adapter()->writableValue($value) : $value;
}
if ($includeRelations) {
foreach($this->datasetHandler->pullRelation($this) as $field => $object) {
$dataset[$field] = $object;
}
}
return $dataset;
}
#[Ignore]
public function resetVirtualProperties() : self
{
foreach($this->resolveEntity()->reflectedClass->getProperties(true) as $prop => $property) {
foreach($this->resolveEntity()->reflectedClass->getProperties(true) as $field => $property) {
foreach($property->attributes as $tag) {
if ( in_array(strtolower($tag->tag), [ 'relation', 'join', 'virtual' ] ) ) {
unset($this->$prop);
if ( $tag->object instanceof ResettablePropertyInterface ) {
unset($this->$field);
}
}
}
@@ -146,74 +123,6 @@ trait EntityTrait {
return $this->entityFillFromDataset($dataset);
}
public function entityGetDataset(bool $includeRelations = false, bool $returnSource = false, bool $rewriteValue = true) : array
{
if ( $returnSource ) {
return $this->entityLoadedDataset;
}
$dataset = [];
$entityResolver = $this->resolveEntity();
foreach($entityResolver->fieldList(Common\EntityResolver::KEY_ENTITY_NAME, true) as $key => $field) {
$annotation = $entityResolver->searchFieldAnnotation($key, [ Attribute\Property\Field::class ]);
if ( isset($this->$key) ) {
$dataset[$annotation->name ?? $key] = $rewriteValue ?
static::repository()->adapter->adapter()->writableValue($this->$key)
:
$this->$key;
}
elseif ( $field->allowsNull() ) {
$dataset[$annotation->name ?? $key] = null;
}
}
if ($includeRelations) {
foreach($entityResolver->reflectedClass->getProperties(true) as $name => $field){
$relation = $entityResolver->searchFieldAnnotation($name, [ Attribute\Property\Relation::class ] );
if ($relation) {
$ignore = $entityResolver->searchFieldAnnotation($name, [ Attribute\Property\Relation\Ignore::class ] );
if ($ignore && $ignore->ignoreExport) {
if ( $relation->isOneToOne() ) {
# empty object
$dataset[$name] = ( new \ReflectionClass($field->getTypes()[0]) )->newInstanceWithoutConstructor();
}
else {
# empty collection
$dataset[$name] = [];
}
continue;
}
# @TODO Must fix recursive bug.. this last check is way too basic to work
if ( isset($this->$name) && ($relation->entity ?? $relation->bridge) !== static::class ) {
if ( null !== $value = $this->$name ?? null ) {
if ( is_iterable($value) ) {
$list = [];
foreach($value as $entity) {
$list[] = $entity->entityGetDataset(false);
}
$dataset[$name] = $list;
}
elseif ( is_object($value) ) {
$dataset[$name] = $value->entityGetDataset(false);
}
}
}
}
}
}
return $dataset;
}
#[Ignore]
public function toArray($includeRelations = false, array $filterFields = null, bool $rewriteValue = true) : array
{