Browse code

Make assets list module filterable

Benjamin Roth authored on14/03/2024 17:05:25
Showing4 changed files
... ...
@@ -133,6 +133,19 @@
133 133
                 <source>Tiefgaragenstellplatz</source>
134 134
             </trans-unit>
135 135
 
136
+            <trans-unit id="REF.re_filter.numberOfRooms">
137
+                <source>Zimmeranzahl</source>
138
+            </trans-unit>
139
+            <trans-unit id="REF.re_filter.city">
140
+                <source>Ort</source>
141
+            </trans-unit>
142
+            <trans-unit id="REF.re_filter.coldRent">
143
+                <source>Kaltmiete</source>
144
+            </trans-unit>
145
+            <trans-unit id="REF.re_filter.livingSpace">
146
+                <source>Wohnfläche</source>
147
+            </trans-unit>
148
+
136 149
         </body>
137 150
     </file>
138 151
 </xliff>
... ...
@@ -14,15 +14,17 @@
14 14
                     <div class="content-grid">
15 15
                         <div class="fragments">
16 16
                             <form class="assets-list-filter" hx-get="{{ pageUrl is defined ? pageUrl : '' }}" hx-push-url="true" hx-headers='{"VR-Ajax": "ReAssetsList"}' hx-trigger="change, submit" hx-target="closest .module-vr-re-assets-list" hx-target="" class="filter">
17
-                                {% if filterOptions.rooms is defined %}
18
-                                    <div class="filter-wrapper">
19
-                                        <select name="filter_zimmer">
20
-                                            <option value="">Anzahl Zimmer</option>
21
-                                            {% for option in filterOptions.rooms %}
22
-                                                <option value="{{ option.value }}"{% if filter.rooms is defined and filter.rooms == option.value %} selected{% endif %}>{{ option.label }}</option>
23
-                                            {% endfor %}
24
-                                        </select>
25
-                                    </div>
17
+                                {% if filterOptions is defined and filterOptions is iterable %}
18
+                                    {% for key, options in filterOptions %}
19
+                                        <div class="filter-wrapper">
20
+                                            <select name="filter[{{ key }}]">
21
+                                                <option value="">{{ ('REF.re_filter.' ~ key)|trans({}, 'contao_default') }}</option>
22
+                                                {% for value, label in options %}
23
+                                                    <option value="{{ value }}"{% if filter[key] is defined and filter[key] == value %} selected{% endif %}>{{ label }}</option>
24
+                                                {% endfor %}
25
+                                            </select>
26
+                                        </div>
27
+                                    {% endfor %}
26 28
                                 {% endif %}
27 29
                             </form>
28 30
                         </div>
... ...
@@ -13,6 +13,7 @@ use Contao\CoreBundle\DependencyInjection\Attribute\AsFrontendModule;
13 13
 use Contao\CoreBundle\Exception\ResponseException;
14 14
 use Contao\CoreBundle\Image\Studio\Studio;
15 15
 use Contao\CoreBundle\Twig\FragmentTemplate;
16
+use Contao\Input;
16 17
 use Contao\ModuleModel;
17 18
 use Contao\PageModel;
18 19
 use Contao\StringUtil;
... ...
@@ -36,17 +37,44 @@ class RealEstateAssetsListController extends RealEstateAssetsModuleController
36 37
         $this->translator = $translator;
37 38
     }
38 39
 
39
-
40 40
     protected function getResponse(FragmentTemplate $template, ModuleModel $model, Request $request): Response
