Completed
Push — master ( 8a489a...b7ae4b )
by Barry
07:22
created

WordPressRepository::empty_trash()   A

Complexity

Conditions 5
Paths 3

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
cc 5
eloc 7
nc 3
nop 0
dl 0
loc 14
ccs 0
cts 0
cp 0
crap 30
rs 9.6111
c 0
b 0
f 0
1
<?php
2
3
namespace Never5\DownloadMonitor\Shop\Order;
4
5
use Never5\DownloadMonitor\Shop\Services\Services;
6
7
class WordPressRepository implements Repository {
8
9
	/**
10
	 * Prep where statement for WP DB SQL queries
11
	 *
12
	 * An example filter is an array like this:
13
	 * array(
14
	 *  'key'       => 'id',
15
	 *  'value'     => 1,
16
	 *  'operator'  => '='
17
	 * )
18
	 *
19
	 * @param $filters
20
	 *
21
	 * @return string
22
	 */
23 10
	private function prep_where_statement( $filters ) {
24 10
		global $wpdb;
25
		// setup where statements
26 10
		$where = array( "WHERE 1=1" );
27 10
		foreach ( $filters as $filter ) {
28 4
			$operator = ( ! empty( $filter['operator'] ) ) ? esc_sql( $filter['operator'] ) : "=";
0 ignored issues
show
Bug introduced by
The function esc_sql was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

28
			$operator = ( ! empty( $filter['operator'] ) ) ? /** @scrutinizer ignore-call */ esc_sql( $filter['operator'] ) : "=";
Loading history...
29 4
			if ( 'IN' == $operator && is_array( $filter['value'] ) ) {
30
				array_walk( $filter['value'], 'esc_sql' );
31
				$value_str = implode( "','", $filter['value'] );
32
				$where[]   = "AND `" . esc_sql( $filter['key'] ) . "` " . $operator . " ('" . $value_str . "')";
33
			} else {
34 4
				$where[] = $wpdb->prepare( "AND `" . esc_sql( $filter['key'] ) . "` " . $operator . " '%s'", $filter['value'] );
35
			}
36
		}
37 10
		$where_str = "";
38 10
		if ( count( $where ) > 1 ) {
39 4
			$where_str = implode( " ", $where );
40
		}
41
42 10
		return $where_str;
43
	}
44
45
	/**
46
	 * Fetch and add orders items to order
47
	 *
48
	 * @param Order $order
49
	 *
50
	 * @return Order
51
	 */
52 7
	private function add_order_items_to_order( $order ) {
53 7
		global $wpdb;
54
55
		/** Fetch order items */
56 7
		$order_items = array();
57 7
		$db_items    = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM `" . $wpdb->prefix . "dlm_order_item` WHERE `order_id` = %d ORDER BY `id` ASC ;", $order->get_id() ) );
58 7
		if ( count( $db_items ) > 0 ) {
59 7
			foreach ( $db_items as $db_item ) {
60 7
				$order_item = new OrderItem();
61
62 7
				$order_item->set_id( $db_item->id );
63 7
				$order_item->set_label( $db_item->label );
64 7
				$order_item->set_qty( $db_item->qty );
65 7
				$order_item->set_download_id( $db_item->download_id );
66 7
				$order_item->set_subtotal( $db_item->subtotal );
67 7
				$order_item->set_tax_class( $db_item->tax_class );
68 7
				$order_item->set_tax_total( $db_item->tax_total );
69 7
				$order_item->set_total( $db_item->total );
70
71 7
				$order_items[] = $order_item;
72
			}
73
		}
74
75 7
		$order->set_items( $order_items );
76
77 7
		return $order;
78
	}
79
80
	/**
81
	 * Fetch and add transactions to order
82
	 *
83
	 * @param Order $order
84
	 *
85
	 * @return Order
86
	 */
87 7
	private function add_transactions_to_order( $order ) {
88 7
		global $wpdb;
89
90
		/** Fetch transactions */
91 7
		$order_transactions = array();
92 7
		$db_items           = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM `" . $wpdb->prefix . "dlm_order_transaction` WHERE `order_id` = %d ORDER BY `id` ASC ;", $order->get_id() ) );
93 7
		if ( count( $db_items ) > 0 ) {
94 7
			foreach ( $db_items as $db_item ) {
95 7
				$order_transaction = new Transaction\OrderTransaction();
96
97 7
				$order_transaction->set_id( $db_item->id );
98
99 7
				if ( ! empty( $db_item->date_created ) ) {
100 7
					$order_transaction->set_date_created( new \DateTimeImmutable( $db_item->date_created ) );
101
				}
102
103 7
				if ( ! empty( $db_item->date_modified ) ) {
104
					$order_transaction->set_date_modified( new \DateTimeImmutable( $db_item->date_modified ) );
105
				}
106
107 7
				$order_transaction->set_amount( $db_item->amount );
108 7
				$order_transaction->set_status( Services::get()->service( 'order_transaction_factory' )->make_status( $db_item->status ) );
109 7
				$order_transaction->set_processor( $db_item->processor );
110 7
				$order_transaction->set_processor_nice_name( $db_item->processor_nice_name );
111 7
				$order_transaction->set_processor_transaction_id( $db_item->processor_transaction_id );
112 7
				$order_transaction->set_processor_status( $db_item->processor_status );
113
114 7
				$order_transactions[] = $order_transaction;
115
			}
116
		}
117
118 7
		$order->set_transactions( $order_transactions );
119
120 7
		return $order;
121
	}
122
123
124
	/**
125
	 * Retrieve session
126
	 *
127
	 * @param array $filters
128
	 * @param int $limit
129
	 * @param int $offset
130
	 * @param string $order_by
131
	 * @param string order
132
	 *
133
	 * @return Order[]
134
	 *
135
	 * @throws \Exception
136
	 */
137 8
	public function retrieve( $filters = array(), $limit = 0, $offset = 0, $order_by = 'id', $order = 'DESC' ) {
138 8
		global $wpdb;
139
140
		// prep order
141 8
		$order_by = ( empty( $order_by ) ) ? 'id' : esc_sql( $order_by );
0 ignored issues
show
Bug introduced by
The function esc_sql was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

141
		$order_by = ( empty( $order_by ) ) ? 'id' : /** @scrutinizer ignore-call */ esc_sql( $order_by );
Loading history...
142 8
		$order    = strtoupper( $order );
143 8
		if ( ! in_array( $order, array( 'ASC', 'DESC' ) ) ) {
144
			$order = 'DESC';
145
		}
146
147
		// prep where statement
148 8
		$where_str = $this->prep_where_statement( $filters );
149
150
		$sql = "
151
		SELECT O.*, C.* 
152 8
		FROM `" . $wpdb->prefix . "dlm_order` O
153 8
		INNER JOIN `" . $wpdb->prefix . "dlm_order_customer` C ON O.id=C.order_id
154 8
		" . $where_str . "
155 8
		ORDER BY O.`" . $order_by . "` " . $order;
156
157 8
		$limit  = absint( $limit );
0 ignored issues
show
Bug introduced by
The function absint was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

157
		$limit  = /** @scrutinizer ignore-call */ absint( $limit );
Loading history...
158 8
		$offset = absint( $offset );
159
160
		// if we have an offset, we NEED a limit
161 8
		if ( $offset > 0 && $limit < 1 ) {
162 1
			$limit = 99999;
163
		}
164
165 8
		if ( $limit > 0 ) {
166 5
			$sql .= " LIMIT " . $limit;
167
		}
168
169 8
		if ( $offset > 0 ) {
170 2
			$sql .= " OFFSET " . $offset;
171
		}
172
173 8
		$sql .= ";";
174
175
		// try to fetch session from database
176 8
		$results = $wpdb->get_results( $sql );
177
178
		// check if result if found
179 8
		if ( null === $results ) {
180
			throw new \Exception( 'SQL error while fetching order' );
181
		}
182
183
		// array that will hold all order objects
184 8
		$orders = array();
185
186 8
		foreach ( $results as $result ) {
187
188 7
			$order = new Order();
189
190 7
			$order->set_id( $result->id );
191 7
			$order->set_status( Services::get()->service( 'order_status_factory' )->make( $result->status ) );
192 7
			$order->set_currency( $result->currency );
193 7
			$order->set_hash( $result->hash );
194
195 7
			if ( ! empty( $result->date_created ) ) {
196 7
				$order->set_date_created( new \DateTimeImmutable( $result->date_created ) );
197
			}
198
199 7
			if ( ! empty( $result->date_modified ) ) {
200 7
				$order->set_date_modified( new \DateTimeImmutable( $result->date_modified ) );
201
			}
202
203
			// create and set customer
204 7
			$order->set_customer( new OrderCustomer(
205 7
				$result->first_name,
206 7
				$result->last_name,
207 7
				$result->company,
208 7
				$result->address_1,
209 7
				$result->address_2,
210 7
				$result->city,
211 7
				$result->state,
212 7
				$result->postcode,
213 7
				$result->country,
214 7
				$result->email,
215 7
				$result->phone,
216 7
				$result->ip_address
217
			) );
218
219
			// add order items to order object
220 7
			$order = $this->add_order_items_to_order( $order );
221
222
			// add transactions to order object
223 7
			$order = $this->add_transactions_to_order( $order );
224
225
			// add new order object to array
226 7
			$orders[] = $order;
227
228
		}
229
230 8
		return $orders;
231
232
	}
233
234
	/**
235
	 * Retrieve a single order
236
	 *
237
	 * @param $id
238
	 *
239
	 * @return Order
240
	 *
241
	 * @throws \Exception
242
	 */
243 3
	public function retrieve_single( $id ) {
244 3
		$orders = $this->retrieve( array( array( 'key' => 'id', 'value' => $id, 'operator' => '=' ) ), 1 );
245 3
		if ( 0 === count( $orders ) ) {
246 1
			throw new \Exception( 'Order not found' );
247
		}
248
249 2
		return $orders[0];
250
	}
251
252
	/**
253
	 * Returns number of rows for given filters
254
	 *
255
	 * @param array $filters
256
	 *
257
	 * @return int
258
	 */
259 2
	public function num_rows( $filters = array() ) {
260 2
		global $wpdb;
261
262
		// prep where statement
263 2
		$where_str = $this->prep_where_statement( $filters );
264
265 2
		$num = $wpdb->get_var( "SELECT COUNT(id) FROM `" . $wpdb->prefix . "dlm_order` {$where_str} " );
266
267 2
		if ( null === $num ) {
268
			$num = 0;
269
		}
270
271 2
		return $num;
272
	}
273
274
	/**
275
	 * Persist order
276
	 *
277
	 * @param Order $order
278
	 *
279
	 * @throws \Exception
280
	 *
281
	 * @return bool
282
	 */
283 9
	public function persist( $order ) {
284 9
		global $wpdb;
285
286 9
		$date_created = '';
287 9
		if ( null !== $order->get_date_created() ) {
288 9
			$date_created = $order->get_date_created()->format( 'Y-m-d H:i:s' );
289
		}
290
291 9
		$date_modified = '';
292 9
		if ( null !== $order->get_date_modified() ) {
293 2
			$date_modified = $order->get_date_modified()->format( 'Y-m-d H:i:s' );
294
		}
295
296 9
		$order_id = $order->get_id();
297
298 9
		$customer = $order->get_customer();
299
300
		// check if it's a new order or if we need to update an existing one
301 9
		if ( empty( $order_id ) ) {
302
			/** New order */
303
304
			// insert order
305 9
			$r = $wpdb->insert(
306 9
				$wpdb->prefix . 'dlm_order',
307
				array(
308 9
					'status'        => $order->get_status()->get_key(),
309 9
					'date_created'  => $date_created,
310 9
					'date_modified' => $date_modified,
311 9
					'currency'      => $order->get_currency(),
312 9
					'hash'          => $order->get_hash()
313
				),
314
				array(
315 9
					'%s',
316
					'%s',
317
					'%s',
318
					'%s',
319
					'%s'
320
				)
321
			);
322
323 9
			if ( false === $r ) {
324
				throw new \Exception( "Failed creating Order" );
325
			}
326
327
			// set the new id as order id
328 9
			$order->set_id( $wpdb->insert_id );
329
330
			// insert customer record
331 9
			$r = $wpdb->insert(
332 9
				$wpdb->prefix . 'dlm_order_customer',
333
				array(
334 9
					'first_name' => $customer->get_first_name(),
335 9
					'last_name'  => $customer->get_last_name(),
336 9
					'company'    => $customer->get_company(),
337 9
					'address_1'  => $customer->get_address_1(),
338 9
					'address_2'  => $customer->get_address_2(),
339 9
					'city'       => $customer->get_city(),
340 9
					'state'      => $customer->get_state(),
341 9
					'postcode'   => $customer->get_postcode(),
342 9
					'country'    => $customer->get_country(),
343 9
					'email'      => $customer->get_email(),
344 9
					'phone'      => $customer->get_phone(),
345 9
					'ip_address' => $customer->get_ip_address(),
346 9
					'order_id'   => $order->get_id()
347
				),
348
				array(
349 9
					'%s',
350
					'%s',
351
					'%s',
352
					'%s',
353
					'%s',
354
					'%s',
355
					'%s',
356
					'%s',
357
					'%s',
358
					'%s',
359
					'%s',
360
					'%s',
361
					'%d'
362
				)
363
			);
364
365 9
			if ( false === $r ) {
366 9
				throw new \Exception( "Failed creating Customer" );
367
			}
368
369
		} else {
370
371
			// update an existing order
372 1
			$r = $wpdb->update( $wpdb->prefix . 'dlm_order',
373
				array(
374 1
					'status'        => $order->get_status()->get_key(),
375 1
					'date_modified' => current_time( 'mysql', 1 ),
0 ignored issues
show
Bug introduced by
The function current_time was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

375
					'date_modified' => /** @scrutinizer ignore-call */ current_time( 'mysql', 1 ),
Loading history...
376 1
					'currency'      => $order->get_currency(),
377 1
					'hash'          => $order->get_hash()
378
				),
379 1
				array( 'id' => $order_id ),
380
				array(
381 1
					'%s',
382
					'%s',
383
					'%s',
384
					'%s'
385
				),
386 1
				array( '%d' )
387
			);
388
389 1
			if ( false === $r ) {
390
				throw new \Exception( "Failed updating Order" );
391
			}
392
393
			// update customer record
394 1
			$r = $wpdb->update(
395 1
				$wpdb->prefix . 'dlm_order_customer',
396
				array(
397 1
					'first_name' => $customer->get_first_name(),
398 1
					'last_name'  => $customer->get_last_name(),
399 1
					'company'    => $customer->get_company(),
400 1
					'address_1'  => $customer->get_address_1(),
401 1
					'address_2'  => $customer->get_address_2(),
402 1
					'city'       => $customer->get_city(),
403 1
					'state'      => $customer->get_state(),
404 1
					'postcode'   => $customer->get_postcode(),
405 1
					'country'    => $customer->get_country(),
406 1
					'email'      => $customer->get_email(),
407 1
					'phone'      => $customer->get_phone(),
408 1
					'ip_address' => $customer->get_ip_address(),
409 1
					'order_id'   => $order->get_id()
410
				),
411 1
				array( 'order_id' => $order_id ),
412
				array(
413 1
					'%s',
414
					'%s',
415
					'%s',
416
					'%s',
417
					'%s',
418
					'%s',
419
					'%s',
420
					'%s',
421
					'%s',
422
					'%s',
423
					'%s',
424
					'%s',
425
					'%d'
426
				),
427 1
				array( '%d' )
428
			);
429
430 1
			if ( false === $r ) {
431
				throw new \Exception( "Failed updating customer" );
432
			}
433
434
		}
435
436
		// handle order items
437 9
		$order_items = $order->get_items();
438 9
		if ( ! empty( $order_items ) ) {
439 9
			foreach ( $order_items as $order_item ) {
440
441
				// check if this order item exists in DB already
442 9
				$order_item_id = $order_item->get_id();
443 9
				if ( empty( $order_item_id ) ) {
444
445
					// insert new order item
446 9
					$r = $wpdb->insert(
447 9
						$wpdb->prefix . 'dlm_order_item',
448
						array(
449 9
							'order_id'    => $order->get_id(),
450 9
							'label'       => $order_item->get_label(),
451 9
							'qty'         => $order_item->get_qty(),
452 9
							'download_id' => $order_item->get_download_id(),
453 9
							'tax_class'   => $order_item->get_tax_class(),
454 9
							'tax_total'   => $order_item->get_tax_total(),
455 9
							'subtotal'    => $order_item->get_subtotal(),
456 9
							'total'       => $order_item->get_total()
457
						),
458
						array(
459 9
							'%d',
460
							'%s',
461
							'%d',
462
							'%d',
463
							'%s',
464
							'%d',
465
							'%d',
466
							'%d',
467
						)
468
					);
469
470 9
					if ( false === $r ) {
471
						throw new \Exception( "Failed creating OrderItem" );
472
					}
473
474 9
					$order_item->set_id( $wpdb->insert_id );
475
				} else {
476
477
					// update existing order item record
478 1
					$r = $wpdb->update(
479 1
						$wpdb->prefix . 'dlm_order_item',
480
						array(
481 1
							'order_id'    => $order->get_id(),
482 1
							'label'       => $order_item->get_label(),
483 1
							'qty'         => $order_item->get_qty(),
484 1
							'download_id' => $order_item->get_download_id(),
485 1
							'tax_class'   => $order_item->get_tax_class(),
486 1
							'tax_total'   => $order_item->get_tax_total(),
487 1
							'subtotal'    => $order_item->get_subtotal(),
488 1
							'total'       => $order_item->get_total()
489
						),
490 1
						array( 'id' => $order_item_id ),
491
						array(
492 1
							'%d',
493
							'%s',
494
							'%d',
495
							'%d',
496
							'%s',
497
							'%d',
498
							'%d',
499
							'%d',
500
						),
501 1
						array( '%d' )
502
					);
503
504 1
					if ( false === $r ) {
505 9
						throw new \Exception( "Failed updating OrderItem" );
506
					}
507
508
				}
509
			}
510
		}
511
512
		// handle transactions
513 9
		$transactions = $order->get_transactions();
514 9
		if ( ! empty( $transactions ) ) {
515
516
			/** @var Transaction\OrderTransaction $transaction */
517 9
			foreach ( $transactions as $transaction ) {
518
519 9
				$transaction_id = $transaction->get_id();
520
521 9
				$transaction_date_created = null;
522 9
				if ( null !== $transaction->get_date_created() ) {
523 9
					$transaction_date_created = $transaction->get_date_created()->format( 'Y-m-d H:i:s' );
524
				}
525
526 9
				$transaction_date_modified = null;
527 9
				if ( null !== $transaction->get_date_modified() ) {
528
					$transaction_date_modified = $transaction->get_date_modified()->format( 'Y-m-d H:i:s' );
529
				}
530
531
				// check if it's a new transaction or an existing one
532 9
				if ( empty( $transaction_id ) ) {
533
534
					// it's a new transaction
535
536 9
					$r = $wpdb->insert(
537 9
						$wpdb->prefix . 'dlm_order_transaction',
538
						array(
539 9
							'order_id'                 => $order->get_id(),
540 9
							'date_created'             => $transaction_date_created,
541 9
							'date_modified'            => $transaction_date_modified,
542 9
							'amount'                   => $transaction->get_amount(),
543 9
							'status'                   => $transaction->get_status()->get_key(),
544 9
							'processor'                => $transaction->get_processor(),
545 9
							'processor_nice_name'      => $transaction->get_processor_nice_name(),
546 9
							'processor_transaction_id' => $transaction->get_processor_transaction_id(),
547 9
							'processor_status'         => $transaction->get_processor_status()
548
						),
549
						array(
550 9
							'%d',
551
							'%s',
552
							'%s',
553
							'%d',
554
							'%s',
555
							'%s',
556
							'%s',
557
							'%s',
558
							'%s'
559
						)
560
					);
561
562 9
					if ( false === $r ) {
563
						throw new \Exception( "Failed creating OrderTransaction" );
564
					}
565
566
567 9
					$transaction->set_id( $wpdb->insert_id );
568
569
				} else {
570
571
					// it's an existing transaction
572
573 1
					$r = $wpdb->update(
574 1
						$wpdb->prefix . 'dlm_order_transaction',
575
						array(
576 1
							'order_id'                 => $order->get_id(),
577 1
							'date_created'             => $transaction_date_created,
578 1
							'date_modified'            => $transaction_date_modified,
579 1
							'amount'                   => $transaction->get_amount(),
580 1
							'status'                   => $transaction->get_status()->get_key(),
581 1
							'processor'                => $transaction->get_processor(),
582 1
							'processor_nice_name'      => $transaction->get_processor_nice_name(),
583 1
							'processor_transaction_id' => $transaction->get_processor_transaction_id(),
584 1
							'processor_status'         => $transaction->get_processor_status()
585
						),
586 1
						array( 'id' => $transaction_id ),
587
						array(
588 1
							'%d',
589
							'%s',
590
							'%s',
591
							'%d',
592
							'%s',
593
							'%s',
594
							'%s',
595
							'%s',
596
							'%s'
597
						),
598 1
						array( '%d' )
599
					);
600
601 1
					if ( false === $r ) {
602 9
						throw new \Exception( "Failed updating OrderTransaction" );
603
					}
604
605
				}
606
607
			}
608
609
		}
610
611 9
	}
612
613
	/**
614
	 * Delete order including all attached items (items, transactions, customer, etc.)
615
	 *
616
	 * @param $id
617
	 *
618
	 * @return bool
619
	 */
620 1
	public function delete( $id ) {
621 1
		global $wpdb;
622
623 1
		$success = true;
624
625
		try {
626
627 1
			if ( false === $wpdb->query( $wpdb->prepare( "DELETE FROM `" . $wpdb->prefix . "dlm_order_transaction` WHERE `order_id` = %d ;", $id ) ) ) {
628
				throw new \Exception( "Failed deleting transactions" );
629
			}
630
631 1
			if ( false === $wpdb->query( $wpdb->prepare( "DELETE FROM `" . $wpdb->prefix . "dlm_order_item` WHERE `order_id` = %d ;", $id ) ) ) {
632
				throw new \Exception( "Failed deleting order items" );
633
			}
634
635 1
			if ( false === $wpdb->query( $wpdb->prepare( "DELETE FROM `" . $wpdb->prefix . "dlm_order_customer` WHERE `order_id` = %d ;", $id ) ) ) {
636
				throw new \Exception( "Failed deleting customer" );
637
			}
638
639 1
			if ( false === $wpdb->query( $wpdb->prepare( "DELETE FROM `" . $wpdb->prefix . "dlm_order` WHERE `id` = %d ;", $id ) ) ) {
640 1
				throw new \Exception( "Failed deleting customer" );
641
			}
642
643
		} catch ( \Exception $exception ) {
644
			\DLM_Debug_Logger::log( $exception->getMessage() );
645
			$success = false;
646
		}
647
648 1
		return $success;
649
	}
650
651
	/**
652
	 * Remove all items in trash
653
	 */
654
	public function empty_trash() {
655
		global $wpdb;
656
657
		$ids = $wpdb->get_col( "SELECT `id` FROM `" . $wpdb->prefix . "dlm_order` WHERE `status` = 'trash' ;" );
658
659
		if ( is_array( $ids ) && count( $ids ) > 0 ) {
660
			foreach ( $ids as $id ) {
661
				if ( ! $this->delete( $id ) ) {
662
					return false;
663
				}
664
			}
665
		}
666
667
		return true;
668
	}
669
}