Passed
Pull Request — master (#582)
by Richard
17:20
created

CriteriaCompo::add()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 2
dl 0
loc 5
rs 10
c 0
b 0
f 0
ccs 4
cts 4
cp 1
crap 1
1
<?php
2
/*
3
 You may not change or alter any portion of this comment or credits
4
 of supporting developers from this source code or any supporting source code
5
 which is considered copyrighted (c) material of the original comment or credit authors.
6
7
 This program is distributed in the hope that it will be useful,
8
 but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10
*/
11
12
namespace Xoops\Core\Kernel;
13
14
use Doctrine\DBAL\Query\QueryBuilder;
15
16
/**
17
 * Collection of multiple CriteriaElement objects
18
 *
19
 * @category  Xoops\Core\Kernel\CriteriaCompo
20
 * @package   Xoops\Core\Kernel
21
 * @author    Kazumi Ono <[email protected]>
22
 * @author    Nathan Dial <[email protected]>
23
 * @author    Taiwen Jiang <[email protected]>
24
 * @copyright 2000-2013 XOOPS Project (http://xoops.org)
25
 * @license   GNU GPL 2 or later (http://www.gnu.org/licenses/gpl-2.0.html)
26
 * @link      http://xoops.org
27
 * @since     2.0.0
28
 */
29
class CriteriaCompo extends CriteriaElement
30
{
31
    /**
32
     * The elements of the collection
33
     *
34
     * @var CriteriaElement[] array of objects
35
     */
36
    protected $criteriaElements = array();
37
38
    /**
39
     * Conditions
40
     *
41
     * @var array
42
     */
43
    protected $conditions = array();
44
45
    /**
46
     * Constructor
47
     *
48
     * @param CriteriaElement|null $ele       a criteria element to start the compo
49
     * @param string               $condition joining condition for element, AND or OR
50
     */
51 28
    public function __construct(CriteriaElement $ele = null, $condition = 'AND')
52
    {
53 28
        if (isset($ele)) {
54 19
            $this->add($ele, $condition);
55
        }
56 28
    }
57
58
    /**
59
     * add a criteria element
60
     *
61
     * @param CriteriaElement $criteriaElement a criteria element to add to the compo
62
     * @param string          $condition       joining condition for element, AND or OR
63
     *
64
     * @return CriteriaCompo
65
     */
66 23
    public function add(CriteriaElement $criteriaElement, $condition = 'AND')
67
    {
68 23
        $this->criteriaElements[] = $criteriaElement;
69 23
        $this->conditions[] = $condition;
70 23
        return $this;
71
    }
72
73
    /**
74
     * Make the criteria into a query string
75
     *
76
     * @return string
77
     */
78 2
    public function render()
79
    {
80 2
        $ret = '';
81 2
        foreach ($this->criteriaElements as $i => $element) {
82 2
            if (!is_object($element)) {
83
                continue;
84
            }
85
            /* @var $element CriteriaElement */
86 2
            if ($i == 0) {
87 2
                $ret = $element->render();
88
            } else {
89
                if (!$render = $element->render()) {
90
                    continue;
91
                }
92
                $ret .= ' ' . $this->conditions[$i] . ' (' . $render . ')';
93
            }
94 2
            $ret = "({$ret})";
95
        }
96 2
        $ret = ($ret==='()') ? '(1)' : $ret;
97 2
        return $ret;
98
    }
99
100
    /**
101
     * Make the criteria into a SQL "WHERE" clause
102
     *
103
     * @return string
104
     */
105 1
    public function renderWhere()
106
    {
107 1
        $ret = $this->render();
108 1
        $ret = ($ret != '') ? 'WHERE ' . $ret : $ret;
109 1
        return $ret;
110
    }
111
112
    /**
113
     * Generate an LDAP filter from criteria
114
     *
115
     * @return string
116
     * @author Nathan Dial [email protected]
117
     */
118 1
    public function renderLdap()
119
    {
120 1
        $ret = '';
121 1
        foreach ($this->criteriaElements as $i => $element) {
122
            /* @var $element CriteriaElement */
123 1
            if ($i == 0) {
124 1
                $ret = $element->renderLdap();
125
            } else {
126
                $cond = strtoupper($this->conditions[$i]);
127
                $op = ($cond === "OR") ? "|" : "&";
128
                $ret = "({$op}{$ret}" . $element->renderLdap() . ")";
129
            }
130
        }
131 1
        return $ret;
132
    }
133
134
    /**
135
     * Render as Doctrine QueryBuilder instructions
136
     *
137
     * @param QueryBuilder $qb        query builder instance
138
     * @param string       $whereMode how does this fit in the passed in QueryBuilder?
139
     *                                '' = as where,'and'= as andWhere, 'or' = as orWhere
140
     *
141
     * @return QueryBuilder query builder instance
142
     */
143 21
    public function renderQb(QueryBuilder $qb = null, $whereMode = '')
144
    {
145 21
        if ($qb==null) {
146 1
            $qb = \Xoops::getInstance()->db()->createXoopsQueryBuilder();
147 1
            $whereMode = ''; // first entry in new instance must be where
148
        }
149
150 21
        $expr = '';
151 21
        foreach ($this->criteriaElements as $i => $element) {
152 18
            $expr_part = $element->buildExpressionQb($qb);
153 18
            if ($expr_part !== false) {
154 18
                if ($i == 0) {
155 18
                    $expr = $expr_part;
156
                } else {
157 12
                    $expr .= ' ' . strtoupper($this->conditions[$i]) . ' ' . $expr_part;
158
                }
159
            }
160
        }
161
162 21
        if (!empty($expr)) {
163 18
            $expr = '(' . $expr . ')'; // group all conditions in this compo
164
165 18
            switch (strtolower($whereMode)) {
166 18
                case 'and':
167
                    $qb->andWhere($expr);
168
                    break;
169 18
                case 'or':
170
                    $qb->orWhere($expr);
171
                    break;
172 18
                case '':
173 18
                    $qb->where($expr);
174 18
                    break;
175
            }
176
        }
177
178 21
        if ($this->limit!=0 || $this->start!=0) {
179 2
            $qb->setFirstResult($this->start)
180 2
                ->setMaxResults($this->limit);
181
        }
182
183 21
        if (!empty($this->groupBy)) {
184
            $qb->groupBy($this->groupBy);
185
        }
186
187 21
        if (!empty($this->sort)) {
188 8
            $qb->orderBy($this->sort, $this->order);
189
        }
190 21
        return $qb;
191
    }
192
193
    /**
194
     * Build an expression to be included in a Doctrine QueryBuilder instance.
195
     *
196
     * This method will build an expression, adding any parameters to the query,
197
     * but the caller is responsible for adding the expression to the query, for
198
     * example as where() parameter. This allows the caller to handle all context,
199
     * such as parenthetical groupings.
200
     *
201
     * @param QueryBuilder $qb query builder instance
202
     *
203
     * @return string expression
204
     */
205 7
    public function buildExpressionQb(QueryBuilder $qb)
206
    {
207 7
        $expr = false;
208 7
        foreach ($this->criteriaElements as $i => $element) {
209 7
            $expr_part = $element->buildExpressionQb($qb);
210 7
            if ($expr_part !== false) {
211 7
                if ($i == 0) {
212 7
                    $expr = $expr_part;
213
                } else {
214 4
                    $expr .= ' ' . strtoupper($this->conditions[$i]) . ' ' . $expr_part;
215
                }
216
            }
217
        }
218
219 7
        if (!empty($expr)) {
220 7
            $expr = '(' . $expr . ')'; // group all conditions in this compo
221
        }
222 7
        return $expr;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $expr could also return false which is incompatible with the documented return type string. Did you maybe forget to handle an error condition?

If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled.

Loading history...
223
    }
224
}
225