Completed
Push — master ( 1da492...320203 )
by Henry
07:00
created

includes/Controller/Recover.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
namespace Redaxscript\Controller;
3
4
use Redaxscript\Filter;
5
use Redaxscript\Html;
6
use Redaxscript\Mailer;
7
use Redaxscript\Model;
8
use Redaxscript\Validator;
9
use function sha1;
10
11
/**
12
 * children class to process the recover request
13
 *
14
 * @since 3.0.0
15
 *
16
 * @package Redaxscript
17
 * @category Controller
18
 * @author Henry Ruhs
19
 * @author Balázs Szilágyi
20
 */
21
22
class Recover extends ControllerAbstract
23
{
24
	/**
25
	 * process the class
26
	 *
27
	 * @since 3.0.0
28
	 *
29
	 * @return string
30
	 */
31
32
	public function process() : string
33
	{
34
		$postArray = $this->_normalizePost($this->_sanitizePost());
35
		$validateArray = $this->_validatePost($postArray);
36
		$users = $this->_getUsers($postArray);
37
38
		/* validate post */
39
40
		if ($validateArray)
41
		{
42
			return $this->_error(
43
			[
44
				'route' => 'login/recover',
45
				'message' => $validateArray
46
			]);
47
		}
48
49
		/* handle mail and validate user */
50
51
		$validateArray = [];
52
		foreach ($users as $user)
0 ignored issues
show
The expression $users of type array|object<IdiormResultSet>|null is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
53
		{
54
			$mailArray =
55
			[
56
				'id' => $user->id,
57
				'name' => $user->name,
58
				'user' => $user->user,
59
				'password' => $user->password,
60
				'email' => $user->email
61
			];
62
			if (!$this->_mail($mailArray))
63
			{
64
				return $this->_error(
65
				[
66
					'route' => 'login/recover',
67
					'message' => $this->_language->get('email_failed')
68
				]);
69
			}
70
			$validateArray[] = $user->name . $this->_language->get('colon') . ' ' . $this->_language->get('recovery_sent');
71
		}
72
		if ($validateArray)
73
		{
74
			return $this->_success(
75
			[
76
				'route' => 'login',
77
				'timeout' => 2,
78
				'message' => $validateArray
79
			]);
80
		}
81
82
		/* handle error */
83
84
		return $this->_error(
85
		[
86
			'route' => 'login/recover'
87
		]);
88
	}
89
90
	/**
91
	 * sanitize the post
92
	 *
93
	 * @since 4.0.0
94
	 *
95
	 * @return array
96
	 */
97
98
	protected function _sanitizePost() : array
99
	{
100
		$numberFilter = new Filter\Number();
101
		$emailFilter = new Filter\Email();
102
103
		/* sanitize post */
104
105
		return
106
		[
107
			'email' => $emailFilter->sanitize($this->_request->getPost('email')),
108
			'task' => $numberFilter->sanitize($this->_request->getPost('task')),
109
			'solution' => $this->_request->getPost('solution')
110
		];
111
	}
112
113
	/**
114
	 * validate the post
115
	 *
116
	 * @since 3.0.0
117
	 *
118
	 * @param array $postArray array of the post
119
	 *
120
	 * @return array
121
	 */
122
123
	protected function _validatePost(array $postArray = []) : array
124
	{
125
		$emailValidator = new Validator\Email();
126
		$captchaValidator = new Validator\Captcha();
127
		$userModel = new Model\User();
128
		$settingModel = new Model\Setting();
129
		$validateArray = [];
130
131
		/* validate post */
132
133
		if (!$postArray['email'])
134
		{
135
			$validateArray[] = $this->_language->get('email_empty');
136
		}
137
		else if (!$emailValidator->validate($postArray['email']))
138
		{
139
			$validateArray[] = $this->_language->get('email_incorrect');
140
		}
141
		else if (!$userModel->query()->where('email', $postArray['email'])->findOne()->id)
142
		{
143
			$validateArray[] = $this->_language->get('email_unknown');
144
		}
145
		if ($settingModel->get('captcha') > 0 && !$captchaValidator->validate($postArray['task'], $postArray['solution']))
146
		{
147
			$validateArray[] = $this->_language->get('captcha_incorrect');
148
		}
149
		return $validateArray;
150
	}
151
152
	/**
153
	 * get the users
154
	 *
155
	 * @since 4.0.0
156
	 *
157
	 * @param array $postArray array of the post
158
	 *
159
	 * @return object|null
160
	 */
161
162
	protected function _getUsers(array $postArray = []) : ?object
163
	{
164
		$userModel = new Model\User();
165
		return $userModel
166
			->query()
167
			->where(
168
			[
169
				'email' => $postArray['email'],
170
				'status' => 1
171
			])
172
			->findMany() ? : null;
173
	}
174
175
	/**
176
	 * send the mail
177
	 *
178
	 * @since 3.0.0
179
	 *
180
	 * @param array $mailArray array of the mail
181
	 *
182
	 * @return bool
183
	 */
184
185
	protected function _mail(array $mailArray = []) : bool
186
	{
187
		$settingModel = new Model\Setting();
188
		$urlReset = $this->_registry->get('root') . '/' . $this->_registry->get('parameterRoute') . 'login/reset/' . sha1($mailArray['password']) . '/' . $mailArray['id'];
189
190
		/* html element */
191
192
		$linkElement = new Html\Element();
193
		$linkElement
194
			->init('a',
195
			[
196
				'href' => $urlReset
197
			])
198
			->text($urlReset);
199
200
		/* prepare mail */
201
202
		$toArray =
203
		[
204
			$mailArray['name'] => $mailArray['email']
205
		];
206
		$fromArray =
207
		[
208
			$settingModel->get('author') => $settingModel->get('email')
209
		];
210
		$subject = $this->_language->get('recovery');
211
		$bodyArray =
212
		[
213
			$this->_language->get('user') . $this->_language->get('colon') . ' ' . $mailArray['user'],
214
			'<br />',
215
			$this->_language->get('password_reset') . $this->_language->get('colon') . ' ' . $linkElement
216
		];
217
218
		/* send mail */
219
220
		$mailer = new Mailer();
221
		$mailer->init($toArray, $fromArray, $subject, $bodyArray);
222
		return $mailer->send();
223
	}
224
}
225