@@ -112,7 +112,10 @@ class Options extends Ext
112
112
*/
113
113
114
114
/**
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.
116
119
*
117
120
* @param string $label The label to use for the option
118
121
* @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)
357
360
$ value = $ this ->_value ;
358
361
$ formatter = $ this ->_renderer ;
359
362
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
-
365
363
// We need a default formatter if one isn't provided
366
364
if (!$ formatter ) {
367
365
$ formatter = static function ($ row ) use ($ label ) {
@@ -376,52 +374,20 @@ public function exec($db, $refresh, $search = null, $find = null)
376
374
}
377
375
378
376
// 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 );
386
378
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 ];
389
382
}
390
383
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
-
418
384
// Create the output array
419
385
$ out = [];
420
386
$ max = $ this ->_limit ;
421
387
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 ];
425
391
426
392
// Apply the search to the rendered label. Need to do it here rather than in SQL since
427
393
// the label is rendered in PHP.
@@ -436,7 +402,7 @@ public function exec($db, $refresh, $search = null, $find = null)
436
402
$ inc = $ this ->_includes [$ j ];
437
403
438
404
if (isset ($ rows [$ i ][$ inc ])) {
439
- $ option [$ inc ] = $ rows [$ i ][$ inc ];
405
+ $ option [$ inc ] = $ options [$ i ][$ inc ];
440
406
}
441
407
}
442
408
@@ -450,11 +416,6 @@ public function exec($db, $refresh, $search = null, $find = null)
450
416
}
451
417
}
452
418
453
- // Stick on any extra manually added options
454
- if (count ($ this ->_manualAdd )) {
455
- $ out = array_merge ($ out , $ this ->_manualAdd );
456
- }
457
-
458
419
// Local sorting
459
420
if ($ this ->_order === true ) {
460
421
usort ($ out , static function ($ a , $ b ) {
@@ -469,15 +430,62 @@ public function exec($db, $refresh, $search = null, $find = null)
469
430
$ bLabel = '' ;
470
431
}
471
432
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 );
475
436
});
476
437
}
477
438
478
439
return $ out ;
479
440
}
480
441
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
+
481
489
/**
482
490
* Get the objects for a set of values.
483
491
*
0 commit comments