@@ -52,25 +52,31 @@ public function index()
5252 $ DTOrderColumnDirection = $ DTOrder [0 ]['dir ' ] == 'desc ' ? 'd ' : '' ;
5353 $ DTOrderColumnName = $ DTColumns [$ DTOrderColumnIndex ]['data ' ];
5454
55- $ DTSearch = $ this ->param ('search ' );
55+ $ DTSearchBuilder = '' ;
56+ if ($ this ->param ('searchBuilder ' )) {
57+ $ DTSearchBuilder = $ this ->param ('searchBuilder ' );
58+ }
5659
5760 $ lproj = lizmap::getProject ($ repository .'~ ' .$ project );
5861 $ layer = $ lproj ->getLayer ($ layerId );
5962 $ typeName = $ layer ->getWfsTypeName ();
6063
6164 $ jsonFeatures = array ();
6265
63- // Get total number of features
64- $ hits = 0 ;
65- $ wfsParamsHits = array (
66+ $ wfsParamsData = array (
6667 'SERVICE ' => 'WFS ' ,
6768 'VERSION ' => '1.0.0 ' ,
6869 'REQUEST ' => 'GetFeature ' ,
6970 'TYPENAME ' => $ typeName ,
71+ );
72+
73+ // Get total number of features
74+ $ hits = 0 ;
75+ $ wfsParamsHits = array (
7076 'RESULTTYPE ' => 'hits ' ,
7177 );
7278
73- $ wfsrequest = new WFSRequest ($ lproj , $ wfsParamsHits , lizmap::getServices ());
79+ $ wfsrequest = new WFSRequest ($ lproj , array_merge ( $ wfsParamsData , $ wfsParamsHits) , lizmap::getServices ());
7480 $ wfsresponse = $ wfsrequest ->process ();
7581 $ hitsData = $ wfsresponse ->getBodyAsString ();
7682 preg_match ('/numberOfFeatures="([0-9]+)"/ ' , $ hitsData , $ matches );
@@ -80,18 +86,6 @@ public function index()
8086 $ recordsFiltered = count ($ filteredFeatureIDs );
8187 }
8288
83- // Get features
84- $ wfsParamsData = array (
85- 'SERVICE ' => 'WFS ' ,
86- 'VERSION ' => '1.0.0 ' ,
87- 'REQUEST ' => 'GetFeature ' ,
88- 'TYPENAME ' => $ typeName ,
89- 'OUTPUTFORMAT ' => 'GeoJSON ' ,
90- 'MAXFEATURES ' => $ DTLength ,
91- 'SORTBY ' => $ DTOrderColumnName .' ' .$ DTOrderColumnDirection ,
92- 'STARTINDEX ' => $ DTStart ,
93- );
94-
9589 if ($ moveSelectedToTop == 'true ' ) {
9690 $ featureIds = array ();
9791 foreach ($ selectedFeatureIDs as $ id ) {
@@ -124,6 +118,108 @@ public function index()
124118 $ wfsParamsData ['EXP_FILTER ' ] = '$id IN ( ' .implode (' , ' , $ filteredFeatureIDs ).') ' ;
125119 }
126120
121+ // Handle search made by searchBuilder
122+ if ($ DTSearchBuilder ) {
123+ foreach ($ DTSearchBuilder ['criteria ' ] as $ criteria ) {
124+ $ column = $ criteria ['data ' ];
125+ $ condition = $ criteria ['condition ' ];
126+ $ value = '' ;
127+ $ value1 = isset ($ criteria ['value1 ' ]) ? addslashes ($ criteria ['value1 ' ]) : '' ;
128+ $ value2 = isset ($ criteria ['value2 ' ]) ? addslashes ($ criteria ['value2 ' ]) : '' ;
129+
130+ // Map DataTables operators to QGIS Server operators
131+ switch ($ condition ) {
132+ case '= ' :
133+ case '!= ' :
134+ case '< ' :
135+ case '<= ' :
136+ case '> ' :
137+ case '>= ' :
138+ $ qgisOperator = $ condition ;
139+ if ($ criteria ['type ' ] == 'num ' ) {
140+ $ value = $ value1 ;
141+ } else {
142+ $ value = '\'' .$ value1 .'\'' ;
143+ }
144+
145+ break ;
146+
147+ case 'starts ' :
148+ $ qgisOperator = 'ILIKE ' ;
149+ $ value = '\'' .$ value1 .'% \'' ;
150+
151+ break ;
152+
153+ case '!starts ' :
154+ $ qgisOperator = 'NOT ILIKE ' ;
155+ $ value = '\'' .$ value1 .'% \'' ;
156+
157+ break ;
158+
159+ case 'contains ' :
160+ $ qgisOperator = 'ILIKE ' ;
161+ $ value = '\'% ' .$ value1 .'% \'' ;
162+
163+ break ;
164+
165+ case '!contains ' :
166+ $ qgisOperator = 'NOT ILIKE ' ;
167+ $ value = '\'% ' .$ value1 .'% \'' ;
168+
169+ break ;
170+
171+ case 'ends ' :
172+ $ qgisOperator = 'ILIKE ' ;
173+ $ value = '\'% ' .$ value1 .'\'' ;
174+
175+ break ;
176+
177+ case '!ends ' :
178+ $ qgisOperator = 'NOT ILIKE ' ;
179+ $ value = '\'% ' .$ value1 .'\'' ;
180+
181+ break ;
182+
183+ case 'null ' :
184+ $ qgisOperator = 'IS NULL ' ;
185+
186+ break ;
187+
188+ case '!null ' :
189+ $ qgisOperator = 'IS NOT NULL ' ;
190+
191+ break ;
192+
193+ case 'between ' :
194+ $ qgisOperator = 'BETWEEN ' ;
195+ if ($ criteria ['type ' ] == 'num ' ) {
196+ $ value = $ value1 .' AND ' .$ value2 ;
197+ } else {
198+ $ value = '\'' .$ value1 .'\' AND \'' .$ value2 .'\'' ;
199+ }
200+
201+ break ;
202+
203+ case '!between ' :
204+ $ qgisOperator = 'NOT BETWEEN ' ;
205+ if ($ criteria ['type ' ] == 'num ' ) {
206+ $ value = $ value1 .' AND ' .$ value2 ;
207+ } else {
208+ $ value = '\'' .$ value1 .'\' AND \'' .$ value2 .'\'' ;
209+ }
210+
211+ break ;
212+ }
213+ // Append the filter to the exp_filter string
214+ if (!empty ($ expFilter )) {
215+ $ logic = isset ($ DTSearchBuilder ['logic ' ]) ? $ DTSearchBuilder ['logic ' ] : 'AND ' ;
216+ $ expFilter .= " {$ logic } " ;
217+ }
218+
219+ $ expFilter .= "{$ column } {$ qgisOperator } {$ value }" ;
220+ }
221+ }
222+
127223 if ($ expFilter ) {
128224 $ wfsParamsData ['EXP_FILTER ' ] = $ expFilter ;
129225 }
@@ -134,29 +230,29 @@ public function index()
134230 $ bboxString = implode (', ' , $ bbox );
135231 $ wfsParamsData ['BBOX ' ] = $ bboxString ;
136232 $ wfsParamsData ['SRSNAME ' ] = $ srsName ;
233+ }
137234
138- // Get total number of features in the bounding box
139- $ wfsParamsFilterByExtentHits = array (
140- 'SERVICE ' => 'WFS ' ,
141- 'VERSION ' => '1.0.0 ' ,
142- 'REQUEST ' => 'GetFeature ' ,
143- 'TYPENAME ' => $ typeName ,
144- 'RESULTTYPE ' => 'hits ' ,
145- 'BBOX ' => $ bboxString ,
146- 'SRSNAME ' => $ srsName ,
147- );
235+ $ wfsParamsPaginated = array (
236+ 'OUTPUTFORMAT ' => 'GeoJSON ' ,
237+ 'MAXFEATURES ' => $ DTLength ,
238+ 'STARTINDEX ' => $ DTStart ,
239+ 'SORTBY ' => $ DTOrderColumnName .' ' .$ DTOrderColumnDirection ,
240+ );
148241
149- $ wfsrequest = new WFSRequest ($ lproj , $ wfsParamsFilterByExtentHits , lizmap::getServices ());
242+ $ wfsrequest = new WFSRequest ($ lproj , array_merge ($ wfsParamsData , $ wfsParamsPaginated ), lizmap::getServices ());
243+ $ wfsresponse = $ wfsrequest ->process ();
244+ $ featureData = $ wfsresponse ->getBodyAsString ();
245+
246+ // Get hits when data is filtered
247+ if ($ expFilter || count ($ bbox ) == 4 ) {
248+
249+ $ wfsrequest = new WFSRequest ($ lproj , array_merge ($ wfsParamsData , $ wfsParamsHits ), lizmap::getServices ());
150250 $ wfsresponse = $ wfsrequest ->process ();
151251 $ filterByExtentHitsData = $ wfsresponse ->getBodyAsString ();
152252 preg_match ('/numberOfFeatures="([0-9]+)"/ ' , $ filterByExtentHitsData , $ matches );
153253 $ recordsFiltered = $ matches [1 ];
154254 }
155255
156- $ wfsrequest = new WFSRequest ($ lproj , $ wfsParamsData , lizmap::getServices ());
157- $ wfsresponse = $ wfsrequest ->process ();
158- $ featureData = $ wfsresponse ->getBodyAsString ();
159-
160256 $ returnedData = array (
161257 'draw ' => (int ) $ this ->param ('draw ' ),
162258 'recordsTotal ' => $ hits ,
0 commit comments