Пользовательский искатель цепочки CakePHP с условием ИЛИ

#php #cakephp #cakephp-4.x

Вопрос:

Как связать пользовательские поисковики с OR условием? У меня есть beforeFind() метод, с помощью которого я проверяю разрешения.

 if (isset($access->corporate)) {
    $query->find('forCorporate', ['corporate_id' => $access->corporate]);
}
if (isset($access->company)) {
    $query->find('forCompany', ['company_id' => $access->company]);
}
 

Мне нужно было бы связать 2 искателя выше с условием ИЛИ с исходным запросом.

Комментарии:

1. На самом деле вам нужно проверить разрешения по адресу: book.cakephp.org/authorization/2/en/policies.html#policy-scopes

2. @Salines Я могу использовать его там, но проблема та же самая. Сцепление с ИЛИ

3. Как выглядят ваши запросы finder?

4. @Солевые растворы, подобные этому. публичная функция findForCorporate(Запрос $запрос, массив $параметры) { возвращает $запрос->где([‘corporate_id’ =>> $параметры[‘corporate_id’]); }

5. попробуйте с комбинаторами book.cakephp.org/4/en/orm/…

Ответ №1:

Я нашел решение и разместил его здесь, надеясь, что оно поможет другим.

Прежде всего, мне нужны были чистые копии запроса, чтобы создавать подзапросы, не попадая в бесконечный цикл. Там я удалил все предыдущие WHERE условия.

Затем я вызвал where() исходный запрос, используя метод обратного вызова. Это дало мне доступ к манипулированию QueryExpression .

Поскольку я хотел связать пользовательские запросы finder с OR условием, мне нужно было начальное условие, которое всегда ложно, вот почему у меня есть 1 = 0 условие. Затем я смог использовать метод QueryExpression » s add() » для цепочки запросов.

 $cleanQueryCorporate = $query->cleanCopy()
    ->select(['Accounts.id'])->where(null, [], true);
$cleanQueryCompany = $query->cleanCopy()
    ->select(['Accounts.id'])->where(null, [], true);

$query->where(function (QueryExpression $exp) use ($access, $cleanQueryCorporate, $cleanQueryCompany, $options) {
    $exp = $exp->or('1 = 0');       // this needed to add the next ones with OR
    if (isset($access->corporate)) {
        $exp = $exp->add(['Accounts.id IN'=> $cleanQueryCorporate
            ->find('forCorporate', ['corporate_id' => $access->corporate])]);
    }
    if (isset($access->company)) {
        $exp = $exp->add(['Accounts.id IN'=> $cleanQueryCompany
            ->find('forCompany', ['company_id' => $access->company])]);
    }
    return $exp;
});