Passed
Push — master ( ffa8d9...6a6a4c )
by Paul
03:54
created

SqlQueries   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 175
Duplicated Lines 0 %

Test Coverage

Coverage 50.64%

Importance

Changes 4
Bugs 2 Features 1
Metric Value
eloc 70
dl 0
loc 175
ccs 39
cts 77
cp 0.5064
rs 10
c 4
b 2
f 1
wmc 16

9 Methods

Rating   Name   Duplication   Size   Complexity  
A getReviewCountsFor() 0 9 1
A getReviewRatingsFromIds() 0 17 1
A __construct() 0 5 1
A getReviewCounts() 0 16 1
A getReviewIdsByType() 0 13 1
A getPostIdFromReviewId() 0 11 1
A getInnerJoinForCounts() 0 9 3
A getReviewsMeta() 0 19 3
A getAndForCounts() 0 14 4
1
<?php
2
3
namespace GeminiLabs\SiteReviews\Database;
4
5
use GeminiLabs\SiteReviews\Application;
6
use GeminiLabs\SiteReviews\Helpers\Arr;
7
use GeminiLabs\SiteReviews\Helpers\Str;
8
9
class SqlQueries
10
{
11
    protected $db;
12
    protected $postType;
13
14 1
    public function __construct()
15
    {
16 1
        global $wpdb;
17 1
        $this->db = $wpdb;
18 1
        $this->postType = Application::POST_TYPE;
19 1
    }
20
21
    /**
22
     * @param string $metaReviewId
23
     * @return int
24
     */
25
    public function getPostIdFromReviewId($metaReviewId)
26
    {
27
        $postId = $this->db->get_var("
28
            SELECT p.ID
29
            FROM {$this->db->posts} AS p
30
            INNER JOIN {$this->db->postmeta} AS m ON p.ID = m.post_id
31
            WHERE p.post_type = '{$this->postType}'
32
            AND m.meta_key = '_review_id'
33
            AND m.meta_value = '{$metaReviewId}'
34
        ");
35
        return intval($postId);
36
    }
37
38
    /**
39
     * @param int $lastPostId
40
     * @param int $limit
41
     * @return array
42
     */
43 1
    public function getReviewCounts(array $args, $lastPostId = 0, $limit = 500)
44
    {
45 1
        return (array) $this->db->get_results("
46
            SELECT DISTINCT p.ID, m1.meta_value AS rating, m2.meta_value AS type
47 1
            FROM {$this->db->posts} AS p
48 1
            INNER JOIN {$this->db->postmeta} AS m1 ON p.ID = m1.post_id
49 1
            INNER JOIN {$this->db->postmeta} AS m2 ON p.ID = m2.post_id
50 1
            {$this->getInnerJoinForCounts($args)}
51 1
            WHERE p.ID > {$lastPostId}
52
            AND p.post_status = 'publish'
53 1
            AND p.post_type = '{$this->postType}'
54
            AND m1.meta_key = '_rating'
55
            AND m2.meta_key = '_review_type'
56 1
            {$this->getAndForCounts($args)}
57
            ORDER By p.ID ASC
58 1
            LIMIT {$limit}
59
        ");
60
    }
61
62
    /**
63
     * @todo remove this?
64
     * @param string $metaKey
65
     * @return array
66
     */
67
    public function getReviewCountsFor($metaKey)
68
    {
69
        $metaKey = Str::prefix('_', $metaKey);
70
        return (array) $this->db->get_results("
71
            SELECT DISTINCT m.meta_value AS name, COUNT(*) num_posts
72
            FROM {$this->db->posts} AS p
73
            INNER JOIN {$this->db->postmeta} AS m ON p.ID = m.post_id
74
            WHERE p.post_type = '{$this->postType}'
75
            AND m.meta_key = '{$metaKey}'
76
            GROUP BY name
77
        ");
78
    }
79
80
    /**
81
     * @todo remove this?
82
     * @param string $reviewType
83
     * @return array
84
     */
85
    public function getReviewIdsByType($reviewType)
86
    {
87
        $results = $this->db->get_col("
88
            SELECT DISTINCT m1.meta_value AS review_id
89
            FROM {$this->db->posts} AS p
90
            INNER JOIN {$this->db->postmeta} AS m1 ON p.ID = m1.post_id
91
            INNER JOIN {$this->db->postmeta} AS m2 ON p.ID = m2.post_id
92
            WHERE p.post_type = '{$this->postType}'
93
            AND m1.meta_key = '_review_id'
94
            AND m2.meta_key = '_review_type'
95
            AND m2.meta_value = '{$reviewType}'
96
        ");
97
        return array_keys(array_flip($results));
98
    }
99
100
    /**
101
     * @param int $greaterThanId
102
     * @param int $limit
103
     * @return array
104
     */
105
    public function getReviewRatingsFromIds(array $postIds, $greaterThanId = 0, $limit = 100)
106
    {
107
        sort($postIds);
108
        $postIds = array_slice($postIds, intval(array_search($greaterThanId, $postIds)), $limit);
109
        $postIds = implode(',', $postIds);
110
        return (array) $this->db->get_results("
111
            SELECT p.ID, m.meta_value AS rating
112
            FROM {$this->db->posts} AS p
113
            INNER JOIN {$this->db->postmeta} AS m ON p.ID = m.post_id
114
            WHERE p.ID > {$greaterThanId}
115
            AND p.ID IN ('{$postIds}')
116
            AND p.post_status = 'publish'
117
            AND p.post_type = '{$this->postType}'
118
            AND m.meta_key = '_rating'
119
            GROUP BY p.ID
120
            ORDER By p.ID ASC
121
            LIMIT {$limit}
122
        ");
123
    }
124
125
    /**
126
     * @param string $key
127
     * @param string $status
128
     * @return array
129
     */
130 1
    public function getReviewsMeta($key, $status = 'publish')
131
    {
132 1
        $postStatusQuery = 'all' != $status && !empty($status)
133 1
            ? "AND p.post_status = '{$status}'"
134 1
            : '';
135 1
        $key = Str::prefix('_', $key);
136 1
        $values = $this->db->get_col("
137
            SELECT DISTINCT m.meta_value
138 1
            FROM {$this->db->postmeta} m
139 1
            LEFT JOIN {$this->db->posts} p ON p.ID = m.post_id
140 1
            WHERE p.post_type = '{$this->postType}'
141 1
            AND m.meta_key = '{$key}'
142
            AND m.meta_value > '' -- No empty values or ID's less than 1
143 1
            $postStatusQuery
144
            GROUP BY p.ID -- remove duplicate meta_value entries
145
            ORDER BY m.meta_id ASC -- sort by oldest meta_value
146
        ");
147 1
        sort($values);
148 1
        return $values;
149
    }
150
151
    /**
152
     * @param string $and
153
     * @return string
154
     */
155 1
    protected function getAndForCounts(array $args, $and = '')
156
    {
157 1
        $postIds = implode(',', array_filter(Arr::get($args, 'post_ids', [])));
158 1
        $termIds = implode(',', array_filter(Arr::get($args, 'term_ids', [])));
159 1
        if (!empty($args['type'])) {
160
            $and.= "AND m2.meta_value = '{$args['type']}' ";
161
        }
162 1
        if ($postIds) {
163
            $and.= "AND m3.meta_key = '_assigned_to' AND m3.meta_value IN ({$postIds}) ";
164
        }
165 1
        if ($termIds) {
166
            $and.= "AND tr.term_taxonomy_id IN ({$termIds}) ";
167
        }
168 1
        return apply_filters('site-reviews/query/and-for-counts', $and);
169
    }
170
171
    /**
172
     * @param string $innerJoin
173
     * @return string
174
     */
175 1
    protected function getInnerJoinForCounts(array $args, $innerJoin = '')
176
    {
177 1
        if (!empty(Arr::get($args, 'post_ids'))) {
178
            $innerJoin.= "INNER JOIN {$this->db->postmeta} AS m3 ON p.ID = m3.post_id ";
179
        }
180 1
        if (!empty(Arr::get($args, 'term_ids'))) {
181
            $innerJoin.= "INNER JOIN {$this->db->term_relationships} AS tr ON p.ID = tr.object_id ";
182
        }
183 1
        return apply_filters('site-reviews/query/inner-join-for-counts', $innerJoin);
184
    }
185
}
186