diff --git a/lib/Providers/Document/CollectionProperties.php b/lib/Providers/Document/CollectionProperties.php index 8847e89..1394ebc 100644 --- a/lib/Providers/Document/CollectionProperties.php +++ b/lib/Providers/Document/CollectionProperties.php @@ -9,7 +9,7 @@ declare(strict_types=1); namespace KTXM\ProviderJmapc\Providers\Document; -use KTXF\Resource\Documents\Collection\CollectionPropertiesMutableAbstract; +use KTXF\Documents\Collection\CollectionPropertiesMutableAbstract; /** * Document Collection Properties Implementation diff --git a/lib/Providers/Document/CollectionResource.php b/lib/Providers/Document/CollectionResource.php index 106a618..64ab2c5 100644 --- a/lib/Providers/Document/CollectionResource.php +++ b/lib/Providers/Document/CollectionResource.php @@ -9,7 +9,7 @@ declare(strict_types=1); namespace KTXM\ProviderJmapc\Providers\Document; -use KTXF\Resource\Documents\Collection\CollectionMutableAbstract; +use KTXF\Documents\Collection\CollectionMutableAbstract; /** * Document Collection Resource Implementation diff --git a/lib/Providers/Document/EntityProperties.php b/lib/Providers/Document/EntityProperties.php index fdfe3e6..4fa3c45 100644 --- a/lib/Providers/Document/EntityProperties.php +++ b/lib/Providers/Document/EntityProperties.php @@ -9,7 +9,7 @@ declare(strict_types=1); namespace KTXM\ProviderJmapc\Providers\Document; -use KTXF\Resource\Documents\Entity\EntityPropertiesMutableAbstract; +use KTXF\Documents\Entity\EntityPropertiesMutableAbstract; /** * Document Collection Properties Implementation diff --git a/lib/Providers/Document/EntityResource.php b/lib/Providers/Document/EntityResource.php index e2e6faa..8805413 100644 --- a/lib/Providers/Document/EntityResource.php +++ b/lib/Providers/Document/EntityResource.php @@ -9,7 +9,7 @@ declare(strict_types=1); namespace KTXM\ProviderJmapc\Providers\Document; -use KTXF\Resource\Documents\Entity\EntityMutableAbstract; +use KTXF\Documents\Entity\EntityMutableAbstract; /** * Mail Entity Resource Implementation diff --git a/lib/Providers/Document/Provider.php b/lib/Providers/Document/Provider.php index 13c5265..113d22f 100644 --- a/lib/Providers/Document/Provider.php +++ b/lib/Providers/Document/Provider.php @@ -9,11 +9,11 @@ declare(strict_types=1); namespace KTXM\ProviderJmapc\Providers\Document; -use KTXF\Resource\Documents\Provider\ProviderBaseInterface; -use KTXF\Resource\Documents\Provider\ProviderServiceMutateInterface; -use KTXF\Resource\Documents\Provider\ProviderServiceTestInterface; -use KTXF\Resource\Documents\Service\ServiceBaseInterface; -use KTXF\Resource\Documents\Service\ServiceMutableInterface; +use KTXF\Documents\Provider\ProviderBaseInterface; +use KTXF\Documents\Provider\ProviderServiceMutateInterface; +use KTXF\Documents\Provider\ProviderServiceTestInterface; +use KTXF\Documents\Service\ServiceBaseInterface; +use KTXF\Documents\Service\ServiceMutableInterface; use KTXF\Resource\Provider\ResourceServiceLocationInterface; use KTXF\Resource\Provider\ResourceServiceMutateInterface; use KTXM\ProviderJmapc\Service\Discovery; @@ -21,9 +21,9 @@ use KTXM\ProviderJmapc\Service\Remote\RemoteService; use KTXM\ProviderJmapc\Stores\ServiceStore; /** - * JMAP Mail Provider + * JMAP Documents Provider */ -class Provider implements ProviderServiceMutateInterface, ProviderServiceTestInterface +class Provider implements ProviderBaseInterface, ProviderServiceMutateInterface, ProviderServiceTestInterface { public const JSON_TYPE = ProviderBaseInterface::JSON_TYPE; @@ -63,7 +63,7 @@ class Provider implements ProviderServiceMutateInterface, ProviderServiceTestInt public function type(): string { - return self::TYPE_MAIL; + return self::TYPE_DOCUMENT; } public function identifier(): string @@ -170,7 +170,7 @@ class Provider implements ProviderServiceMutateInterface, ProviderServiceTestInt return $discovery->discover($identity, $location, $secret, $verifySSL); } - public function serviceTest(ServiceBaseInterface $service, array $options = []): array { + public function serviceTest(ServiceBaseInterface|ServiceMutableInterface $service, array $options = []): array { $startTime = microtime(true); try { diff --git a/lib/Providers/Document/Service.php b/lib/Providers/Document/Service.php index fd8ba33..d51a796 100644 --- a/lib/Providers/Document/Service.php +++ b/lib/Providers/Document/Service.php @@ -10,17 +10,20 @@ declare(strict_types=1); namespace KTXM\ProviderJmapc\Providers\Document; use Generator; -use KTXF\Resource\Provider\ResourceServiceIdentityInterface; -use KTXF\Resource\Provider\ResourceServiceLocationInterface; +use KTXF\Documents\Collection\CollectionBaseInterface; +use KTXF\Documents\Collection\CollectionMutableInterface; +use KTXF\Documents\Collection\CollectionPropertiesBaseInterface; +use KTXF\Documents\Service\ServiceBaseInterface; +use KTXF\Documents\Service\ServiceCollectionMutableInterface; +use KTXF\Documents\Service\ServiceConfigurableInterface; +use KTXF\Documents\Service\ServiceMutableInterface; use KTXF\Resource\Delta\Delta; -use KTXF\Resource\Documents\Collection\CollectionBaseInterface; -use KTXF\Resource\Documents\Collection\CollectionMutableInterface; -use KTXF\Resource\Documents\Service\ServiceBaseInterface; -use KTXF\Resource\Documents\Service\ServiceCollectionMutableInterface; -use KTXF\Resource\Documents\Service\ServiceConfigurableInterface; -use KTXF\Resource\Documents\Service\ServiceMutableInterface; use KTXF\Resource\Filter\Filter; use KTXF\Resource\Filter\IFilter; +use KTXF\Resource\Identifier\CollectionIdentifierInterface; +use KTXF\Resource\Identifier\EntityIdentifierInterface; +use KTXF\Resource\Provider\ResourceServiceIdentityInterface; +use KTXF\Resource\Provider\ResourceServiceLocationInterface; use KTXF\Resource\Range\IRange; use KTXF\Resource\Range\Range; use KTXF\Resource\Range\RangeType; @@ -316,18 +319,30 @@ class Service implements ServiceBaseInterface, ServiceMutableInterface, ServiceC return new CollectionResource(provider: $this->provider(), service: $this->identifier()); } - public function collectionCreate(string|int|null $location, CollectionMutableInterface $collection, array $options = []): CollectionBaseInterface + /** + * Convert incoming collection properties into a native CollectionResource + */ + private function collectionNative(CollectionPropertiesBaseInterface $properties, string|int|null $identifier = null): CollectionResource + { + if ($properties instanceof CollectionResource) { + return clone $properties; + } + $object = new CollectionResource(provider: $this->provider(), service: $this->identifier()); + $object->jsonDeserialize(array_filter([ + CollectionResource::PROPERTY_IDENTIFIER => $identifier, + CollectionResource::PROPERTY_PROPERTIES => $properties->jsonSerialize(), + ], fn($v) => $v !== null)); + return $object; + } + + public function collectionCreate(CollectionIdentifierInterface|null $target, CollectionPropertiesBaseInterface $properties, array $options = []): CollectionBaseInterface { $this->initialize(); - if ($collection instanceof CollectionResource === false) { - $object = new CollectionResource(provider: $this->provider(), service: $this->identifier()); - $object->jsonDeserialize($collection->jsonSerialize()); - $collection = $object; - } + $collection = $this->collectionNative($properties); $collection = $collection->toJmap(); - $collection = $this->remoteService->collectionCreate($location, $collection, $options); + $collection = $this->remoteService->collectionCreate($target?->collection(), $collection, $options); $object = new CollectionResource(provider: $this->provider(), service: $this->identifier()); $object->fromJmap($collection); @@ -335,15 +350,12 @@ class Service implements ServiceBaseInterface, ServiceMutableInterface, ServiceC return $object; } - public function collectionUpdate(string|int $identifier, CollectionMutableInterface $collection): CollectionBaseInterface + public function collectionUpdate(CollectionIdentifierInterface $target, CollectionPropertiesBaseInterface $properties): CollectionBaseInterface { $this->initialize(); - if ($collection instanceof CollectionResource === false) { - $object = new CollectionResource(provider: $this->provider(), service: $this->identifier()); - $object->jsonDeserialize($collection->jsonSerialize()); - $collection = $object; - } + $identifier = $target->collection(); + $collection = $this->collectionNative($properties, $identifier); $collection = $collection->toJmap(); $collection = $this->remoteService->collectionModify($identifier, $collection); @@ -354,14 +366,17 @@ class Service implements ServiceBaseInterface, ServiceMutableInterface, ServiceC return $object; } - public function collectionDelete(string|int $identifier, bool $force = false, bool $recursive = false): bool + public function collectionDelete(CollectionIdentifierInterface $target, bool $force = false): CollectionBaseInterface | true { $this->initialize(); - return $this->remoteService->collectionDestroy($identifier, $force, $recursive) !== null; + if ($this->remoteService->collectionDestroy($target->collection(), $force, $force) === null) { + throw new \RuntimeException("Failed to delete collection: {$target->collection()}"); + } + return true; } - public function collectionMove(string|int $identifier, string|int|null $targetLocation): CollectionBaseInterface + public function collectionMove(CollectionIdentifierInterface|null $target, CollectionIdentifierInterface $source): CollectionBaseInterface { // TODO: Implement collection move $this->initialize(); @@ -369,12 +384,20 @@ class Service implements ServiceBaseInterface, ServiceMutableInterface, ServiceC return $collection; } + public function collectionCopy(CollectionIdentifierInterface|null $target, CollectionIdentifierInterface $source): CollectionBaseInterface + { + // TODO: Implement collection copy + $this->initialize(); + $collection = new CollectionResource(provider: $this->provider(), service: $this->identifier()); + return $collection; + } + // Entity operations - public function entityList(string|int|null $collection, ?IFilter $filter = null, ?ISort $sort = null, ?IRange $range = null, ?array $properties = null): array + public function entityListBulk(string|int|null $collection, ?IFilter $filter = null, ?ISort $sort = null, ?IRange $range = null, ?array $properties = null): array { $this->initialize(); - + $result = $this->remoteService->entityList($collection, $filter, $sort, $range, $properties); $list = []; @@ -390,7 +413,7 @@ class Service implements ServiceBaseInterface, ServiceMutableInterface, ServiceC return $list; } - public function entityListStream(string|int $collection, ?IFilter $filter = null, ?ISort $sort = null, ?IRange $range = null, ?array $properties = null): Generator + public function entityListStream(string|int|null $collection, ?IFilter $filter = null, ?ISort $sort = null, ?IRange $range = null, ?array $properties = null): Generator { $this->initialize(); @@ -421,11 +444,11 @@ class Service implements ServiceBaseInterface, ServiceMutableInterface, ServiceC return new Range(); } - public function entityDelta(string|int|null $collection, string $signature, string $detail = 'ids'): Delta + public function entityDelta(string|int|null $collection, string $signature): Delta { $this->initialize(); - return $this->remoteService->entityDelta($collection, $signature, $detail); + return $this->remoteService->entityDelta($collection, $signature, 'ids'); } public function entityExtant(string|int|null $collection, string|int ...$identifiers): array @@ -435,48 +458,45 @@ class Service implements ServiceBaseInterface, ServiceMutableInterface, ServiceC return $this->remoteService->entityExtant(...$identifiers); } - public function entityFetch(string|int|null $collection, string|int ...$identifiers): array + public function entityFetchBulk(EntityIdentifierInterface ...$identifiers): array { $this->initialize(); - $entities = $this->remoteService->entityFetch(...$identifiers); - - foreach ($entities as &$entity) { + $entityIds = array_map(fn($identifier) => $identifier->entity(), $identifiers); + $entities = $this->remoteService->entityFetch(...$entityIds); + + $list = []; + foreach ($entities as $key => $entity) { if (is_array($entity) && isset($entity['id'])) { $object = new EntityResource(provider: $this->provider(), service: $this->identifier()); $object->fromJmap($entity); - $entity = $object; + $list[$object->identifier()] = $object; + } else { + $list[$key] = $entity; } } - return $entities; + return $list; } - public function entityRead(string|int|null $collection, string|int $identifier): ?string + public function entityFetchStream(EntityIdentifierInterface ...$identifiers): Generator + { + yield from $this->entityFetchBulk(...$identifiers); + } + + public function entityRead(EntityIdentifierInterface $target): ?string { return null; } - // Node operations - - public function nodeList(string|int|null $collection, bool $recursive = false, ?IFilter $filter = null, ?ISort $sort = null, ?IRange $range = null, ?array $properties = null): array + public function entityReadStream(EntityIdentifierInterface $target) { - return []; + return null; } - public function nodeListFilter(): IFilter + public function entityReadChunk(EntityIdentifierInterface $target, int $offset, int $length): ?string { - return new Filter(['']); - } - - public function nodeListSort(): ISort - { - return new Sort(['']); - } - - public function nodeDelta(string|int|null $collection, string $signature, string $detail = 'ids'): Delta - { - return new Delta(); + return null; } }