PluginProbe
Defender Security – Malware Scanner, Login Security & Firewall / 3.1.0
Defender Security – Malware Scanner, Login Security & Firewall v3.1.0
6.3.0 6.2.3 6.2.4 6.2.0 6.2.1 6.2.2 6.1.0 5.3.1 5.4.0 5.4.1 5.5.0 5.5.1 5.6.0 5.6.1 5.6.2 5.7.0 5.7.1 5.7.2 5.8.0 5.8.1 5.9.0 6.0.0 6.0.1 3.0.1 3.1.0 All 141 releases
defender-security / framework / db / mapper.php

mapper.php in Defender Security – Malware Scanner, Login Security & Firewall 3.1.0, at framework/db/mapper.php

486 lines 8.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Calotes\DB;
4
5 use Calotes\Base\Component;
6 use Calotes\Base\Model;
7
8 /**
9 * This is a data mapper for CRUD
10 *
11 * Class DB
12 *
13 * @package Calotes\Helper
14 */
15 class Mapper extends Component {
16
17 /**
18 * Contain the current model class name
19 *
20 * @string
21 */
22 private $repository;
23
24 /**
25 * @var string
26 */
27 private $select = '';
28
29 /**
30 * Where statements
31 *
32 * @var array
33 */
34 private $where = array();
35
36 /**
37 * @var string
38 */
39 private $group = '';
40
41 /**
42 * @var string
43 */
44 private $order = '';
45
46 /**
47 * @var string
48 */
49 private $limit = '';
50
51 /**
52 * Use this to cache the records
53 */
54 private $known = array();
55
56 /**
57 * Use to store last query
58 *
59 * @var string
60 */
61 public $saved_queries = '';
62
63 /**
64 *
65 * @param $class
66 *
67 * @return $this
68 */
69 public function get_repository( $class ) {
70 $this->repository = $class;
71
72 return $this;
73 }
74
75 /**
76 * @param string $select
77 *
78 * @return $this
79 */
80 public function select( $select ) {
81 $this->select = $select;
82
83 return $this;
84 }
85
86 /**
87 * Define the conditions, this is for generic where
88 *
89 * @param mixed ...$args
90 *
91 * @return $this
92 */
93 public function where( ...$args ) {
94 global $wpdb;
95 if ( 2 === count( $args ) ) {
96 list( $key, $value ) = $args;
97 $this->where[] = $wpdb->prepare( "`$key` = " . $this->guess_var_type( $value ), $value );
98
99 return $this;
100 }
101
102 list( $key, $operator, $value ) = $args;
103 if ( ! $this->valid_operator( $operator ) ) {
104 // prevent this operator
105 return $this;
106 }
107 if ( in_array( strtolower( $operator ), array( 'in', 'not in' ), true ) ) {
108 $tmp = $key . " {$operator} (" . implode( ', ', array_fill( 0, count( $value ), $this->guess_var_type( $value ) ) ) . ')';
109 $sql = call_user_func_array(
110 array(
111 $wpdb,
112 'prepare',
113 ),
114 array_merge( array( $tmp ), $value )
115 );
116 $this->where[] = $sql;
117 } elseif ( 'between' === strtolower( $operator ) ) {
118 $this->where[] = $wpdb->prepare(
119 "{$key} {$operator} {$this->guess_var_type($value[0])} AND {$this->guess_var_type($value[1])}",
120 $value[0],
121 $value[1]
122 );
123 } else {
124 $this->where[] = $wpdb->prepare( "`$key` $operator {$this->guess_var_type($value)}", $value );
125 }
126
127 return $this;
128 }
129
130 /**
131 * Guess the type of value for correcting placeholder
132 *
133 * @param $value
134 *
135 * @return string
136 */
137 private function guess_var_type( $value ) {
138 if ( filter_var( $value, FILTER_VALIDATE_INT ) ) {
139 return '%d';
140 }
141
142 if ( filter_var( $value, FILTER_VALIDATE_FLOAT ) ) {
143 return '%f';
144 }
145
146 return '%s';
147 }
148
149 /**
150 * Find a record by it's ID
151 *
152 * @param $id
153 *
154 * @return $this
155 */
156 public function find_by_id( $id ) {
157 global $wpdb;
158 $this->where[] = $wpdb->prepare( 'id = %d', $id );
159
160 return $this;
161 }
162
163 /**
164 * @param string $group_by
165 *
166 * @return $this
167 */
168 public function group_by( $group_by ) {
169 global $wpdb;
170 $this->group = str_replace(
171 "'",
172 "",
173 $wpdb->prepare( 'GROUP BY %s', $group_by )
174 );
175
176 return $this;
177 }
178
179 /**
180 * @param string $order_by
181 * @param string $order
182 *
183 * @return $this
184 */
185 public function order_by( $order_by, $order = 'asc' ) {
186 global $wpdb;
187 if ( ! in_array( $order, array( 'asc', 'desc' ) ) ) {
188 // fall it back
189 $order = 'asc';
190 }
191 $this->order = str_replace(
192 "'",
193 "",
194 $wpdb->prepare( "ORDER BY %s %s", $order_by, $order )
195 );
196
197 return $this;
198 }
199
200 /**
201 * @param int|string $offset
202 *
203 * @return $this
204 */
205 public function limit( $offset ) {
206 global $wpdb;
207 $this->limit = str_replace(
208 "'",
209 "",
210 $wpdb->prepare( 'LIMIT ' . $this->guess_var_type( $offset ), $offset )
211 );
212
213 return $this;
214 }
215
216 /**
217 * Find the first
218 *
219 * @return null|Model
220 */
221 public function first() {
222 $this->limit = 'LIMIT 0,1';
223 $sql = $this->query_build();
224 $this->saved_queries = $sql;
225 global $wpdb;
226 $data = $wpdb->get_row( $sql, ARRAY_A );
227 if ( is_null( $data ) ) {
228 return null;
229 }
230 // check if e have any json string in property
231 foreach ( $data as &$datum ) {
232 $tmp = json_decode( $datum, true );
233 if ( is_array( $tmp ) ) {
234 $datum = $tmp;
235 }
236 }
237 $class_name = $this->repository;
238 $model = new $class_name();
239 $model->import( $data );
240
241 return $model;
242 }
243
244 /**
245 * @return array
246 */
247 public function get() {
248 $data = $this->get_results();
249
250 $models = array();
251 foreach ( $data as $row ) {
252 foreach ( $row as &$property ) {
253 $tmp = json_decode( $property, true );
254 if ( is_array( $tmp ) ) {
255 $property = $tmp;
256 }
257 }
258 $class_name = $this->repository;
259 $model = new $class_name();
260 $model->import( $row );
261 $models[] = $model;
262 }
263
264 return $models;
265 }
266
267 /**
268 * Get records in array form.
269 *
270 * @return array
271 * @since 2.7.0
272 */
273 public function get_results() {
274 $sql = $this->query_build();
275 $this->saved_queries = $sql;
276
277 global $wpdb;
278 $data = $wpdb->get_results( $sql, ARRAY_A );
279 if ( is_null( $data ) ) {
280 $data = array();
281 }
282
283 return $data;
284 }
285
286 /**
287 * @return string|null
288 */
289 public function count() {
290 global $wpdb;
291 $sql = $this->query_build( 'COUNT(*)' );
292
293 return $wpdb->get_var( $sql );
294 }
295
296 /**
297 * Handle the insert/update of current model
298 *
299 * @param Model $model
300 *
301 * @return int The ID of current record
302 */
303 public function save( Model &$model ) {
304 global $wpdb;
305 $data = $model->export();
306 unset( $data['table'] );
307 unset( $data['safe'] );
308 foreach ( $data as $key => &$val ) {
309 if ( is_array( $val ) ) {
310 $val = json_encode( $val );
311 }
312 }
313 $table = self::table( $model );
314 if ( $model->id ) {
315 $ret = $wpdb->update(
316 $table,
317 $data,
318 array(
319 'id' => $model->id,
320 )
321 );
322 } else {
323 $ret = $wpdb->insert( $table, $data );
324 // bind this for later use
325 $model->id = $wpdb->insert_id;
326 }
327
328 if ( false === $ret ) {
329 return false;
330 }
331
332 return $wpdb->insert_id;
333 }
334
335 /**
336 *
337 * @param $where
338 *
339 * @return false|int
340 */
341 public function delete( $where ) {
342 $table = self::table();
343 global $wpdb;
344
345 return $wpdb->delete( $table, $where );
346 }
347
348 /**
349 * @return int|bool
350 */
351 public function delete_all() {
352 $table = self::table();
353 global $wpdb;
354
355 $where = implode( ' AND ', $this->where );
356 $sql = "DELETE FROM $table WHERE $where";
357 $this->clear();
358
359 return $wpdb->query( $sql );
360 }
361
362 /**
363 * @return int|bool
364 */
365 public function delete_by_limit() {
366 $table = self::table();
367 global $wpdb;
368
369 $where = implode( ' AND ', $this->where );
370 $limit = $this->limit;
371 $order = $this->order;
372 $sql = "DELETE FROM $table WHERE $where $order $limit";
373 $this->clear();
374
375 return $wpdb->query( $sql );
376 }
377
378 /**
379 * @return bool|int
380 */
381 public function truncate() {
382 $table = self::table();
383 global $wpdb;
384
385 return $wpdb->query( sprintf( 'TRUNCATE TABLE `%s`', $table ) );
386 }
387
388 private function table( $model = null ) {
389 if ( is_null( $model ) ) {
390 $class_name = $this->repository;
391 $model = $this->get_model();
392 } else {
393 $class_name = $model;
394 }
395 try {
396 $refection = new \ReflectionClass( $class_name );
397 if ( $refection->hasProperty( 'table' ) ) {
398 $property = $refection->getProperty( 'table' );
399 $property->setAccessible( true );
400
401 $table = $property->getValue( $model );
402 global $wpdb;
403
404 // have to set the prefix
405 return $wpdb->base_prefix . $table;
406 }
407 } catch ( \Exception $e ) {
408 // this when class doesn't exists
409 return false;
410 }
411 }
412
413 /**
414 * Reset all the queries prepare after an action
415 */
416 private function clear() {
417 $this->select = '';
418 $this->where = array();
419 $this->group = '';
420 $this->order = '';
421 $this->limit = '';
422 }
423
424 /**
425 * Join the stuff on the table to make a full query statement.
426 * SQL params e.g. WHERE, ORDER or LIMIT were escaped on separate methods
427 *
428 * @param string $select
429 *
430 * @return string
431 */
432 private function query_build( $select = '*' ) {
433 $table = $this->table();
434 $where = implode( ' AND ', $this->where );
435
436 $select = ! empty( $this->select ) ? $this->select : $select;
437 $group_by = $this->group;
438 $order_by = $this->order;
439 $limit = $this->limit;
440 $sql = "SELECT $select FROM $table WHERE $where $group_by $order_by $limit";
441 $this->clear();
442
443 return $sql;
444 }
445
446 /**
447 * @param $operator
448 *
449 * @return bool
450 */
451 private function valid_operator( $operator ) {
452 $operator = strtolower( $operator );
453 $allowed = array(
454 'in',
455 'not in',
456 '>',
457 '<',
458 '=',
459 '<=',
460 '>=',
461 'like',
462 'between',
463 'regexp',
464 'not regexp',
465 );
466
467 return in_array( $operator, $allowed );
468 }
469
470 /**
471 * Cache the model instance for clone & reference use
472 *
473 * @return mixed
474 */
475 private function get_model() {
476 if ( isset( $this->known[ $this->repository ] ) ) {
477 return $this->known[ $this->repository ];
478 }
479 $class = $this->repository;
480 $model = new $class();
481 $this->known[ $this->repository ] = $model;
482
483 return $model;
484 }
485 }
486