RApiPaymentHelper   F
last analyzed

Complexity

Total Complexity 151

Size/Duplication

Total Lines 1234
Duplicated Lines 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
wmc 151
eloc 495
c 3
b 0
f 0
dl 0
loc 1234
rs 2

23 Methods

Rating   Name   Duplication   Size   Complexity  
A isInstantCapture() 0 11 3
A refundPayment() 0 13 2
A getExtensionHelperObject() 0 32 5
C updatePaymentData() 0 59 13
B generatePaymentLog() 0 21 7
A getPaymentParams() 0 46 2
A saveNewPaymentLog() 0 31 6
A deletePayment() 0 13 2
A triggerExtensionHelperMethod() 0 24 3
A listPayments() 0 31 3
F getChartData() 0 175 23
C logToFile() 0 90 12
A getLastPaymentLog() 0 13 1
A getPaymentByExtensionId() 0 31 6
C prepareChartData() 0 88 14
A updatePaymentCounter() 0 6 1
A getPaymentById() 0 28 5
A capturePayment() 0 20 3
D updatePaymentStatus() 0 120 24
A checkPayment() 0 11 2
A createNewPayment() 0 8 1
F getChartDataQuery() 0 67 12
A displayPayment() 0 8 1

How to fix   Complexity   

Complex Class

Complex classes like RApiPaymentHelper often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use RApiPaymentHelper, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * @package     Redcore
4
 * @subpackage  Api
5
 *
6
 * @copyright   Copyright (C) 2008 - 2021 redWEB.dk. All rights reserved.
7
 * @license     GNU General Public License version 2 or later, see LICENSE.
8
 */
9
10
defined('JPATH_BASE') or die;
11
12
use Joomla\Utilities\ArrayHelper;
0 ignored issues
show
Bug introduced by
The type Joomla\Utilities\ArrayHelper was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
13
14
/**
15
 * Helper class for Payment calls
16
 *
17
 * @package     Redcore
18
 * @subpackage  Api
19
 * @since       1.5
20
 */
