From c70f00e22629dda956da16f177bf72aff5294df9 Mon Sep 17 00:00:00 2001 From: Stephen Cameron Date: Wed, 28 Aug 2019 19:48:11 +0200 Subject: [PATCH] WIP #2961 @6 --- app/Http/Controllers/AjaxController.php | 119 +--------------- app/Http/Controllers/ProductController.php | 11 +- app/Models/Product.php | 128 +++++++++++++++++ .../views/pages/product-detail.blade.php | 20 +-- resources/views/pages/products.blade.php | 130 ++++++++---------- 5 files changed, 205 insertions(+), 203 deletions(-) diff --git a/app/Http/Controllers/AjaxController.php b/app/Http/Controllers/AjaxController.php index cb4a890..de423a5 100644 --- a/app/Http/Controllers/AjaxController.php +++ b/app/Http/Controllers/AjaxController.php @@ -208,123 +208,6 @@ class AjaxController extends CubistFrontController $product_type = $request->productType; $filterValues = $request->filter ?? []; - $res = []; - $type = ProductType::find($product_type); - $rawproducts = Product::where('product_type', $product_type)->where('online', 1)->where('public', 1)->get(); - $products = []; - foreach ($rawproducts as $idx => $rawproduct) { - $products[$idx] = $rawproduct->getPageData(); - } - $locale = App::getLocale(); - - $specifications = $type->filters; - - $allmatches = []; - - $filters = Specification::whereIn('id', $specifications)->get(); - $res['filters'] = []; - foreach ($filters as $filter) { - - $filterValue = null; - if (isset($filterValues[$filter->id])) { - $filterValue = explode(';', $filterValues[$filter->id]); - sort($filterValue); - } - - $specname = 's_' . Str::snake($filter->name); - $data = $filter->getPageData(); - $f = ['label' => $data->label, - 'id' => $data->id, - 'type' => $data->type, - ]; - - $matching = []; - - if ($data->type == 'list') { - $options = []; - $values = []; - foreach ($products as $product) { - $v = $product->get($specname); - if (!$v) { - $v = '-'; - } - if (!isset($values[$v])) { - $values[$v] = 0; - } - $values[$v]++; - if (null === $filterValue) { - $matching[] = $product->id; - } else { - if (in_array($v, $filterValue)) { - $matching[] = $product->id; - } - } - } - foreach ($data->options as $index => $option) { - if (is_scalar($option)) { - $o = $option; - } else { - $o = $option[$locale] ?? $option['fr']; - } - if ($o) { - $nb = $values[$index] ?? 0; - if ($nb > 0) { - $options[] = ['label' => $o, 'value' => $index, 'nb_products' => $nb]; - } - } - } - if (isset($values['-'])) { - $options[] = ['label' => __('Non défini'), 'value' => '-', 'nb_products' => $values['-']]; - } - $f['options'] = $options; - } else if ($data->type == 'numeric' || $data->type == 'range') { - $f['min'] = INF; - $f['max'] = -INF; - $f['unit'] = $data->unit; - - if ($data->type == 'numeric') { - $f['prefix'] = $data['prefix']; - } else { - $f['prefix'] = ''; - } - - foreach ($products as $product) { - $v = $product->get($specname); - if ($data->type == 'range') { - $f['min'] = min($f['min'], $v['first'] ?? INF, $v['second'] ?? INF); - $f['max'] = max($f['max'], $v['first'] ?? -INF, $v['second'] ?? -INF); - if (null !== $filterValue && !($v['first'] == '' && $v['second'] == '')) { - $min = min($v['first'], $v['second']); - $max = max($v['first'], $v['second']); - - if ($min <= $filterValue[1] && $max >= $filterValue[0]) { - $matching[] = $product->id; - } - } - } else { - $f['min'] = min($f['min'], $v); - $f['max'] = min($f['max'], $v); - if (null !== $filterValue) { - if ($v >= $filterValue[0] && $v <= $filterValue[0]) { - $matching[] = $product->id; - } - } - } - if (null === $filterValue && $v != '') { - $matching[] = $product->id; - } - } - } else { - continue; - } - $f['matching'] = ['count' => count($matching), 'hits' => $matching]; - $allmatches[] = $matching; - - $res['filters'][$data->id] = $f; - } - - $intersection = call_user_func_array('array_intersect', $allmatches); - $res['results'] = ['count' => count($intersection), 'hits' => $intersection]; - return $res; + return Product::getFilteredProducts($product_type, $filterValues); } } diff --git a/app/Http/Controllers/ProductController.php b/app/Http/Controllers/ProductController.php index de13e73..8232d42 100644 --- a/app/Http/Controllers/ProductController.php +++ b/app/Http/Controllers/ProductController.php @@ -13,24 +13,29 @@ class ProductController extends CubistFrontController public function productList(Request $request, $id) { $productType = ProductType::find($id); + if (!$productType) { $this->_404(); } $this->data['title'] = $productType->name; - $this->data['page'] = $this->data['product_type'] = $productType->getPageData(); - $this->data['products'] = []; $products = Product::with('media') // Eager load media to avoid N+1 query problem - ->where('product_type', $id) + ->where('product_type', $id) ->where('online', 1) + ->where('public', 1) ->get(); + $this->data['products'] = []; foreach ($products as $item) { $this->data['products'][$item->id] = $item->getPageData(); } + // Get available filters + $filters = Product::getFilteredProducts($id); + $this->data['filters'] = $filters ? $filters['filters'] : []; // To be used by Vue component + return view('pages.products', $this->data); } diff --git a/app/Models/Product.php b/app/Models/Product.php index d73ebce..fbc4f34 100644 --- a/app/Models/Product.php +++ b/app/Models/Product.php @@ -369,4 +369,132 @@ class Product extends CubistMagicPageModel return $cart_data; } + + public static function getFilteredProducts($product_type, $filter_values = []) { + + $res = []; + $type = ProductType::find($product_type); + + if (!$type || !$type->filters) { + return $res; + } + + $raw_products = Product::where('product_type', $product_type)->where('online', 1)->where('public', 1)->get(); + $products = []; + foreach ($raw_products as $idx => $raw_product) { + $products[$idx] = $raw_product->getPageData(); + } + $locale = App::getLocale(); + + $specifications = $type->filters; + + $all_matches = []; + + $filters = Specification::whereIn('id', $specifications)->get(); + $res['filters'] = []; + foreach ($filters as $filter) { + + $filter_value = null; + if (isset($filter_values[$filter->id])) { + $filter_value = explode(';', $filter_values[$filter->id]); + sort($filter_value); + } + + $spec_name = 's_' . Str::snake($filter->name); + $data = $filter->getPageData(); + $f = ['label' => $data->label, + 'id' => $data->id, + 'type' => $data->type, + ]; + + $matching = []; + + if ($data->type == 'list') { + $options = []; + $values = []; + foreach ($products as $product) { + $v = $product->get($spec_name); + if (!$v) { + $v = '-'; + } + if (!isset($values[$v])) { + $values[$v] = 0; + } + $values[$v]++; + if (null === $filter_value) { + $matching[] = $product->id; + } else { + if (in_array($v, $filter_value)) { + $matching[] = $product->id; + } + } + } + foreach ($data->options as $index => $option) { + if (is_scalar($option)) { + $o = $option; + } else { + $o = $option[$locale] ?? $option['fr']; + } + if ($o) { + $nb = $values[$index] ?? 0; + if ($nb > 0) { + $options[] = ['label' => $o, 'value' => $index, 'nb_products' => $nb]; + } + } + } + if (isset($values['-'])) { + $options[] = ['label' => __('Non défini'), 'value' => '-', 'nb_products' => $values['-']]; + } + $f['options'] = $options; + } else if ($data->type == 'numeric' || $data->type == 'range') { + $f['min'] = INF; + $f['max'] = -INF; + $f['unit'] = $data->unit; + + if ($data->type == 'numeric') { + $f['prefix'] = $data['prefix']; + } else { + $f['prefix'] = ''; + } + + foreach ($products as $product) { + $v = $product->get($spec_name); + if ($data->type == 'range') { + $f['min'] = min($f['min'], $v['first'] ?? INF, $v['second'] ?? INF); + $f['max'] = max($f['max'], $v['first'] ?? -INF, $v['second'] ?? -INF); + if (null !== $filter_value && !($v['first'] == '' && $v['second'] == '')) { + $min = min($v['first'], $v['second']); + $max = max($v['first'], $v['second']); + + if ($min <= $filter_value[1] && $max >= $filter_value[0]) { + $matching[] = $product->id; + } + } + } else { + $f['min'] = min($f['min'], $v); + $f['max'] = min($f['max'], $v); + if (null !== $filter_value) { + if ($v >= $filter_value[0] && $v <= $filter_value[0]) { + $matching[] = $product->id; + } + } + } + if (null === $filter_value && $v != '') { + $matching[] = $product->id; + } + } + } else { + continue; + } + $f['matching'] = ['count' => count($matching), 'hits' => $matching]; + $all_matches[] = $matching; + + $res['filters'][$data->id] = $f; + } + + $intersection = call_user_func_array('array_intersect', $all_matches); + $res['results'] = ['count' => count($intersection), 'hits' => $intersection]; + return $res; + } + } diff --git a/resources/views/pages/product-detail.blade.php b/resources/views/pages/product-detail.blade.php index d29a172..2dac6ff 100644 --- a/resources/views/pages/product-detail.blade.php +++ b/resources/views/pages/product-detail.blade.php @@ -1,5 +1,5 @@ @php - $technical_sheet=$product->getMediaUrl('technical_sheet',false) + $technical_sheet = $product->getMediaUrl('technical_sheet', false) @endphp @extends('layouts/app') @@ -18,7 +18,7 @@ {{-- Product images --}} getEntity()->image_fallback]))' class="flex-grow" style="max-width: 348px"> @@ -32,7 +32,7 @@ @if($technical_sheet)

- + {{ __('Télécharger la fiche produit') }}

@@ -41,7 +41,7 @@ @if(config('features.quote')) - {{__('Ajouter à ma sélection')}} + {{ __('Ajouter à ma sélection') }}