@@ -411,4 +411,73 @@ protected function get_date_sql(string $tablealias, string $fieldname): conditio
411
411
412
412
return new condition_sql ('' , $ where , $ params );
413
413
}
414
+
415
+ /**
416
+ * Get SQL data for multi select type fields.
417
+ *
418
+ * @param string $tablealias Alias for a table.
419
+ * @param string $fieldname Field name.
420
+ * @param bool $addspace Does a field type add space?
421
+ * @return condition_sql
422
+ */
423
+ protected function get_multiselect_sql (string $ tablealias , string $ fieldname , bool $ addspace = true ): condition_sql {
424
+ global $ DB ;
425
+
426
+ $ fieldvalue = $ this ->get_field_value ();
427
+ $ operatorvalue = $ this ->get_operator_value ();
428
+
429
+ if ($ this ->is_broken ()) {
430
+ return new condition_sql ('' , '' , []);
431
+ }
432
+ // For some reason user profile field autocomplete adds space when saving field values
433
+ // like implode(', ', $data). However multiselect custom field doesn't do it, instead it does
434
+ // like implode(',', $data). To make it flexible we add space when we consider (or not) an extra
435
+ // space when we build following SQL.
436
+ $ space = $ addspace ? ' ' : '' ;
437
+
438
+ // User data for multiselect fields is stored like Option 1, Option 2, Option 3.
439
+ // So to be accurate in our SQL we have to cover three scenarios:
440
+ // 1. Value is in the beginning of the string.
441
+ // 2. Value is somewhere in the middle.
442
+ // 3. Value is at the end of the string.
443
+ // So our SQL should like:
444
+ // WHERE data like 'value%' OR data like '% value, %' OR data like '%, value'
445
+ // This is a bit hacky, but should give us accurate results.
446
+ $ startparam = condition_sql::generate_param_alias ();
447
+ $ middleparam = condition_sql::generate_param_alias ();
448
+ $ endparam = condition_sql::generate_param_alias ();
449
+
450
+ switch ($ operatorvalue ) {
451
+ case self ::TEXT_IS_EQUAL_TO :
452
+ $ value = $ DB ->sql_like_escape ($ fieldvalue );
453
+
454
+ $ where = $ DB ->sql_like ("$ tablealias. $ fieldname " , ": $ startparam " , false , false );
455
+ $ params [$ startparam ] = "$ value% " ;
456
+
457
+ $ where .= ' OR ' . $ DB ->sql_like ("$ tablealias. $ fieldname " , ": $ middleparam " , false , false );
458
+ $ params [$ middleparam ] = "%, $ space$ value, $ space% " ;
459
+
460
+ $ where .= ' OR ' . $ DB ->sql_like ("$ tablealias. $ fieldname " , ": $ endparam " , false , false );
461
+ $ params [$ endparam ] = "%, $ space$ value " ;
462
+
463
+ break ;
464
+ case self ::TEXT_IS_NOT_EQUAL_TO :
465
+ $ value = $ DB ->sql_like_escape ($ fieldvalue );
466
+
467
+ $ where = $ DB ->sql_like ("$ tablealias. $ fieldname " , ": $ startparam " , false , false , true );
468
+ $ params [$ startparam ] = "$ value% " ;
469
+
470
+ $ where .= ' AND ' . $ DB ->sql_like ("$ tablealias. $ fieldname " , ": $ middleparam " , false , false , true );
471
+ $ params [$ middleparam ] = "%, $ space$ value, $ space% " ;
472
+
473
+ $ where .= ' AND ' . $ DB ->sql_like ("$ tablealias. $ fieldname " , ": $ endparam " , false , false , true );
474
+ $ params [$ endparam ] = "%, $ space$ value " ;
475
+
476
+ break ;
477
+ default :
478
+ return new condition_sql ('' , '' , []);
479
+ }
480
+
481
+ return new condition_sql ('' , $ where , $ params );
482
+ }
414
483
}
0 commit comments