Passed
Push — master ( 5e727b...fa3796 )
by Paul
07:53
created

Sql::sql()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1

Importance

Changes 2
Bugs 0 Features 1
Metric Value
eloc 5
c 2
b 0
f 1
dl 0
loc 7
ccs 6
cts 6
cp 1
rs 10
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
namespace GeminiLabs\SiteReviews\Database;
4
5
use GeminiLabs\SiteReviews\Helper;
6
use GeminiLabs\SiteReviews\Helpers\Arr;
7
use GeminiLabs\SiteReviews\Helpers\Str;
8
9
trait Sql
10
{
11
    /**
12
     * @var array
13
     */
14
    public $args;
15
16
    /**
17
     * @var \wpdb
18
     */
19
    public $db;
20
21
    /**
22
     * @param string $clause
23
     * @return array
24
     */
25 8
    public function clauses($clause, array $values = [])
26
    {
27 8
        $prefix = Str::restrictTo('and,join', $clause);
28 8
        foreach (array_keys($this->args) as $key) {
29 8
            $method = Helper::buildMethodName($key, 'clause-'.$prefix);
30 8
            if (method_exists($this, $method)) {
31 8
                $values[$key] = call_user_func([$this, $method]);
32
            }
33
        }
34 8
        return $values;
35
    }
36
37
    /**
38
     * @return string
39
     */
40 13
    public function escFieldsForInsert(array $fields)
41
    {
42 13
        return sprintf('(`%s`)', implode('`,`', $fields));
43
    }
44
45
    /**
46
     * @return string
47
     */
48 13
    public function escValuesForInsert(array $values)
49
    {
50 13
        $values = array_values(array_map('esc_sql', $values));
51 13
        return sprintf("('%s')", implode("','", $values));
52
    }
53
54
    /**
55
     * @param string $statement
56
     * @return string
57
     */
58 14
    public function sql($statement)
59
    {
60 14
        $handle = $this->sqlHandle();
61 14
        $statement = glsr()->filterString('database/sql/'.$handle, $statement);
62 14
        glsr()->action('database/sql/'.$handle, $statement);
63 14
        glsr()->action('database/sql', $statement, $handle);
64 14
        return $statement;
65
    }
66
67
    /**
68
     * @return string
69
     */
70 7
    public function sqlJoin()
71
    {
72 7
        $join = $this->clauses('join');
73 7
        $join = glsr()->filterArrayUnique('query/sql/join', $join, $this->sqlHandle(), $this);
74 7
        return implode(' ', $join);
75
    }
76
77
    /**
78
     * @return string
79
     */
80 1
    public function sqlLimit()
81
    {
82 1
        $limit = Helper::ifTrue($this->args['per_page'] > 0,
83 1
            $this->db->prepare('LIMIT %d', $this->args['per_page'])
84
        );
85 1
        return glsr()->filterString('query/sql/limit', $limit, $this->sqlHandle(), $this);
86
    }
87
88
    /**
89
     * @return string
90
     */
91 1
    public function sqlOffset()
92
    {
93 1
        $offsetBy = (($this->args['page'] - 1) * $this->args['per_page']) + $this->args['offset'];
94 1
        $offset = Helper::ifTrue($offsetBy > 0,
95 1
            $this->db->prepare('OFFSET %d', $offsetBy)
96
        );
97 1
        return glsr()->filterString('query/sql/offset', $offset, $this->sqlHandle(), $this);
98
    }
99
100
    /**
101
     * @return string|void
102
     */
103 1
    public function sqlOrderBy()
104
    {
105
        $values = [
106 1
            'random' => 'RAND()',
107
        ];
108 1
        $order = $this->args['order'];
109 1
        $orderby = $this->args['orderby'];
110 1
        $orderedby = [];
111 1
        if (Str::startsWith('p.', $orderby)) {
112 1
            $orderedby[] = "r.is_pinned {$order}";
113 1
            $orderedby[] = "{$orderby} {$order}";
114
        } elseif (array_key_exists($orderby, $values)) {
115
            $orderedby[] = $values[$orderby];
116
        }
117 1
        $orderedby = glsr()->filterArrayUnique('query/sql/order-by', $orderedby, $this->sqlHandle(), $this);
118 1
        if (!empty($orderedby)) {
119 1
            return "ORDER BY ".implode(', ', $orderedby);
120
        }
121
    }
122
123
    /**
124
     * @return string
125
     */
126 7
    public function sqlWhere()
127
    {
128 7
        $and = $this->clauses('and');
129 7
        $and = glsr()->filterArrayUnique('query/sql/and', $and, $this->sqlHandle(), $this);
130 7
        return 'WHERE 1=1 '.implode(' ', $and);
131
    }
132
133
    /**
134
     * @return string
135
     */
136 15
    public function table($table)
137
    {
138 15
        return glsr(SqlSchema::class)->table($table);
139
    }
140
141
    /**
142
     * @return string
143
     */
144 7
    protected function clauseAndAssignedPosts()
145
    {
146 7
        $clauses = [];
147 7
        if ($postIds = $this->args['assigned_posts']) {
148 2
            $clauses[] = sprintf('(apt.post_id IN (%s) AND apt.is_published = 1)', implode(',', $postIds));
149
        }
150 7
        if ($termIds = $this->args['assigned_terms']) {
151 2
            $clauses[] = sprintf('(att.term_id IN (%s))', implode(',', $termIds));
152
        }
153 7
        if ($userIds = $this->args['assigned_users']) {
154 2
            $clauses[] = sprintf('(aut.user_id IN (%s))', implode(',', $userIds));
155
        }
156 7
        $operator = glsr()->filterString('query/sql/clause/operator', 'OR', $clauses, $this->args);
157 7
        $operator = strtoupper($operator);
158 7
        $operator = Helper::ifTrue(in_array($operator, ['AND', 'OR']), $operator, 'OR');
159 7
        if ($clauses = implode(" {$operator} ", $clauses)) {
160 6
            return "AND ($clauses)";
161
        }
162 1
        return '';
163
    }
164
165
    /**
166
     * @return string
167
     */
168 7
    protected function clauseAndAuthorId()
169
    {
170 7
        return Helper::ifTrue(!empty($this->args['author_id']),
171 7
            $this->db->prepare('AND p.post_author = %d', $this->args['author_id'])
172
        );
173
    }
174
175
    /**
176
     * @return string
177
     */
178 7
    protected function clauseAndEmail()
179
    {
180 7
        return Helper::ifTrue(!empty($this->args['email']),
181 7
            $this->db->prepare('AND r.email = %s', $this->args['email'])
182
        );
183
    }
184
185
    /**
186
     * @return string
187
     */
188 7
    protected function clauseAndIpAddress()
189
    {
190 7
        return Helper::ifTrue(!empty($this->args['ip_address']),
191 7
            $this->db->prepare('AND r.ip_address = %s', $this->args['ip_address'])
192
        );
193
    }
194
195
    /**
196
     * @return string
197
     */
198 7
    protected function clauseAndPostIn()
199
    {
200 7
        return Helper::ifTrue(!empty($this->args['post__in']),
201 7
            $this->db->prepare('AND r.review_id IN (%s)', implode(',', $this->args['post__in']))
202
        );
203
    }
204
205
    /**
206
     * @return string
207
     */
208 7
    protected function clauseAndPostNotIn()
209
    {
210 7
        return Helper::ifTrue(!empty($this->args['post__not_in']),
211 7
            $this->db->prepare('AND r.review_id NOT IN (%s)', implode(',', $this->args['post__not_in']))
212
        );
213
    }
214
215
    /**
216
     * @return string
217
     */
218 7
    protected function clauseAndRating()
219
    {
220 7
        return Helper::ifTrue(!empty($this->args['rating']),
221 7
            $this->db->prepare('AND r.rating > %d', --$this->args['rating'])
222
        );
223
    }
224
225
    /**
226
     * @return string
227
     */
228 7
    protected function clauseAndStatus()
229
    {
230 7
        return Helper::ifTrue(!Helper::isEmpty($this->args['status']),
231 7
            $this->db->prepare('AND r.is_approved = %d', $this->args['status'])
232
        );
233
    }
234
235
    /**
236
     * @return string
237
     */
238 7
    protected function clauseAndType()
239
    {
240 7
        return Helper::ifTrue(!empty($this->args['type']),
241 7
            $this->db->prepare('AND r.type = %s', $this->args['type'])
242
        );
243
    }
244
245
    /**
246
     * @return string
247
     */
248 8
    protected function clauseJoinAssignedPosts()
249
    {
250 8
        return Helper::ifTrue(!empty($this->args['assigned_posts']),
251 8
            "INNER JOIN {$this->table('assigned_posts')} AS apt ON r.ID = apt.rating_id"
252
        );
253
    }
254
255
    /**
256
     * @return string
257
     */
258 8
    protected function clauseJoinAssignedTerms()
259
    {
260 8
        return Helper::ifTrue(!empty($this->args['assigned_terms']),
261 8
            "INNER JOIN {$this->table('assigned_terms')} AS att ON r.ID = att.rating_id"
262
        );
263
    }
264
265
    /**
266
     * @return string
267
     */
268 8
    protected function clauseJoinAssignedUsers()
269
    {
270 8
        return Helper::ifTrue(!empty($this->args['assigned_users']),
271 8
            "INNER JOIN {$this->table('assigned_users')} AS aut ON r.ID = aut.rating_id"
272
        );
273
    }
274
275
    /**
276
     * @return string
277
     */
278 8
    protected function clauseJoinAuthorId()
279
    {
280 8
        return Helper::ifTrue(!empty($this->args['author_id']),
281 8
            "INNER JOIN {$this->db->posts} AS p ON r.review_id = p.ID"
282
        );
283
    }
284
285
    /**
286
     * @return string
287
     */
288 8
    protected function clauseJoinOrderBy()
289
    {
290 8
        return Helper::ifTrue(Str::startsWith('p.', $this->args['orderby']),
291 8
            "INNER JOIN {$this->db->posts} AS p ON r.review_id = p.ID"
292
        );
293
    }
294
295
    /**
296
     * @param int $depth
297
     * @return string
298
     */
299 14
    protected function sqlHandle($depth = 2)
300
    {
301 14
        return Str::dashCase(Arr::get((new \Exception())->getTrace(), $depth.'.function'));
302
    }
303
}
304