Как сделать «по-уму» обработку параметров запроса и их трансформацию? контроллер:foreach( $request as $k => $v ) { if( in_array( $k, ['limit', 'page' ] ) ) { continue; } if( is_array( $v ) ) { if( isset($v['type']) ) { switch($v['type']) { case "parent": $criterias[] = new Criterion\ParentLocationId($v['val']); break; } } if( isset( $v['like'] ) ) { switch( $v['like'] ) { case 0: $criterias[] = new Criterion\FullText( $v['val'] ); break; case 1: $criterias[] = new Criterion\Field( $v['name'], Criterion\Operator::LIKE, $v['val'] . "%" ); break; case 2: $criterias[] = new Criterion\Field( $v['name'], Criterion\Operator::LIKE, "%" . $v['val'] . "%" ); break; case 3: $criterias[] = new Criterion\Field( $v['name'], Criterion\Operator::EQ, $v['val'] ); break; } } else { $criterias[] = new Criterion\Field( $k, Criterion\Operator::IN, $v ); } } else { $criterias[] = new Criterion\Field( $k, Criterion\Operator::EQ, $v); } } if( count( $criterias ) > 0 ) { $query->filter = new Criterion\LogicalAnd( $criterias ); } эта "лапша" проверяет каждое значения реквеста, если значение текстового типа добавляет $criterias[] = new Criterion\Field( $k, Criterion\Operator::EQ, $v); т.е. сравнивание если простой массив то $criterias[] = new Criterion\Field( $k, Criterion\Operator::IN, $v ); если массив имеет ключ type то $criterias[] = new Criterion\ParentLocationId($v['val']); дальше эта лапша будет только расти, как я понимаю надо перейти на объекты дальше надо предусмотреть чтобы другой программист мог определить в своем другом бандле своей typeswitch($v['type']) { case "parent": $criterias[] = new Criterion\ParentLocationId($v['val']); и свой кастомный класс типа Criterion который надо применить в входяшему параметру реквеста в ООП не очень силён, подскажите как мне это грамотно сделать
Для более гибкого и расширяемого решения можно использовать паттерн фабричного метода или абстрактной фабрики.
Создайте интерфейс CriterionInterface с методом applyCriteria($request) и реализуйте его в классах-критериях, например CriterionField, CriterionParentLocationId и других. Классы-критерии будут содержать логику обработки конкретных типов запросов.
Затем создайте фабрику (например CriterionFactory), которая будет принимать параметры запроса и возвращать соответствующий объект-критерий в зависимости от типа запроса.
Примерно так:
interface CriterionInterface { public function applyCriteria($request); } class CriterionFactory { public static function createCriterion($request) { if( isset($request['type']) ) { switch($request['type']) { case "parent": return new CriterionParentLocationId($request['val']); } } // Добавьте другие типы критериев здесь } } class Controller { public function processRequest($request) { $criterias = []; foreach( $request as $k => $v ) { if( in_array( $k, ['limit', 'page' ] ) ) { continue; } if( is_array( $v ) ) { $criterias[] = CriterionFactory::createCriterion($v); } else { $criterias[] = new CriterionField( $k, Criterion\Operator::EQ, $v); } } if( count( $criterias ) > 0 ) { $query->filter = new Criterion\LogicalAnd( $criterias ); } } }
Такой подход позволит легко добавлять новые типы критериев, не изменяя основной логики обработки запросов. Каждый разработчик сможет создать свой собственный критерий, реализуя интерфейс CriterionInterface, и добавить его в фабрику.
Для более гибкого и расширяемого решения можно использовать паттерн фабричного метода или абстрактной фабрики.
Создайте интерфейс CriterionInterface с методом applyCriteria($request) и реализуйте его в классах-критериях, например CriterionField, CriterionParentLocationId и других. Классы-критерии будут содержать логику обработки конкретных типов запросов.
Затем создайте фабрику (например CriterionFactory), которая будет принимать параметры запроса и возвращать соответствующий объект-критерий в зависимости от типа запроса.
Примерно так:
interface CriterionInterface {public function applyCriteria($request);
}
class CriterionFactory {
public static function createCriterion($request) {
if( isset($request['type']) ) {
switch($request['type']) {
case "parent":
return new CriterionParentLocationId($request['val']);
}
}
// Добавьте другие типы критериев здесь
}
}
class Controller {
public function processRequest($request) {
$criterias = [];
foreach( $request as $k => $v ) {
if( in_array( $k, ['limit', 'page' ] ) ) {
continue;
}
if( is_array( $v ) ) {
$criterias[] = CriterionFactory::createCriterion($v);
} else {
$criterias[] = new CriterionField( $k, Criterion\Operator::EQ, $v);
}
}
if( count( $criterias ) > 0 ) {
$query->filter = new Criterion\LogicalAnd( $criterias );
}
}
}
Такой подход позволит легко добавлять новые типы критериев, не изменяя основной логики обработки запросов. Каждый разработчик сможет создать свой собственный критерий, реализуя интерфейс CriterionInterface, и добавить его в фабрику.