/** * @param GammaSelection $gamma * @param GammaNotification $notification * @param GammaSubscriptionManager $subscriptions * @param Request $request * @return Collection */ public function categories(GammaSelection $gamma, GammaNotification $notification, GammaSubscriptionManager $subscriptions, Request $request) { $productRequirements = function ($query) use($subscriptions) { $query->whereIn('products.account_id', $subscriptions->subscribedIds()); }; $categories = Category::whereHas('products', $productRequirements); //if we passed in a category, we used the suggest to find a category. //but we want to show our synonyms too. if ($category = $request->get('category')) { $category = Category::find($category); if ($category) { $showingIds = array_merge([$category->id], $category->synonyms->lists('id')->toArray()); $categories->whereIn('id', $showingIds); } } if ($category) { $categories = $categories->paginate(5, ['*'], 'page', 1); } else { $categories = $categories->paginate(5); } $ids = $categories->lists('id')->toArray(); if (!count($ids)) { return new Collection(); } $categories->load(['translations', 'selection']); //load brands separately, or you'll be getting bad results foreach ($categories as $category) { $category->load(['brands' => function ($query) use($subscriptions, $category) { $query->join('products', 'products.brand_id', '=', 'product_brands.id')->join('product_categories_pivot', 'product_categories_pivot.product_id', '=', 'products.id')->where('product_categories_pivot.category_id', $category->id)->whereIn('products.account_id', $subscriptions->subscribedIds())->distinct(['product_brands.*'])->get(['product_brands.*']); }, 'brands.translations', 'brands.selection']); } $selections = $this->selections($gamma, 'category_id', $ids); $reviews = $this->reviews($notification, 'category_id', $ids); //use foreach instead of map, so we can reuse the original paginator. foreach ($categories as $key => $category) { $category->activated = $category->selection ? true : false; $category->selection = null; $bSelections = $selections->get($category->id); $bReviews = $reviews->get($category->id); $category->brands = $category->brands->map(function ($brand) use($bSelections, $bReviews) { $brand->activated = $brand->selection ? true : false; $brand->selection = null; $inReview = $bReviews && $bReviews->contains('brand_id', $brand->id); $actuallySelected = $bSelections && $bSelections->contains('brand_id', $brand->id); $brand->selected = $actuallySelected && !$inReview || !$actuallySelected && $inReview; $brand->inReview = $inReview; return $brand; }); $categories[$key] = $category; } return $categories; }
/** * @param Request $request * @return string */ public function removeCategory(Request $request) { $this->validate($request, ['product_id' => 'exists:products,id', 'category_id' => 'exists:product_categories,id']); $product = Product::find($request->get('product_id')); $category = Category::find($request->get('category_id')); $product->load('categories'); $category->load('translations'); if ($product->categories->contains($category->id)) { //is the category the main category or a synonym? if (!$category->original_id) { //we can only have 1 main category and synonyms to that category //so we can do an empty sync here $product->categories()->sync([]); return json_encode(['status' => 'flushed']); } else { $product->categories()->detach($category); return $category; } } return json_encode(['status' => false]); }