Skip to content

Commit 6140bf1

Browse files
authored
Merge pull request #177 from Planetbiru/feature/version-3.22.1
Normalizes boolean values
2 parents fa4510a + 790f51c commit 6140bf1

1 file changed

Lines changed: 81 additions & 16 deletions

File tree

src/Database/PicoSpecification.php

Lines changed: 81 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
* This class is responsible for building complex database query specifications,
1212
* allowing for the combination of predicates using logical operators (AND, OR).
13-
*
13+
*
1414
* @author Kamshory
1515
* @package MagicObject\Database
1616
* @link https://github.com/Planetbiru/MagicObject
@@ -47,7 +47,7 @@ class PicoSpecification // NOSONAR
4747
* @var string
4848
*/
4949
private $defaultLogic = self::LOGIC_AND;
50-
50+
5151
/**
5252
* Gets an instance of PicoSpecification.
5353
*
@@ -61,13 +61,13 @@ public static function getInstance()
6161
/**
6262
* Creates and returns an instance of the class with an optional PicoPredicate condition.
6363
*
64-
* This static method creates a new instance of the class and, if the provided parameters
64+
* This static method creates a new instance of the class and, if the provided parameters
6565
* are set, adds a PicoPredicate condition using the given field and value.
6666
*
67-
* @param string|null $field The name of the field to be used in the predicate.
67+
* @param string|null $field The name of the field to be used in the predicate.
6868
* If null, no predicate is added.
69-
* @param mixed|null $value The value to compare against the field in the predicate.
70-
*
69+
* @param mixed|null $value The value to compare against the field in the predicate.
70+
*
7171
* @return self A new instance of the class with the optionally added predicate.
7272
*/
7373
public static function getInstanceOf($field = null, $value = null)
@@ -289,7 +289,7 @@ public function isEmpty()
289289
{
290290
return empty($this->specifications);
291291
}
292-
292+
293293
/**
294294
* Check if the given input is an array.
295295
*
@@ -309,6 +309,10 @@ public static function isArray($array)
309309
*/
310310
public static function isValueEmpty($value)
311311
{
312+
if($value === false)
313+
{
314+
return false;
315+
}
312316
return !isset($value) || (is_string($value) && empty(trim($value)));
313317
}
314318

@@ -373,15 +377,15 @@ private function getWhere($specifications)
373377
}
374378
return $arr;
375379
}
376-
380+
377381
/**
378382
* Retrieves the full column name, including any parent field.
379-
*
383+
*
380384
* This method returns the column name formatted as "parentField.field" if the parent field is provided; otherwise, it returns just the field name.
381-
*
385+
*
382386
* @param string $field The field name of the entity.
383387
* @param string|null $parentField The parent field name, if applicable.
384-
*
388+
*
385389
* @return string The full column name, either just the field name or the parent field concatenated with the field.
386390
*/
387391
private function getColumnName($field, $parentField)
@@ -438,7 +442,7 @@ private function hasValue($specification)
438442
*
439443
* Supported dynamic method:
440444
*
441-
* - `set<FieldName>(value)`:
445+
* - `set<FieldName>(value)`:
442446
* Sets a predicate for the specified field.
443447
* For example, calling `$obj->setAge(30)` would:
444448
* - Extract the field name `age` from the method name.
@@ -549,7 +553,7 @@ public static function fromUserInput($request, $map = null) // NOSONAR
549553
}
550554
return $specification;
551555
}
552-
556+
553557
/**
554558
* Validates whether a given filter value and filter object are usable.
555559
*
@@ -583,8 +587,8 @@ public static function toLowerCase($input)
583587
* Adjusts the filter value based on the filter's configuration.
584588
*
585589
* This method ensures that the input value aligns with the filter type.
586-
* If the filter does not expect an array but the input is an array,
587-
* the first value in the array is selected. If no adjustment is needed,
590+
* If the filter does not expect an array but the input is an array,
591+
* the first value in the array is selected. If no adjustment is needed,
588592
* the input value is returned as-is.
589593
*
590594
* @param mixed $filterValue The raw user input value.
@@ -596,9 +600,70 @@ private static function fixInput($filterValue, $filter)
596600
if(!$filter->isArray() && is_array($filterValue) && !empty($filterValue)) {
597601
$filterValue = array_values($filterValue)[0];
598602
}
603+
if($filter->isArrayBoolean() && is_array($filterValue)) {
604+
foreach($filterValue as $key => $value)
605+
{
606+
// Parameter is array
607+
// Result is array
608+
$filterValue[$key] = self::fixInputArrayBoolean($value);
609+
}
610+
}
611+
else if($filter->isBoolean()) {
612+
// Parameter is boolean
613+
// Result is boolean
614+
$filterValue = self::fixInputBoolean($filterValue);
615+
}
616+
599617
return $filterValue;
600618
}
601619

620+
/**
621+
* Normalizes boolean values within an array.
622+
*
623+
* This method iterates through the array and converts each element
624+
* into a proper boolean value if possible. If the input is a string,
625+
* it is also normalized into a boolean.
626+
*
627+
* @param array|string $value The array or string containing raw boolean-like values.
628+
* @return array|bool The normalized array of booleans, or a single boolean if input was a string.
629+
*/
630+
private static function fixInputArrayBoolean($value)
631+
{
632+
if(is_array($value)) {
633+
foreach($value as $key => $val)
634+
{
635+
$value[$key] = self::fixInputBoolean($val);
636+
}
637+
}
638+
else if(is_string($value)) {
639+
$value = self::fixInputBoolean($value);
640+
}
641+
return $value;
642+
}
643+
644+
/**
645+
* Converts a raw input into a boolean value.
646+
*
647+
* This method interprets common string representations of boolean values
648+
* such as "true", "false", "yes", "no", "1", and "0". If the input
649+
* matches one of these values, it is converted into a boolean.
650+
* Otherwise, the original value is returned unchanged.
651+
*
652+
* @param mixed $value The raw input value to be normalized.
653+
* @return bool|mixed A boolean value if conversion is possible, otherwise the original input.
654+
*/
655+
private static function fixInputBoolean($value)
656+
{
657+
if(is_string($value)) {
658+
if(strtolower($value) === "true" || strtolower($value) === "yes" || strtolower($value) === "1"){
659+
return true;
660+
} else if(strtolower($value) === "false" || strtolower($value) === "no" || strtolower($value) === "0"){
661+
return false;
662+
}
663+
}
664+
return $value;
665+
}
666+
602667
/**
603668
* Creates a full text search specification based on keywords.
604669
*
@@ -710,7 +775,7 @@ public function setDefaultLogicOr()
710775
* Checks if a real join table is required based on the specifications.
711776
*
712777
* @return bool true if a join is required, false otherwise.
713-
*/
778+
*/
714779
public function getRequireJoin()
715780
{
716781
return $this->requireJoin;

0 commit comments

Comments
 (0)