diff --git a/app/Libraries/Api/Models/BaseApiModel.php b/app/Libraries/Api/Models/BaseApiModel.php deleted file mode 100644 index 5d7b3a4a9..000000000 --- a/app/Libraries/Api/Models/BaseApiModel.php +++ /dev/null @@ -1,1165 +0,0 @@ - '', - 'resource' => '', - 'search' => '', - ]; - - /** - * The number of entities to return for pagination. - * - * @var int - */ - protected $perPage = 15; - - /** - * Create a new Eloquent model instance. - * - * @return void - */ - public function __construct(array $attributes = []) - { - $this->fill($attributes); - } - - /** - * Fill the model with an array of attributes. - * - * @return $this - * - * @throws MassAssignmentException - */ - public function fill(array $attributes) - { - $totallyGuarded = $this->totallyGuarded(); - - foreach ($this->fillableFromArray($attributes) as $key => $value) { - // The developers may choose to place some attributes in the "fillable" - // array, which means only those attributes may be set through mass - // assignment to the model, and all others will just be ignored. - if ($this->isFillable($key)) { - $this->setAttribute($key, $value); - } elseif ($totallyGuarded) { - throw new MassAssignmentException($key); - } - } - - return $this; - } - - /** - * Fill the model with an array of attributes. Force mass assignment. - * - * @return $this - */ - public function forceFill(array $attributes) - { - // Since some versions of PHP have a bug that prevents it from properly - // binding the late static context in a closure, we will first store - // the model in a variable, which we will then use in the closure. - $model = $this; - - return static::unguarded(function () use ($model, $attributes) { - return $model->fill($attributes); - }); - } - - /** - * Get the fillable attributes of a given array. - * - * @return array - */ - protected function fillableFromArray(array $attributes) - { - if (count($this->fillable) > 0 && !static::$unguarded) { - return array_intersect_key($attributes, array_flip($this->fillable)); - } - - return $attributes; - } - - /** - * Create a new instance of the given model. - * - * @param array $attributes - * @return \Jenssegers\Model\Model - */ - public function newInstance($attributes = []) - { - $model = new static((array) $attributes); - - return $model; - } - - /** - * Create a collection of models from plain arrays. - * - * @return array - */ - public static function hydrate(array $items) - { - $instance = new static(); - - $items = array_map(function ($item) use ($instance) { - return $instance->newInstance($item); - }, $items); - - return $items; - } - - /** - * Get the hidden attributes for the model. - * - * @return array - */ - public function getHidden() - { - return $this->hidden; - } - - /** - * Set the hidden attributes for the model. - * - * @return $this - */ - public function setHidden(array $hidden) - { - $this->hidden = $hidden; - - return $this; - } - - /** - * Make the given, typically visible, attributes hidden. - * - * @param array|string|null $attributes - * @return $this - */ - public function makeHidden($attributes = null) - { - $attributes = is_array($attributes) ? $attributes : func_get_args(); - - $this->hidden = array_merge($this->hidden, $attributes); - - return $this; - } - - /** - * Make the given, typically hidden, attributes visible. - * - * @param array|string $attributes - * @return $this - */ - public function withHidden($attributes) - { - $this->hidden = array_diff($this->hidden, (array) $attributes); - - return $this; - } - - /** - * Get the visible attributes for the model. - * - * @return array - */ - public function getVisible() - { - return $this->visible; - } - - /** - * Set the visible attributes for the model. - * - * @return $this - */ - public function setVisible(array $visible) - { - $this->visible = $visible; - - return $this; - } - - /** - * Make the given, typically hidden, attributes visible. - * - * @param array|string|null $attributes - * @return $this - */ - public function makeVisible($attributes = null) - { - $attributes = is_array($attributes) ? $attributes : func_get_args(); - - $this->visible = array_merge($this->visible, $attributes); - - return $this; - } - - /** - * Set the accessors to append to model arrays. - * - * @return $this - */ - public function setAppends(array $appends) - { - $this->appends = $appends; - - return $this; - } - - /** - * Get the fillable attributes for the model. - * - * @return array - */ - public function getFillable(): array - { - return $this->fillable; - } - - /** - * Set the fillable attributes for the model. - * - * @return $this - */ - public function fillable(array $fillable) - { - $this->fillable = $fillable; - - return $this; - } - - /** - * Get the guarded attributes for the model. - * - * @return array - */ - public function getGuarded() - { - return $this->guarded; - } - - /** - * Set the guarded attributes for the model. - * - * @return $this - */ - public function guard(array $guarded) - { - $this->guarded = $guarded; - - return $this; - } - - /** - * Disable all mass assignable restrictions. - * - * @param bool $state - * @return void - */ - public static function unguard($state = true) - { - static::$unguarded = $state; - } - - /** - * Enable the mass assignment restrictions. - * - * @return void - */ - public static function reguard() - { - static::$unguarded = false; - } - - /** - * Determine if current state is "unguarded". - * - * @return bool - */ - public static function isUnguarded() - { - return static::$unguarded; - } - - /** - * Run the given callable while being unguarded. - * - * @return mixed - */ - public static function unguarded(callable $callback) - { - if (static::$unguarded) { - return $callback(); - } - - static::unguard(); - - $result = $callback(); - - static::reguard(); - - return $result; - } - - /** - * Determine if the given attribute may be mass assigned. - * - * @param string $key - * @return bool - */ - public function isFillable($key) - { - if (static::$unguarded) { - return true; - } - - // If the key is in the "fillable" array, we can of course assume that it's - // a fillable attribute. Otherwise, we will check the guarded array when - // we need to determine if the attribute is black-listed on the model. - if (in_array($key, $this->fillable)) { - return true; - } - - if ($this->isGuarded($key)) { - return false; - } - - return empty($this->fillable); - } - - /** - * Determine if the given key is guarded. - * - * @param string $key - * @return bool - */ - public function isGuarded($key) - { - return in_array($key, $this->guarded) || $this->guarded == ['*']; - } - - /** - * Determine if the model is totally guarded. - * - * @return bool - */ - public function totallyGuarded() - { - return count($this->fillable) == 0 && $this->guarded == ['*']; - } - - /** - * Convert the model instance to JSON. - * - * @param int $options - * @return string - */ - public function toJson($options = 0) - { - return json_encode($this->jsonSerialize(), $options); - } - - /** - * Convert the object into something JSON serializable. - * - * @return array - */ - public function jsonSerialize(): mixed - { - return $this->toArray(); - } - - /** - * Convert the model instance to an array. - * - * @return array - */ - public function toArray() - { - return $this->attributesToArray(); - } - - /** - * Convert the model's attributes to an array. - * - * @return array - */ - public function attributesToArray() - { - $attributes = $this->getArrayableAttributes(); - - $mutatedAttributes = $this->getMutatedAttributes(); - - // We want to spin through all the mutated attributes for this model and call - // the mutator for the attribute. We cache off every mutated attributes so - // we don't have to constantly check on attributes that actually change. - foreach ($mutatedAttributes as $key) { - if (!array_key_exists($key, $attributes)) { - continue; - } - - $attributes[$key] = $this->mutateAttributeForArray( - $key, - $attributes[$key] - ); - } - - // Next we will handle any casts that have been setup for this model and cast - // the values to their appropriate type. If the attribute has a mutator we - // will not perform the cast on those attributes to avoid any confusion. - foreach ($this->casts as $key => $value) { - if ( - !array_key_exists($key, $attributes) || - in_array($key, $mutatedAttributes) - ) { - continue; - } - - $attributes[$key] = $this->castAttribute( - $key, - $attributes[$key] - ); - } - - // Here we will grab all of the appended, calculated attributes to this model - // as these attributes are not really in the attributes array, but are run - // when we need to array or JSON the model for convenience to the coder. - foreach ($this->getArrayableAppends() as $key) { - $attributes[$key] = $this->mutateAttributeForArray($key, null); - } - - return $attributes; - } - - /** - * Get an attribute array of all arrayable attributes. - * - * @return array - */ - protected function getArrayableAttributes() - { - return $this->getArrayableItems($this->attributes); - } - - /** - * Get all of the appendable values that are arrayable. - * - * @return array - */ - protected function getArrayableAppends() - { - if (!count($this->appends)) { - return []; - } - - return $this->getArrayableItems( - array_combine($this->appends, $this->appends) - ); - } - - /** - * Get an attribute array of all arrayable values. - * - * @return array - */ - protected function getArrayableItems(array $values) - { - if (count($this->getVisible()) > 0) { - return array_intersect_key($values, array_flip($this->getVisible())); - } - - return array_diff_key($values, array_flip($this->getHidden())); - } - - /** - * Get an attribute from the model. - * - * @param string $key - * @return mixed - */ - public function getAttribute($key) - { - if ( - array_key_exists($key, $this->attributes) || - $this->hasGetMutator($key) - ) { - return $this->getAttributeValue($key); - } - - return $this->getRelationValue($key); - } - - /** - * Get a plain attribute (not a relationship). - * - * @param string $key - * @return mixed - */ - protected function getAttributeValue($key) - { - $value = $this->getAttributeFromArray($key); - - // If the attribute has a get mutator, we will call that then return what - // it returns as the value, which is useful for transforming values on - // retrieval from the model to a form that is more useful for usage. - if ($this->hasGetMutator($key)) { - app('debug')->log(class_basename(get_called_class()), $key, true); - - return $this->mutateAttribute($key, $value); - } - - // If the attribute exists within the cast array, we will convert it to - // an appropriate native PHP type dependant upon the associated value - // given with the key in the pair. Dayle made this comment line up. - if ($this->hasCast($key)) { - $value = $this->castAttribute($key, $value); - } - - app('debug')->log(class_basename(get_called_class()), $key); - - return $value; - } - - /** - * Get an attribute from the $attributes array. - * - * @param string $key - * @return mixed - */ - protected function getAttributeFromArray($key) - { - if (array_key_exists($key, $this->attributes)) { - return $this->attributes[$key]; - } - } - - /** - * Determine if a get mutator exists for an attribute. - * - * @param string $key - * @return bool - */ - public function hasGetMutator($key) - { - return method_exists($this, 'get' . Str::studly($key) . 'Attribute'); - } - - /** - * Get the value of an attribute using its mutator. - * - * @param string $key - * @param mixed $value - * @return mixed - */ - protected function mutateAttribute($key, $value) - { - return $this->{'get' . Str::studly($key) . 'Attribute'}($value); - } - - /** - * Get the value of an attribute using its mutator for array conversion. - * - * @param string $key - * @param mixed $value - * @return mixed - */ - protected function mutateAttributeForArray($key, $value) - { - $value = $this->mutateAttribute($key, $value); - - return $value instanceof Arrayable ? $value->toArray() : $value; - } - - /** - * Determine whether an attribute should be casted to a native type. - * - * @param string $key - * @return bool - */ - protected function hasCast($key) - { - return array_key_exists($key, $this->casts); - } - - /** - * Determine whether a value is JSON castable for inbound manipulation. - * - * @param string $key - * @return bool - */ - protected function isJsonCastable($key) - { - return $this->hasCast($key) && - in_array($this->getCastType($key), ['array', 'json', 'object'], true); - } - - /** - * Get the type of cast for a model attribute. - * - * @param string $key - * @return string - */ - protected function getCastType($key) - { - return trim(strtolower($this->casts[$key])); - } - - /** - * Cast an attribute to a native PHP type. - * - * @param string $key - * @param mixed $value - * @return mixed - */ - protected function castAttribute($key, $value) - { - if (is_null($value)) { - return $value; - } - - switch ($this->getCastType($key)) { - case 'int': - case 'integer': - return (int) $value; - case 'real': - case 'float': - case 'double': - return (float) $value; - case 'string': - return (string) $value; - case 'bool': - case 'boolean': - return (bool) $value; - case 'object': - return $this->fromJson($value, true); - case 'array': - case 'json': - return $this->fromJson($value); - case 'collection': - return new BaseCollection($this->fromJson($value)); - case 'datetime': - return $this->asDateTime($value); - default: - return $value; - } - } - - /** - * Set a given attribute on the model. - * - * @param string $key - * @param mixed $value - * @return $this - */ - public function setAttribute($key, $value) - { - // First we will check for the presence of a mutator for the set operation - // which simply lets the developers tweak the attribute as it is set on - // the model, such as "json_encoding" an listing of data for storage. - if ($this->hasSetMutator($key)) { - $method = 'set' . Str::studly($key) . 'Attribute'; - - return $this->{$method}($value); - } - - if ($this->isJsonCastable($key) && !is_null($value)) { - $value = $this->asJson($value); - } - - $this->attributes[$key] = $value; - - return $this; - } - - /** - * Determine if a set mutator exists for an attribute. - * - * @param string $key - * @return bool - */ - public function hasSetMutator($key) - { - return method_exists($this, 'set' . Str::studly($key) . 'Attribute'); - } - - /** - * Encode the given value as JSON. - * - * @param mixed $value - * @return string - */ - public function asJson($value) - { - return json_encode($value); - } - - /** - * Return a timestamp as DateTime object. - * - * @param mixed $value - * @return \Illuminate\Support\Carbon - */ - public function asDateTime($value) - { - if ($value instanceof Carbon) { - return $value; - } - - if ($value instanceof DateTimeInterface) { - return new Carbon( - $value->format('Y-m-d H:i:s.u'), - $value->getTimezone() - ); - } - - if (is_numeric($value)) { - return Carbon::createFromTimestamp($value); - } - - if ($this->isStandardDateFormat($value)) { - return Carbon::createFromFormat('Y-m-d', $value)->startOfDay(); - } - - return new Carbon($value); - } - - public function getClassName() - { - return (new \ReflectionClass($this))->getShortName(); - } - - /** - * Determine if the given value is a standard date format. - * - * @param string $value - * @return bool - */ - protected function isStandardDateFormat($value) - { - return preg_match('/^(\d{4})-(\d{1,2})-(\d{1,2})$/', $value); - } - - /** - * Decode the given JSON back into an array or object. - * - * @param string $value - * @param bool $asObject - * @return mixed - */ - public function fromJson($value, $asObject = false) - { - return json_decode($value, !$asObject); - } - - /** - * Clone the model into a new, non-existing instance. - * - * @return \Jenssegers\Model\Model - */ - public function replicate(array $except = null) - { - $except = $except ?: []; - - $attributes = Arr::except($this->attributes, $except); - - return with($instance = new static())->fill($attributes); - } - - /** - * Get all of the current attributes on the model. - * - * @return array - */ - public function getAttributes() - { - return $this->attributes; - } - - /** - * Get the mutated attributes for a given instance. - * - * @return array - */ - public function getMutatedAttributes() - { - $class = get_class($this); - - if (!isset(static::$mutatorCache[$class])) { - static::cacheMutatedAttributes($class); - } - - return static::$mutatorCache[$class]; - } - - /** - * Extract and cache all the mutated attributes of a class. - * - * @param string $class - * @return void - */ - public static function cacheMutatedAttributes($class) - { - $mutatedAttributes = []; - - // Here we will extract all of the mutated attributes so that we can quickly - // spin through them after we export models to their array form, which we - // need to be fast. This'll let us know the attributes that can mutate. - if (preg_match_all('/(?<=^|;)get([^;]+?)Attribute(;|$)/', implode(';', get_class_methods($class)), $matches)) { - foreach ($matches[1] as $match) { - if (static::$snakeAttributes) { - $match = Str::snake($match); - } - - $mutatedAttributes[] = lcfirst($match); - } - } - - static::$mutatorCache[$class] = $mutatedAttributes; - } - - /** - * Create a new Eloquent Collection instance. - * - * @param array $models - * @return \Illuminate\Database\Eloquent\Collection - */ - public function newCollection($models = []) - { - if ($models instanceof BaseCollection) { - return $models; - } - - return new BaseCollection($models); - } - - /** - * Dynamically retrieve attributes on the model. - * - * @param string $key - */ - public function __get($key): mixed - { - $value = $this->getAttribute($key); - - if ($value === null && method_exists($this, 'getAugmentedModel') && $this->getAugmentedModel()) { - return $this->getAugmentedModel()->{$key}; - } - - return $value; - } - - /** - * TODO: Consider adding _isset() here? e.g. for WEB-1245 - */ - - /** - * Dynamically set attributes on the model. - * - * @param string $key - * @param mixed $value - */ - public function __set($key, $value): void - { - $this->setAttribute($key, $value); - } - - /** - * Determine if the given attribute exists. - * - * @param mixed $offset - * @return bool - */ - public function offsetExists($offset): bool - { - return isset($this->{$offset}); - } - - /** - * Get the value for a given offset. - * - * @param mixed $offset - * @return mixed - */ - public function offsetGet($offset): mixed - { - return $this->{$offset}; - } - - /** - * Set the value for a given offset. - * - * @param mixed $offset - * @param mixed $value - * @return void - */ - public function offsetSet($offset, $value): void - { - $this->{$offset} = $value; - } - - /** - * Unset the value for a given offset. - * - * @param mixed $offset - * @return void - */ - public function offsetUnset($offset): void - { - unset($this->{$offset}); - } - - /** - * Get the number of models to return per page. - * - * @return int - */ - public function getPerPage() - { - return $this->perPage; - } - - /** - * Set the number of models to return per page. - * - * @param int $perPage - * @return $this - */ - public function setPerPage($perPage) - { - $this->perPage = $perPage; - - return $this; - } - - /** - * Get the endpoint - * - * @return string endpoint - */ - public function getEndpoint($type) - { - return $this->endpoints[$type]; - } - - public function getTable() - { - } - - /** - * Implement Basic URLRoutable functions - * - */ - - public function getRouteKey() - { - return $this->getAttribute($this->getRouteKeyName()); - } - - public function getRouteKeyName() - { - return $this->getKeyName(); - } - - public function resolveRouteBinding($value, $field = null) - { - return $this->entity; - } - - public function resolveChildRouteBinding($childType, $value, $field) - { - } - - public function getKeyName() - { - return $this->primaryKey; - } - - /** - * TODO: Implement TwillModelContract - */ - public function scopePublished(Builder $query): Builder - { - return $query; - } - - public function scopeAccessible(Builder $query): Builder - { - return $query; - } - - public function scopeOnlyTrashed(Builder $query): Builder - { - return $query; - } - - public function scopeDraft(Builder $query): Builder - { - return $query; - } - - public function getTranslatedAttributes(): array - { - return array(); - } - - /** - * Determine if an attribute exists on the model. - * - * @param string $key - */ - public function __isset($key): bool - { - return (isset($this->attributes[$key]) || isset($this->relations[$key])) || - ($this->hasGetMutator($key) && !is_null($this->getAttributeValue($key))); - } - - /** - * Unset an attribute on the model. - * - * @param string $key - */ - public function __unset($key): void - { - unset($this->attributes[$key]); - } - - /** - * Handle dynamic static method calls into the method. - * - * @param string $method - * @param array $parameters - */ - public static function __callStatic($method, $parameters): mixed - { - $instance = new static(); - - return call_user_func_array([$instance, $method], $parameters); - } - - /** - * Convert the model to its string representation. - * - * @return string - */ - public function __toString(): string - { - return $this->toJson(); - } -} diff --git a/app/Models/Api/Artist.php b/app/Models/Api/Artist.php index e8fdb0c9b..8c01efea1 100644 --- a/app/Models/Api/Artist.php +++ b/app/Models/Api/Artist.php @@ -2,12 +2,12 @@ namespace App\Models\Api; -use App\Libraries\Api\Models\BaseApiModel; +use Aic\Hub\Foundation\Library\Api\Models\BaseApiModel; use App\Helpers\StringHelpers; class Artist extends BaseApiModel { - protected $endpoints = [ + protected array $endpoints = [ 'collection' => '/api/v1/artists', 'resource' => '/api/v1/artists/{id}', 'search' => '/api/v1/artists/search' diff --git a/app/Models/Api/Artwork.php b/app/Models/Api/Artwork.php index 985062cf6..ae9a9a8f5 100644 --- a/app/Models/Api/Artwork.php +++ b/app/Models/Api/Artwork.php @@ -2,14 +2,14 @@ namespace App\Models\Api; -use App\Libraries\Api\Models\BaseApiModel; +use Aic\Hub\Foundation\Library\Api\Models\BaseApiModel; use Aic\Hub\Foundation\Library\Api\Builders\ApiModelBuilder; use App\Models\Behaviors\HasMediasApi; use App\Models\Behaviors\HasFeaturedRelated; use App\Helpers\DateHelpers; use App\Helpers\ImageHelpers; use App\Helpers\StringHelpers; -use Database\Factories\Api\HasApiFactory; +use Aic\Hub\Foundation\Library\Api\Models\Behaviors\HasApiFactory; class Artwork extends BaseApiModel { @@ -29,7 +29,7 @@ class Artwork extends BaseApiModel protected $showDefaultRelatedItems = true; - protected $endpoints = [ + protected array $endpoints = [ 'collection' => '/api/v1/artworks', 'resource' => '/api/v1/artworks/{id}', 'search' => '/api/v1/artworks/search', diff --git a/app/Models/Api/ArtworkType.php b/app/Models/Api/ArtworkType.php index 9328cbd19..f8dd1c4a6 100644 --- a/app/Models/Api/ArtworkType.php +++ b/app/Models/Api/ArtworkType.php @@ -2,11 +2,11 @@ namespace App\Models\Api; -use App\Libraries\Api\Models\BaseApiModel; +use Aic\Hub\Foundation\Library\Api\Models\BaseApiModel; class ArtworkType extends BaseApiModel { - protected $endpoints = [ + protected array $endpoints = [ 'collection' => '/api/v1/artwork-types', 'resource' => '/api/v1/artwork-types/{id}', 'search' => '/api/v1/artwork-types/search', diff --git a/app/Models/Api/Asset.php b/app/Models/Api/Asset.php index 02d845495..96c4cd826 100644 --- a/app/Models/Api/Asset.php +++ b/app/Models/Api/Asset.php @@ -2,7 +2,7 @@ namespace App\Models\Api; -use App\Libraries\Api\Models\BaseApiModel; +use Aic\Hub\Foundation\Library\Api\Models\BaseApiModel; use Aic\Hub\Foundation\Library\Api\Builders\ApiModelBuilder; use App\Models\Behaviors\HasMediasApi; use App\Helpers\ImageHelpers; @@ -16,7 +16,7 @@ class Asset extends BaseApiModel imageFront as public imageDams; } - protected $endpoints = [ + protected array $endpoints = [ 'collection' => '/api/v1/assets', 'resource' => '/api/v1/assets/{id}', 'search' => '/api/v1/assets/search', diff --git a/app/Models/Api/Category.php b/app/Models/Api/Category.php index 352bd2455..0b17eb98a 100644 --- a/app/Models/Api/Category.php +++ b/app/Models/Api/Category.php @@ -2,11 +2,11 @@ namespace App\Models\Api; -use App\Libraries\Api\Models\BaseApiModel; +use Aic\Hub\Foundation\Library\Api\Models\BaseApiModel; class Category extends BaseApiModel { - protected $endpoints = [ + protected array $endpoints = [ 'collection' => '/api/v1/categories', 'resource' => '/api/v1/categories/{id}', 'search' => '/api/v1/categories/search' diff --git a/app/Models/Api/CategoryTerm.php b/app/Models/Api/CategoryTerm.php index 76ec75cc9..34916b6a8 100644 --- a/app/Models/Api/CategoryTerm.php +++ b/app/Models/Api/CategoryTerm.php @@ -2,11 +2,11 @@ namespace App\Models\Api; -use App\Libraries\Api\Models\BaseApiModel; +use Aic\Hub\Foundation\Library\Api\Models\BaseApiModel; class CategoryTerm extends BaseApiModel { - protected $endpoints = [ + protected array $endpoints = [ 'collection' => '/api/v1/category-terms', 'resource' => '/api/v1/category-terms/{id}', 'search' => '/api/v1/category-terms/search', diff --git a/app/Models/Api/Department.php b/app/Models/Api/Department.php index b3eff93f7..0be0e60b0 100644 --- a/app/Models/Api/Department.php +++ b/app/Models/Api/Department.php @@ -2,12 +2,12 @@ namespace App\Models\Api; -use App\Libraries\Api\Models\BaseApiModel; +use Aic\Hub\Foundation\Library\Api\Models\BaseApiModel; use App\Helpers\StringHelpers; class Department extends BaseApiModel { - protected $endpoints = [ + protected array $endpoints = [ 'collection' => '/api/v1/departments', 'resource' => '/api/v1/departments/{id}', 'search' => '/api/v1/departments/search', diff --git a/app/Models/Api/Exhibition.php b/app/Models/Api/Exhibition.php index 1ecc1368c..6c3bb2f41 100644 --- a/app/Models/Api/Exhibition.php +++ b/app/Models/Api/Exhibition.php @@ -4,10 +4,10 @@ use Illuminate\Support\Carbon; use App\Models\Behaviors\HasFeaturedRelated; -use App\Libraries\Api\Models\BaseApiModel; +use Aic\Hub\Foundation\Library\Api\Models\BaseApiModel; use Aic\Hub\Foundation\Library\Api\Builders\ApiModelBuilder; use App\Helpers\StringHelpers; -use Database\Factories\Api\HasApiFactory; +use Aic\Hub\Foundation\Library\Api\Models\Behaviors\HasApiFactory; class Exhibition extends BaseApiModel { @@ -17,7 +17,7 @@ class Exhibition extends BaseApiModel use HasApiFactory; - protected $endpoints = [ + protected array $endpoints = [ 'collection' => '/api/v1/exhibitions', 'resource' => '/api/v1/exhibitions/{id}', 'search' => '/api/v1/exhibitions/search', diff --git a/app/Models/Api/Gallery.php b/app/Models/Api/Gallery.php index 635489878..990d35899 100644 --- a/app/Models/Api/Gallery.php +++ b/app/Models/Api/Gallery.php @@ -2,12 +2,12 @@ namespace App\Models\Api; -use App\Libraries\Api\Models\BaseApiModel; +use Aic\Hub\Foundation\Library\Api\Models\BaseApiModel; use App\Helpers\StringHelpers; class Gallery extends BaseApiModel { - protected $endpoints = [ + protected array $endpoints = [ 'collection' => '/api/v1/galleries', 'resource' => '/api/v1/galleries/{id}', 'search' => '/api/v1/galleries/search', diff --git a/app/Models/Api/Image.php b/app/Models/Api/Image.php index a358104b4..64a55315d 100644 --- a/app/Models/Api/Image.php +++ b/app/Models/Api/Image.php @@ -2,12 +2,12 @@ namespace App\Models\Api; -use App\Libraries\Api\Models\BaseApiModel; +use Aic\Hub\Foundation\Library\Api\Models\BaseApiModel; use DamsImageService; class Image extends BaseApiModel { - protected $endpoints = [ + protected array $endpoints = [ 'collection' => '/api/v1/images', 'resource' => '/api/v1/images/{id}', 'search' => '/api/v1/images/search' diff --git a/app/Models/Api/Place.php b/app/Models/Api/Place.php index e297408e5..d6207a35b 100644 --- a/app/Models/Api/Place.php +++ b/app/Models/Api/Place.php @@ -2,11 +2,11 @@ namespace App\Models\Api; -use App\Libraries\Api\Models\BaseApiModel; +use Aic\Hub\Foundation\Library\Api\Models\BaseApiModel; class Place extends BaseApiModel { - protected $endpoints = [ + protected array $endpoints = [ 'collection' => '/api/v1/places', 'search' => '/api/v1/places/search' ]; diff --git a/app/Models/Api/Publication.php b/app/Models/Api/Publication.php index 1eccb6402..b21343407 100644 --- a/app/Models/Api/Publication.php +++ b/app/Models/Api/Publication.php @@ -2,11 +2,11 @@ namespace App\Models\Api; -use App\Libraries\Api\Models\BaseApiModel; +use Aic\Hub\Foundation\Library\Api\Models\BaseApiModel; class Publication extends BaseApiModel { - protected $endpoints = [ + protected array $endpoints = [ 'collection' => '/api/v1/publications', 'resource' => '/api/v1/publications/{id}', 'search' => '/api/v1/publications/search' diff --git a/app/Models/Api/Search.php b/app/Models/Api/Search.php index 432f9f149..49b11d09a 100644 --- a/app/Models/Api/Search.php +++ b/app/Models/Api/Search.php @@ -2,7 +2,7 @@ namespace App\Models\Api; -use App\Libraries\Api\Models\BaseApiModel; +use Aic\Hub\Foundation\Library\Api\Models\BaseApiModel; use Aic\Hub\Foundation\Library\Api\Builders\ApiModelBuilderSearch; use App\Libraries\Search\Filters\Departments as DepartmentFilter; use Illuminate\Database\Eloquent\Builder; @@ -13,7 +13,7 @@ class Search extends BaseApiModel { - protected $endpoints = [ + protected array $endpoints = [ 'search' => '/api/v1/search', 'msearch' => '/api/v1/msearch', ]; diff --git a/app/Models/Api/Section.php b/app/Models/Api/Section.php index 6da427554..d14890f8b 100644 --- a/app/Models/Api/Section.php +++ b/app/Models/Api/Section.php @@ -2,11 +2,11 @@ namespace App\Models\Api; -use App\Libraries\Api\Models\BaseApiModel; +use Aic\Hub\Foundation\Library\Api\Models\BaseApiModel; class Section extends BaseApiModel { - protected $endpoints = [ + protected array $endpoints = [ 'collection' => '/api/v1/sections', 'resource' => '/api/v1/sections/{id}', 'search' => '/api/v1/sections/search' diff --git a/app/Models/Api/ShopItem.php b/app/Models/Api/ShopItem.php index 523011aa0..ccd6a7a0d 100644 --- a/app/Models/Api/ShopItem.php +++ b/app/Models/Api/ShopItem.php @@ -2,7 +2,7 @@ namespace App\Models\Api; -use App\Libraries\Api\Models\BaseApiModel; +use Aic\Hub\Foundation\Library\Api\Models\BaseApiModel; use App\Models\Behaviors\HasMediasApi; use App\Helpers\ImageHelpers; @@ -10,7 +10,7 @@ class ShopItem extends BaseApiModel { use HasMediasApi; - protected $endpoints = [ + protected array $endpoints = [ 'collection' => '/api/v1/products', 'resource' => '/api/v1/products/{id}', 'search' => '/api/v1/products/search' diff --git a/app/Models/Api/TicketedEvent.php b/app/Models/Api/TicketedEvent.php index 2b5760f9c..0ac096108 100644 --- a/app/Models/Api/TicketedEvent.php +++ b/app/Models/Api/TicketedEvent.php @@ -2,12 +2,12 @@ namespace App\Models\Api; -use App\Libraries\Api\Models\BaseApiModel; +use Aic\Hub\Foundation\Library\Api\Models\BaseApiModel; use Carbon\Carbon; class TicketedEvent extends BaseApiModel { - protected $endpoints = [ + protected array $endpoints = [ 'collection' => '/api/v1/ticketed-events', 'resource' => '/api/v1/ticketed-events/{id}', 'search' => '/api/v1/ticketed-events/search' diff --git a/app/Models/Api/TicketedEventType.php b/app/Models/Api/TicketedEventType.php index 67c2fc966..5e171e601 100644 --- a/app/Models/Api/TicketedEventType.php +++ b/app/Models/Api/TicketedEventType.php @@ -2,11 +2,11 @@ namespace App\Models\Api; -use App\Libraries\Api\Models\BaseApiModel; +use Aic\Hub\Foundation\Library\Api\Models\BaseApiModel; class TicketedEventType extends BaseApiModel { - protected $endpoints = [ + protected array $endpoints = [ 'collection' => '/api/v1/ticketed-event-types', 'resource' => '/api/v1/ticketed-event-types/{id}', ]; diff --git a/app/Models/Api/TourStop.php b/app/Models/Api/TourStop.php index e11353421..fc0d8954d 100644 --- a/app/Models/Api/TourStop.php +++ b/app/Models/Api/TourStop.php @@ -2,11 +2,11 @@ namespace App\Models\Api; -use App\Libraries\Api\Models\BaseApiModel; +use Aic\Hub\Foundation\Library\Api\Models\BaseApiModel; class TourStop extends BaseApiModel { - protected $endpoints = [ + protected array $endpoints = [ 'collection' => '/api/v1/mobile-sounds', 'resource' => '/api/v1/mobile-sounds/{id}', 'search' => '/api/v1/mobile-sounds/search' diff --git a/app/Models/Api/Video.php b/app/Models/Api/Video.php index f283bf111..9dd9c37ed 100644 --- a/app/Models/Api/Video.php +++ b/app/Models/Api/Video.php @@ -2,11 +2,11 @@ namespace App\Models\Api; -use App\Libraries\Api\Models\BaseApiModel; +use Aic\Hub\Foundation\Library\Api\Models\BaseApiModel; class Video extends BaseApiModel { - protected $endpoints = [ + protected array $endpoints = [ 'collection' => '/api/v1/videos', 'resource' => '/api/v1/videos/{id}', 'search' => '/api/v1/videos/search' diff --git a/app/Models/Api/WaitTime.php b/app/Models/Api/WaitTime.php index 5f44c8cb4..8b41fa349 100644 --- a/app/Models/Api/WaitTime.php +++ b/app/Models/Api/WaitTime.php @@ -2,11 +2,11 @@ namespace App\Models\Api; -use App\Libraries\Api\Models\BaseApiModel; +use Aic\Hub\Foundation\Library\Api\Models\BaseApiModel; class WaitTime extends BaseApiModel { - protected $endpoints = [ + protected array $endpoints = [ 'collection' => '/api/v1/wait-times', 'resource' => '/api/v1/wait-times/{id}', ]; diff --git a/database/factories/Api/ApiFactory.php b/database/factories/Api/ApiFactory.php deleted file mode 100644 index 1d87529a5..000000000 --- a/database/factories/Api/ApiFactory.php +++ /dev/null @@ -1,673 +0,0 @@ -count = $count; - $this->states = $states ?: new Collection(); - $this->has = $has ?: new Collection(); - $this->for = $for ?: new Collection(); - $this->afterMaking = $afterMaking ?: new Collection(); - $this->afterCreating = $afterCreating ?: new Collection(); - $this->connection = $connection; - $this->faker = $this->withFaker(); - } - - /** - * Define the model's default state. - */ - abstract public function definition(): array; - - /** - * Get a new factory instance for the given attributes. - */ - public static function new(callable|array $attributes = []): static - { - return (new static())->state($attributes)->configure(); - } - - /** - * Get a new factory instance for the given number of models. - */ - public static function times(int $count): static - { - return static::new()->count($count); - } - - /** - * Configure the factory. - */ - public function configure() - { - return $this; - } - - /** - * Get the raw attributes generated by the factory. - */ - public function raw(array $attributes = [], ?ApiModel $parent = null): array - { - if ($this->count === null) { - return $this->state($attributes)->getExpandedAttributes($parent); - } - - return array_map(function () use ($attributes, $parent) { - return $this->state($attributes)->getExpandedAttributes($parent); - }, range(1, $this->count)); - } - - /** - * Create a single model and persist it to the database. - */ - public function createOne(array $attributes = []): ApiModel - { - return $this->count(null)->create($attributes); - } - - /** - * Create a single model and persist it to the database. - */ - public function createOneQuietly(array $attributes = []): ApiModel - { - return $this->count(null)->createQuietly($attributes); - } - - /** - * Create a collection of models and persist them to the database. - */ - public function createMany(iterable $records): ApiCollection - { - return new ApiCollection( - collect($records)->map(function ($record) { - return $this->state($record)->create(); - }) - ); - } - - /** - * Create a collection of models and persist them to the database. - */ - public function createManyQuietly(iterable $records): ApiCollection - { - return ApiModel::withoutEvents(function () use ($records) { - return $this->createMany($records); - }); - } - - /** - * Create a collection of models and persist them to the database. - */ - public function create(array $attributes = [], ?ApiModel $parent = null): ApiCollection|ApiModel - { - if (! empty($attributes)) { - return $this->state($attributes)->create([], $parent); - } - - $results = $this->make($attributes, $parent); - - if ($results instanceof ApiModel) { - $this->store(collect([$results])); - - $this->callAfterCreating(collect([$results]), $parent); - } else { - $this->store($results); - - $this->callAfterCreating($results, $parent); - } - - return $results; - } - - /** - * Create a collection of models and persist them to the database. - */ - public function createQuietly(array $attributes = [], ?ApiModel $parent = null): ApiCollection|ApiModel - { - return ApiModel::withoutEvents(function () use ($attributes, $parent) { - return $this->create($attributes, $parent); - }); - } - - /** - * Create a callback that persists a model in the database when invoked. - */ - public function lazy(array $attributes = [], ?ApiModel $parent = null): Closure - { - return function () use ($attributes, $parent) { - return $this->create($attributes, $parent); - }; - } - - /** - * Do NOT store result models. - */ - protected function store($results) - { - // no-op - } - - /** - * Create the children for the given model. - */ - protected function createChildren(ApiModel $model): void - { - ApiModel::unguarded(function () use ($model) { - $this->has->each(function ($has) use ($model) { - $has->createFor($model); - }); - }); - } - - /** - * Make a single instance of the model. - */ - public function makeOne(callable|array $attributes = []): ApiModel - { - return $this->count(null)->make($attributes); - } - - /** - * Create a collection of models. - */ - public function make(array $attributes = [], ?ApiModel $parent = null): ApiCollection|ApiModel - { - if (! empty($attributes)) { - return $this->state($attributes)->make([], $parent); - } - - if ($this->count === null) { - return tap($this->makeInstance($parent), function ($instance) { - $this->callAfterMaking(collect([$instance])); - }); - } - - if ($this->count < 1) { - return $this->newModel()->newCollection(); - } - - $instances = $this->newModel()->newCollection(array_map(function () use ($parent) { - return $this->makeInstance($parent); - }, range(1, $this->count))); - - $this->callAfterMaking($instances); - - return $instances; - } - - /** - * Make an instance of the model with the given attributes. - */ - protected function makeInstance(?ApiModel $parent): ApiModel - { - return ApiModel::unguarded(function () use ($parent) { - return tap($this->newModel($this->getExpandedAttributes($parent)), function ($instance) { - if (isset($this->connection)) { - $instance->setConnection($this->connection); - } - }); - }); - } - - /** - * Get a raw attributes array for the model. - */ - protected function getExpandedAttributes(?ApiModel $parent): mixed - { - return $this->expandAttributes($this->getRawAttributes($parent)); - } - - /** - * Get the raw attributes for the model as an array. - */ - protected function getRawAttributes(?ApiModel $parent): array - { - return $this->states->pipe(function ($states) { - return $this->for->isEmpty() ? $states : new Collection(array_merge([function () { - return $this->parentResolvers(); - }], $states->all())); - })->reduce(function ($carry, $state) use ($parent) { - if ($state instanceof Closure) { - $state = $state->bindTo($this); - } - - return array_merge($carry, $state($carry, $parent)); - }, $this->definition()); - } - - /** - * Create the parent relationship resolvers (as deferred Closures). - */ - protected function parentResolvers(): array - { - $model = $this->newModel(); - - return $this->for->map(function (BelongsToRelationship $for) use ($model) { - return $for->attributesFor($model); - })->collapse()->all(); - } - - /** - * Expand all attributes to their underlying values. - */ - protected function expandAttributes(array $definition): array - { - return collect($definition)->map(function ($attribute, $key) use (&$definition) { - if (is_callable($attribute) && ! is_string($attribute) && ! is_array($attribute)) { - $attribute = $attribute($definition); - } - - if ($attribute instanceof self) { - $attribute = $attribute->create()->getKey(); - } elseif ($attribute instanceof ApiModel) { - $attribute = $attribute->getKey(); - } - - $definition[$key] = $attribute; - - return $attribute; - })->all(); - } - - /** - * Add a new state transformation to the model definition. - */ - public function state(callable|array $state): static - { - return $this->newInstance([ - 'states' => $this->states->concat([ - is_callable($state) ? $state : function () use ($state) { - return $state; - }, - ]), - ]); - } - - /** - * Add a new sequenced state transformation to the model definition. - */ - public function sequence(...$sequence): static - { - return $this->state(new Sequence(...$sequence)); - } - - /** - * Add a new cross joined sequenced state transformation to the model definition. - */ - public function crossJoinSequence(...$sequence): static - { - return $this->state(new CrossJoinSequence(...$sequence)); - } - - /** - * Define a child relationship for the model. - */ - public function has(self $factory, ?string $relationship = null): static - { - return $this->newInstance([ - 'has' => $this->has->concat([new Relationship( - $factory, - $relationship ?: $this->guessRelationship($factory->modelName()) - )]), - ]); - } - - /** - * Attempt to guess the relationship name for a "has" relationship. - */ - protected function guessRelationship(string $related): string - { - $guess = Str::camel(Str::plural(class_basename($related))); - - return method_exists($this->modelName(), $guess) ? $guess : Str::singular($guess); - } - - /** - * Define an attached relationship for the model. - */ - public function hasAttached( - ApiFactory|Collection|ApiModel $factory, - callable|array $pivot = [], - ?string $relationship = null, - ): static { - return $this->newInstance([ - 'has' => $this->has->concat([new BelongsToManyRelationship( - $factory, - $pivot, - $relationship ?: Str::camel(Str::plural(class_basename( - $factory instanceof ApiFactory - ? $factory->modelName() - : Collection::wrap($factory)->first() - ))) - )]), - ]); - } - - /** - * Define a parent relationship for the model. - */ - public function for(ApiFactory|ApiModel $factory, ?string $relationship = null): static - { - return $this->newInstance(['for' => $this->for->concat([new BelongsToRelationship( - $factory, - $relationship ?: Str::camel(class_basename( - $factory instanceof ApiFactory ? $factory->modelName() : $factory - )) - )])]); - } - - /** - * Add a new "after making" callback to the model definition. - */ - public function afterMaking(Closure $callback): static - { - return $this->newInstance(['afterMaking' => $this->afterMaking->concat([$callback])]); - } - - /** - * Add a new "after creating" callback to the model definition. - */ - public function afterCreating(Closure $callback): static - { - return $this->newInstance(['afterCreating' => $this->afterCreating->concat([$callback])]); - } - - /** - * Call the "after making" callbacks for the given model instances. - */ - protected function callAfterMaking(Collection $instances): void - { - $instances->each(function ($model) { - $this->afterMaking->each(function ($callback) use ($model) { - $callback($model); - }); - }); - } - - /** - * Call the "after creating" callbacks for the given model instances. - */ - protected function callAfterCreating(Collection $instances, ?ApiModel $parent = null): void - { - $instances->each(function ($model) use ($parent) { - $this->afterCreating->each(function ($callback) use ($model, $parent) { - $callback($model, $parent); - }); - }); - } - - /** - * Specify how many models should be generated. - */ - public function count(?int $count): static - { - return $this->newInstance(['count' => $count]); - } - - /** - * Specify the database connection that should be used to generate models. - */ - public function connection(string $connection): static - { - return $this->newInstance(['connection' => $connection]); - } - - /** - * Create a new instance of the factory builder with the given mutated properties. - */ - protected function newInstance(array $arguments = []): static - { - return new static(...array_values(array_merge([ - 'count' => $this->count, - 'states' => $this->states, - 'has' => $this->has, - 'for' => $this->for, - 'afterMaking' => $this->afterMaking, - 'afterCreating' => $this->afterCreating, - 'connection' => $this->connection, - ], $arguments))); - } - - /** - * Get a new model instance. - */ - public function newModel(array $attributes = []): ApiModel - { - $model = $this->modelName(); - - return new $model($attributes); - } - - /** - * Get the name of the model that is generated by the factory. - */ - public function modelName(): string - { - $resolver = static::$modelNameResolver ?: function (self $factory) { - $namespacedFactoryBasename = Str::replaceLast( - 'Factory', - '', - Str::replaceFirst(static::$namespace, '', get_class($factory)) - ); - - $factoryBasename = Str::replaceLast('Factory', '', class_basename($factory)); - - $appNamespace = static::appNamespace(); - - return class_exists($appNamespace . 'Models\\Api\\' . $namespacedFactoryBasename) - ? $appNamespace . 'Models\\Api\\' . $namespacedFactoryBasename - : $appNamespace . $factoryBasename; - }; - - return $this->model ?: $resolver($this); - } - - /** - * Specify the callback that should be invoked to guess model names based on factory names. - */ - public static function guessModelNamesUsing(callable $callback): void - { - static::$modelNameResolver = $callback; - } - - /** - * Specify the default namespace that contains the application's model factories. - */ - public static function useNamespace(string $namespace): void - { - static::$namespace = $namespace; - } - - /** - * Get a new factory instance for the given model name. - */ - public static function factoryForModel(string $modelName): static - { - $factory = static::resolveFactoryName($modelName); - - return $factory::new(); - } - - /** - * Specify the callback that should be invoked to guess factory names based on dynamic relationship names. - */ - public static function guessFactoryNamesUsing(callable $callback): void - { - static::$factoryNameResolver = $callback; - } - - /** - * Get a new Faker instance. - */ - protected function withFaker(): FakerGenerator - { - return Container::getInstance()->make(FakerGenerator::class); - } - - /** - * Get the factory name for the given model name. - */ - public static function resolveFactoryName(string $modelName): string - { - $resolver = static::$factoryNameResolver ?: function (string $modelName) { - $appNamespace = static::appNamespace(); - - $modelName = Str::startsWith($modelName, $appNamespace . 'Models\\Api\\') - ? Str::after($modelName, $appNamespace . 'Models\\Api\\') - : Str::after($modelName, $appNamespace); - - return static::$namespace . $modelName . 'Factory'; - }; - - return $resolver($modelName); - } - - /** - * Get the application namespace for the application. - */ - protected static function appNamespace(): string - { - try { - return Container::getInstance() - ->make(Application::class) - ->getNamespace(); - } catch (Throwable $e) { - return 'App\\'; - } - } - - /** - * Proxy dynamic factory methods onto their proper methods. - */ - public function __call(string $method, array $parameters): mixed - { - if (static::hasMacro($method)) { - return $this->macroCall($method, $parameters); - } - - if (! Str::startsWith($method, ['for', 'has'])) { - static::throwBadMethodCallException($method); - } - - $relationship = Str::camel(Str::substr($method, 3)); - - $relatedModel = get_class($this->newModel()->{$relationship}()->getRelated()); - - if (method_exists($relatedModel, 'newFactory')) { - $factory = $relatedModel::newFactory() ?: static::factoryForModel($relatedModel); - } else { - $factory = static::factoryForModel($relatedModel); - } - - if (Str::startsWith($method, 'for')) { - return $this->for($factory->state($parameters[0] ?? []), $relationship); - } elseif (Str::startsWith($method, 'has')) { - return $this->has( - $factory - ->count(is_numeric($parameters[0] ?? null) ? $parameters[0] : 1) - ->state((is_callable($parameters[0] ?? null) || is_array($parameters[0] ?? null)) ? $parameters[0] : ($parameters[1] ?? [])), - $relationship - ); - } - } -} diff --git a/database/factories/Api/ArtworkFactory.php b/database/factories/Api/ArtworkFactory.php index ebab65e88..daf7329c4 100644 --- a/database/factories/Api/ArtworkFactory.php +++ b/database/factories/Api/ArtworkFactory.php @@ -3,6 +3,7 @@ namespace Database\Factories\Api; use App\Models\Api\Artwork; +use Aic\Hub\Foundation\Library\Database\ApiFactory; class ArtworkFactory extends ApiFactory { diff --git a/database/factories/Api/ExhibitionFactory.php b/database/factories/Api/ExhibitionFactory.php index 0e5b9fb2a..151832bee 100644 --- a/database/factories/Api/ExhibitionFactory.php +++ b/database/factories/Api/ExhibitionFactory.php @@ -3,6 +3,7 @@ namespace Database\Factories\Api; use App\Models\Api\Exhibition; +use Aic\Hub\Foundation\Library\Database\ApiFactory; class ExhibitionFactory extends ApiFactory { diff --git a/database/factories/Api/HasApiFactory.php b/database/factories/Api/HasApiFactory.php deleted file mode 100644 index c5b55b155..000000000 --- a/database/factories/Api/HasApiFactory.php +++ /dev/null @@ -1,29 +0,0 @@ -count(is_numeric($parameters[0] ?? null) ? $parameters[0] : null) - ->state(is_array($parameters[0] ?? null) ? $parameters[0] : ($parameters[1] ?? [])); - } - - /** - * Create a new factory instance for the model. - */ - protected static function newFactory() - { - // - } -} diff --git a/docs/apiModels.md b/docs/apiModels.md index 9fee3113d..ed60a2160 100644 --- a/docs/apiModels.md +++ b/docs/apiModels.md @@ -470,7 +470,7 @@ If you don't want to use the general endpoints, you can specify the name for the ```php class Artwork extends BaseApiModel { - protected $endpoints = [ + protected array $endpoints = [ 'collection' => '/api/v1/artworks', 'resource' => '/api/v1/artworks/{id}', 'search' => '/api/v1/artworks/search',