diff --git a/src/OData/BaseResource.php b/src/OData/BaseResource.php index d56cb9b..de27abe 100644 --- a/src/OData/BaseResource.php +++ b/src/OData/BaseResource.php @@ -10,6 +10,7 @@ use JustBetter\DynamicsClient\Concerns\HasCasts; use JustBetter\DynamicsClient\Concerns\HasData; use JustBetter\DynamicsClient\Concerns\HasKeys; +use JustBetter\DynamicsClient\Exceptions\DynamicsException; use JustBetter\DynamicsClient\Query\QueryBuilder; use SaintSystems\OData\Entity; use SaintSystems\OData\ODataClient; @@ -28,7 +29,8 @@ abstract class BaseResource implements ArrayAccess, Arrayable final public function __construct(?string $connection = null, ?string $endpoint = null) { $this->connection ??= $connection ?? config('dynamics.connection'); - $this->endpoint ??= $endpoint ?? config('dynamics.resources.'.static::class, Str::afterLast(static::class, '\\')); + $this->endpoint ??= $endpoint ?? config('dynamics.resources.'.static::class, + Str::afterLast(static::class, '\\')); } public static function new(?string $connection = null, ?string $endpoint = null): static @@ -69,15 +71,16 @@ public function fromPage(BaseResource $page): static return $this; } - public function create(array $data): ?static + public function create(array $data): static { /** @var array $entities */ $entities = $this->client()->post($this->endpoint, $data); if (empty($entities)) { - return null; + throw new DynamicsException('No data returned after creation'); } + /** @var Entity $entity */ $entity = reset($entities); return static::new($this->connection, $this->endpoint)->fromEntity($entity); diff --git a/src/Query/QueryBuilder.php b/src/Query/QueryBuilder.php index 796b8bc..77744bd 100644 --- a/src/Query/QueryBuilder.php +++ b/src/Query/QueryBuilder.php @@ -37,12 +37,17 @@ public function __call(string $name, array $arguments): mixed return $this; } - public function mapToClass(Entity $entity): BaseResource + public function newResourceInstance(): BaseResource { /** @var class-string $class */ $class = $this->class; - return $class::new($this->connection, $this->endpoint)->fromEntity($entity); + return $class::new($this->connection, $this->endpoint); + } + + public function mapToClass(Entity $entity): BaseResource + { + return $this->newResourceInstance()->fromEntity($entity); } public function get(): Enumerable @@ -73,11 +78,7 @@ public function firstOrFail(): BaseResource public function find(mixed ...$values): ?BaseResource { - /** @var class-string $class */ - $class = $this->class; - - /** @var BaseResource $baseResource */ - $baseResource = app($class); + $baseResource = $this->newResourceInstance(); $combined = array_combine($baseResource->primaryKey, $values); @@ -108,6 +109,20 @@ public function findOrFail(mixed ...$values): BaseResource return $resource; } + public function firstOrCreate(array $attributes = [], array $values = []): BaseResource + { + /** @var ?BaseResource $resource */ + $resource = $this->where($attributes)->first(); + + if ($resource !== null) { + return $resource; + } + + $data = array_merge($attributes, $values); + + return $this->newResourceInstance()->create($data); + } + public function lazy(): LazyCollection { return LazyCollection::make(function (): Generator {