21
class RApiPaymentHelper
22
{
23
	/**
24
	 * Payments container
25
	 * @var array
26
	 */
27
	protected static $payments = array();
28
29
	/**
30
	 * Extension payments container
31
	 * @var array
32
	 */
33
	protected static $extensionPayments = array();
34
35
	/**
36
	 * Plugin parameters container
37
	 * @var array
38
	 */
39
	protected static $pluginParams = array();
40
41
	/**
42
	 * Extension helper classes container
43
	 * @var array
44
	 */
45
	protected static $extensionHelperClasses = array();
46
47
	/**
48
	 * Gets Payment parameters
49
	 * If owner name config is not found it will use extension config, and if extension config is not found it will use default plugin config
50
	 *
51
	 * @param   string  $paymentName    Payment Name
52
	 * @param   string  $extensionName  Extension Name
53
	 * @param   string  $ownerName      Owner Name
54
	 *
55
	 * @return  object
56
	 */
57
	public static function getPaymentParams($paymentName = '', $extensionName = '', $ownerName = '')
58
	{
59
		if (isset(self::$pluginParams[$paymentName][$extensionName][$ownerName]))
60
		{
61
			return self::$pluginParams[$paymentName][$extensionName][$ownerName];
62
		}
63
64
		// This query will make a fallback
65
		// If owner name config is not found it will use extension config, and if extension config is not found it will use default plugin config
66
		$db = JFactory::getDbo();
0 ignored issues
show
Bug introduced by
The type JFactory was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
67
		$query = $db->getQuery(true)
68
			->select('pc1.*, p.*, COALESCE(pc2.params, COALESCE(pc1.params, p.params)) as params, COALESCE(pc2.state, COALESCE(pc1.state, p.state)) as state')
69
			->select('CONCAT("plg_redpayment_", p.element) as plugin_path_name')
70
			->select('COALESCE(pc2.extension_name, COALESCE(pc1.extension_name, ' . $db->q('') . ')) as extension_name')
71
			->select('COALESCE(pc2.owner_name, COALESCE(pc1.owner_name, ' . $db->q('') . ')) as owner_name')
72
			->select('COALESCE(pc2.state, COALESCE(pc1.state, p.enabled)) as state')
73
			->select('p.params AS original_params')
74
			->from($db->qn('#__extensions', 'p'))
75
			->where($db->qn('p.type') . '= ' . $db->q('plugin'))
76
			->where($db->qn('p.folder') . '= ' . $db->q('redpayment'))
77
			->where($db->qn('p.element') . ' = ' . $db->q($paymentName))
78
			->leftJoin(
79
				$db->qn('#__redcore_payment_configuration', 'pc1') . ' ON pc1.payment_name = p.element AND pc1.extension_name = ' . $db->q($extensionName)
80
				. ' AND pc1.owner_name = ' . $db->q('')
81
			)
82
			->leftJoin(
83
				$db->qn('#__redcore_payment_configuration', 'pc2') . ' ON pc2.payment_name = p.element AND pc2.extension_name = ' . $db->q($extensionName)
84
				. ' AND pc2.owner_name = ' . $db->q($ownerName)
85
			);
86
87
		$db->setQuery($query);
88
		$item = $db->loadObject();
89
90
		$registry = new Joomla\Registry\Registry;
0 ignored issues
show
Bug introduced by
The type Joomla\Registry\Registry was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
91
		$registry->loadString($item->original_params);
92
		$item->original_params = $registry;
93
		$originalParams = clone $registry;
94
95
		$registry = new Joomla\Registry\Registry;
96
		$registry->loadString($item->params);
97
		$originalParams->merge($registry);
98
		$item->params = $originalParams;
99
100
		self::$pluginParams[$paymentName][$extensionName][$ownerName] = $item;
101
102
		return self::$pluginParams[$paymentName][$extensionName][$ownerName];
103
	}
104
105
	/**
106
	 * Gets Payment data
107
	 *
108
	 * @param   int  $paymentId  Payment Id
109
	 *
110
	 * @return  object
111
	 */
112
	public static function getPaymentById($paymentId)
113
	{
114
		if (empty($paymentId))
115
		{
116
			return null;
117
		}
118
119
		if (isset(self::$payments[$paymentId]))
120
		{
121
			return self::$payments[$paymentId];
122
		}
123
124
		$db = JFactory::getDbo();
125
126
		$query = $db->getQuery(true)
127
			->select('p.*')
128
			->from($db->qn('#__redcore_payments', 'p'))
129
			->where('p.id = ' . (int) $paymentId);
130
		$db->setQuery($query);
131
		$item = $db->loadObject();
132
		self::$payments[$paymentId] = $item;
133
134
		if ($item && !empty($item->extension_name))
135
		{
136
			self::$extensionPayments[$item->extension_name][$item->order_id] = $paymentId;
137
		}
138
139
		return self::$payments[$paymentId];
140
	}
141
142
	/**
143
	 * Gets Payment data
144
	 *
145
	 * @param   string  $extensionName  Extension name (ex: com_content)
146
	 * @param   string  $orderId        Extension order Id
147
	 *
148
	 * @return  object
149
	 */
150
	public static function getPaymentByExtensionId($extensionName, $orderId)
151
	{
152
		if (empty($extensionName) || empty($orderId))
153
		{
154
			return null;
155
		}
156
157
		if (isset(self::$extensionPayments[$extensionName][$orderId]))
158
		{
159
			return self::getPaymentById(self::$extensionPayments[$extensionName][$orderId]);
160
		}
161
162
		$db = JFactory::getDbo();
163
164
		$query = $db->getQuery(true)
165
			->select('p.*')
166
			->from($db->qn('#__redcore_payments', 'p'))
167
			->where('p.order_id = ' . $db->q($orderId))
168
			->where('p.extension_name = ' . $db->q($extensionName));
169
		$db->setQuery($query);
170
		$payment = $db->loadObject();
171
172
		if ($payment && $payment->id)
173
		{
174
			self::$payments[$payment->id] = $payment;
175
			self::$extensionPayments[$extensionName][$orderId] = $payment->id;
176
177
			return self::getPaymentById(self::$extensionPayments[$extensionName][$orderId]);
178
		}
179
180
		return null;
181
	}
182
183
	/**
184
	 * Prepare Payment data for chart
185
	 *
186
	 * @param   array   $data       Data used for chart definition
187
	 * @param   string  $chartType  Chart types: Line, Bar, Radar, PolarArea, Pie, Doughnut
188
	 *
189
	 * @return  string
190
	 *
191
	 * @since   1.5
192
	 */
193
	public static function prepareChartData($data, $chartType = 'Line')
194
	{
195
		$chartType = RHtmlRchart::getChartType($chartType);
196
		$chartData = array();
197
		$amounts = $data['amounts'];
198
		$labels  = $data['labels'];
199
200
		switch ($chartType)
201
		{
202
			case 'PolarArea':
203
			case 'Pie':
204
			case 'Doughnut':
205
206
				foreach ($amounts as $extensionName => $amount)
207
				{
208
					$dataValues = 0;
209
					$color = implode(',', RHtmlRchart::getColorFromHash($extensionName));
210
					$strokeColor = implode(',', RHtmlRchart::getColorFromHash($extensionName, 'redcore'));
211
212
					foreach ($amount as $value)
213
					{
214
						$dataValues += $value['sum'];
215
					}
216
217
					$dataSet = new stdClass;
218
					$dataSet->value = $dataValues;
219
					$dataSet->color = 'rgba(' . $color . ',0.5)';
220
					$dataSet->highlight = 'rgba(' . $strokeColor . ',1)';
221
					$dataSet->label = $extensionName;
222
223
					$chartData[] = $dataSet;
224
				}
225
226
				break;
227
228
			case 'Line':
229
			case 'Radar':
230
			case 'Bar':
231
			default:
232
				$chartData['labels'] = $labels;
233
				$chartData['datasets'] = array();
234
235
				if (empty($amounts))
236
				{
237
					// Needed for proper chart display
238
					$chartData['datasets'] = array(array());
239
				}
240
				else
241
				{
242
					foreach ($amounts as $extensionName => $amount)
243
					{
244
						$dataValues = array();
245
						$color = implode(',', RHtmlRchart::getColorFromHash($extensionName));
246
						$strokeColor = implode(',', RHtmlRchart::getColorFromHash($extensionName, 'redcore'));
247
248
						foreach ($chartData['labels'] as $label)
249
						{
250
							$dataValues[] = !isset($amount[$label]) ? 0 : $amount[$label];
251
						}
252
253
						$dataSet = array(
254
							'label' => $extensionName,
255
							'fillColor' => 'rgba(' . $color . ',0.2)',
256
							'strokeColor' => 'rgba(' . $strokeColor . ',1)',
257
							'data' => $dataValues,
258
						);
259
260
						if ($chartType == 'Bar')
261
						{
262
							$dataSet['highlightFill'] = 'rgba(' . $color . ',0.75)';
263
							$dataSet['highlightStroke'] = 'rgba(' . $color . ',1)';
264
						}
265
						else
266
						{
267
							$dataSet['pointColor'] = 'rgba(' . $color . ',1)';
268
							$dataSet['pointStrokeColor'] = '#fff';
269
							$dataSet['pointHighlightFill'] = '#fff';
270
							$dataSet['pointHighlightStroke'] = 'rgba(' . $color . ',1)';
271
						}
272
273
						$chartData['datasets'][] = $dataSet;
274
					}
275
				}
276
277
				break;
278
		}
279
280
		return $chartData;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $chartData returns the type array|stdClass[] which is incompatible with the documented return type string.
Loading history...
281
	}
282
283
	/**
284
	 * Prepare Payment data for chart
285
	 *
286
	 * @param   array   $filters   Filters for chart data
287
	 * @param   int     $interval  Chart interval points
288
	 * @param   string  $sortItem  On which field should it sort the values
289
	 *
290
	 * @return  mixed
291
	 *
292
	 * @since   1.5
293
	 */
294
	public static function getChartData($filters = array(), $interval = 7, $sortItem = 'all')
295
	{
296
		$db = JFactory::getDbo();
297
298
		$db->setQuery(self::getChartDataQuery($filters));
299
		$data = $db->loadObjectList();
300
		$chartData = array();
301
		$chartData['amounts'] = array();
302
		$chartData['labels'] = array();
303
		$chartData['currency'] = 'USD';
304
305
		// Is status is not set then we are in the statuses view graph and we are not looking only confirmed payments
306
		$dateField = !isset($filters['status']) ? 'created_date' : 'confirmed_date';
307
308
		if (empty($filters['start_date']))
309
		{
310
			if (!empty($filters['end_date']))
311
			{
312
				$startDate = date('Y-m-d', strtotime($filters['end_date'] . ' -7 weeks'));
313
			}
314
			else
315
			{
316
				$startDate = date('Y-m-d', strtotime('today -7 weeks'));
317
			}
318
		}
319
		else
320
		{
321
			$startDate = $filters['start_date'];
322
		}
323
324
		if (empty($filters['end_date']))
325
		{
326
			$endDate = date('Y-m-d', strtotime($startDate . ' +7 weeks'));
327
		}
328
		else
329
		{
330
			$endDate = $filters['end_date'];
331
		}
332
333
		$startDateNumber = strtotime($startDate);
334
		$endDateNumber = strtotime($endDate);
335
		$checkPoints = array();
336
		$chartData['days'] = round(($endDateNumber - $startDateNumber) / 86400);
337
		$point = round($chartData['days'] / $interval);
338
339
		for ($i = $interval; $i >= 1; $i--)
340
		{
341
			$startDateNumber = strtotime($endDate . ' -' . ($i * $point) . ' days');
342
			$endDateNumber = strtotime($endDate . ' -' . (($i - 1) * $point) . ' days');
343
344
			$startDatelabel = date('Y-m-d', $startDateNumber);
345
			$endDateLabel = date('Y-m-d', $endDateNumber);
346
			$chartData['labels'][] = $startDatelabel;
347
348
			$checkPoints[] = array(
349
				'startDate' => $startDatelabel,
350
				'endDate' => $endDateLabel,
351
			);
352
		}
353
354
		foreach ($data as $key => $item)
355
		{
356
			$sortName = $sortItem == 'all' ? 'all' : $item->{$sortItem};
357
358
			if (!isset($chartData['amounts'][$sortName]))
359
			{
360
				$chartData['amounts'][$sortName] = array();
361
			}
362
363
			$createdDate = explode('-', $item->{$dateField});
364
			$itemYear = $createdDate[0];
365
			$itemMonth = $createdDate[1];
366
			$itemDay = explode(' ', $createdDate[2]);
367
			$itemDay = $itemDay[0];
368
369
			if (!isset($chartData['amounts'][$sortName]['sum'][$itemYear]['val'][$itemMonth]['val'][$itemDay]))
370
			{
371
				$chartData['amounts'][$sortName]['sum'][$itemYear]['sum'] = 0;
372
				$chartData['amounts'][$sortName]['sum'][$itemYear]['count'] = 0;
373
				$chartData['amounts'][$sortName]['sum'][$itemYear]['val'][$itemMonth]['sum'] = 0;
374
				$chartData['amounts'][$sortName]['sum'][$itemYear]['val'][$itemMonth]['count'] = 0;
375
				$chartData['amounts'][$sortName]['sum'][$itemYear]['val'][$itemMonth]['val'][$itemDay]['sum'] = 0;
376
				$chartData['amounts'][$sortName]['sum'][$itemYear]['val'][$itemMonth]['val'][$itemDay]['count'] = 0;
377
				$chartData['amounts'][$sortName]['sum'][$itemYear]['val'][$itemMonth]['val'][$itemDay]['val'] = array();
378
			}
379
380
			$chartData['amounts'][$sortName]['sum'][$itemYear]['val'][$itemMonth]['val'][$itemDay]['val'][] = $item->amount_paid;
381
			$chartData['currency'] = $item->currency;
382
383
			foreach ($checkPoints as $checkPoint)
384
			{
385
				if ($item->{$dateField} > $checkPoint['startDate'] && $item->{$dateField} < $checkPoint['endDate'])
386
				{
387
					if (!isset($chartData['amounts'][$sortName][$checkPoint['startDate']]))
388
					{
389
						$chartData['amounts'][$sortName][$checkPoint['startDate']] = 0;
390
					}
391
392
					$chartData['amounts'][$sortName][$checkPoint['startDate']] += $item->amount_paid;
393
				}
394
			}
395
396
			unset($data[$key]);
397
		}
398
399
		$currentYear = date('Y');
400
401
		foreach ($chartData['amounts'] as $extensionName => $options)
402
		{
403
			$sum = 0;
404
			$count = 0;
405
			$maxCount = 0;
406
			$maxSum = 0;
407
408
			foreach ($options['sum'] as $year => $months)
409
			{
410
				foreach ($months['val'] as $month => $days)
411
				{
412
					foreach ($days['val'] as $day => $values)
413
					{
414
						$daySum = array_sum($values['val']);
415
						$dayCount = count($values['val']);
416
						$chartData['amounts'][$extensionName]['sum'][$year]['sum'] += $daySum;
417
						$chartData['amounts'][$extensionName]['sum'][$year]['count'] += $dayCount;
418
						$chartData['amounts'][$extensionName]['sum'][$year]['val'][$month]['sum'] += $daySum;
419
						$chartData['amounts'][$extensionName]['sum'][$year]['val'][$month]['count'] += $dayCount;
420
						$chartData['amounts'][$extensionName]['sum'][$year]['val'][$month]['val'][$day]['sum'] += $daySum;
421
						$chartData['amounts'][$extensionName]['sum'][$year]['val'][$month]['val'][$day]['count'] = $dayCount;
422
						$chartData['amounts'][$extensionName]['sum'][$year]['val'][$month]['val'][$day]['average'] = round($daySum / $dayCount, 2);
423
						$sum += $daySum;
424
						$count += $dayCount;
425
426
						if ($maxCount < $dayCount)
427
						{
428
							$maxCount = $dayCount;
429
						}
430
431
						if ($maxSum < $daySum)
432
						{
433
							$maxSum = $daySum;
434
						}
435
					}
436
437
					$daysInMonth = date('t', strtotime($year . '-' . $month . '-01'));
438
					$chartData['amounts'][$extensionName]['sum'][$year]['val'][$month]['averageCount']
439
									= round($chartData['amounts'][$extensionName]['sum'][$year]['val'][$month]['count'] / $daysInMonth, 2);
440
					$chartData['amounts'][$extensionName]['sum'][$year]['val'][$month]['averageSum']
441
									= round($chartData['amounts'][$extensionName]['sum'][$year]['val'][$month]['sum'] / $daysInMonth, 2);
442
				}
443
444
				// If this is current year then it is not over yet we need to get only up to current date
445
				if ($currentYear == $year)
446
				{
447
					$daysInYear = round((strtotime(date('Y-m-d')) - strtotime($year . '-01-01')) / 86400);
448
				}
449
				else
450
				{
451
					$daysInYear = date('z', strtotime($year . '-12-31')) + 1;
452
				}
453
454
				$chartData['amounts'][$extensionName]['sum'][$year]['averageCount']
455
								= round($chartData['amounts'][$extensionName]['sum'][$year]['count'] / $daysInYear, 2);
456
				$chartData['amounts'][$extensionName]['sum'][$year]['averageSum']
457
								= round($chartData['amounts'][$extensionName]['sum'][$year]['sum'] / $daysInYear, 2);
458
			}
459
460
			$chartData['amounts'][$extensionName]['sum']['sum'] = $sum;
461
			$chartData['amounts'][$extensionName]['sum']['count'] = $count;
462
			$chartData['amounts'][$extensionName]['sum']['maxCount'] = $maxCount;
463
			$chartData['amounts'][$extensionName]['sum']['maxSum'] = $maxSum;
464
			$chartData['amounts'][$extensionName]['sum']['averageCount'] = $chartData['days'] > 0 ? round($count / $chartData['days'], 2) : 0;
465
			$chartData['amounts'][$extensionName]['sum']['averageSum'] = $chartData['days'] > 0 ? round($sum / $chartData['days'], 2) : 0;
466
		}
467
468
		return $chartData;
469
	}
470
471
	/**
472
	 * Create Payments query for chart
473
	 *
474
	 * @param   array  $filters  Filters for chart data
475
	 *
476
	 * @return  mixed
477
	 *
478
	 * @since   1.5
479
	 */
480
	public static function getChartDataQuery($filters = array())
481
	{
482
		$db = JFactory::getDbo();
483
484
		$query = $db->getQuery(true)
485
			->select('p.*')
486
			->from($db->qn('#__redcore_payments', 'p'));
487
488
		if (RBootstrap::getConfig('payment_enable_chart_sandbox_payments', 1) == 0)
489
		{
490
			$query->where('p.sandbox = 0');
491
		}
492
493
		// Is status is not set then we are in the statuses view graph and we are not looking only confirmed payments
494
		$dateField = !isset($filters['status']) ? 'created_date' : 'confirmed_date';
495
496
		// Filter search
497
		if (!empty($filters['search_payments']))
498
		{
499
			$search = $db->quote('%' . $db->escape($filters['search_payments'], true) . '%');
500
			$query->where('(p.order_name LIKE ' . $search . ')');
501
		}
502
503
		if (!empty($filters['payment_name']))
504
		{
505
			$paymentName = $db->quote($filters['payment_name']);
506
			$query->where('p.payment_name = ' . $paymentName);
507
		}
508
509
		if (!empty($filters['extension_name']))
510
		{
511
			$extensionName = $db->quote($filters['extension_name']);
512
			$query->where('p.extension_name = ' . $extensionName);
513
		}
514
515
		if (!empty($filters['owner_name']))
516
		{
517
			$ownerName = $db->quote($filters['owner_name']);
518
			$query->where('p.owner_name = ' . $ownerName);
519
		}
520
521
		elseif (!empty($filters['start_date']))
522
		{
523
			$filters['start_date'] = date('Y-m-d H:i:s', strtotime($filters['start_date']));
524
			$startDate = $db->quote($filters['start_date']);
525
			$query->where('p.' . $dateField . ' >= ' . $startDate);
526
		}
527
528
		if (!empty($filters['end_date']))
529
		{
530
			$filters['end_date'] = date('Y-m-d H:i:s', strtotime($filters['end_date']));
531
			$endDate = $db->quote($filters['end_date']);
532
			$query->where('p.' . $dateField . ' <= ' . $endDate);
533
		}
534
535
		if (!empty($filters['status']))
536
		{
537
			$status = $db->quote($filters['status']);
538
			$query->where('p.status = ' . $status);
539
		}
540
541
		// Ordering
542
		$order = !empty($filters['ordering']) ? $filters['ordering'] : 'p.payment_name';
543
		$direction = !empty($filters['direction']) ? $filters['direction'] : 'ASC';
544
		$query->order($db->escape($order) . ' ' . $db->escape($direction));
545
546
		return $query;
547
	}
548
549
	/**
550
	 * Update payment status
551
	 *
552
	 * @param   int  $paymentId     Id of the payment
553
	 * @param   int  $retryCounter  Id of the payment
554
	 *
555
	 * @return  bool
556
	 *
557
	 * @since   1.5
558
	 */
559
	public static function updatePaymentCounter($paymentId, $retryCounter)
560
	{
561
		$paymentOriginal = self::getPaymentById($paymentId);
562
		$paymentOriginal->retry_counter = $retryCounter;
563
564
		return self::updatePaymentData($paymentOriginal);
565
	}
566
567
	/**
568
	 * Update payment status
569
	 *
570
	 * @param   mixed  $paymentData  Payment data
571
	 *
572
	 * @return  bool
573
	 */
574
	public static function updatePaymentData($paymentData)
575
	{
576
		if (is_object($paymentData))
577
		{
578
			$paymentData = ArrayHelper::fromObject($paymentData);
579
		}
580
581
		// If there is no payment Id, we are checking if that payment data is saved under another row
582
		if (empty($paymentData['id']))
583
		{
584
			$oldPayment = self::getPaymentByExtensionId($paymentData['extension_name'], $paymentData['order_id']);
585
586
			// We add all relevant data to the object
587
			if ($oldPayment)
0 ignored issues
show
introduced by
$oldPayment is of type object, thus it always evaluated to true.
Loading history...
588
			{
589
				$paymentData['id'] = $oldPayment->id;
590
			}
591
		}
592
		else
593
		{
594
			$oldPayment = self::getPaymentById($paymentData['id']);
595
		}
596
597
		if ($oldPayment)
0 ignored issues
show
introduced by
$oldPayment is of type object, thus it always evaluated to true.
Loading history...
598
		{
599
			// We are in different payment
600
			if (isset($paymentData['payment_name']) && !empty($oldPayment->payment_name) && $oldPayment->payment_name != $paymentData['payment_name'])
601
			{
602
				// We check for status in old Payment data, if it is confirmed, then this order is already processed and should not be processed again
603
				if (in_array($oldPayment->status, array(RApiPaymentStatus::getStatusCompleted(), RApiPaymentStatus::getStatusCanceled_Reversal())))
604
				{
605
					return false;
606
				}
607
			}
608
		}
609
610
		// Set status to created if not set
611
		if (empty($paymentData['status']))
612
		{
613
			$paymentData['status'] = RApiPaymentStatus::getStatusCreated();
614
		}
615
616
		/** @var RedcoreModelPayment $model */
617
		$model = RModelAdmin::getAdminInstance('Payment', array(), 'com_redcore');
618
619
		if (!$model->save($paymentData))
620
		{
621
			return false;
622
		}
623
624
		$paymentId = (isset($paymentData['id']) ? $paymentData['id'] : (int) $model->getState('payment.id'));
625
626
		if (!empty($paymentData['id']))
627
		{
628
			// We unset the object so we can load a fresh one on next request
629
			unset(self::$payments[$paymentData['id']]);
630
		}
631
632
		return $paymentId;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $paymentId also could return the type integer which is incompatible with the documented return type boolean.
Loading history...
633
	}
634
635
	/**
636
	 * Update payment status
637
	 *
638
	 * @param   int  $paymentId  Id of the payment
639
	 *
640
	 * @return  mixed
641
	 *
642
	 * @since   1.5
643
	 */
644
	public static function updatePaymentStatus($paymentId)
645
	{
646
		if (empty($paymentId))
647
		{
648
			return false;
649
		}
650
651
		$db = JFactory::getDbo();
652
653
		$query = $db->getQuery(true)
654
			->select('pl.*')
655
			->from($db->qn('#__redcore_payment_log', 'pl'))
656
			->where('pl.payment_id = ' . (int) $paymentId)
657
			->order('pl.created_date ASC');
658
659
		$db->setQuery($query);
660
		$paymentLogs = $db->loadObjectList();
661
662
		if ($paymentLogs)
663
		{
664
			$paymentOriginal = self::getPaymentById($paymentId);
665
			$payment = ArrayHelper::fromObject($paymentOriginal);
666
			$customerNote = array();
667
			$amountPaid = 0;
668
			$currency = '';
669
			$status = RApiPaymentStatus::getStatusCreated();
670
671
			foreach ($paymentLogs as $paymentLog)
672
			{
673
				if ($paymentLog->status == RApiPaymentStatus::getStatusCompleted())
674
				{
675
					if (!empty($currency) && $currency != $paymentLog->currency)
676
					{
677
						// We have a problem. Two different confirmed payments but in different currencies.
678
						// We will only set latest payment data
679
						$amountPaid = $paymentLog->amount;
680
						$currency = $paymentLog->currency;
681
					}
682
					else
683
					{
684
						if ($payment['transaction_id'] != $paymentLog->transaction_id || $amountPaid == 0)
685
						{
686
							$amountPaid += $paymentLog->amount;
687
						}
688
689
						if (!empty($paymentLog->currency))
690
						{
691
							$currency = $paymentLog->currency;
692
						}
693
					}
694
695
					$payment['coupon_code'] = $paymentLog->coupon_code;
696
					$payment['confirmed_date'] = $paymentLog->created_date;
697
				}
698
699
				if (!empty($paymentLog->transaction_id))
700
				{
701
					$payment['transaction_id'] = $paymentLog->transaction_id;
702
				}
703
704
				// We will take customer note from every log but not duplicates
705
				if (!empty($paymentLog->customer_note) && !in_array($paymentLog->customer_note, $customerNote))
706
				{
707
					$customerNote[] = $paymentLog->customer_note;
708
				}
709
710
				$status = RApiPaymentStatus::changeStatus($status, $paymentLog->status);
711
712
				// Handle statuses that subtract paid amount
713
				if (in_array($status, array(RApiPaymentStatus::getStatusRefunded(), RApiPaymentStatus::getStatusReversed())))
714
				{
715
					$amountPaid -= $paymentLog->amount;
716
717
					if ($amountPaid < 0)
718
					{
719
						$amountPaid = 0;
720
					}
721
				}
722
			}
723
724
			$payment['amount_paid'] = $amountPaid;
725
			$payment['customer_note'] = implode("\r\n", $customerNote);
726
727
			if ($status == RApiPaymentStatus::getStatusCompleted() && $payment['amount_paid'] != $payment['amount_total'])
728
			{
729
				// If not ePay partial payment capture
730
				if (self::isInstantCapture((object) $payment) || $payment['amount_original'] <= $payment['amount_total'])
731
				{
732
					$status = RApiPaymentStatus::getStatusPending();
733
				}
734
			}
735
736
			$payment['status'] = $status;
737
738
			if (empty($payment['currency']))
739
			{
740
				$payment['currency'] = $currency;
741
			}
742
743
			// Currency should not be numeric
744
			if (!empty($payment['currency']) && is_numeric($payment['currency']))
745
			{
746
				$payment['currency'] = RHelperCurrency::getIsoCode($payment['currency']);
747
			}
748
749
			if (!self::updatePaymentData($payment))
750
			{
751
				return false;
752
			}
753
754
			// If we changed status we need to call extension helper file to trigger its update method
755
			if ($paymentOriginal->status != $payment['status'])
756
			{
757
				$paymentNew = self::getPaymentById($paymentId);
758
759
				self::triggerExtensionHelperMethod($paymentNew->extension_name, 'paymentStatusChanged', $paymentOriginal, $paymentNew);
760
			}
761
		}
762
763
		return true;
764
	}
765
766
	/**
767
	 * Check if ePay is using  instant capture
768
	 *
769
	 * @param   object	$payment	Payment object
770
	 *
771
	 * @return  boolean
772
	 */
773
	public static function isInstantCapture($payment)
774
	{
775
		$plugin 		= RApiPaymentHelper::getPaymentParams($payment->payment_name, $payment->extension_name, $payment->owner_name);
776
		$instantcapture = false;
777
778
		if ($plugin && strcmp($plugin->element, 'epay') === 0)
779
		{
780
			$instantcapture = (boolean) $plugin->params->get('instantcapture', 0);
781
		}
782
783
		return $instantcapture;
784
	}
785
786
	/**
787
	 * Display payment
788
	 *
789
	 * @param   string  $paymentName    Payment name
790
	 * @param   string  $extensionName  Extension name
791
	 * @param   string  $ownerName      Owner name
792
	 * @param   array   $data           Data for the payment form
793
	 *
794
	 * @return  string|false
795
	 *
796
	 * @since   1.5
797
	 */
798
	public static function displayPayment($paymentName, $extensionName, $ownerName = '', $data = array())
799
	{
800
		JPluginHelper::importPlugin('redpayment');
0 ignored issues
show
Bug introduced by
The type JPluginHelper was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
801
		$app = JFactory::getApplication();
802
		$html = '';
803
		$app->triggerEvent('onRedpaymentDisplayPayment', array($paymentName, $extensionName, $ownerName, $data, &$html));
804
805
		return $html;
806
	}
807
808
	/**
809
	 * Create new payment
810
	 *
811
	 * @param   string  $paymentName    Payment name
812
	 * @param   string  $extensionName  Extension name
813
	 * @param   string  $ownerName      Owner name
814
	 * @param   array   $data           Data for the payment form
815
	 *
816
	 * @return  string|false
817
	 *
818
	 * @since   1.5
819
	 */
820
	public static function createNewPayment($paymentName, $extensionName, $ownerName, $data = array())
821
	{
822
		JPluginHelper::importPlugin('redpayment');
823
		$app = JFactory::getApplication();
824
		$paymentId = null;
825
		$app->triggerEvent('onRedpaymentCreatePayment', array($paymentName, $extensionName, $ownerName, $data, &$paymentId));
826
827
		return $paymentId;
828
	}
829
830
	/**
831
	 * List payments
832
	 *
833
	 * @param   string  $extensionName  Extension name
834
	 * @param   string  $ownerName      Owner name
835
	 * @param   string  $listType       List type can be between radio and dropdown (if parameter not set then default redcore plugin option is used)
836
	 * @param   string  $name           Name of the field
837
	 * @param   string  $value          Selected value of the field
838
	 * @param   string  $id             Id of the field
839
	 * @param   string  $attributes     Attributes for the field
840
	 *
841
	 * @return  string|false
842
	 *
843
	 * @since   1.5
844
	 */
845
	public static function listPayments($extensionName = null, $ownerName = null, $listType = null, $name = '', $value = '', $id = '', $attributes = '')
846
	{
847
		JPluginHelper::importPlugin('redpayment');
848
		$app = JFactory::getApplication();
849
850
		if (empty($listType))
851
		{
852
			$listType = RBootstrap::getConfig('payment_list_payments_type', 'radio');
853
		}
854
855
		if (empty($extensionName))
856
		{
857
			$extensionName = $app->input->get->getString('option', '');
858
		}
859
860
		$payments = array();
861
862
		$app->triggerEvent('onRedpaymentListPayments', array($extensionName, $ownerName, &$payments));
863
864
		return RLayoutHelper::render(
865
			'redpayment.list.' . strtolower($listType),
866
			array(
867
				'options' => array(
868
					'payments' => $payments,
869
					'extensionName' => $extensionName,
870
					'ownerName' => $ownerName,
871
					'name' => $name,
872
					'value' => $value,
873
					'id' => $id,
874
					'attributes' => $attributes,
875
					'selectSingleOption' => true,
876
				)
877
			)
878
		);
879
	}
880
881
	/**
882
	 * Check payment status
883
	 *
884
	 * @param   int  $paymentId  Id of the payment
885
	 *
886
	 * @return  array|false
887
	 *
888
	 * @since   1.5
889
	 */
890
	public static function checkPayment($paymentId)
891
	{
892
		JPluginHelper::importPlugin('redpayment');
893
		$status = array();
894
895
		if ($item = self::getPaymentById($paymentId))
896
		{
897
			JFactory::getApplication()->triggerEvent('onRedpaymentCheckPayment', array($item->payment_name, $paymentId, &$status));
898
		}
899
900
		return $status;
901
	}
902
903
	/**
904
	 * Refund payment
905
	 *
906
	 * @param   int  $paymentId  Id of the payment
907
	 *
908
	 * @return  bool
909
	 *
910
	 * @since   1.5
911
	 */
912
	public static function refundPayment($paymentId)
913
	{
914
		JPluginHelper::importPlugin('redpayment');
915
		$isRefunded = null;
916
917
		if ($item = self::getPaymentById($paymentId))
918
		{
919
			JFactory::getApplication()->triggerEvent(
920
				'onRedpaymentRefundPayment', array($item->payment_name, $item->extension_name, $item->owner_name, $item, &$isRefunded)
921
			);
922
		}
923
924
		return $isRefunded;
925
	}
926
927
	/**
928
	 * Capture payment
929
	 *
930
	 * @param   int  $paymentId  Id of the payment
931
	 *
932
	 * @return  bool
933
	 *
934
	 * @since   1.5
935
	 */
936
	public static function capturePayment($paymentId)
937
	{
938
		JPluginHelper::importPlugin('redpayment');
939
		$isCaptured = null;
940
941
		if ($item = self::getPaymentById($paymentId))
942
		{
943
			if ((float) $item->amount_total > (float) $item->amount_original)
944
			{
945
				$item->amount_total = $item->amount_original;
946
			}
947
948
			$item->amount_paid = $item->amount_total;
949
950
			JFactory::getApplication()->triggerEvent(
951
				'onRedpaymentCapturePayment', array($item->payment_name, $item->extension_name, $item->owner_name, $item, &$isCaptured)
952
			);
953
		}
954
955
		return $isCaptured;
956
	}
957
958
	/**
959
	 * Delete payment
960
	 *
961
	 * @param   int  $paymentId  Id of the payment
962
	 *
963
	 * @return  bool
964
	 *
965
	 * @since   1.5
966
	 */
967
	public static function deletePayment($paymentId)
968
	{
969
		JPluginHelper::importPlugin('redpayment');
970
		$isDeleted = null;
971
972
		if ($item = self::getPaymentById($paymentId))
973
		{
974
			JFactory::getApplication()->triggerEvent(
975
				'onRedpaymentDeletePayment', array($item->payment_name, $item->extension_name, $item->owner_name, $item, &$isDeleted)
976
			);
977
		}
978
979
		return $isDeleted;
980
	}
981
982
	/**
983
	 * Logs the relevant data from payment gateway to file
984
	 *
985
	 * @param   string   $paymentName    Payment name
986
	 * @param   string   $extensionName  Extension name
987
	 * @param   mixed    $data           Request data
988
	 * @param   boolean  $isValid        Is Valid payment
989
	 * @param   string   $statusText     Status text
990
	 *
991
	 * @return  void
992
	 */
993
	public static function logToFile($paymentName, $extensionName, $data, $isValid = true, $statusText = '')
994
	{
995
		if (RBootstrap::getConfig('payment_enable_file_logger', 0))
996
		{
997
			return;
998
		}
999
1000
		JLoader::import('joomla.filesystem.file');
0 ignored issues
show
Deprecated Code introduced by
The function JLoader::import() has been deprecated: 4.3 will be removed in 7.0 Classes should be autoloaded. Use JLoader::registerPrefix() or JLoader::registerNamespace() to register an autoloader for your files. ( Ignorable by Annotation )

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

1000
		/** @scrutinizer ignore-deprecated */ JLoader::import('joomla.filesystem.file');

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
1001
		$config = JFactory::getConfig();
1002
		$logpath = $config->get('log_path');
1003
1004
		$logFilename = $logpath . '/redpayment/' . $paymentName . '/' . $extensionName . '/'
1005
			. date('Y-m-') . strtolower($paymentName) . '-' . strtolower($extensionName) . '_log';
1006
		$logFile = $logFilename . '.php';
1007
1008
		if (JFile::exists($logFile))
0 ignored issues
show
Bug introduced by
The type JFile was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
1009
		{
1010
			// If file is over 1MB we break it in new file
1011
			if (@filesize($logFile) > 1048576)
1012
			{
1013
				$i = 1;
1014
1015
				while (true)
1016
				{
1017
					$newFilename = $logFilename . '-' . $i . '.php';
1018
1019
					if (!JFile::exists($newFilename))
1020
					{
1021
						// Copy old file contents to a new location
1022
						JFile::copy($logFile, $newFilename);
1023
						JFile::delete($logFile);
1024
1025
						// We start our logger from start
1026
						$dummy = "<?php die(); ?>\n";
1027
						JFile::write($logFile, $dummy);
1028
1029
						break;
1030
					}
1031
1032
					$i++;
1033
				}
1034
			}
1035
		}
1036
		else
1037
		{
1038
			// New log file in a month
1039
			$dummy = "<?php die(); ?>\n";
1040
			JFile::write($logFile, $dummy);
1041
		}
1042
1043
		// Current file contents
1044
		$logData = @file_get_contents($logFile);
1045
1046
		if ($logData === false)
1047
		{
1048
			$logData = '';
1049
		}
1050
1051
		$logData .= "\n" . str_repeat('=', 20);
1052
		$logData .= $isValid ? ' VALID ' . $paymentName . ' ' : ' INVALID ' . $paymentName . ' *** FRAUD ATTEMPT OR INVALID NOTIFICATION *** ';
1053
		$logData .= str_repeat('=', 20);
1054
1055
		if (!empty($statusText))
1056
		{
1057
			$logData .= "\n" . str_repeat('=', 20);
1058
			$logData .= "\n" . $statusText;
1059
			$logData .= "\n" . str_repeat('=', 20);
1060
		}
1061
1062
		$logData .= "\nDatetime : " . gmdate('Y-m-d H:i:s') . " GMT\n\n";
1063
1064
		if (is_array($data))
1065
		{
1066
			foreach ($data as $key => $value)
1067
			{
1068
				$logData .= str_pad($key, 30, ' ') . $value . "\n";
1069
			}
1070
		}
1071
		elseif (is_object($data))
1072
		{
1073
			$logData .= (json_encode($data)) . "\n";
1074
		}
1075
		else
1076
		{
1077
			$logData .= $data . "\n";
1078
		}
1079
1080
		$logData .= "\n";
1081
1082
		JFile::write($logFile, $logData);
1083
	}
1084
1085
	/**
1086
	 * Generate Payment Log depending on the status
1087
	 *
1088
	 * @param   string        $status   Status string
1089
	 * @param   array|object  $data     Data from gateway
1090
	 * @param   string        $message  Message Text
1091
	 *
1092
	 * @return array
1093
	 */
1094
	public static function generatePaymentLog($status, $data, $message = null)
1095
	{
1096
		if (is_object($data))
1097
		{
1098
			$data = ArrayHelper::fromObject($data);
1099
		}
1100
1101
		$paymentLog = array();
1102
1103
		$paymentLog['payment_id'] = !empty($data['payment_id']) ? $data['payment_id'] : @$data['id'];
1104
		$paymentLog['ip_address'] = $_SERVER['REMOTE_ADDR'];
1105
		$paymentLog['referrer'] = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : null;
1106
		$paymentLog['transaction_id'] = !empty($data['transaction_id']) ? $data['transaction_id'] : '';
1107
		$paymentLog['status'] = RApiPaymentStatus::getStatus($status);
1108
		$paymentLog['message_uri'] = JUri::getInstance()->toString();
0 ignored issues
show
Bug introduced by
The type JUri was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
1109
		$paymentLog['message_post'] = json_encode($data);
1110
		$paymentLog['message_text'] = !is_null($message) ?
1111
			$message : JText::sprintf('LIB_REDCORE_PAYMENT_LOG_DEFAULT_MESSAGE', $data['extension_name'], $data['payment_name']);
0 ignored issues
show
Bug introduced by
The type JText was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
1112
		$paymentLog['coupon_code'] = !empty($data['coupon_code']) ? $data['coupon_code'] : '';
1113
1114
		return $paymentLog;
1115
	}
1116
1117
	/**
1118
	 * Generate Payment Log depending on the status
1119
	 *
1120
	 * @param   array  $paymentLog           Data for payment log storage
1121
	 * @param   bool   $updatePaymentStatus  Update Payment Status
1122
	 *
1123
	 * @return bool
1124
	 */
1125
	public static function saveNewPaymentLog($paymentLog, $updatePaymentStatus = true)
1126
	{
1127
		if (empty($paymentLog['payment_id']))
1128
		{
1129
			return false;
1130
		}
1131
1132
		// Forcing default set of statuses
1133
		$paymentLog['status'] = RApiPaymentStatus::getStatus($paymentLog['status']);
1134
1135
		// Currency should not be numeric
1136
		if (!empty($paymentLog['currency']) && is_numeric($paymentLog['currency']))
1137
		{
1138
			$paymentLog['currency'] = RHelperCurrency::getIsoCode($paymentLog['currency']);
1139
		}
1140
1141
		/** @var RedcoreModelPayment_Log $logModel */
1142
		$logModel = RModelAdmin::getAdminInstance('Payment_Log', array(), 'com_redcore');
1143
1144
		// Avoid ghost id from URL
1145
		$paymentLog['id'] = 0;
1146
1147
		if ($logModel->save($paymentLog))
1148
		{
1149
			if ($updatePaymentStatus)
1150
			{
1151
				self::updatePaymentStatus($paymentLog['payment_id']);
1152
			}
1153
		}
1154
1155
		return true;
1156
	}
1157
1158
	/**
1159
	 * Calls method from extension helper file if exists
1160
	 *
1161
	 * @param   string  $extensionName  Extension name
1162
	 * @param   string  $functionName   Function name
1163
	 *
1164
	 * @return  mixed It will return Extension helper class function result or false if it does not exists
1165
	 */
1166
	public static function triggerExtensionHelperMethod($extensionName, $functionName)
1167
	{
1168
		$apiHelperClass = self::getExtensionHelperObject($extensionName);
1169
		$args = func_get_args();
1170
1171
		// Remove extension and function name from arguments
1172
		array_shift($args);
1173
		array_shift($args);
1174
1175
		// PHP 5.3 workaround
1176
		$temp = array();
1177
1178
		foreach ($args as &$arg)
1179
		{
1180
			$temp[] = &$arg;
1181
		}
1182
1183
		// Checks if that method exists in helper file and executes it
1184
		if (method_exists($apiHelperClass, $functionName))
1185
		{
1186
			return call_user_func_array(array($apiHelperClass, $functionName), $temp);
1187
		}
1188
1189
		return false;
1190
	}
1191
1192
	/**
1193
	 * Gets instance of extension helper object if exists
1194
	 *
1195
	 * @param   string  $extensionName  Extension name
1196
	 *
1197
	 * @return  mixed It will return Extension helper class or false if it does not exists
1198
	 */
1199
	public static function getExtensionHelperObject($extensionName)
1200
	{
1201
		if (!$extensionName)
1202
		{
1203
			return false;
1204
		}
1205
1206
		if (isset(self::$extensionHelperClasses[$extensionName]))
1207
		{
1208
			return self::$extensionHelperClasses[$extensionName];
1209
		}
1210
1211
		// Helper file location to search inside of the extension
1212
		$helperFile = JPath::clean(JPATH_ADMINISTRATOR . '/components/' . strtolower($extensionName) . '/helpers/redpayment/extension_helper.php');
0 ignored issues
show
Bug introduced by
The type JPath was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
1213
1214
		if (file_exists($helperFile))
1215
		{
1216
			require_once $helperFile;
1217
		}
1218
1219
		$helperClassName = 'RApiPaymentExtensionHelper' . ucfirst(strtolower($extensionName));
1220
1221
		if (class_exists($helperClassName))
1222
		{
1223
			self::$extensionHelperClasses[$extensionName] = new $helperClassName;
1224
		}
1225
		else
1226
		{
1227
			self::$extensionHelperClasses[$extensionName] = null;
1228
		}
1229
1230
		return self::$extensionHelperClasses[$extensionName];
1231
	}
1232
1233
	/**
1234
	 * Gets last payment log object
1235
	 *
1236
	 * @param   int  $paymentId  Id of the payment
1237
	 *
1238
	 * @return  object
1239
	 *
1240
	 * @since   1.5
1241
	 */
1242
	public static function getLastPaymentLog($paymentId)
1243
	{
1244
		$db = JFactory::getDbo();
1245
1246
		$query = $db->getQuery(true)
1247
			->select('pl.*')
1248
			->from($db->qn('#__redcore_payment_log', 'pl'))
1249
			->where('pl.payment_id = ' . (int) $paymentId)
1250
			->order('pl.created_date DESC');
1251
1252
		$db->setQuery($query, 0, 1);
1253
1254
		return $db->loadObject();
1255
	}
1256
}
1257