Skip to content

Commit 3c4ed25

Browse files
committed
Add Datatables searchBuilder backend logic
1 parent c0f60a4 commit 3c4ed25

File tree

2 files changed

+130
-33
lines changed

2 files changed

+130
-33
lines changed

assets/src/legacy/attributeTable.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1481,7 +1481,8 @@ var lizAttributeTable = function() {
14811481
extend: 'searchBuilder',
14821482
config: {
14831483
liveSearch: false,
1484-
columns: '.dt-orderable-asc'
1484+
columns: '.dt-orderable-asc',
1485+
depthLimit: 1
14851486
}
14861487
}
14871488
]

lizmap/modules/lizmap/controllers/datatables.classic.php

Lines changed: 128 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)