From d6542a09b8358d0ede7dcb5d3f205a3893ed93f1 Mon Sep 17 00:00:00 2001 From: Richard Dern Date: Thu, 25 Apr 2024 15:44:29 +0200 Subject: [PATCH] Filters handling --- .../BundleRendererServiceProvider.php | 2 + .../Renderers/BaseRenderer.php | 16 ++ .../Renderers/DateBasedListRenderer.php | 172 ++++++++++++++++++ .../Renderers/DossiersListRenderer.php | 10 - .../Renderers/ListRenderer.php | 10 - .../Renderers/ProductBasedListRenderer.php | 144 +++++++++++++++ app/View/Components/PaginationFilters.php | 26 +++ resources/css/paginator.css | 2 +- .../components/pagination-filters.blade.php | 14 ++ .../views/components/paginator.blade.php | 62 ++++--- 10 files changed, 412 insertions(+), 46 deletions(-) create mode 100644 app/Services/BundleRenderers/Renderers/DateBasedListRenderer.php create mode 100644 app/Services/BundleRenderers/Renderers/ProductBasedListRenderer.php create mode 100644 app/View/Components/PaginationFilters.php create mode 100644 resources/views/components/pagination-filters.blade.php diff --git a/app/Providers/BundleRendererServiceProvider.php b/app/Providers/BundleRendererServiceProvider.php index f869944..2cab31e 100644 --- a/app/Providers/BundleRendererServiceProvider.php +++ b/app/Providers/BundleRendererServiceProvider.php @@ -10,6 +10,8 @@ class BundleRendererServiceProvider extends ServiceProvider protected array $bundleRenderers = [ \App\Services\BundleRenderers\Renderers\DossiersListRenderer::class, \App\Services\BundleRenderers\Renderers\DossierRenderer::class, + \App\Services\BundleRenderers\Renderers\DateBasedListRenderer::class, + \App\Services\BundleRenderers\Renderers\ProductBasedListRenderer::class, ]; /** diff --git a/app/Services/BundleRenderers/Renderers/BaseRenderer.php b/app/Services/BundleRenderers/Renderers/BaseRenderer.php index 9758bdb..d0acd6a 100644 --- a/app/Services/BundleRenderers/Renderers/BaseRenderer.php +++ b/app/Services/BundleRenderers/Renderers/BaseRenderer.php @@ -20,6 +20,16 @@ public function __construct(protected Bundle $bundle) $this->shareCommonDataWithView(); } + /** + * Renders a complete HTML view of the bundle + */ + public function render() + { + $this->prepareRender(); + + return view('article', $this->viewData); + } + /** * Renders a card HTML view of the bundle, suitable to display in lists */ @@ -153,6 +163,12 @@ protected function handlePagination() ]; data_set($this->viewData, 'pagination', $data); + + $this->handleFilters($subBundles); + } + + protected function handleFilters($subBundles) + { } protected function collectSubBundles() diff --git a/app/Services/BundleRenderers/Renderers/DateBasedListRenderer.php b/app/Services/BundleRenderers/Renderers/DateBasedListRenderer.php new file mode 100644 index 0000000..1e2adb5 --- /dev/null +++ b/app/Services/BundleRenderers/Renderers/DateBasedListRenderer.php @@ -0,0 +1,172 @@ +prepareRender(); + + $parts = preg_split('#/#', $this->bundle->getPath(), -1, PREG_SPLIT_NO_EMPTY); + $count = count($parts); + + switch ($count) { + case 2: + // A year is specified + $date = sprintf('%s-%s-%s', $parts[1], '01', '01'); + $date = Carbon::parse($date); + $articleTitle = $date->isoFormat('YYYY'); + $siteTitle = sprintf('Articles publiés en %s', $date->isoFormat('YYYY')); + break; + case 3: + // A month is specified + $date = sprintf('%s-%s-%s', $parts[1], $parts[2], '01'); + $date = Carbon::parse($date); + $articleTitle = $date->isoFormat('MMMM YYYY'); + $siteTitle = sprintf('Articles publiés en %s %s', $date->isoFormat('MMMM'), $date->isoFormat('YYYY')); + break; + case 4: + // A day is specified + $date = sprintf('%s-%s-%s', $parts[1], $parts[2], $parts[3]); + $date = Carbon::parse($date); + $articleTitle = $date->isoFormat('DD MMMM YYYY'); + $siteTitle = sprintf('Articles publiés le %s %s %s', $date->isoFormat('DD'), $date->isoFormat('MMMM'), $date->isoFormat('YYYY')); + break; + } + + if (!empty($articleTitle)) { + data_set($this->viewData, 'articleTitle', $articleTitle); + data_set($this->viewData, 'siteTitle', $siteTitle); + } + + return view('article', $this->viewData); + } + + /** + * Return a boolean value indicating if this creator in particular can + * create bundles for specified section + */ + public static function handles(Bundle $bundle): bool + { + $parts = preg_split('#/#', $bundle->getPath(), -1, PREG_SPLIT_NO_EMPTY); + $count = count($parts); + $sections = ['blog', 'liens-interessants']; + + return $count > 0 + && in_array($parts[0], $sections) + && $count < 5; + } + + protected function handleFilters($subBundles) + { + $url = $this->bundle->getPath(); + $parts = preg_split('#/#', $url, -1, PREG_SPLIT_NO_EMPTY); + + // $parts[0] is section + $selectedYear = $parts[1] ?? null; + $selectedMonth = $parts[2] ?? null; + $selectedDay = $parts[3] ?? null; + + $filters = [ + 'Année' => [ + 'values' => [], + 'selected' => $selectedYear ?? 'Toutes', + 'visible' => true, + ], + 'Mois' => [ + 'values' => [], + 'selected' => $selectedMonth ?? 'Tous', + 'visible' => $selectedYear !== null, + ], + 'Jour' => [ + 'values' => [], + 'selected' => $selectedDay ?? 'Tous', + 'visible' => $selectedMonth !== null, + ], + ]; + + $prefix = sprintf('%s/', $parts[0]); + + if ($selectedYear) { + $prefix .= $selectedYear . '/'; + + if ($selectedMonth) { + $prefix .= $selectedMonth . '/'; + + if ($selectedDay) { + $prefix .= $selectedDay . '/'; + } + } + } + + foreach ($subBundles as $subBundle) { + $fileParts = preg_split('#/#', $subBundle, -1, PREG_SPLIT_NO_EMPTY); + + // $parts[0] is section + $year = $fileParts[1] ?? null; + $month = $fileParts[2] ?? null; + $day = $fileParts[3] ?? null; + + if ($year) { + $filters['Année']['values'][$year] = [ + 'title' => $year, + 'path' => sprintf('/%s/%s/', $parts[0], $year), + ]; + + if ($month && $selectedYear !== null) { + $date = Carbon::parse(sprintf('%s-%s-%s', $year, $month, '01')); + $monthName = $date->isoFormat('MMMM'); + + $filters['Mois']['values'][$month] = [ + 'title' => $monthName, + 'path' => sprintf('/%s/%s/%s/', $parts[0], $year, $month), + ]; + + if ($day && $selectedMonth !== null) { + $filters['Jour']['values'][$day] = [ + 'title' => $day, + 'path' => sprintf('/%s/%s/%s/%s/', $parts[0], $year, $month, $day), + ]; + } + } + } + } + + ksort($filters['Année']['values']); + ksort($filters['Mois']['values']); + ksort($filters['Jour']['values']); + + $filters['Année']['values'] = [ + 'Toutes' => [ + 'title' => 'Toutes', + 'path' => sprintf('/%s/', $parts[0]), + ], + ] + + $filters['Année']['values']; + + $filters['Mois']['values'] = [ + 'Tous' => [ + 'title' => 'Tous', + 'path' => sprintf('/%s/%s/', $parts[0], $selectedYear), + ], + ] + + $filters['Mois']['values']; + + $filters['Jour']['values'] = [ + 'Tous' => [ + 'title' => 'Tous', + 'path' => sprintf('/%s/%s/%s/', $parts[0], $selectedYear, $selectedMonth), + ], + ] + + $filters['Jour']['values']; + + data_set($this->viewData['pagination'], 'filters', $filters); + } +} diff --git a/app/Services/BundleRenderers/Renderers/DossiersListRenderer.php b/app/Services/BundleRenderers/Renderers/DossiersListRenderer.php index 6050c50..d8bb870 100644 --- a/app/Services/BundleRenderers/Renderers/DossiersListRenderer.php +++ b/app/Services/BundleRenderers/Renderers/DossiersListRenderer.php @@ -7,16 +7,6 @@ class DossiersListRenderer extends BaseRenderer { - /** - * Renders a complete HTML view of the bundle - */ - public function render() - { - $this->prepareRender(); - - return view('article', $this->viewData); - } - /** * Return a boolean value indicating if this creator in particular can * create bundles for specified section diff --git a/app/Services/BundleRenderers/Renderers/ListRenderer.php b/app/Services/BundleRenderers/Renderers/ListRenderer.php index eabdcf5..baa6779 100644 --- a/app/Services/BundleRenderers/Renderers/ListRenderer.php +++ b/app/Services/BundleRenderers/Renderers/ListRenderer.php @@ -6,16 +6,6 @@ class ListRenderer extends BaseRenderer { - /** - * Renders a complete HTML view of the bundle - */ - public function render() - { - $this->prepareRender(); - - return view('article', $this->viewData); - } - /** * Return a boolean value indicating if this creator in particular can * create bundles for specified section diff --git a/app/Services/BundleRenderers/Renderers/ProductBasedListRenderer.php b/app/Services/BundleRenderers/Renderers/ProductBasedListRenderer.php new file mode 100644 index 0000000..12aece3 --- /dev/null +++ b/app/Services/BundleRenderers/Renderers/ProductBasedListRenderer.php @@ -0,0 +1,144 @@ +prepareRender(); + + $parts = preg_split('#/#', $this->bundle->getPath(), -1, PREG_SPLIT_NO_EMPTY); + $count = count($parts); + + switch ($count) { + case 2: + // A brand is specified + $brandPath = sprintf('%s/%s', 'collections', $parts[1]); + $brandBundle = new Bundle($brandPath, $this->bundle->getDisk()); + $articleTitle = $brandBundle->getArticleTitle(); + $siteTitle = sprintf('Objets de ma collection %s', $articleTitle); + break; + case 3: + // A collection is specified + $brandPath = sprintf('%s/%s', 'collections', $parts[1]); + $brandBundle = new Bundle($brandPath, $this->bundle->getDisk()); + $collectionPath = sprintf('%s/%s/%s', 'collections', $parts[1], $parts[2]); + $collectionBundle = new Bundle($collectionPath, $this->bundle->getDisk()); + $articleTitle = sprintf('%s %s', $brandBundle->getArticleTitle(), $collectionBundle->getArticleTitle()); + $siteTitle = sprintf('Objets de ma collection %s', $articleTitle); + break; + } + + if (!empty($articleTitle)) { + data_set($this->viewData, 'articleTitle', $articleTitle); + data_set($this->viewData, 'siteTitle', $siteTitle); + } + + return view('article', $this->viewData); + } + + /** + * Return a boolean value indicating if this creator in particular can + * create bundles for specified section + */ + public static function handles(Bundle $bundle): bool + { + $parts = preg_split('#/#', $bundle->getPath(), -1, PREG_SPLIT_NO_EMPTY); + $count = count($parts); + $sections = ['collections']; + + return $count > 0 + && in_array($parts[0], $sections) + && $count < 4; + } + + protected function handleFilters($subBundles) + { + $url = $this->bundle->getPath(); + $parts = preg_split('#/#', $url, -1, PREG_SPLIT_NO_EMPTY); + + // $parts[0] is section + $selectedBrand = $parts[1] ?? null; + $selectedCollection = $parts[2] ?? null; + + $filters = [ + 'Marque' => [ + 'values' => [], + 'selected' => $selectedBrand ?? 'Toutes', + 'visible' => true, + ], + 'Collection' => [ + 'values' => [], + 'selected' => $selectedCollection ?? 'Toutes', + 'visible' => $selectedBrand !== null, + ], + ]; + + $prefix = sprintf('%s/', $parts[0]); + + if ($selectedBrand) { + $prefix .= $selectedBrand . '/'; + + if ($selectedCollection) { + $prefix .= $selectedCollection . '/'; + } + } + + foreach ($subBundles as $subBundle) { + $fileParts = preg_split('#/#', $subBundle, -1, PREG_SPLIT_NO_EMPTY); + + // $parts[0] is section + $brand = $fileParts[1] ?? null; + $collection = $fileParts[2] ?? null; + + if ($brand) { + $brandPath = sprintf('/%s/%s/', $parts[0], $brand); + $bundle = new Bundle($brandPath, $this->bundle->getDisk()); + $brandName = $bundle->getArticleTitle(); + + $filters['Marque']['values'][$brand] = [ + 'title' => $brandName, + 'path' => $brandPath, + ]; + + if ($collection && $selectedBrand !== null) { + $collectionPath = sprintf('/%s/%s/%s/', $parts[0], $brand, $collection); + $bundle = new Bundle($collectionPath, $this->bundle->getDisk()); + $collectionName = $bundle->getArticleTitle(); + + $filters['Collection']['values'][$collection] = [ + 'title' => $collectionName, + 'path' => $collectionPath, + ]; + } + } + } + + ksort($filters['Marque']['values']); + ksort($filters['Collection']['values']); + + $filters['Marque']['values'] = [ + 'Toutes' => [ + 'title' => 'Toutes', + 'path' => sprintf('/%s/', $parts[0]), + ], + ] + + $filters['Marque']['values']; + + $filters['Collection']['values'] = [ + 'Toutes' => [ + 'title' => 'Toutes', + 'path' => sprintf('/%s/%s/', $parts[0], $selectedBrand), + ], + ] + + $filters['Collection']['values']; + + data_set($this->viewData['pagination'], 'filters', $filters); + } +} diff --git a/app/View/Components/PaginationFilters.php b/app/View/Components/PaginationFilters.php new file mode 100644 index 0000000..6040f4a --- /dev/null +++ b/app/View/Components/PaginationFilters.php @@ -0,0 +1,26 @@ + + Filtrer par : + + @foreach($filters as $name => $options) +
+ {{ $name }} + +
+ @endforeach + diff --git a/resources/views/components/paginator.blade.php b/resources/views/components/paginator.blade.php index 7de7151..9f5a103 100644 --- a/resources/views/components/paginator.blade.php +++ b/resources/views/components/paginator.blade.php @@ -1,29 +1,41 @@ @props(['orientation']) -@if ($totalPages > 1) -
- @if ($currentPage > 1) -
- -
- @endif +@if ($totalPages > 1 || isset($filters)) +
+ @if($orientation === 'up') + @isset($filters) + @include('components.pagination-filters', ['filters' => $filters, 'orientation' => $orientation]) + @endisset + @endif - @if ($totalPages > 1) -
- {{ $currentPage }} - -
- @endif + @if ($totalPages > 1) + @if ($currentPage > 1) +
+ +
+ @endif - @if ($currentPage < $totalPages) -
- -
- @endif -
+
+ {{ $currentPage }} + +
+ + @if ($currentPage < $totalPages) +
+ +
+ @endif + @endif + + @if($orientation === 'down') + @isset($filters) + @include('components.pagination-filters', ['filters' => $filters, 'orientation' => $orientation]) + @endisset + @endif +
@endif