Passed
Push — develop-3.3.x ( c85e2c...2b4c5a )
by Mario
02:35
created

core::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 20
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 9
c 0
b 0
f 0
nc 1
nop 9
dl 0
loc 20
rs 9.9666

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
/**
3
 *
4
 * PayPal Donation extension for the phpBB Forum Software package.
5
 *
6
 * @copyright (c) 2015-2024 Skouat
7
 * @license GNU General Public License, version 2 (GPL-2.0)
8
 *
9
 */
10
11
namespace skouat\ppde\actions;
12
13
use phpbb\config\config;
14
use phpbb\event\dispatcher_interface;
15
use phpbb\language\language;
16
use phpbb\path_helper;
17
use phpbb\user;
18
19
class core
20
{
21
	/**
22
	 * Services properties declaration
23
	 */
24
	public $notification;
25
	protected $config;
26
	protected $dispatcher;
27
	protected $language;
28
	protected $php_ext;
29
	protected $ppde_entity_transaction;
30
	protected $ppde_operator_transaction;
31
	protected $transaction_data;
32
	protected $user;
33
34
	/**
35
	 * @var boolean
36
	 */
37
	private $donor_is_member = false;
38
	/**
39
	 * @var boolean
40
	 */
41
	private $is_ipn_test = false;
42
	/**
43
	 * @var array
44
	 */
45
	private $payer_data = array();
46
	/**
47
	 * phpBB root path
48
	 *
49
	 * @var string
50
	 */
51
	private $root_path;
52
	/**
53
	 * @var string
54
	 */
55
	private $ipn_suffix;
56
57
	/**
58
	 * Constructor
59
	 *
60
	 * @param config                              $config                    Config object
61
	 * @param language                            $language                  Language user object
62
	 * @param \skouat\ppde\notification\core      $notification              PPDE Notification object
63
	 * @param path_helper                         $path_helper               Path helper object
64
	 * @param \skouat\ppde\entity\transactions    $ppde_entity_transaction   Transaction entity object
65
	 * @param \skouat\ppde\operators\transactions $ppde_operator_transaction Transaction operator object
66
	 * @param dispatcher_interface                $dispatcher                Dispatcher object
67
	 * @param user                                $user                      User object
68
	 * @param string                              $php_ext                   phpEx
69
	 *
70
	 * @access public
71
	 */
72
	public function __construct(
73
		config $config,
74
		language $language,
75
		\skouat\ppde\notification\core $notification,
76
		path_helper $path_helper,
77
		\skouat\ppde\entity\transactions $ppde_entity_transaction,
78
		\skouat\ppde\operators\transactions $ppde_operator_transaction,
79
		dispatcher_interface $dispatcher,
80
		user $user,
81
		$php_ext)
82
	{
83
		$this->config = $config;
84
		$this->dispatcher = $dispatcher;
85
		$this->language = $language;
86
		$this->notification = $notification;
87
		$this->ppde_entity_transaction = $ppde_entity_transaction;
88
		$this->ppde_operator_transaction = $ppde_operator_transaction;
89
		$this->php_ext = $php_ext;
90
		$this->root_path = $path_helper->get_phpbb_root_path();
91
		$this->user = $user;
92
	}
93
94
	/**
95
	 * Sets properties related to ipn tests
96
	 *
97
	 * @param bool $ipn_test
98
	 *
99
	 * @return void
100
	 * @access public
101
	 */
102
	public function set_ipn_test_properties($ipn_test): void
103
	{
104
		$this->set_ipn_test($ipn_test);
105
		$this->set_ipn_suffix();
106
	}
107
108
	/**
109
	 * Sets the property $this->is_ipn_test
110
	 *
111
	 * @param bool $ipn_test
112
	 *
113
	 * @return void
114
	 * @access private
115
	 */
116
	private function set_ipn_test($ipn_test): void
117
	{
118
		$this->is_ipn_test = (bool) $ipn_test;
119
	}
120
121
	/**
122
	 * Sets the property $this->ipn_suffix
123
	 *
124
	 * @return void
125
	 * @access private
126
	 */
127
	private function set_ipn_suffix(): void
128
	{
129
		$this->ipn_suffix = $this->is_ipn_test ? '_ipn' : '';
130
	}
131
132
	/**
133
	 * Gets the property $this->ipn_suffix
134
	 *
135
	 * @return string
136
	 * @access private
137
	 */
138
	public function get_ipn_suffix(): string
139
	{
140
		return $this->get_ipn_test() ? $this->ipn_suffix : '';
141
	}
142
143
	/**
144
	 * @return boolean
145
	 * @access private
146
	 */
147
	public function get_ipn_test(): bool
148
	{
149
		return $this->is_ipn_test;
150
	}
151
152
	/**
153
	 * Checks if the donor is a member then gets payer_data values
154
	 *
155
	 * @return void
156
	 * @access public
157
	 */
158
159
	public function is_donor_is_member(): void
160
	{
161
		if ($this->is_donor_anonymous())
162
		{
163
			$this->donor_is_member = $this->check_donor_status_based_on_email($this->transaction_data['payer_email']);
164
165
		}
166
		else
167
		{
168
			$this->donor_is_member = $this->check_donors_status('user', $this->transaction_data['user_id']);
169
		}
170
	}
171
172
	/**
173
	 * @return boolean
174
	 */
175
	public function get_donor_is_member(): bool
176
	{
177
		return $this->donor_is_member;
178
	}
179
180
	/**
181
	 * Determine if the donor is anonymous.
182
	 *
183
	 * @return bool True if the donor is anonymous, false otherwise.
184
	 */
185
	private function is_donor_anonymous(): bool
186
	{
187
		return (int) $this->transaction_data['user_id'] === ANONYMOUS || !$this->check_donors_status('user', $this->transaction_data['user_id']);
188
	}
189
190
	/**
191
	 * Gets donor informations (user id, username, amount donated) and returns if exists
192
	 *
193
	 * @param string     $type Allowed value : 'user' or 'email'
194
	 * @param string|int $args If $type is set to 'user', $args must be a user id.
195
	 *                         If $type is set to 'email', $args must be an email address
196
	 *
197
	 * @return bool
198
	 * @access private
199
	 */
200
	private function check_donors_status($type, $args): bool
201
	{
202
		$this->payer_data = $this->ppde_operator_transaction->query_donor_user_data($type, $args);
203
204
		return (bool) count((array) $this->payer_data);
205
	}
206
207
	/**
208
	 * Checks the donor status based on email.
209
	 *
210
	 * @param string $email The email of the donor.
211
	 * @return bool Returns true if the status of the donor is active, false otherwise.
212
	 */
213
	private function check_donor_status_based_on_email($email): bool
214
	{
215
		if (empty($email))
216
		{
217
			return false;
218
		}
219
220
		return $this->check_donors_status('email', $email);
221
	}
222
223
	/**
224
	 * @return array
225
	 */
226
	public function get_payer_data(): array
227
	{
228
		return (count($this->payer_data) != 0) ? $this->payer_data : [];
229
	}
230
231
	/**
232
	 * Log the transaction to the database
233
	 *
234
	 * @param array $data Transaction data array
235
	 *
236
	 * @return void
237
	 * @access public
238
	 */
239
	public function log_to_db($data): void
240
	{
241
		$this->set_transaction_data($data);
242
		$this->validate_and_set_transaction_data();
243
		$this->ppde_entity_transaction->add_edit_data();
244
	}
245
246
	/**
247
	 * Set Transaction Data array
248
	 *
249
	 * @param array $transaction_data Array of the donation transaction.
250
	 *
251
	 * @return void
252
	 * @access public
253
	 */
254
	public function set_transaction_data(array $transaction_data): void
255
	{
256
		$this->transaction_data = $this->merge_transaction_data($transaction_data);
257
	}
258
259
	/**
260
	 * Merge transaction data if existing transaction data is not empty, else return passed transaction data
261
	 *
262
	 * @param array $transaction_data Array of the donation transaction.
263
	 *
264
	 * @return array Merged or original transaction data
265
	 * @access private
266
	 */
267
	private function merge_transaction_data(array $transaction_data): array
268
	{
269
		return !empty($this->transaction_data)
270
			? array_merge($this->transaction_data, $transaction_data)
271
			: $transaction_data;
272
	}
273
274
	private function validate_and_set_transaction_data(): void
275
	{
276
		// Handle user_id data
277
		$this->extract_user_id();
278
		$this->validate_user_id();
279
280
		// Set username in extra_data property in $entity
281
		$user_ary = $this->ppde_operator_transaction->query_donor_user_data('user', $this->transaction_data['user_id']);
282
		$this->ppde_entity_transaction->set_username($user_ary['username']);
283
284
		// Set 'net_amount' in $this->transaction_data
285
		$this->transaction_data['net_amount'] = $this->net_amount(
286
			$this->transaction_data['mc_gross'],
287
			$this->transaction_data['mc_fee']
288
		);
289
290
		$data = $this->ppde_operator_transaction->build_data_ary($this->transaction_data);
291
292
		// Load data in the entity
293
		$this->ppde_entity_transaction->set_entity_data($data);
294
		$this->ppde_entity_transaction->set_id($this->ppde_entity_transaction->transaction_exists());
295
	}
296
297
	/**
298
	 * Retrieve user_id from custom args
299
	 *
300
	 * @return void
301
	 * @access private
302
	 */
303
	private function extract_user_id(): void
304
	{
305
		[$this->transaction_data['user_id']] = explode('_', substr($this->transaction_data['custom'], 4), -1);
306
	}
307
308
	/**
309
	 * Avoid the user_id to be set to 0
310
	 *
311
	 * @return void
312
	 * @access private
313
	 */
314
	private function validate_user_id(): void
315
	{
316
		if (empty($this->transaction_data['user_id']) || !is_numeric($this->transaction_data['user_id']))
317
		{
318
			$this->transaction_data['user_id'] = ANONYMOUS;
319
		}
320
	}
321
322
	/**
323
	 * Returns the net amount of a donation
324
	 *
325
	 * @param float  $amount
326
	 * @param float  $fee
327
	 * @param string $dec_point
328
	 * @param string $thousands_sep
329
	 *
330
	 * @return string
331
	 * @access public
332
	 */
333
	public function net_amount($amount, $fee, $dec_point = '.', $thousands_sep = ''): string
334
	{
335
		return number_format((float) $amount - (float) $fee, 2, $dec_point, $thousands_sep);
336
	}
337
338
	/**
339
	 * Check we are in the ACP
340
	 *
341
	 * @return bool
342
	 * @access public
343
	 */
344
	public function is_in_admin(): bool
345
	{
346
		return defined('IN_ADMIN') && isset($this->user->data['session_admin']) && $this->user->data['session_admin'];
347
	}
348
349
	/**
350
	 * Perform actions for validated transaction
351
	 *
352
	 * @param bool $is_member
353
	 */
354
	public function do_transactions_actions($is_member): void
355
	{
356
		$this->update_overview_stats();
357
		$this->update_raised_amount();
358
359
		if ($is_member)
360
		{
361
			$this->update_donor_stats();
362
			$this->donors_group_user_add();
363
			$this->notification->notify_donor_donation_received();
364
		}
365
	}
366
367
	/**
368
	 * Updates the Overview module statistics
369
	 *
370
	 * @return void
371
	 * @access public
372
	 */
373
	public function update_overview_stats(): void
374
	{
375
		$this->config->set('ppde_anonymous_donors_count' . $this->ipn_suffix, $this->get_count_result('ppde_anonymous_donors_count' . $this->ipn_suffix));
376
		$this->config->set('ppde_known_donors_count' . $this->ipn_suffix, $this->get_count_result('ppde_known_donors_count' . $this->ipn_suffix), true);
377
		$this->config->set('ppde_transactions_count' . $this->ipn_suffix, $this->get_count_result('ppde_transactions_count' . $this->ipn_suffix), true);
378
	}
379
380
	/**
381
	 * Returns count result for updating stats
382
	 *
383
	 * @param string $config_name
384
	 *
385
	 * @return int
386
	 * @access private
387
	 */
388
	private function get_count_result($config_name): int
389
	{
390
		if (!$this->config->offsetExists($config_name))
391
		{
392
			trigger_error($this->language->lang('EXCEPTION_INVALID_CONFIG_NAME', $config_name), E_USER_WARNING);
393
		}
394
395
		return $this->ppde_operator_transaction->sql_query_count_result($config_name, $this->is_ipn_test);
396
	}
397
398
	/**
399
	 * Updates the amount of donation raised
400
	 *
401
	 * @return void
402
	 * @access public
403
	 */
404
	public function update_raised_amount(): void
405
	{
406
		$net_amount = (float) $this->net_amount($this->transaction_data['mc_gross'], $this->transaction_data['mc_fee']);
407
408
		if (!empty($this->transaction_data['settle_amount']))
409
		{
410
			$net_amount = $this->transaction_data['settle_amount'];
411
		}
412
413
		$this->config->set('ppde_raised' . $this->ipn_suffix, (float) $this->config['ppde_raised' . $this->ipn_suffix] + $net_amount);
414
	}
415
416
	/**
417
	 * Updates donor member stats
418
	 *
419
	 * @return void
420
	 * @access public
421
	 */
422
	public function update_donor_stats(): void
423
	{
424
		if ($this->donor_is_member)
425
		{
426
			$this->update_user_stats((int) $this->payer_data['user_id'], (float) $this->payer_data['user_ppde_donated_amount'] + (float) $this->transaction_data['mc_gross']);
427
		}
428
	}
429
430
	/**
431
	 * @param int   $user_id
432
	 * @param float $amount
433
	 */
434
	public function update_user_stats($user_id, $amount): void
435
	{
436
		if (!$user_id)
437
		{
438
			trigger_error($this->language->lang('EXCEPTION_INVALID_USER_ID', $user_id), E_USER_WARNING);
439
		}
440
441
		$this->ppde_operator_transaction->sql_update_user_stats($user_id, $amount);
442
	}
443
444
	/**
445
	 * Add donor to the donors group
446
	 *
447
	 * @return void
448
	 * @access public
449
	 */
450
	public function donors_group_user_add(): void
451
	{
452
		// We add the user to the donors group
453
		$can_use_autogroup = $this->can_use_autogroup();
454
		$group_id = (int) $this->config['ppde_ipn_group_id'];
455
		$payer_id = (int) $this->payer_data['user_id'];
456
		$payer_username = $this->payer_data['username'];
457
		$default_group = $this->config['ppde_ipn_group_as_default'];
458
		$payer_donated_amount = $this->payer_data['user_ppde_donated_amount'];
459
460
		/**
461
		 * Event to modify data before a user is added to the donors group
462
		 *
463
		 * @event skouat.ppde.donors_group_user_add_before
464
		 * @var bool    can_use_autogroup      Whether or not to add the user to the group
465
		 * @var int     group_id               The ID of the group to which the user will be added
466
		 * @var int     payer_id               The ID of the user who will we added to the group
467
		 * @var string  payer_username         The user name
468
		 * @var bool    default_group          Whether or not the group should be made default for the user
469
		 * @var float   payer_donated_amount   The user donated amount
470
		 * @since 1.0.3
471
		 * @changed 2.1.2 Added var $payer_donated_amount
472
		 */
473
		$vars = [
474
			'can_use_autogroup',
475
			'group_id',
476
			'payer_id',
477
			'payer_username',
478
			'default_group',
479
			'payer_donated_amount',
480
		];
481
		extract($this->dispatcher->trigger_event('skouat.ppde.donors_group_user_add_before', compact($vars)));
482
483
		if ($can_use_autogroup)
484
		{
485
			if (!function_exists('group_user_add'))
486
			{
487
				include($this->root_path . 'includes/functions_user.' . $this->php_ext);
488
			}
489
490
			// Adds the user to the donors group and set as default.
491
			group_user_add($group_id, [$payer_id], [$payer_username], get_group_name($group_id), $default_group);
492
		}
493
	}
494
495
	/**
496
	 * Checks if all required settings are meet for adding the donor to the group of donors
497
	 *
498
	 * @return bool
499
	 * @access private
500
	 */
501
	private function can_use_autogroup(): bool
502
	{
503
		return
504
			$this->autogroup_is_enabled() &&
505
			$this->donor_is_member &&
506
			$this->payment_status_is_completed() &&
507
			$this->minimum_donation_raised();
508
	}
509
510
	/**
511
	 * Checks if Autogroup could be used
512
	 *
513
	 * @return bool
514
	 * @access private
515
	 */
516
	private function autogroup_is_enabled(): bool
517
	{
518
		return $this->config['ppde_ipn_enable'] && $this->config['ppde_ipn_autogroup_enable'];
519
	}
520
521
	/**
522
	 * Checks if payment_status is completed
523
	 *
524
	 * @return bool
525
	 * @access public
526
	 */
527
	public function payment_status_is_completed(): bool
528
	{
529
		return $this->transaction_data['payment_status'] === 'Completed';
530
	}
531
532
	/**
533
	 * Checks if member's donation is upper or equal to the minimum defined
534
	 *
535
	 * @return bool
536
	 * @access public
537
	 */
538
	public function minimum_donation_raised(): bool
539
	{
540
		// Updates payer_data info before checking values
541
		$this->check_donors_status('user', $this->payer_data['user_id']);
542
543
		return (float) $this->payer_data['user_ppde_donated_amount'] >= (float) $this->config['ppde_ipn_min_before_group'];
544
	}
545
}
546