Skip to content

Commit

Permalink
Merge pull request #19 from FarhanShares/media-collection-updates
Browse files Browse the repository at this point in the history
Media collection updates
  • Loading branch information
FarhanShares authored Mar 17, 2021
2 parents 83a56f2 + 077271e commit bbb10f5
Show file tree
Hide file tree
Showing 2 changed files with 146 additions and 38 deletions.
91 changes: 75 additions & 16 deletions src/Models/Media.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down Expand Up @@ -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)) {
Expand All @@ -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)) {
Expand All @@ -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();
Expand 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)) {
Expand All @@ -206,17 +257,25 @@ 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
// it's treated as a valid source of MediaCollection resource
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);
Expand Down Expand Up @@ -246,6 +305,6 @@ private function fetchCollections($collections)
}
}

return false;
return null;
}
}
93 changes: 71 additions & 22 deletions src/Models/MediaCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand All @@ -23,6 +20,7 @@ class MediaCollection extends Model
'name', 'created_at', 'updated_at',
];


/**
* The table associated with the model.
*
Expand All @@ -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)) {
Expand All @@ -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)) {
Expand All @@ -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
Expand All @@ -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)) {
Expand All @@ -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;
Expand All @@ -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
Expand All @@ -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);
Expand Down Expand Up @@ -180,6 +229,6 @@ private function fetchMedia($media)
}
}

return false;
return null;
}
}

0 comments on commit bbb10f5

Please sign in to comment.