Completed
Push — master ( 060c1d...ab2f3f )
by Barry
07:03
created

WordPressRepository::persist()   F

Complexity

Conditions 20
Paths 320

Size

Total Lines 320
Code Lines 225

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 20
eloc 225
nc 320
nop 1
dl 0
loc 320
rs 1.4665
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
	private function prep_where_statement( $filters ) {
24
		global $wpdb;
25
		// setup where statements
26
		$where = array( "WHERE 1=1" );
27
		foreach ( $filters as $filter ) {
28
			$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
			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
				$where[] = $wpdb->prepare( "AND `" . esc_sql( $filter['key'] ) . "` " . $operator . " '%s'", $filter['value'] );
35
			}
36
		}
37
		$where_str = "";
38
		if ( count( $where ) > 1 ) {
39
			$where_str = implode( " ", $where );
40
		}
41
42
		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
	private function add_order_items_to_order( $order ) {
53
		global $wpdb;
54
55
		/** Fetch order items */
56
		$order_items = array();
57
		$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
		if ( count( $db_items ) > 0 ) {
59
			foreach ( $db_items as $db_item ) {
60
				$order_item = new OrderItem();
61
62
				$order_item->set_id( $db_item->id );
63
				$order_item->set_label( $db_item->label );
64
				$order_item->set_qty( $db_item->qty );
65
				$order_item->set_download_id( $db_item->download_id );
66
				$order_item->set_subtotal( $db_item->subtotal );
67
				$order_item->set_tax_class( $db_item->tax_class );
68
				$order_item->set_tax_total( $db_item->tax_total );
69
				$order_item->set_total( $db_item->total );
70
71
				$order_items[] = $order_item;
72
			}
73
		}
74
75
		$order->set_items( $order_items );
76
77
		return $order;
78
	}
79
80
	/**
81
	 * Fetch and add transactions to order
82
	 *
83
	 * @param Order $order
84
	 *
85
	 * @return Order
86
	 */