41 41
     {
42 42
         $arrGroups = [];
43
-        $arrFilterOptions = [];
43
+        $arrFilterOptions = [
44
+            'numberOfRooms' => [],
45
+            'coldRent' => [],
46
+            'livingSpace' => [],
47
+            'city' => []
48
+        ];
49
+        $arrFilterSelected = [];
50
+        $arrAssetsOptions = [];
44 51
 
45 52
         $jumpTo = PageModel::findByPk($model->jumpTo);
46 53
         $urlGenerator = System::getContainer()->get('contao.routing.content_url_generator');
47 54
 
55
+        // Filter
56
+        if (isset($_GET['filter']) && \is_array(Input::get('filter')))
57
+        {
58
+            foreach (Input::get('filter') as $filter=>$value)
59
+            {
60
+                if (in_array($filter, array_keys($arrFilterOptions)) && !empty($value))
61
+                {
62
+                    $rawValue = StringUtil::decodeEntities($value);
63
+                    $arrFilterSelected[$filter] = $rawValue;
64
+
65
+                    if (preg_match('/^.*<>.*$/',$rawValue))
66
+                    {
67
+                        list($start,$stop) = preg_split('/<>/',$rawValue, 2);
68
+                        $arrAssetsOptions['column'][] = "$filter BETWEEN $start AND $stop";
69
+                    } else {
70
+                        $arrAssetsOptions['column'][] = "$filter = ?";
71
+                        $arrAssetsOptions['value'][] = $rawValue;
72
+                    }
73
+                }
74
+            }
75
+        }
48 76
 
49
-        if (($assets = $this->getRealEstateAssets(StringUtil::deserialize($model->vr_re_categories))) === null)
77
+        if (($assets = $this->getRealEstateAssets(StringUtil::deserialize($model->vr_re_categories),$arrAssetsOptions)) === null)
50 78
         {
51 79
             return $template->getResponse();
52 80
         }
... ...
@@ -85,14 +113,34 @@ class RealEstateAssetsListController extends RealEstateAssetsModuleController
85 113
             // Filter options
86 114
             if (!empty($asset->numberOfRooms))
87 115
             {
88
-                $arrFilterOptions['rooms'][] = ['value'=>$asset->numberOfRooms, 'label'=>$asset->numberOfRooms . ' ' . ($asset->numberOfRooms > 1 ? $this->translator->trans('MSC.re_rooms', [], 'contao_default') : $this->translator->trans('MSC.re_room', [], 'contao_default'))];
116
+                $arrFilterOptions['numberOfRooms'][$asset->numberOfRooms] = $asset->numberOfRooms . ' ' . ($asset->numberOfRooms > 1 ? $this->translator->trans('MSC.re_rooms', [], 'contao_default') : $this->translator->trans('MSC.re_room', [], 'contao_default'));
117
+            }
118
+            if (!empty($asset->city))
119
+            {
120
+                $arrFilterOptions['city'][$asset->city] = $asset->city;
121
+            }
122
+            if (!empty($asset->coldRent))
123
+            {
124
+                $rangeStart = floor($asset->coldRent / 100) * 100;
125
+                $rangeEnd = $rangeStart + 99;
126
+                $arrFilterOptions['coldRent'][$rangeStart.'<>'.$rangeEnd] = $rangeStart . ' - ' . $rangeEnd . ' €';
127
+            }
128
+            if (!empty($asset->livingSpace))
129
+            {
130
+                $rangeStart = floor($asset->livingSpace / 10) * 10;
131
+                $rangeEnd = $rangeStart + 9;
132
+                $arrFilterOptions['livingSpace'][$rangeStart.'<>'.$rangeEnd] = $rangeStart . ' - ' . $rangeEnd . ' m²';
89 133
             }
90 134
 
91 135
         }
92 136
 
93
-        $arrFilterOptions = array_unique($arrFilterOptions);
137
+        foreach (array_keys($arrFilterOptions) as $filterName)
138
+        {
139
+            $arrFilterOptions[$filterName] = array_unique($arrFilterOptions[$filterName]);
140
+        }
94 141
 
95 142
         $template->set('filterOptions',$arrFilterOptions);
143
+        $template->set('filter',$arrFilterSelected);
96 144
         $template->set('groups',$arrGroups);
97 145
 
98 146
         // Handle ajax
... ...
@@ -21,14 +21,14 @@ abstract class RealEstateAssetsModuleController extends AbstractFrontendModuleCo
21 21
    *
22 22
    * @return RealEstateAssetsModel|RealEstateAssetsModel[]|Collection|null
23 23
    */
24
-  public function getRealEstateAssets($arrCategories)
24
+  public function getRealEstateAssets($arrCategories, array $arrOptions=array())
25 25
   {
26 26
     if (empty($arrCategories) || !\is_array($arrCategories))
27 27
     {
28 28
       return null;
29 29
     }
30 30
 
31
-    return RealEstateAssetsModel::findPublishedByParent($arrCategories);
31
+    return RealEstateAssetsModel::findPublishedByParent($arrCategories, 0,0,$arrOptions);
32 32
   }
33 33
 
34 34
   /**