learningProductService = $learningProductService; $this->middleware('auth:sanctum', [ 'except' => [ 'getPublished', ] ]); } public function index() { $learningProducts = $this->learningProductService->withTrashedAndChildren([ 'filters', 'filters.filter_item.filter', // 'versions', 'accreditations', 'notifications', ])->sortDesc(); return response()->json( LearningProductResource::collection($learningProducts), 201, );; } public function getPublished() { $withColumnAll = [ 'filters', 'filters.filter_item.filter', 'accreditations', 'accreditations.filters.filter_item', 'notifications' ]; $learningProductAll = $this->learningProductService->getPublishedWith($withColumnAll) ->groupBy('code') ->map(function (Collection $groupedLearningProductAll) { return $groupedLearningProductAll->last(); }) ->sortDesc() ->flatten(1); return response()->json( LearningProductResource::collection($learningProductAll), 201, ); } public function store(LearningProductStore $request) { try { Log::info('Store method called'); $isSuperAdmin = auth()->user()->hasRole('super_admin'); $isAdmin = auth()->user()->hasRole('admin'); $isOperator = auth()->user()->hasRole('operator'); Log::info('User roles checked', ['isSuperAdmin' => $isSuperAdmin, 'isAdmin' => $isAdmin, 'isOperator' => $isOperator]); if (!$isSuperAdmin && !$isAdmin && !$isOperator) { return response()->json(['message' => 'You have no rights to do this'], 401); } // Is it draft with parent_id marked as published? $is_draft = isset($request['parent_id']); $is_draft_published = $is_draft && $request['published']; Log::info('Draft status checked', ['is_draft' => $is_draft, 'is_draft_published' => $is_draft_published]); $hasCover = isset($request['cover']) && $request->hasFile('cover'); $hasTile = isset($request['tile']) && $request->hasFile('tile'); Log::info('File status checked', ['hasCover' => $hasCover, 'hasTile' => $hasTile]); // Validate and prepare request data $request_data = $request->validated(); if ($hasCover) { $request_data = Arr::except($request_data, ['cover']); } if ($hasTile) { $request_data = Arr::except($request_data, ['tile']); } // Publish without parent_id if ($is_draft_published) { $request_data['parent_id'] = null; } $request_data = Arr::except($request_data, ['filtersGrouped', 'synonymsSelected']); Log::info('Request data prepared', ['request_data' => $request_data]); // Save finally the product $learning_product = $this->learningProductService->save($request_data); Log::info('Learning product saved', ['learning_product' => $learning_product]); // Get Filter Items passed $filter_items = json_decode(html_entity_decode(stripslashes($request['filtersGrouped']))); $synonyms_selected = json_decode(html_entity_decode(stripslashes($request['synonymsSelected']))); Log::info('Filters and synonyms decoded', ['filter_items' => $filter_items, 'synonyms_selected' => $synonyms_selected]); if ($synonyms_selected) { $learning_product->synonyms()->sync($synonyms_selected); } $arrayTmp = []; if ($filter_items) { foreach ($filter_items as $key => $value) { $arrayTmp[] = $value; } $filter_items = Arr::collapse($arrayTmp); $filter_items = Arr::flatten($arrayTmp); // Saves filter items associations with this learning product $learning_product->filters()->delete(); foreach ($filter_items as $filter_item_id) { $filter_association = new FilterItemsAssociation(); $filter_association->filter_item_id = $filter_item_id; $learning_product->filters()->save($filter_association); } } // if a file was uploaded as cover or tile, add them if ($hasCover) { $learning_product->addMediaFromRequest('cover')->toMediaCollection('learning_products_covers'); } if ($hasTile) { $learning_product->addMediaFromRequest('tile')->toMediaCollection('learning_products_tiles'); } if ($is_draft) { // 1st draft of the published product $original_product_published = $this->learningProductService->get($request['parent_id']); // If no cover has been attached before if (!$hasCover && !$learning_product->cover) { $image = $original_product_published->getMedia('learning_products_covers')->first(); if ($image) { $learning_product->copyMedia($image->getPath())->toMediaCollection('learning_products_covers'); } } // If no tile has been attached before if (!$hasTile && !$learning_product->tile) { $image = $original_product_published->getMedia('learning_products_tiles')->first(); if ($image) { $learning_product->copyMedia($image->getPath())->toMediaCollection('learning_products_tiles'); } } } // ForceDelete the parent if draft published if ($is_draft_published && $learning_product) { $this->destroy($request['parent_id'], true); } Log::info('Learning product processed successfully', ['learning_product' => $learning_product]); // Emit Event to update products // broadcast(new \App\Events\ProductsCatalogUpdated); if ($learning_product) { return response()->json(new LearningProductResource($learning_product), 201); } else { return response()->json(['message' => 'Learning Product not found.'], 404); } } catch (\Exception $e) { Log::error('Error in LearningProductController@store: ' . $e->getMessage(), ['exception' => $e]); return response()->json(['message' => 'Internal Server Error'], 500); } } public function show($id) { $learning_product = $this->learningProductService->getOneWithChildrenAndTrashed($id, [ 'filters', 'filters.filter_item.filter', 'versions', 'accreditations', 'notifications', 'synonyms', ]); return response()->json(new LearningProductResource($learning_product)); } public function countAll() { return response()->json($this->learningProductService->countAll()); } public function destroy(String $id, $forceDelete = false) { try { Log::info('Destroy method called', ['id' => $id, 'forceDelete' => $forceDelete]); $isSuperAdmin = auth()->user()->hasRole('super_admin'); $isAdmin = auth()->user()->hasRole('admin'); $isOperator = auth()->user()->hasRole('operator'); if (!$isSuperAdmin && !$isAdmin && !$isOperator) { return response()->json(['message' => 'You have no rights to do this'], 401); } $learning_product = $this->learningProductService->get($id); if (!$learning_product) { return response()->json(['message' => 'Learning Product not found.'], 404); } // Verwijder gerelateerde records in de versions tabel \DB::table('versions')->where('learning_product_id', $id)->delete(); if ($forceDelete) { $learning_product->forceDelete(); } else { $learning_product->delete(); } Log::info('Learning product deleted successfully', ['id' => $id]); return response()->json(null, 204); } catch (\Exception $e) { Log::error('Error in LearningProductController@destroy: ' . $e->getMessage(), ['exception' => $e]); return response()->json(['message' => 'Internal Server Error'], 500); } } public function clone(LearningProductId $request) { $isSuperAdmin = auth()->user()->hasRole('super_admin'); $isAdmin = auth()->user()->hasRole('admin'); $isOperator = auth()->user()->hasRole('operator'); if (!$isSuperAdmin && !$isAdmin && !$isOperator) { return response()->json(['message' => 'You have no rights to do this'], 401); } if (!isset($request['product_id']) || !$request['product_id']) { return response()->json(['message' => 'Product id missing.'], 400); } // get original product to clone $original_product = $this->learningProductService->getOneWith($request['product_id'], [ 'filters', 'filters.filter_item.filter', 'versions', 'accreditations', 'notifications', 'synonyms', ]); // Return if not published if (!$original_product->published) { return response()->json([ 'error' => 'You cannot duplicate a draft' ], 400); } // Return already has a draft if ($original_product->draft) { return response()->json(['message' => 'There is already a draft for this product'], 400); } // set as draft $draft = $original_product->replicate(); $draft->parent_id = $original_product->id; $draft->published = false; // clone cover & tiles, finally save $cover = $original_product->getMedia('learning_products_covers')->first(); $tile = $original_product->getMedia('learning_products_tiles')->first(); if ($cover) { $draft ->copyMedia($cover->getPath()) ->toMediaCollection('learning_products_covers'); } if ($tile) { $draft ->copyMedia($tile->getPath()) ->toMediaCollection('learning_products_covers'); } $draft->save(); // TODO: clone accreditations, versions too? // Clone Filter Items if ($original_product->filters()) { $filter_items_ids = $original_product->filters->pluck('filter_item_id'); foreach ($filter_items_ids as $filter_item_id) { $filter_association = new FilterItemsAssociation(); $filter_association->filter_item_id = $filter_item_id; $draft->filters()->save($filter_association); } } // Clone Synonyms if ($original_product->synonyms()) { $synonyms_ids = $original_product->synonyms->pluck('id'); $draft->synonyms()->sync($synonyms_ids); } return response()->json(null, 201); } }