Passed
Push — develop-3.3.x ( 26c82c...08c99e )
by Mario
05:09 queued 02:39
created

transaction_validator_helper::validate_time()   B

Complexity

Conditions 7
Paths 5

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 8
nc 5
nop 1
dl 0
loc 15
rs 8.8333
c 0
b 0
f 0
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\helpers;
12
13
use phpbb\language\language;
14
use phpbb\request\request;
15
use phpbb\user;
16
use phpbb\user_loader;
17
use skouat\ppde\exception\transaction_exception;
18
19
class transaction_validator_helper
20
{
21
	/** @var language */
22
	protected $language;
23
24
	/** @var user */
25
	protected $user;
26
27
	/** @var user_loader */
28
	protected $user_loader;
29
30
	/** @var request */
31
	protected $request;
32
33
	/**
34
	 * Constructor
35
	 *
36
	 * @param language    $language
37
	 * @param request     $request
38
	 * @param user        $user
39
	 * @param user_loader $user_loader
40
	 */
41
	public function __construct(language $language, request $request, user $user, user_loader $user_loader)
42
	{
43
		$this->language = $language;
44
		$this->request = $request;
45
		$this->user = $user;
46
		$this->user_loader = $user_loader;
47
	}
48
49
	/**
50
	 * Validate and return the user ID
51
	 *
52
	 * @param string $username
53
	 * @param int    $donor_id
54
	 * @return int
55
	 * @throws transaction_exception
56
	 */
57
	public function validate_user_id(string $username, int $donor_id = 0): int
58
	{
59
		if (empty($username) && ($donor_id === ANONYMOUS || $this->request->is_set('u')))
60
		{
61
			return ANONYMOUS;
62
		}
63
64
		$user_id = ($username !== '') ? $this->user_loader->load_user_by_username($username) : $donor_id;
65
66
		if ($user_id <= ANONYMOUS)
67
		{
68
			throw new transaction_exception([$this->language->lang('PPDE_MT_DONOR_NOT_FOUND')]);
69
		}
70
71
		return $user_id;
72
	}
73
74
	/**
75
	 * Validate payment date and time
76
	 *
77
	 * @param array $transaction_data
78
	 * @return int
79
	 * @throws transaction_exception
80
	 */
81
	public function validate_payment_date_time(array $transaction_data): int
82
	{
83
		$payment_date = implode('-', [
84
			$transaction_data['MT_PAYMENT_DATE_YEAR'],
85
			$transaction_data['MT_PAYMENT_DATE_MONTH'],
86
			$transaction_data['MT_PAYMENT_DATE_DAY'],
87
		]);
88
89
		$payment_time = $transaction_data['MT_PAYMENT_TIME'];
90
		$date_time_string = $payment_date . ' ' . $payment_time;
91
92
		$payment_date_time = $this->parse_date_time($date_time_string);
93
94
		if ($payment_date_time === false)
95
		{
96
			throw new transaction_exception([$this->language->lang('PPDE_MT_PAYMENT_DATE_ERROR', $date_time_string)]);
97
		}
98
99
		if ($payment_date_time > time())
100
		{
101
			throw new transaction_exception([$this->language->lang('PPDE_MT_PAYMENT_DATE_FUTURE', $this->user->format_date($payment_date_time))]);
102
		}
103
104
		$this->validate_time($payment_time);
105
106
		return $payment_date_time;
107
	}
108
109
	/**
110
	 * Parse date and time string
111
	 *
112
	 * @param string $date_time_string
113
	 * @return int|false
114
	 */
115
	private function parse_date_time($date_time_string)
116
	{
117
		$formats = ['Y-m-d H:i:s', 'Y-m-d G:i', 'Y-m-d h:i:s a', 'Y-m-d g:i A'];
118
119
		foreach ($formats as $format)
120
		{
121
			$parsed = \DateTime::createFromFormat($format, $date_time_string);
122
			if ($parsed !== false)
123
			{
124
				return $parsed->getTimestamp();
125
			}
126
		}
127
128
		return false;
129
	}
130
131
	/**
132
	 * Validate time format
133
	 *
134
	 * @param string $payment_time
135
	 * @throws transaction_exception
136
	 */
137
	private function validate_time(string $payment_time): void
138
	{
139
		$time_parts = explode(':', $payment_time);
140
		if (count($time_parts) < 2 || count($time_parts) > 3)
141
		{
142
			throw new transaction_exception([$this->language->lang('PPDE_MT_PAYMENT_TIME_ERROR', $payment_time)]);
143
		}
144
145
		$hours = (int) $time_parts[0];
146
		$minutes = (int) $time_parts[1];
147
		$seconds = isset($time_parts[2]) ? (int) $time_parts[2] : 0;
148
149
		if ($hours >= 24 || $minutes >= 60 || $seconds >= 60)
150
		{
151
			throw new transaction_exception([$this->language->lang('PPDE_MT_PAYMENT_TIME_ERROR', $payment_time)]);
152
		}
153
	}
154
155
	/**
156
	 * Validate transaction amounts
157
	 *
158
	 * @param array $transaction_data
159
	 * @throws transaction_exception
160
	 */
161
	public function validate_transaction_amounts(array $transaction_data): void
162
	{
163
		$errors = [];
164
165
		if ($transaction_data['MT_MC_GROSS'] <= 0)
166
		{
167
			$errors[] = $this->language->lang('PPDE_MT_MC_GROSS_TOO_LOW');
168
		}
169
170
		if ($transaction_data['MT_MC_FEE'] < 0)
171
		{
172
			$errors[] = $this->language->lang('PPDE_MT_MC_FEE_NEGATIVE');
173
		}
174
175
		if ($transaction_data['MT_MC_FEE'] >= $transaction_data['MT_MC_GROSS'])
176
		{
177
			$errors[] = $this->language->lang('PPDE_MT_MC_FEE_TOO_HIGH');
178
		}
179
180
		if (!empty($errors))
181
		{
182
			throw new transaction_exception($errors);
183
		}
184
	}
185
}
186