Skip to content

Instantly share code, notes, and snippets.

@mr4torr
Created March 3, 2025 14:37
Show Gist options
  • Save mr4torr/e788cd1a4f3e7956ee8e44348046efc0 to your computer and use it in GitHub Desktop.
Save mr4torr/e788cd1a4f3e7956ee8e44348046efc0 to your computer and use it in GitHub Desktop.
<?php
class ApplyAccordingToParametersHelper
{
private const DIVISOR_OR = '||';
private const DIVISOR_AND = '&&';
private const DIVISOR_TYPE = ':';
private const DENIAL = '!';
/**
* Função que executa a closure conforme o parâmetro informado na chave isso evita o uso de if/else
* com $searchRequest->hasColumn('XXX') e $searchRequest->hasFilter('XXX')
*
* @param array<string, callable> $values
*
* Exemplo:
* ```php
* $values = [
* "field" => fn () => error_log('se tiver no column esse campos executa 0 callback'),
* "field||column:field" => fn () => error_log('se tiver no column um desses campos executa o callback'),
* "field&&column:field" => fn () => error_log('se tiver no column os 2 campos executa o callback'),
* "column:field" => fn () => error_log('se tiver no column esse campos executa 0 callback'),
* "column:field||column:field" => fn () => error_log('se tiver no column um desses campos executa o callback'),
* "column:field&&column:field" => fn () => error_log('se tiver no column os 2 campos executa o callback'),
* "filter:field" => fn () => error_log('se tiver no filter esse campos executa 0 callback'),
* "filter:field||column:field" => fn () => error_log('se tiver no filter um desses campos executa o callback'),
* "filter:field&&column:field" => fn () => error_log('se tiver no filter os 2 campos executa o callback'),
* ];
*
* ApplyAccordingToParametersHelper::apply($values, $searchRequest);
* ```
*/
public static function apply(array $values, SearchParametersInterface $searchRequest): void
{
foreach ($values as $typeAndFields => $callback) {
$arrOR = explode(self::DIVISOR_OR, $typeAndFields);
$arrAND = explode(self::DIVISOR_AND, $typeAndFields);
$hasOR = count($arrOR) > 1;
$hasAND = count($arrAND) > 1;
if ($hasOR && $hasAND) {
throw new \Exception('More than one operator cannot be defined, select || or &&');
}
$fields = $hasAND ? $arrAND : $arrOR;
$results = array_filter(array_map(function ($typeAndField) use ($searchRequest) {
$arr = explode(self::DIVISOR_TYPE, $typeAndField, 2);
$type = count($arr) === 1 ? 'column' : $arr[0];
$field = count($arr) === 1 ? $arr[0] : $arr[1];
$isDenial = strpos($field, self::DENIAL) === 0;
if (!in_array($type, ['column', 'filter'])) {
throw new \Exception('The type ' . $type . ' is not allowed. It must be "column" or "filter".');
}
$action = $type === 'column' ? 'hasColumn' : 'hasFilter';
$return = [1, null];
if ($isDenial) {
$field = substr($field, 1);
$return = [null, 1];
}
return $searchRequest->$action($field) ? $return[0] : $return[1];
}, $fields));
if ($hasAND && count($results) !== count($fields) || !$results) {
continue;
}
$callback();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment