Passed
Push — develop-3.2.x-2.2 ( 55159b...647685 )
by Mario
04:39
created

transactions::sql_last_donation_ary()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 7
rs 10
1
<?php
2
/**
3
 *
4
 * PayPal Donation extension for the phpBB Forum Software package.
5
 *
6
 * @copyright (c) 2015 Skouat
7
 * @license GNU General Public License, version 2 (GPL-2.0)
8
 *
9
 */
10
11
namespace skouat\ppde\operators;
12
13
use phpbb\db\driver\driver_interface;
14
use Symfony\Component\DependencyInjection\ContainerInterface;
15
16
class transactions
17
{
18
	protected $container;
19
	protected $db;
20
	protected $ppde_transactions_log_table;
21
22
	/**
23
	 * Constructor
24
	 *
25
	 * @param ContainerInterface $container                   Service container interface
26
	 * @param driver_interface   $db                          Database connection
27
	 * @param string             $ppde_transactions_log_table Table name
28
	 *
29
	 * @access public
30
	 */
31
	public function __construct(ContainerInterface $container, driver_interface $db, $ppde_transactions_log_table)
32
	{
33
		$this->container = $container;
34
		$this->db = $db;
35
		$this->ppde_transactions_log_table = $ppde_transactions_log_table;
36
	}
37
38
	/**
39
	 * SQL Query to return Transaction log data table
40
	 *
41
	 * @param $transaction_id
42
	 *
43
	 * @return string
44
	 * @access public
45
	 */
46
	public function build_sql_data($transaction_id = 0)
47
	{
48
		// Build main sql request
49
		$sql_ary = array(
50
			'SELECT'    => '*, u.username, u.user_colour',
51
			'FROM'      => array($this->ppde_transactions_log_table => 'txn'),
52
			'LEFT_JOIN' => array(
53
				array(
54
					'FROM' => array(USERS_TABLE => 'u'),
55
					'ON'   => 'u.user_id = txn.user_id',
56
				),
57
			),
58
			'ORDER_BY'  => 'txn.transaction_id',
59
		);
60
61
		// Use WHERE clause when $currency_id is different from 0
62
		if ((int) $transaction_id)
63
		{
64
			$sql_ary['WHERE'] = 'txn.transaction_id = ' . (int) $transaction_id;
65
		}
66
67
		// Return all transactions entities
68
		return $this->db->sql_build_query('SELECT', $sql_ary);
69
	}
70
71
	/**
72
	 * SQL Query to count how many donated
73
	 *
74
	 * @param bool   $detailed
75
	 * @param string $order_by
76
	 *
77
	 * @return array
78
	 * @access public
79
	 */
80
	public function sql_donorlist_ary($detailed = false, $order_by = '')
81
	{
82
		// Build sql request
83
		$sql_donorslist_ary = array(
84
			'SELECT'   => 'txn.user_id',
85
			'FROM'     => array($this->ppde_transactions_log_table => 'txn'),
86
			'WHERE'    => 'txn.user_id <> ' . ANONYMOUS . "
87
							AND txn.payment_status = 'Completed'
88
							AND txn.test_ipn = 0",
89
			'GROUP_BY' => 'txn.user_id',
90
		);
91
92
		if ($order_by)
93
		{
94
			$sql_donorslist_ary['ORDER_BY'] = $order_by;
95
		}
96
97
		if ($detailed)
98
		{
99
			$sql_donorslist_ary['SELECT'] = 'txn.user_id, MAX(txn.transaction_id) AS max_txn_id, SUM(txn.mc_gross) AS amount, MAX(u.username)';
100
			$sql_donorslist_ary['LEFT_JOIN'] = array(
101
				array(
102
					'FROM' => array(USERS_TABLE => 'u'),
103
					'ON'   => 'u.user_id = txn.user_id',
104
				));
105
		}
106
107
		return $sql_donorslist_ary;
108
	}
109
110
	/**
111
	 * SQL Query to return information of the last donation of the donor
112
	 *
113
	 * @param $transaction_id
114
	 *
115
	 * @return array
116
	 * @access public
117
	 */
118
	public function sql_last_donation_ary($transaction_id)
119
	{
120
		// Build sql request
121
		return array(
122
			'SELECT' => 'txn.payment_date, txn.mc_gross',
123
			'FROM'   => array($this->ppde_transactions_log_table => 'txn'),
124
			'WHERE'  => 'txn.transaction_id = ' . (int) $transaction_id,
125
		);
126
	}
127
128
	/**
129
	 * Build SQL Query to return the donors list
130
	 *
131
	 * @param array $sql_donorlist_ary
132
	 *
133
	 * @return string
134
	 * @access public
135
	 */
136
	public function build_sql_donorlist_data($sql_donorlist_ary)
137
	{
138
		// Return all transactions entities
139
		return $this->db->sql_build_query('SELECT', $sql_donorlist_ary);
140
	}
141
142
	/**
143
	 * Returns total entries of selected field
144
	 *
145
	 * @param array  $count_sql_ary
146
	 * @param string $selected_field
147
	 *
148
	 * @return int
149
	 * @access public
150
	 */
151
	public function query_sql_count($count_sql_ary, $selected_field)
152
	{
153
		$count_sql_ary['SELECT'] = 'COUNT(' . $selected_field . ') AS total_entries';
154
155
		if (array_key_exists('GROUP_BY', $count_sql_ary))
156
		{
157
			$count_sql_ary['SELECT'] = 'COUNT(DISTINCT ' . $count_sql_ary['GROUP_BY'] . ') AS total_entries';
158
		}
159
		unset($count_sql_ary['ORDER_BY'], $count_sql_ary['GROUP_BY']);
160
161
		$sql = $this->db->sql_build_query('SELECT', $count_sql_ary);
162
		$result = $this->db->sql_query($sql);
163
		$field = (int) $this->db->sql_fetchfield('total_entries');
164
		$this->db->sql_freeresult($result);
165
166
		return $field;
167
	}
168
169
	/**
170
	 * Returns the SQL Query for displaying simple transactions details
171
	 *
172
	 * @param string $keywords
173
	 * @param string $sort_by
174
	 * @param int    $log_time
175
	 *
176
	 * @return array
177
	 * @access public
178
	 */
179
	public function get_logs_sql_ary($keywords, $sort_by, $log_time)
180
	{
181
		$sql_keywords = '';
182
		if (!empty($keywords))
183
		{
184
			// Get the SQL condition for our keywords
185
			$sql_keywords = $this->generate_sql_keyword($keywords);
186
		}
187
188
		$get_logs_sql_ary = array(
189
			'SELECT'   => 'txn.transaction_id, txn.txn_id, txn.test_ipn, txn.confirmed, txn.txn_errors, txn.payment_date, txn.payment_status, txn.user_id, u.username, u.user_colour',
190
			'FROM'     => array(
191
				$this->ppde_transactions_log_table => 'txn',
192
				USERS_TABLE                        => 'u',
193
			),
194
			'WHERE'    => 'txn.user_id = u.user_id ' . $sql_keywords,
195
			'ORDER_BY' => $sort_by,
196
		);
197
198
		if ($log_time)
199
		{
200
			$get_logs_sql_ary['WHERE'] = 'txn.payment_date >= ' . (int) $log_time . '
201
					AND ' . $get_logs_sql_ary['WHERE'];
202
		}
203
204
		return $get_logs_sql_ary;
205
	}
206
207
	/**
208
	 * Generates a sql condition for the specified keywords
209
	 *
210
	 * @param string $keywords           The keywords the user specified to search for
211
	 * @param string $statement_operator The operator used to prefix the statement ('AND' by default)
212
	 *
213
	 * @return string Returns the SQL condition searching for the keywords
214
	 * @access private
215
	 */
216
	private function generate_sql_keyword($keywords, $statement_operator = 'AND')
217
	{
218
		// Use no preg_quote for $keywords because this would lead to sole
219
		// backslashes being added. We also use an OR connection here for
220
		// spaces and the | string. Currently, regex is not supported for
221
		// searching (but may come later).
222
		$keywords = preg_split('#[\s|]+#u', utf8_strtolower($keywords), 0, PREG_SPLIT_NO_EMPTY);
0 ignored issues
show
Bug introduced by
The function utf8_strtolower 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

222
		$keywords = preg_split('#[\s|]+#u', /** @scrutinizer ignore-call */ utf8_strtolower($keywords), 0, PREG_SPLIT_NO_EMPTY);
Loading history...
223
		$sql_keywords = '';
224
225
		if (!empty($keywords))
226
		{
227
			// Build pattern and keywords...
228
			for ($i = 0, $num_keywords = count($keywords); $i < $num_keywords; $i++)
229
			{
230
				$keywords[$i] = $this->db->sql_like_expression($this->db->get_any_char() . $keywords[$i] . $this->db->get_any_char());
231
			}
232
233
			$sql_keywords = ' ' . $statement_operator . ' (';
234
			$sql_lower = $this->db->sql_lower_text('txn.txn_id');
235
			$sql_keywords .= ' ' . $sql_lower . ' ' . implode(' OR ' . $sql_lower . ' ', $keywords) . ')';
236
		}
237
238
		return $sql_keywords;
239
	}
240
241
	/**
242
	 * Returns user information based on the donor ID or email
243
	 *
244
	 * @param string     $type
245
	 * @param int|string $arg
246
	 *
247
	 * @return array|bool
248
	 * @access public
249
	 */
250
	public function query_donor_user_data($type = 'user', $arg = 1)
251
	{
252
253
		switch ($type)
254
		{
255
			case 'user':
256
				$sql_where = ' WHERE user_id = ' . (int) $arg;
257
			break;
258
			case 'username':
259
				$sql_where = " WHERE username_clean = '" . $this->db->sql_escape(utf8_clean_string($arg)) . "'";
260
			break;
261
			case 'email':
262
				$sql_where = " WHERE user_email_hash = '" . $this->db->sql_escape(phpbb_email_hash($arg)) . "'";
263
			break;
264
			default:
265
				$sql_where = '';
266
		}
267
268
		$sql = 'SELECT user_id, username, user_ppde_donated_amount
269
			FROM ' . USERS_TABLE .
270
			$sql_where;
271
		$result = $this->db->sql_query($sql);
272
		$row = $this->db->sql_fetchrow($result);
273
		$this->db->sql_freeresult($result);
274
275
		return $row;
276
	}
277
278
	/**
279
	 * Returns simple details of all PayPal transactions logged in the database
280
	 *
281
	 * @param array $get_logs_sql_ary
282
	 * @param array $url_ary
283
	 * @param int   $limit
284
	 * @param int   $last_page_offset
285
	 *
286
	 * @return array $log
287
	 * @access public
288
	 */
289
	public function build_log_ary($get_logs_sql_ary, $url_ary, $limit = 0, $last_page_offset = 0)
290
	{
291
		$sql = $this->db->sql_build_query('SELECT', $get_logs_sql_ary);
292
		$result = $this->db->sql_query_limit($sql, $limit, $last_page_offset);
293
294
		$log = array();
295
296
		while ($row = $this->db->sql_fetchrow($result))
297
		{
298
			$log[] = array(
299
				'confirmed'      => $row['confirmed'],
300
				'payment_date'   => $row['payment_date'],
301
				'payment_status' => $row['payment_status'],
302
				'test_ipn'       => $row['test_ipn'],
303
				'transaction_id' => $row['transaction_id'],
304
				'txn_errors'     => $row['txn_errors'],
305
				'txn_id'         => $this->build_transaction_url($row['transaction_id'], $row['txn_id'], $url_ary['txn_url'], $row['confirmed']),
306
				'username_full'  => get_username_string('full', $row['user_id'], $row['username'], $row['user_colour'], false, $url_ary['profile_url']),
0 ignored issues
show
Bug introduced by
false of type false is incompatible with the type string expected by parameter $guest_username of get_username_string(). ( Ignorable by Annotation )

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

306
				'username_full'  => get_username_string('full', $row['user_id'], $row['username'], $row['user_colour'], /** @scrutinizer ignore-type */ false, $url_ary['profile_url']),
Loading history...
307
			);
308
		}
309
310
		$this->db->sql_freeresult($result);
311
312
		return $log;
313
	}
314
315
	/**
316
	 * Build transaction url for placing into templates.
317
	 *
318
	 * @param int    $id         The users transaction id
319
	 * @param string $txn_id     The txn number id
320
	 * @param string $custom_url optional parameter to specify a profile url. The transaction id get appended to this
321
	 *                           url as &amp;id={id}
322
	 * @param bool   $colour     If false the color #FF0000 will be applied on the URL.
323
	 *
324
	 * @return string A string consisting of what is wanted.
325
	 * @access private
326
	 */
327
	private function build_transaction_url($id, $txn_id, $custom_url = '', $colour = false)
328
	{
329
		static $_profile_cache;
330
331
		// We cache some common variables we need within this function
332
		if (empty($_profile_cache))
333
		{
334
			$_profile_cache['tpl_nourl'] = '{{ TRANSACTION }}';
335
			$_profile_cache['tpl_url'] = '<a href="{{ TXN_URL }}">{{ TRANSACTION }}</a>';
336
			$_profile_cache['tpl_url_colour'] = '<a href="{{ TXN_URL }}" style="{{ TXN_COLOUR }}">{{ TRANSACTION }}</a>';
337
		}
338
339
		// Build correct transaction url
340
		$txn_url = '';
341
		if ($txn_id)
342
		{
343
			$txn_url = ($custom_url !== '') ? $custom_url . '&amp;action=view&amp;id=' . $id : $txn_id;
344
		}
345
346
		// Return
347
348
		if (!$txn_url)
349
		{
350
			return str_replace('{{ TRANSACTION }}', $txn_id, $_profile_cache['tpl_nourl']);
351
		}
352
353
		return str_replace(array('{{ TXN_URL }}', '{{ TXN_COLOUR }}', '{{ TRANSACTION }}'), array($txn_url, 'color: #FF0000;', $txn_id), (!$colour) ? $_profile_cache['tpl_url_colour'] : $_profile_cache['tpl_url']);
354
	}
355
356
	/**
357
	 * Returns SQL WHERE clause for all marked items
358
	 *
359
	 * @param $marked
360
	 *
361
	 * @return string
362
	 * @access public
363
	 */
364
	public function build_marked_where_sql($marked)
365
	{
366
		$sql_in = array();
367
		foreach ($marked as $mark)
368
		{
369
			$sql_in[] = $mark;
370
		}
371
372
		return ' WHERE ' . $this->db->sql_in_set('transaction_id', $sql_in);
373
	}
374
375
	/**
376
	 * Returns the count result for updating stats
377
	 *
378
	 * @param string $type
379
	 * @param bool   $test_ipn
380
	 *
381
	 * @return int
382
	 * @access public
383
	 */
384
	public function sql_query_count_result($type, $test_ipn)
385
	{
386
		switch ($type)
387
		{
388
			case 'ppde_transactions_count':
389
			case 'ppde_transactions_count_ipn':
390
				$sql_ary = $this->sql_select_stats_main('txn_id');
391
				$sql_ary['WHERE'] = "confirmed = 1 AND payment_status = 'Completed' AND txn.test_ipn = " . (int) $test_ipn;
392
			break;
393
			case 'ppde_known_donors_count':
394
			case 'ppde_known_donors_count_ipn':
395
				$sql_ary = $this->sql_select_stats_main('payer_id');
396
				$sql_ary['LEFT_JOIN'] = array(
397
					array(
398
						'FROM' => array(USERS_TABLE => 'u'),
399
						'ON'   => 'txn.user_id = u.user_id',
400
					),
401
				);
402
				$sql_ary['WHERE'] = '(u.user_type = ' . USER_NORMAL . ' OR u.user_type = ' . USER_FOUNDER . ') AND txn.test_ipn = ' . (int) $test_ipn;
403
			break;
404
			case 'ppde_anonymous_donors_count':
405
			case 'ppde_anonymous_donors_count_ipn':
406
				$sql_ary = $this->sql_select_stats_main('payer_id');
407
				$sql_ary['WHERE'] = 'txn.user_id = ' . ANONYMOUS . ' AND txn.test_ipn = ' . (int) $test_ipn;
408
			break;
409
			default:
410
				$sql_ary = $this->sql_select_stats_main('txn_id');
411
		}
412
413
		$result = $this->db->sql_query($this->db->sql_build_query('SELECT', $sql_ary));
414
		$count = (int) $this->db->sql_fetchfield('count_result');
415
		$this->db->sql_freeresult($result);
416
417
		return $count;
418
	}
419
420
	/**
421
	 * Make body of SQL query for stats calculation.
422
	 *
423
	 * @param string $field_name Name of the field
424
	 *
425
	 * @return array
426
	 * @access private
427
	 */
428
	private function sql_select_stats_main($field_name)
429
	{
430
		return array(
431
			'SELECT' => 'COUNT(DISTINCT txn.' . $field_name . ') AS count_result',
432
			'FROM'   => array($this->ppde_transactions_log_table => 'txn'),
433
		);
434
	}
435
436
	/**
437
	 * Updates the user donated amount
438
	 *
439
	 * @param int    $user_id
440
	 * @param string $value
441
	 *
442
	 * @return void
443
	 * @access public
444
	 */
445
	public function sql_update_user_stats($user_id, $value)
446
	{
447
		$sql = 'UPDATE ' . USERS_TABLE . '
448
			SET user_ppde_donated_amount = ' . (float) $value . '
449
			WHERE user_id = ' . (int) $user_id;
450
		$this->db->sql_query($sql);
451
	}
452
453
	/**
454
	 * Prepare data array() before send it to $entity
455
	 *
456
	 * @param array $data
457
	 *
458
	 * @return array
459
	 * @access public
460
	 */
461
	public function build_data_ary($data)
462
	{
463
		return array(
464
			'business'          => $data['business'],
465
			'confirmed'         => (bool) $data['confirmed'],
466
			'exchange_rate'     => $data['exchange_rate'],
467
			'first_name'        => $data['first_name'],
468
			'item_name'         => $data['item_name'],
469
			'item_number'       => $data['item_number'],
470
			'last_name'         => $data['last_name'],
471
			'mc_currency'       => $data['mc_currency'],
472
			'mc_gross'          => floatval($data['mc_gross']),
473
			'mc_fee'            => floatval($data['mc_fee']),
474
			'net_amount'        => floatval($data['net_amount']),
475
			'parent_txn_id'     => $data['parent_txn_id'],
476
			'payer_email'       => $data['payer_email'],
477
			'payer_id'          => $data['payer_id'],
478
			'payer_status'      => $data['payer_status'],
479
			'payment_date'      => $data['payment_date'],
480
			'payment_status'    => $data['payment_status'],
481
			'payment_type'      => $data['payment_type'],
482
			'memo'              => $data['memo'],
483
			'receiver_id'       => $data['receiver_id'],
484
			'receiver_email'    => $data['receiver_email'],
485
			'residence_country' => $data['residence_country'],
486
			'settle_amount'     => floatval($data['settle_amount']),
487
			'settle_currency'   => $data['settle_currency'],
488
			'test_ipn'          => (bool) $data['test_ipn'],
489
			'txn_errors'        => $data['txn_errors'],
490
			'txn_id'            => $data['txn_id'],
491
			'txn_type'          => $data['txn_type'],
492
			'user_id'           => (int) $data['user_id'],
493
		);
494
	}
495
}
496