Skip to content

Commit d9d79a7

Browse files
committed
Fix: Options class now considers add()ed options for ordering, filtering and limiting.
1 parent 4ef39a7 commit d9d79a7

File tree

2 files changed

+62
-56
lines changed

2 files changed

+62
-56
lines changed

Database/Query.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1313,8 +1313,6 @@ protected function _where($where, $value = null, $type = 'AND ', $op = '=', $bin
13131313
/**
13141314
* Add parentheses to a where condition.
13151315
*
1316-
* @return void
1317-
*
13181316
* @internal
13191317
*/
13201318
protected function _where_group($inOut, $op)

Editor/Options.php

Lines changed: 62 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,10 @@ class Options extends Ext
112112
*/
113113

114114
/**
115-
* Add extra options to the list, in addition to any obtained from the database.
115+
* Add extra options to the list, in addition to any obtained from the database. Note
116+
* that these go through the same filtering and ordering operation as database retrieved
117+
* values (they are merged together if both are used). Use a custom function if you want
118+
* complete control over the options and their order.
116119
*
117120
* @param string $label The label to use for the option
118121
* @param string|null $value Value for the option. If not given, the label will be used
@@ -357,11 +360,6 @@ public function exec($db, $refresh, $search = null, $find = null)
357360
$value = $this->_value;
358361
$formatter = $this->_renderer;
359362

360-
// Create a list of the fields that we need to get from the db
361-
$fields = [];
362-
$fields[] = $value;
363-
$fields = array_merge($fields, $label);
364-
365363
// We need a default formatter if one isn't provided
366364
if (!$formatter) {
367365
$formatter = static function ($row) use ($label) {
@@ -376,52 +374,20 @@ public function exec($db, $refresh, $search = null, $find = null)
376374
}
377375

378376
// Get the data
379-
$q = $db
380-
->query('select')
381-
->distinct(true)
382-
->table($this->_table)
383-
->left_join($this->_leftJoin)
384-
->get($fields)
385-
->where($this->_where);
377+
$options = $this->execDb($db, $find);
386378

387-
if (is_array($find)) {
388-
$q->where_in($value, $find);
379+
// Manually added options
380+
for ($i = 0; $i < count($this->_manualAdd); ++$i) {
381+
$options[] = $this->_manualAdd[$i];
389382
}
390383

391-
if (is_string($this->_order)) {
392-
// For cases where we are ordering by a field which isn't included in the list
393-
// of fields to display, we need to add the ordering field, due to the
394-
// select distinct.
395-
$orderFields = explode(',', $this->_order);
396-
397-
for ($i = 0, $ien = count($orderFields); $i < $ien; ++$i) {
398-
$field = strtolower($orderFields[$i]);
399-
$field = str_replace(' asc', '', $field);
400-
$field = str_replace(' desc', '', $field);
401-
$field = trim($field);
402-
403-
if (!in_array($field, $fields)) {
404-
$q->get($field);
405-
}
406-
}
407-
408-
$q->order($this->_order);
409-
} elseif ($this->_order === true) {
410-
// Attempt to do a database order, needed for "limit()"ed results
411-
$q->order($this->_label[0]);
412-
}
413-
414-
$rows = $q
415-
->exec()
416-
->fetchAll();
417-
418384
// Create the output array
419385
$out = [];
420386
$max = $this->_limit;
421387

422-
for ($i = 0, $ien = count($rows); $i < $ien; ++$i) {
423-
$rowLabel = $formatter($rows[$i]);
424-
$rowValue = $rows[$i][$value];
388+
for ($i = 0, $ien = count($options); $i < $ien; ++$i) {
389+
$rowLabel = $formatter($options[$i]);
390+
$rowValue = $options[$i][$value];
425391

426392
// Apply the search to the rendered label. Need to do it here rather than in SQL since
427393
// the label is rendered in PHP.
@@ -436,7 +402,7 @@ public function exec($db, $refresh, $search = null, $find = null)
436402
$inc = $this->_includes[$j];
437403

438404
if (isset($rows[$i][$inc])) {
439-
$option[$inc] = $rows[$i][$inc];
405+
$option[$inc] = $options[$i][$inc];
440406
}
441407
}
442408

@@ -450,11 +416,6 @@ public function exec($db, $refresh, $search = null, $find = null)
450416
}
451417
}
452418

453-
// Stick on any extra manually added options
454-
if (count($this->_manualAdd)) {
455-
$out = array_merge($out, $this->_manualAdd);
456-
}
457-
458419
// Local sorting
459420
if ($this->_order === true) {
460421
usort($out, static function ($a, $b) {
@@ -469,15 +430,62 @@ public function exec($db, $refresh, $search = null, $find = null)
469430
$bLabel = '';
470431
}
471432

472-
return is_numeric($aLabel) && is_numeric($bLabel) ?
473-
($aLabel * 1) - ($bLabel * 1) :
474-
strcmp($aLabel, $bLabel);
433+
return is_numeric($aLabel) && is_numeric($bLabel)
434+
? ($aLabel * 1) - ($bLabel * 1)
435+
: strcmp($aLabel, $bLabel);
475436
});
476437
}
477438

478439
return $out;
479440
}
480441

442+
public function execDb($db, $find)
443+
{
444+
// Create a list of the fields that we need to get from the db
445+
$fields = [];
446+
$fields[] = $this->_value;
447+
$fields = array_merge($fields, $this->_label);
448+
449+
$q = $db
450+
->query('select')
451+
->distinct(true)
452+
->table($this->_table)
453+
->left_join($this->_leftJoin)
454+
->get($fields)
455+
->where($this->_where);
456+
457+
if (is_array($find)) {
458+
$q->where_in($this->_value, $find);
459+
}
460+
461+
if (is_string($this->_order)) {
462+
// For cases where we are ordering by a field which isn't included in the list
463+
// of fields to display, we need to add the ordering field, due to the
464+
// select distinct.
465+
$orderFields = explode(',', $this->_order);
466+
467+
for ($i = 0, $ien = count($orderFields); $i < $ien; ++$i) {
468+
$field = strtolower($orderFields[$i]);
469+
$field = str_replace(' asc', '', $field);
470+
$field = str_replace(' desc', '', $field);
471+
$field = trim($field);
472+
473+
if (!in_array($field, $fields)) {
474+
$q->get($field);
475+
}
476+
}
477+
478+
$q->order($this->_order);
479+
} elseif ($this->_order === true) {
480+
// Attempt to do a database order, needed for "limit()"ed results
481+
$q->order($this->_label[0]);
482+
}
483+
484+
return $q
485+
->exec()
486+
->fetchAll();
487+
}
488+
481489
/**
482490
* Get the objects for a set of values.
483491
*

0 commit comments

Comments
 (0)