Completed
Push — master ( c48be5...74cac1 )
by Pedro García
02:29
created

FeaturedFlagsImpl::_getStmt()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 8
ccs 6
cts 6
cp 1
rs 9.4285
cc 2
eloc 5
nc 2
nop 2
crap 2
1
<?php
2
3
namespace FeaturedFlags;
4
5
use PDO;
6
use Redis;
7
8
class FeaturedFlagsImpl implements FeaturedFlags
9
{
10
    protected $_pdo;
11
    protected $_redis;
12
    protected $_date;
13
14
    CONST TABLE_NAME = 'featured_flags';
15
    CONST ISENABLED_PREFIX = 'isEnabled_';
16
    CONST GETVALUES_PREFIX = 'getEnabledValues_';
17
18
    /**
19
     * FeaturedFlags constructor.
20
     * @param PDO $pdo
21
     * @param Redis|null $redis
22
     * @param string|null $date
23
     */
24 26
    public function __construct(PDO $pdo, Redis $redis = null, $date = null)
25 1
    {
26 26
        $this->_pdo = $pdo;
27 26
        if ($redis) {
28 26
            $this->_redis = $redis;
29 26
        }
30 26
        if (!is_null($date)) {
31 26
            $this->_date = $date;
32 26
        }
33 26
    }
34
35
    /**
36
     * @param PDO $pdo
37
     * @param Redis $redis
38
     * @return FeaturedFlags
39
     */
40 2
    public static function getInstance(PDO $pdo, Redis $redis = null) {
41 2
        return new self($pdo, $redis);
42
    }
43
44
    /**
45
     * @param string $flagName
46
     * @param null|array $filterParams
47
     * @return boolean
48
     */
49 17
    public function isEnabled($flagName, $filterParams = null)
50
    {
51 17
        $cacheKey = $this->_getKey($flagName, $filterParams, self::ISENABLED_PREFIX);
52 17
        $cacheModel = $this->_getCacheModel($cacheKey);
53 17
        if ($cacheModel instanceof FeaturedFlagsModel)
54 17
        {
55 2
            return $cacheModel->isEnabled();
56
        }
57
58 15
        $featureFlagModel = $this->_getBDFlag($flagName, $filterParams);
59 15
        $this->_setCacheKey($cacheKey, $featureFlagModel);
60 15
        return $featureFlagModel->isEnabled();
61
    }
62
63
    /**
64
     * @param string $flagName
65
     * @param null|array $filterParams
66
     * @return array
67
     */
68 7
    public function getEnabledValues($flagName, $filterParams = null)
69
    {
70 7
        $cacheKey = $this->_getKey($flagName, $filterParams, self::GETVALUES_PREFIX);
71 7
        $cacheValue = $this->_getCacheModel($cacheKey);
72 7
        if ($cacheValue instanceof FeaturedFlagsModel)
73 7
        {
74 1
            return $cacheValue->getParamsArray();
75
        }
76
77 6
        $featureFlagModel = $this->_getBDFlag($flagName, $filterParams);
78 6
        $this->_setCacheKey($cacheKey, $featureFlagModel);
79 6
        return $featureFlagModel->getParamsArray();
80
    }
81
82
    /**
83
     * @param Redis $redis
84
     */
85 3
    public function setRedis(Redis $redis)
86
    {
87 3
        $this->_redis = $redis;
88 3
    }
89
90
    /**
91
     * @param string $flagName
92
     * @param null|array $filterParams
93
     * @return FeaturedFlagsModel
94
     */
95 21
    private function _getBDFlag($flagName, $filterParams)
96
    {
97 21
        $flagsData = $this->_getDBFlagsData($flagName);
98 21
        foreach ($flagsData as $flag) {
99 13
            if ($this->_checkParams($flag['params'], $filterParams))
100 13
            {
101 9
                return new FeaturedFlagsModel(true, $flag['return_params'], $flag['end_date']);
102
            }
103 14
        }
104
105 12
        return new FeaturedFlagsModel(false);
106
    }
107
108
    /**
109
     * @param string $cacheKey
110
     * @return FeaturedFlagsModel
111
     */
112 24
    private function _getCacheModel($cacheKey)
113
    {
114 24
        if (!is_null($this->_redis) && $this->_redis->get($cacheKey))
115 24
        {
116 3
            return $this->_redis->get($cacheKey);
117
        }
118
119 21
        return null;
120
    }
121
122
    /**
123
     * @param string $cacheKey
124
     * @param FeaturedFlagsModel $featuredFlagsModel
125
     */
126 21
    private function _setCacheKey($cacheKey, FeaturedFlagsModel $featuredFlagsModel)
127
    {
128 21
        if (!is_null($this->_redis)) {
129 21
            $timeOut = $this->_getTimeout($featuredFlagsModel->getEndDate());
130 21
            $this->_redis->set($cacheKey, $featuredFlagsModel, $timeOut);
131 21
        }
132 21
    }
133
134
    /**
135
     * @param string $query
136
     * @param array $params
137
     * @return \mysqli_stmt
138
     */
139 21
    private function _getStmt($query, $params)
140
    {
141 21
        $stmt = $this->_pdo->prepare($query);
142 21
        foreach ($params as $field => $value) {
143 21
            $stmt->bindValue(":$field", $value);
144 21
        }
145 21
        return $stmt;
146
    }
147
148
    /**
149
     * @param string $flagName
150
     * @return array
151
     */
152 21
    private function _getDBFlagsData($flagName)
153
    {
154 21
        $query = "SELECT * FROM ".self::TABLE_NAME." WHERE 
155
        name = :flag AND 
156
        status = 1 AND
157
        (   (start_date IS NULL AND end_date IS NULL)
158
                OR
159
            (start_date <= :now AND :now <= end_date)
160
                OR
161
            (:now <= end_date AND (start_date IS NULL OR start_date = ''))
162
                OR
163
            (start_date <= :now AND (end_date IS NULL OR end_date = ''))
164 21
        )";
165
166
        $params = array(
167 21
            'flag' => $flagName,
168 21
            'now'  =>  $this->_getDate()
169 21
        );
170
171 21
        return $this->_executeForSelect($query, $params);
172
    }
173
174
    /**
175
     * @param string $query
176
     * @param array $params
177
     * @return array
178
     */
179 21
    private function _executeForSelect($query, $params = array())
180
    {
181 21
        $stmt = $this->_getStmt($query, $params);
182 21
        $stmt->execute();
183 21
        return $stmt->fetchAll();
184
    }
185
186
    /**
187
     * @return string
188
     */
189 21
    private function _getDate() {
190 21
        if ($this->_date) {
191 20
            return $this->_date;
192
        }
193
194 1
        return date("Y-m-d H:i:s");
195
    }
196
197
    /**
198
     * @param array $flagParams
199
     * @param array $filterParams
200
     * @return boolean
201
     */
202 7
    private function _compareParams($flagParams, $filterParams)
203
    {
204 7
        $checkParams = true;
205 7
        foreach ($filterParams as $key => $value)
206
        {
207 7
            $checkParams = $checkParams && isset($flagParams[$key]) && $flagParams[$key] == $value;
208 7
        }
209
210 7
        return $checkParams;
211
    }
212
213
    /**
214
     * @param string $flagParamsJson
215
     * @param null|array $filterParams
216
     * @return boolean
217
     */
218 13
    private function _checkParams($flagParamsJson, $filterParams = null)
219
    {
220 13
        if (is_null($filterParams)) {
221 6
            return true;
222
        }
223
224 7
        $flagParamsData = json_decode($flagParamsJson, true);
225 7
        if (!is_array($flagParamsData) || count($flagParamsData) === 0) {
226 5
            return false;
227
        }
228
229 7
        return $this->_compareParams($flagParamsData, $filterParams);
230
    }
231
232
    /**
233
     * @param string $flagName
234
     * @param array|null $filterParams
235
     * @param string $prefix
236
     * @return boolean
237
     */
238 24
    private function _getKey($flagName, $filterParams = null, $prefix = "")
239
    {
240 24
        return $prefix."FF_".$flagName.json_encode($filterParams);
241
    }
242
243
    /**
244
     * @param string $endDate
245
     * @return int
246
     */
247 21
    private function _getTimeout($endDate)
248
    {
249 21
        if (!$endDate) {
250 17
            return 0;
251
        }
252
253 4
        return strtotime($endDate) - strtotime($this->_getDate());
254
    }
255
}
256