Issues (3627)

Filter/ComplexRelationValueFilterQueryBuilder.php (1 issue)

1
<?php
2
/*
3
 * @copyright   2018 Mautic Contributors. All rights reserved
4
 * @author      Mautic, Inc.
5
 *
6
 * @link        https://mautic.org
7
 *
8
 * @license     GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
9
 */
10
11
namespace Mautic\LeadBundle\Segment\Query\Filter;
12
13
use Mautic\LeadBundle\Segment\ContactSegmentFilter;
14
use Mautic\LeadBundle\Segment\Query\Expression\CompositeExpression;
15
use Mautic\LeadBundle\Segment\Query\QueryBuilder;
16
17
/**
18
 * Class ComplexRelationValueFilterQueryBuilder is used to connect foreign tables using third table.
19
 *
20
 * Currently only company decorator uses this functionality but it may be used by plugins in the future
21
 *
22
 * filter decorator must implement methods:
23
 *  $filter->getRelationJoinTable()
24
 *  $filter->getRelationJoinTableField()
25
 *
26
 * @see \Mautic\LeadBundle\Segment\Decorator\CompanyDecorator
27
 */
28
class ComplexRelationValueFilterQueryBuilder extends BaseFilterQueryBuilder
29
{
30
    /** {@inheritdoc} */
31
    public static function getServiceId()
32
    {
33
        return 'mautic.lead.query.builder.complex_relation.value';
34
    }
35
36
    /** {@inheritdoc} */
37
    public function applyQuery(QueryBuilder $queryBuilder, ContactSegmentFilter $filter)
38
    {
39
        $filterOperator = $filter->getOperator();
40
41
        $filterParameters = $filter->getParameterValue();
42
43
        if (is_array($filterParameters)) {
44
            $parameters = [];
45
            foreach ($filterParameters as $filterParameter) {
46
                $parameters[] = $this->generateRandomParameterName();
47
            }
48
        } else {
49
            $parameters = $this->generateRandomParameterName();
50
        }
51
52
        $filterParametersHolder = $filter->getParameterHolder($parameters);
53
54
        $tableAlias = $queryBuilder->getTableAlias($filter->getTable());
55
56
        if (!$tableAlias) {
57
            $tableAlias = $this->generateRandomParameterName();
58
59
            $relTable = $this->generateRandomParameterName();
60
            $queryBuilder->leftJoin('l', $filter->getRelationJoinTable(), $relTable, $relTable.'.lead_id = l.id');
61
            $queryBuilder->leftJoin($relTable, $filter->getTable(), $tableAlias, $tableAlias.'.id = '.$relTable.'.'
62
                .$filter->getRelationJoinTableField());
63
        }
64
65
        switch ($filterOperator) {
66
            case 'empty':
67
                $expression = new CompositeExpression(CompositeExpression::TYPE_OR,
68
                    [
69
                        $queryBuilder->expr()->isNull($tableAlias.'.'.$filter->getField()),
0 ignored issues
show
Are you sure $tableAlias of type array|string|true can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

69
                        $queryBuilder->expr()->isNull(/** @scrutinizer ignore-type */ $tableAlias.'.'.$filter->getField()),
Loading history...
70
                        $queryBuilder->expr()->eq($tableAlias.'.'.$filter->getField(), $queryBuilder->expr()->literal('')),
71
                    ]
72
                );
73
                break;
74
            case 'notEmpty':
75
                $expression = new CompositeExpression(CompositeExpression::TYPE_AND,
76
                    [
77
                        $queryBuilder->expr()->isNotNull($tableAlias.'.'.$filter->getField()),
78
                        $queryBuilder->expr()->neq($tableAlias.'.'.$filter->getField(), $queryBuilder->expr()->literal('')),
79
                    ]
80
                );
81
82
                break;
83
            case 'neq':
84
                $expression = $queryBuilder->expr()->orX(
85
                    $queryBuilder->expr()->isNull($tableAlias.'.'.$filter->getField()),
86
                    $queryBuilder->expr()->$filterOperator(
87
                        $tableAlias.'.'.$filter->getField(),
88
                        $filterParametersHolder
89
                    )
90
                );
91
                break;
92
            case 'startsWith':
93
            case 'endsWith':
94
            case 'gt':
95
            case 'eq':
96
            case 'gte':
97
            case 'like':
98
            case 'lt':
99
            case 'lte':
100
            case 'in':
101
            case 'between':   //Used only for date with week combination (EQUAL [this week, next week, last week])
102
            case 'regexp':
103
            case 'notRegexp': //Different behaviour from 'notLike' because of BC (do not use condition for NULL). Could be changed in Mautic 3.
104
                $expression = $queryBuilder->expr()->$filterOperator(
105
                    $tableAlias.'.'.$filter->getField(),
106
                    $filterParametersHolder
107
                );
108
                break;
109
            case 'notLike':
110
            case 'notBetween': //Used only for date with week combination (NOT EQUAL [this week, next week, last week])
111
            case 'notIn':
112
                $expression = $queryBuilder->expr()->orX(
113
                    $queryBuilder->expr()->$filterOperator($tableAlias.'.'.$filter->getField(), $filterParametersHolder),
114
                    $queryBuilder->expr()->isNull($tableAlias.'.'.$filter->getField())
115
                );
116
                break;
117
            case 'multiselect':
118
            case '!multiselect':
119
                $operator    = 'multiselect' === $filterOperator ? 'regexp' : 'notRegexp';
120
                $expressions = [];
121
                foreach ($filterParametersHolder as $parameter) {
122
                    $expressions[] = $queryBuilder->expr()->$operator($tableAlias.'.'.$filter->getField(), $parameter);
123
                }
124
125
                $expression = $queryBuilder->expr()->andX($expressions);
126
                break;
127
            default:
128
                throw new \Exception('Dunno how to handle operator "'.$filterOperator.'"');
129
        }
130
131
        $queryBuilder->addLogic($expression, $filter->getGlue());
132
133
        $queryBuilder->setParametersPairs($parameters, $filterParameters);
134
135
        return $queryBuilder;
136
    }
137
}
138