Completed
Push — master ( aaa756...6a04f6 )
by Henry
70:00 queued 35:28
created

includes/Controller/Recover.php (1 issue)

Labels
Severity

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
10
/**
11
 * children class to process the recover request
12
 *
13
 * @since 3.0.0
14
 *
15
 * @package Redaxscript
16
 * @category Controller
17
 * @author Henry Ruhs
18
 * @author Balázs Szilágyi
19
 */
20
21
class Recover extends ControllerAbstract
22
{
23
	/**
24
	 * process the class
25
	 *
26
	 * @since 3.0.0
27
	 *
28
	 * @return string
29
	 */
30
31 5
	public function process() : string
32
	{
33 5
		$postArray = $this->_normalizePost($this->_sanitizePost());
34 5
		$validateArray = $this->_validatePost($postArray);
35 5
		$users = $this->_getUsers($postArray);
36
37
		/* validate post */
38
39 5
		if ($validateArray)
40
		{
41 3
			return $this->_error(
42
			[
43 3
				'route' => 'login/recover',
44 3
				'message' => $validateArray
45
			]);
46
		}
47
48
		/* handle mail and validate user */
49
50 2
		$validateArray = [];
51 2
		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...
52
		{
53
			$mailArray =
54
			[
55 2
				'id' => $user->id,
56 2
				'name' => $user->name,
57 2
				'user' => $user->user,
58 2
				'password' => $user->password,
59 2
				'email' => $user->email
60
			];
61 2
			if (!$this->_mail($mailArray))
62
			{
63 1
				return $this->_error(
64
				[
65 1
					'route' => 'login/recover',
66 1
					'message' => $this->_language->get('email_failed')
67
				]);
68
			}
69 1
			$validateArray[] = $user->name . $this->_language->get('colon') . ' ' . $this->_language->get('recovery_sent');
70
		}
71 1
		if ($validateArray)
72
		{
73 1
			return $this->_success(
74
			[
75 1
				'route' => 'login',
76 1
				'timeout' => 2,
77 1
				'message' => $validateArray
78
			]);
79
		}
80
81
		/* handle error */
82
83
		return $this->_error(
84
		[
85
			'route' => 'login/recover'
86
		]);
87
	}
88
89
	/**
90
	 * sanitize the post
91
	 *
92
	 * @since 4.0.0
93
	 *
94
	 * @return array
95
	 */
96
97 5
	protected function _sanitizePost() : array
98
	{
99 5
		$numberFilter = new Filter\Number();
100 5
		$emailFilter = new Filter\Email();
101
102
		/* sanitize post */
103
104
		return
105
		[
106 5
			'email' => $emailFilter->sanitize($this->_request->getPost('email')),
107 5
			'task' => $numberFilter->sanitize($this->_request->getPost('task')),
108 5
			'solution' => $this->_request->getPost('solution')
109
		];
110
	}
111
112
	/**
113
	 * validate the post
114
	 *
115
	 * @since 3.0.0
116
	 *
117
	 * @param array $postArray array of the post
118
	 *
119
	 * @return array
120
	 */
121
122 5
	protected function _validatePost(array $postArray = []) : array
123
	{
124 5
		$emailValidator = new Validator\Email();
125 5
		$captchaValidator = new Validator\Captcha();
126 5
		$userModel = new Model\User();
127 5
		$settingModel = new Model\Setting();
128 5
		$validateArray = [];
129
130
		/* validate post */
131
132 5
		if (!$postArray['email'])
133
		{
134 1
			$validateArray[] = $this->_language->get('email_empty');
135
		}
136 4
		else if (!$emailValidator->validate($postArray['email']))
137
		{
138 1
			$validateArray[] = $this->_language->get('email_incorrect');
139
		}
140 3
		else if (!$userModel->query()->where('email', $postArray['email'])->findOne()->id)
141
		{
142 1
			$validateArray[] = $this->_language->get('email_unknown');
143
		}
144 5
		if ($settingModel->get('captcha') > 0 && !$captchaValidator->validate($postArray['task'], $postArray['solution']))
145
		{
146 1
			$validateArray[] = $this->_language->get('captcha_incorrect');
147
		}
148 5
		return $validateArray;
149
	}
150
151
	/**
152
	 * get the users
153
	 *
154
	 * @since 4.0.0
155
	 *
156
	 * @param array $postArray array of the post
157
	 *
158
	 * @return object|null
159
	 */
160
161 5
	protected function _getUsers(array $postArray = []) : ?object
162
	{
163 5
		$userModel = new Model\User();
164
		return $userModel
165 5
			->query()
166 5
			->where(
167
			[
168 5
				'email' => $postArray['email'],
169 5
				'status' => 1
170
			])
171 5
			->findMany() ? : null;
172
	}
173
174
	/**
175
	 * send the mail
176
	 *
177
	 * @since 3.0.0
178
	 *
179
	 * @param array $mailArray array of the mail
180
	 *
181
	 * @return bool
182
	 */
183
184 1
	protected function _mail(array $mailArray = []) : bool
185
	{
186 1
		$settingModel = new Model\Setting();
187 1
		$urlReset = $this->_registry->get('root') . '/' . $this->_registry->get('parameterRoute') . 'login/reset/' . sha1($mailArray['password']) . '/' . $mailArray['id'];
188
189
		/* html element */
190
191 1
		$linkElement = new Html\Element();
192
		$linkElement
193 1
			->init('a',
194
			[
195 1
				'href' => $urlReset
196
			])
197 1
			->text($urlReset);
198
199
		/* prepare mail */
200
201
		$toArray =
202
		[
203 1
			$mailArray['name'] => $mailArray['email']
204
		];
205
		$fromArray =
206
		[
207 1
			$settingModel->get('author') => $settingModel->get('email')
208
		];
209 1
		$subject = $this->_language->get('recovery');
210
		$bodyArray =
211
		[
212 1
			$this->_language->get('user') . $this->_language->get('colon') . ' ' . $mailArray['user'],
213 1
			'<br />',
214 1
			$this->_language->get('password_reset') . $this->_language->get('colon') . ' ' . $linkElement
215
		];
216
217
		/* send mail */
218
219 1
		$mailer = new Mailer();
220 1
		$mailer->init($toArray, $fromArray, $subject, $bodyArray);
221 1
		return $mailer->send();
222
	}
223
}
224