diff --git a/app/Http/Controllers/Api/ArticleController.php b/app/Http/Controllers/Api/ArticleController.php
index d334c2d..53fedcc 100644
--- a/app/Http/Controllers/Api/ArticleController.php
+++ b/app/Http/Controllers/Api/ArticleController.php
@@ -8,17 +8,14 @@ use App\Enum\HttpResponseCodes;
use App\Http\Requests\ArticleRequest;
use App\Models\Media;
use App\Models\Article;
-use App\Models\Gallery;
+use App\Traits\HasAttachments;
use App\Traits\HasGallery;
use Illuminate\Http\JsonResponse;
-use Carbon\Exceptions\InvalidFormatException;
-use Illuminate\Contracts\Container\BindingResolutionException;
-use Illuminate\Database\Eloquent\InvalidCastException;
-use Illuminate\Database\Eloquent\MassAssignmentException;
use Illuminate\Http\Request;
class ArticleController extends ApiController
{
+ use HasAttachments;
use HasGallery;
@@ -78,7 +75,11 @@ class ArticleController extends ApiController
public function store(ArticleRequest $request)
{
if (ArticleConductor::creatable() === true) {
- $article = Article::create($request->except('gallery'));
+ $article = Article::create($request->except(['attachments', 'gallery']));
+
+ if ($request->has('attachments') === true) {
+ $article->attachmentsAddMany($request->get('attachments'));
+ }
if ($request->has('gallery') === true) {
$article->galleryAddMany($request->get('gallery'));
@@ -103,12 +104,17 @@ class ArticleController extends ApiController
public function update(ArticleRequest $request, Article $article)
{
if (ArticleConductor::updatable($article) === true) {
+ if ($request->has('attachments') === true) {
+ $article->attachments()->delete();
+ $article->attachmentsAddMany($request->get('attachments'));
+ }
+
if ($request->has('gallery') === true) {
$article->gallery()->delete();
$article->galleryAddMany($request->get('gallery'));
}
- $article->update($request->except('gallery'));
+ $article->update($request->except(['attachments', 'gallery']));
return $this->respondAsResource(ArticleConductor::model($request, $article));
}
@@ -130,125 +136,4 @@ class ArticleController extends ApiController
return $this->respondForbidden();
}
}
-
- /**
- * Get a list of attachments related to this model.
- *
- * @param Request $request The user request.
- * @param Article $article The article model.
- * @return JsonResponse Returns the article attachments.
- */
- public function attachmentIndex(Request $request, Article $article): JsonResponse
- {
- if (ArticleConductor::viewable($article) === true) {
- $medium = $article->attachments->map(function ($attachment) {
- return $attachment->media;
- });
-
- return $this->respondAsResource(MediaConductor::collection($request, $medium), ['isCollection' => true, 'resourceName' => 'attachment']);
- }
-
- return $this->respondForbidden();
- }
-
- /**
- * Store an attachment related to this model.
- *
- * @param Request $request The user request.
- * @param Article $article The article model.
- * @return JsonResponse The response.
- */
- public function attachmentStore(Request $request, Article $article): JsonResponse
- {
- if (ArticleConductor::updatable($article) === true) {
- if ($request->has("medium") === true && Media::find($request->medium) !== null) {
- $article->attachments()->create(['media_id' => $request->medium]);
- return $this->respondCreated();
- }
-
- return $this->respondWithErrors(['media' => 'The media ID was not found']);
- }
-
- return $this->respondForbidden();
- }
-
- /**
- * Update/replace attachments related to this model.
- *
- * @param Request $request The user request.
- * @param Article $article The related model.
- * @return JsonResponse
- */
- public function attachmentUpdate(Request $request, Article $article): JsonResponse
- {
- if (ArticleConductor::updatable($article) === true) {
- $mediaIds = $request->attachments;
- if (is_array($mediaIds) === false) {
- $mediaIds = explode(',', $request->attachments);
- }
-
- $mediaIds = array_map('trim', $mediaIds); // trim each media ID
- $attachments = $article->attachments;
-
- // Delete attachments that are not in $mediaIds
- foreach ($attachments as $attachment) {
- if (in_array($attachment->media_id, $mediaIds) === false) {
- $attachment->delete();
- }
- }
-
- // Create new attachments for media IDs that are not already in $article->attachments()
- foreach ($mediaIds as $mediaId) {
- $found = false;
-
- foreach ($attachments as $attachment) {
- if ($attachment->media_id === $mediaId) {
- $found = true;
- break;
- }
- }
-
- if ($found === false) {
- $article->attachments()->create(['media_id' => $mediaId]);
- }
- }
-
- return $this->respondNoContent();
- }//end if
-
- return $this->respondForbidden();
- }
-
- /**
- * Delete a specific related attachment.
- * @param Request $request The user request.
- * @param Article $article The model.
- * @param Media $medium The attachment medium.
- * @return JsonResponse
- */
- public function attachmentDelete(Request $request, Article $article, Media $medium): JsonResponse
- {
- if (ArticleConductor::updatable($article) === true) {
- $attachments = $article->attachments;
- $deleted = false;
-
- foreach ($attachments as $attachment) {
- if ($attachment->media_id === $medium->id) {
- $attachment->delete();
- $deleted = true;
- break;
- }
- }
-
- if ($deleted === true) {
- // Attachment was deleted successfully
- return $this->respondNoContent();
- } else {
- // Attachment with matching media ID was not found
- return $this->respondNotFound();
- }
- }
-
- return $this->respondForbidden();
- }
}
diff --git a/app/Models/Article.php b/app/Models/Article.php
index 3dc2e87..94b2acd 100644
--- a/app/Models/Article.php
+++ b/app/Models/Article.php
@@ -39,14 +39,4 @@ class Article extends Model
{
return $this->belongsTo(User::class);
}
-
- /**
- * Get all of the article's attachments.
- *
- * @return Illuminate\Database\Eloquent\Relations\MorphMany
- */
- public function attachments(): MorphMany
- {
- return $this->morphMany(\App\Models\Attachment::class, 'attachable');
- }
}
diff --git a/app/Models/Event.php b/app/Models/Event.php
index 7f44314..54c36e7 100644
--- a/app/Models/Event.php
+++ b/app/Models/Event.php
@@ -2,6 +2,7 @@
namespace App\Models;
+use App\Traits\HasAttachments;
use App\Traits\Uuids;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
@@ -10,6 +11,7 @@ use Illuminate\Database\Eloquent\Relations\MorphMany;
class Event extends Model
{
+ use HasAttachments;
use HasFactory;
use Uuids;
@@ -37,16 +39,10 @@ class Event extends Model
];
- /**
- * Get all of the article's attachments.
- */
- public function attachments(): MorphMany
- {
- return $this->morphMany(\App\Models\Attachment::class, 'attachable');
- }
-
/**
* Get all the associated users.
+ *
+ * @return BelongsToMany
*/
public function users(): BelongsToMany
{
diff --git a/app/Traits/HasAttachments.php b/app/Traits/HasAttachments.php
new file mode 100644
index 0000000..db88eb4
--- /dev/null
+++ b/app/Traits/HasAttachments.php
@@ -0,0 +1,63 @@
+attachments()->delete();
+ });
+ }
+
+ /**
+ * Add multiple attachments items to the model.
+ *
+ * @param array|string $ids The media ids to add.
+ * @param string $delimiter The split delimiter if $ids is a string.
+ * @param boolean $allowDuplicates Whether to allow duplicate media IDs or not.
+ * @return void
+ */
+ public function attachmentsAddMany(array|string $ids, string $delimiter = ',', bool $allowDuplicates = false): void
+ {
+ if (is_array($ids) === false) {
+ $ids = explode($delimiter, $ids);
+ }
+
+ $ids = array_map('trim', $ids);
+ $existingIds = $this->gallery()->pluck('media_id')->toArray();
+
+ $galleryItems = [];
+ foreach ($ids as $id) {
+ if ($allowDuplicates === false && in_array($id, $existingIds) === true) {
+ continue;
+ }
+
+ $media = Media::find($id);
+ if ($media !== null) {
+ $galleryItems[] = ['media_id' => $id];
+ }
+ }
+
+ $this->attachments()->createMany($galleryItems);
+ }
+
+ /**
+ * Get the article's attachments.
+ *
+ * @return Illuminate\Database\Eloquent\Relations\MorphMany The attachments items
+ */
+ public function attachments(): MorphMany
+ {
+ return $this->morphMany(\App\Models\Attachment::class, 'addendum');
+ }
+}
diff --git a/database/migrations/2023_07_19_041445_update_attachments_table.php b/database/migrations/2023_07_19_041445_update_attachments_table.php
new file mode 100644
index 0000000..7eb29de
--- /dev/null
+++ b/database/migrations/2023_07_19_041445_update_attachments_table.php
@@ -0,0 +1,30 @@
+renameColumn('attachable_type', 'addendum_type');
+ $table->renameColumn('attachable_id', 'addendum_id');
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::table('attachments', function (Blueprint $table) {
+ $table->renameColumn('addendum_type', 'attachable_type');
+ $table->renameColumn('addendum_id', 'attachable_id');
+ });
+ }
+};
diff --git a/resources/js/components/SMAttachments.vue b/resources/js/components/SMAttachments.vue
index f981d79..05a016b 100644
--- a/resources/js/components/SMAttachments.vue
+++ b/resources/js/components/SMAttachments.vue
@@ -1,28 +1,32 @@
+ {{ modelValue.length }} file{{ modelValue.length != 1 ? "s" : "" }}
+
-
+
-
+
+
-
+
{{ file.title || file.name }}
-
+
-
+