87
	private function add_transactions_to_order( $order ) {
88
		global $wpdb;
89
90
		/** Fetch transactions */
91
		$order_transactions = array();
92
		$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
		if ( count( $db_items ) > 0 ) {
94
			foreach ( $db_items as $db_item ) {
95
				$order_transaction = new Transaction\OrderTransaction();
96
97
				$order_transaction->set_id( $db_item->id );
98
99
				if ( ! empty( $db_item->date_created ) ) {
100
					$order_transaction->set_date_created( new \DateTimeImmutable( $db_item->date_created ) );
101
				}
102
103
				if ( ! empty( $db_item->date_modified ) ) {
104
					$order_transaction->set_date_modified( new \DateTimeImmutable( $db_item->date_modified ) );
105
				}
106
107
				$order_transaction->set_amount( $db_item->amount );
108
				$order_transaction->set_status( Services::get()->service( 'order_transaction_factory' )->make_status( $db_item->status ) );
109
				$order_transaction->set_processor( $db_item->processor );
110
				$order_transaction->set_processor_nice_name( $db_item->processor_nice_name );
111
				$order_transaction->set_processor_transaction_id( $db_item->processor_transaction_id );
112
				$order_transaction->set_processor_status( $db_item->processor_status );
113
114
				$order_transactions[] = $order_transaction;
115
			}
116
		}
117
118
		$order->set_transactions( $order_transactions );
119
120
		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
	public function retrieve( $filters = array(), $limit = 0, $offset = 0, $order_by = 'id', $order = 'DESC' ) {
138
		global $wpdb;
139
140
		// prep order
141
		$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
		$order    = strtoupper( $order );
143
		if ( ! in_array( $order, array( 'ASC', 'DESC' ) ) ) {
144
			$order = 'DESC';
145
		}
146
147
		// prep where statement
148
		$where_str = $this->prep_where_statement( $filters );
149
150
		$sql = "
151
		SELECT O.*, C.* 
152
		FROM `" . $wpdb->prefix . "dlm_order` O
153
		INNER JOIN `" . $wpdb->prefix . "dlm_order_customer` C ON O.id=C.order_id
154
		" . $where_str . "
155
		ORDER BY O.`" . $order_by . "` " . $order;
156
157
		$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
		$offset = absint( $offset );
159
160
		if ( $limit > 0 ) {
161
			$sql .= " LIMIT " . $limit;
162
		}
163
164
		if ( $offset > 0 ) {
165
			$sql .= " OFFSET " . $offset;
166
		}
167
168
		$sql .= ";";
169
170
		// try to fetch session from database
171
		$results = $wpdb->get_results( $sql );
172
173
		// check if result if found
174
		if ( null === $results ) {
175
			throw new \Exception( 'SQL error while fetching order' );
176
		}
177
178
		// array that will hold all order objects
179
		$orders = array();
180
181
		foreach ( $results as $result ) {
182
183
			$order = new Order();
184
185
			$order->set_id( $result->id );
186
			$order->set_status( Services::get()->service( 'order_status_factory' )->make( $result->status ) );
187
			$order->set_currency( $result->currency );
188
			$order->set_hash( $result->hash );
189
190
			if ( ! empty( $result->date_created ) ) {
191
				$order->set_date_created( new \DateTimeImmutable( $result->date_created ) );
192
			}
193
194
			if ( ! empty( $result->date_modified ) ) {
195
				$order->set_date_modified( new \DateTimeImmutable( $result->date_modified ) );
196
			}
197
198
			// create and set customer
199
			$order->set_customer( new OrderCustomer(
200
				$result->first_name,
201
				$result->last_name,
202
				$result->company,
203
				$result->address_1,
204
				$result->address_2,
205
				$result->city,
206
				$result->state,
207
				$result->postcode,
208
				$result->country,
209
				$result->email,
210
				$result->phone,
211
				$result->ip_address
212
			) );
213
214
			// add order items to order object
215
			$order = $this->add_order_items_to_order( $order );
216
217
			// add transactions to order object
218
			$order = $this->add_transactions_to_order( $order );
219
220
			// add new order object to array
221
			$orders[] = $order;
222
223
		}
224
225
		return $orders;
226
227
	}
228
229
	/**
230
	 * Retrieve a single order
231
	 *
232
	 * @param $id
233
	 *
234
	 * @return Order
235
	 *
236
	 * @throws \Exception
237
	 */
238
	public function retrieve_single( $id ) {
239
		$orders = $this->retrieve( array( array( 'key' => 'id', 'value' => $id, 'operator' => '=' ) ), 1 );
240
		if ( 0 === count( $orders ) ) {
241
			throw new \Exception( 'Order not found' );
242
		}
243
244
		return $orders[0];
245
	}
246
247
	/**
248
	 * Returns number of rows for given filters
249
	 *
250
	 * @param array $filters
251
	 *
252
	 * @return int
253
	 */
254
	public function num_rows( $filters = array() ) {
255
		global $wpdb;
256
257
		// prep where statement
258
		$where_str = $this->prep_where_statement( $filters );
259
260
		$num = $wpdb->get_var( "SELECT COUNT(id) FROM `" . $wpdb->prefix . "dlm_order` {$where_str} " );
261
262
		if ( null === $num ) {
263
			$num = 0;
264
		}
265
266
		return $num;
267
	}
268
269
	/**
270
	 * Persist order
271
	 *
272
	 * @param Order $order
273
	 *
274
	 * @throws \Exception
275
	 *
276
	 * @return bool
277
	 */
278
	public function persist( $order ) {
279
		global $wpdb;
280
281
		$date_created = '';
282
		if ( null !== $order->get_date_created() ) {
283
			$date_created = $order->get_date_created()->format( 'Y-m-d H:i:s' );
284
		}
285
286
		$date_modified = '';
287
		if ( null !== $order->get_date_modified() ) {
288
			$date_modified = $order->get_date_modified()->format( 'Y-m-d H:i:s' );
289
		}
290
291
		$order_id = $order->get_id();
292
293
		$customer = $order->get_customer();
294
295
		// check if it's a new order or if we need to update an existing one
296
		if ( empty( $order_id ) ) {
297
			/** New order */
298
299
			// insert order
300
			$r = $wpdb->insert(
301
				$wpdb->prefix . 'dlm_order',
302
				array(
303
					'status'        => $order->get_status()->get_key(),
304
					'date_created'  => $date_created,
305
					'date_modified' => $date_modified,
306
					'currency'      => $order->get_currency(),
307
					'hash'          => $order->get_hash()
308
				),
309
				array(
310
					'%s',
311
					'%s',
312
					'%s',
313
					'%s',
314
					'%s'
315
				)
316
			);
317
318
			if ( false === $r ) {
319
				throw new \Exception( "Failed creating Order" );
320
			}
321
322
			// set the new id as order id
323
			$order->set_id( $wpdb->insert_id );
324
325
			// insert customer record
326
			$r = $wpdb->insert(
327
				$wpdb->prefix . 'dlm_order_customer',
328
				array(
329
					'first_name' => $customer->get_first_name(),
330
					'last_name'  => $customer->get_last_name(),
331
					'company'    => $customer->get_company(),
332
					'address_1'  => $customer->get_address_1(),
333
					'address_2'  => $customer->get_address_2(),
334
					'city'       => $customer->get_city(),
335
					'state'      => $customer->get_state(),
336
					'postcode'   => $customer->get_postcode(),
337
					'country'    => $customer->get_country(),
338
					'email'      => $customer->get_email(),
339
					'phone'      => $customer->get_phone(),
340
					'ip_address' => $customer->get_ip_address(),
341
					'order_id'   => $order->get_id()
342
				),
343
				array(
344
					'%s',
345
					'%s',
346
					'%s',
347
					'%s',
348
					'%s',
349
					'%s',
350
					'%s',
351
					'%s',
352
					'%s',
353
					'%s',
354
					'%s',
355
					'%s',
356
					'%d'
357
				)
358
			);
359
360
			if ( false === $r ) {
361
				throw new \Exception( "Failed creating Customer" );
362
			}
363
364
		} else {
365
366
			// update an existing order
367
			$r = $wpdb->update( $wpdb->prefix . 'dlm_order',
368
				array(
369
					'status'        => $order->get_status()->get_key(),
370
					'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

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