diff --git a/src/Models/Media.php b/src/Models/Media.php index b7bb302..401ee28 100644 --- a/src/Models/Media.php +++ b/src/Models/Media.php @@ -2,15 +2,16 @@ namespace FarhanShares\MediaMan\Models; -use Countable; use Illuminate\Support\Str; -use Illuminate\Support\Collection as BaseCollection; use FarhanShares\MediaMan\Casts\Json; use Illuminate\Database\Eloquent\Model; -use Illuminate\Database\Eloquent\Collection as EloquentCollection; use Illuminate\Support\Facades\Storage; +use Illuminate\Database\Eloquent\Collection; use Illuminate\Contracts\Filesystem\Filesystem; use FarhanShares\MediaMan\Models\MediaCollection; +use Illuminate\Support\Collection as BaseCollection; +use Illuminate\Database\Eloquent\Relations\BelongsToMany; +use Illuminate\Database\Eloquent\Collection as EloquentCollection; class Media extends Model { @@ -131,6 +132,15 @@ public function filesystem() return Storage::disk($this->disk); } + + /** + * Find a media by media name + * + * @param $query + * @param string $names + * @param array $columns + * @return Collection|Media|null + */ public function scopeFindByName($query, $names, array $columns = ['*']) { if (is_array($names)) { @@ -140,11 +150,25 @@ public function scopeFindByName($query, $names, array $columns = ['*']) return $query->select($columns)->where('name', $names)->first(); } - public function collections() + + /** + * A media belongs to many collection + * + * @return BelongsToMany + */ + public function collections(): BelongsToMany { return $this->belongsToMany(MediaCollection::class, config('mediaman.tables.collection_media'), 'collection_id', 'media_id'); } + + /** + * Sync collections of a media + * + * @param null|int|string|array|MediaCollection|Collection $collections + * @param boolean $detaching + * @return array of synced status + */ public function syncCollections($collections, $detaching = true) { if ($this->shouldDetachAll($collections)) { @@ -154,33 +178,52 @@ public function syncCollections($collections, $detaching = true) $fetch = $this->fetchCollections($collections); if (is_countable($fetch)) { $ids = $fetch->pluck('id')->all(); - return $this->collections()->sync($ids, $detaching); + return ($this->collections()->sync($ids, $detaching)); } else { - return $this->collections()->sync($fetch->id, $detaching); + return ($this->collections()->sync($fetch->id, $detaching)); } return false; } + + /** + * Attach a media to collections + * + * @param null|int|string|array|MediaCollection|Collection $collections + * @return int|null + */ public function attachCollections($collections) { $fetch = $this->fetchCollections($collections); if (is_countable($fetch)) { $ids = $fetch->pluck('id'); - return $this->collections()->attach($ids); + $res = $this->collections()->sync($ids, false); + $attached = count($res['attached']); + return $attached > 0 ? $attached : null; } else { - return $this->collections()->attach($fetch->id); + $res = $this->collections()->sync($fetch->id, false); + $attached = count($res['attached']); + return $attached > 0 ? $attached : null; } - return false; + return null; } + + /** + * Detach a media from collections + * + * @param null|int|string|array|MediaCollection|Collection $collections + * @return int|null + */ public function detachCollections($collections) { if ($this->shouldDetachAll($collections)) { return $this->collections()->detach(); } + // todo: check if null is returned on failure $fetch = $this->fetchCollections($collections); if (is_countable($fetch)) { $ids = $fetch->pluck('id')->all(); @@ -189,10 +232,18 @@ public function detachCollections($collections) return $this->collections()->detach($fetch->id); } - return false; + return null; } - // bool|null|empty-string|empty-array to detach all collections + + /** + * Check if all collections should be detached + * + * bool|null|empty-string|empty-array to detach all collections + * + * @param mixed $collections + * @return boolean + */ private function shouldDetachAll($collections) { if (is_bool($collections) || is_null($collections) || empty($collections)) { @@ -206,9 +257,17 @@ private function shouldDetachAll($collections) return false; } - // returns single collection for single item - // and multiple collections for multiple items - // todo: exception / strict return types + + /** + * Fetch collections + * + * returns single collection for single item + * and multiple collections for multiple items + * todo: exception / strict return types + * + * @param int|string|array|MediaCollection|Collection $collections + * @return Collection|Model|Object|null + */ private function fetchCollections($collections) { // eloquent collection doesn't need to be fetched again @@ -216,7 +275,7 @@ private function fetchCollections($collections) if ($collections instanceof EloquentCollection) { return $collections; } - + // todo: check for instance of media model / collection instead? if ($collections instanceof BaseCollection) { $ids = $collections->pluck('id')->all(); return MediaCollection::find($ids); @@ -246,6 +305,6 @@ private function fetchCollections($collections) } } - return false; + return null; } } diff --git a/src/Models/MediaCollection.php b/src/Models/MediaCollection.php index e84785c..36aefe6 100644 --- a/src/Models/MediaCollection.php +++ b/src/Models/MediaCollection.php @@ -3,14 +3,11 @@ namespace FarhanShares\MediaMan\Models; -use Illuminate\Support\Str; use FarhanShares\MediaMan\Models\Media; use Illuminate\Database\Eloquent\Model; -use Illuminate\Support\Facades\Storage; -use Illuminate\Contracts\Filesystem\Filesystem; use Illuminate\Support\Collection as BaseCollection; use Illuminate\Database\Eloquent\Collection as EloquentCollection; - +use Illuminate\Database\Eloquent\Relations\BelongsToMany; class MediaCollection extends Model { @@ -23,6 +20,7 @@ class MediaCollection extends Model 'name', 'created_at', 'updated_at', ]; + /** * The table associated with the model. * @@ -33,6 +31,15 @@ public function getTable() return config('mediaman.tables.collections'); } + + /** + * Find a collection by name + * + * @param $query + * @param string $names + * @param array $columns + * @return Collection|MediaCollection|null + */ public function scopeFindByName($query, $names, array $columns = ['*']) { if (is_array($names)) { @@ -42,22 +49,33 @@ public function scopeFindByName($query, $names, array $columns = ['*']) return $query->select($columns)->where('name', $names)->first(); } + /** - * The media that belong to the collection. + * A collection belongs to many media. + * + * @return BelongsToMany */ public function media() { return $this->belongsToMany(Media::class, config('mediaman.tables.collection_media'), 'media_id', 'collection_id'); } - public function syncMedia($media, $detaching = true) + + /** + * Sync media of a collection + * + * @param null|int|string|array|Media|Collection $media + * @param boolean $detaching + * @return array|null + */ + public function syncMedia($media, $detaching = true): ?array { if ($this->shouldDetachAll($media)) { return $this->media()->sync([]); } if (!$fetch = $this->fetchMedia($media)) { - return false; + return null; } if (is_countable($fetch)) { @@ -69,15 +87,22 @@ public function syncMedia($media, $detaching = true) return $this->media()->sync($fetch->id); } - return false; + return null; } - public function attachMedia($media) + + /** + * Attach media to a collection + * + * @param null|int|string|array|Media|Collection $media + * @return int|null number of attached media or null + */ + public function attachMedia($media): ?int { $fetch = $this->fetchMedia($media); if (!$fetch = $this->fetchMedia($media)) { - return false; + return null; } // to be consistent with the return type of detach method @@ -87,27 +112,34 @@ public function attachMedia($media) $res = $this->media()->sync($ids, false); $attached = count($res['attached']); - return $attached > 0 ? $attached : false; + return $attached > 0 ? $attached : null; } if (isset($fetch->id)) { $res = $this->media()->sync($fetch->id, false); $attached = count($res['attached']); - return $attached > 0 ? $attached : false; + return $attached > 0 ? $attached : null; } - return false; + return null; } - public function detachMedia($media) + + /** + * Detach media from a collection + * + * @param null|int|string|array|Media|Collection $media + * @return int|null number of detached media or null + */ + public function detachMedia($media): ?int { if ($this->shouldDetachAll($media)) { return $this->media()->detach(); } if (!$fetch = $this->fetchMedia($media)) { - return false; + return null; } if (is_countable($fetch)) { @@ -119,11 +151,19 @@ public function detachMedia($media) return $this->media()->detach($fetch->id); } - return false; + return null; } - // bool|null|empty-string|empty-array to detach all media - private function shouldDetachAll($media) + + /** + * Check if all media should be detached + * + * bool|null|empty-string|empty-array to detach all media + * + * @param mixed $collections + * @return boolean + */ + private function shouldDetachAll($media): bool { if (is_bool($media) || is_null($media) || empty($media)) { return true; @@ -136,9 +176,17 @@ private function shouldDetachAll($media) return false; } - // returns single collection for single item - // and multiple collections for multiple items - // todo: exception / strict return types + + /** + * Fetch media + * + * returns single collection for single item + * and multiple collections for multiple items + * todo: exception / strict return types + * + * @param int|string|array|MediaCollection|Collection $collections + * @return Collection|Media|Object|null + */ private function fetchMedia($media) { // eloquent collection doesn't need to be fetched again @@ -147,6 +195,7 @@ private function fetchMedia($media) return $media; } + // todo: check for instance of media model / collection instead? if ($media instanceof BaseCollection) { $ids = $media->pluck('id')->all(); return Media::find($ids); @@ -180,6 +229,6 @@ private function fetchMedia($media) } } - return false; + return null; } }