1 | <?php |
||||||||
2 | |||||||||
3 | namespace Shetabit\Captcha\Drivers\Simple; |
||||||||
4 | |||||||||
5 | use Illuminate\Support\Facades\View; |
||||||||
6 | use Illuminate\Support\ServiceProvider; |
||||||||
7 | use Shetabit\Captcha\Abstracts\Driver; |
||||||||
8 | |||||||||
9 | class SimpleDriver extends Driver |
||||||||
10 | { |
||||||||
11 | protected $serviceProvider; |
||||||||
12 | |||||||||
13 | /** |
||||||||
14 | * Driver settings. |
||||||||
15 | * |
||||||||
16 | * @var object |
||||||||
17 | */ |
||||||||
18 | protected $settings; |
||||||||
19 | |||||||||
20 | /** |
||||||||
21 | * SimpleDriver constructor. |
||||||||
22 | * Construct the class with the relevant settings. |
||||||||
23 | * |
||||||||
24 | * SimpleDriver constructor. |
||||||||
25 | * @param ServiceProvider $serviceProvider |
||||||||
26 | * @param $settings |
||||||||
27 | */ |
||||||||
28 | public function __construct(ServiceProvider $serviceProvider, $settings) |
||||||||
29 | { |
||||||||
30 | $this->serviceProvider = $serviceProvider; |
||||||||
31 | $this->settings = (object) $settings; |
||||||||
32 | |||||||||
33 | $this->bindViews() |
||||||||
34 | ->bindRoutes() |
||||||||
35 | ->publishResources(); |
||||||||
36 | } |
||||||||
37 | |||||||||
38 | /** |
||||||||
39 | * Bind driver views |
||||||||
40 | * |
||||||||
41 | * @return $this |
||||||||
42 | */ |
||||||||
43 | protected function bindViews() |
||||||||
44 | { |
||||||||
45 | $this->serviceProvider->bindViewFile(__DIR__ . '/resources/views', 'captchaSimpleDriver'); |
||||||||
0 ignored issues
–
show
Bug
introduced
by
![]() |
|||||||||
46 | |||||||||
47 | return $this; |
||||||||
48 | } |
||||||||
49 | |||||||||
50 | /** |
||||||||
51 | * Bind driver routes |
||||||||
52 | * |
||||||||
53 | * @return $this |
||||||||
54 | */ |
||||||||
55 | protected function bindRoutes() |
||||||||
56 | { |
||||||||
57 | $this->serviceProvider->bindRouteFile(__DIR__ . '/routes.php'); |
||||||||
0 ignored issues
–
show
The method
bindRouteFile() does not exist on Illuminate\Support\ServiceProvider . It seems like you code against a sub-type of Illuminate\Support\ServiceProvider such as Illuminate\Foundation\Su...rs\RouteServiceProvider or Shetabit\Captcha\Provider\CaptchaServiceProvider .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
58 | |||||||||
59 | return $this; |
||||||||
60 | } |
||||||||
61 | |||||||||
62 | /** |
||||||||
63 | * Publish driver assets |
||||||||
64 | * |
||||||||
65 | * @return $this |
||||||||
66 | */ |
||||||||
67 | protected function publishResources() |
||||||||
68 | { |
||||||||
69 | $destinationPath = resource_path('views/vendor/captchaSimpleDriver'); |
||||||||
70 | |||||||||
71 | $this->serviceProvider |
||||||||
72 | ->publish(__DIR__ . '/resources/views', $destinationPath, 'views') |
||||||||
0 ignored issues
–
show
The method
publish() does not exist on Illuminate\Support\ServiceProvider . Did you maybe mean publishes() ?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed. ![]() |
|||||||||
73 | ->publish(__DIR__ . '/resources/assets', $destinationPath.'/assets', 'assets'); |
||||||||
74 | |||||||||
75 | return $this; |
||||||||
76 | } |
||||||||
77 | |||||||||
78 | /** |
||||||||
79 | * Prepare CAPTCHA image and memorize its token. |
||||||||
80 | * |
||||||||
81 | * @return false|string |
||||||||
82 | */ |
||||||||
83 | public function prepareCaptchaImage() |
||||||||
84 | { |
||||||||
85 | $settings = $this->settings; |
||||||||
86 | |||||||||
87 | $token = $this->randomString( |
||||||||
88 | $settings->characters, |
||||||||
89 | $settings->length[0], |
||||||||
90 | $settings->length[1] |
||||||||
91 | ); |
||||||||
92 | |||||||||
93 | // save token in memory |
||||||||
94 | $this->pushInMemory($settings->sessionKey, $token); |
||||||||
95 | |||||||||
96 | $image = $this->drawImage( |
||||||||
97 | $token, |
||||||||
98 | $settings->width, |
||||||||
99 | $settings->height, |
||||||||
100 | $settings->foregroundColors, |
||||||||
101 | $settings->backgroundColor, |
||||||||
102 | $settings->letterSpacing, |
||||||||
103 | $settings->fontSize, |
||||||||
104 | $settings->fontFamily |
||||||||
105 | ); |
||||||||
106 | |||||||||
107 | return $image; |
||||||||
108 | } |
||||||||
109 | |||||||||
110 | /** |
||||||||
111 | * Generate captcha. |
||||||||
112 | * |
||||||||
113 | * @return mixed |
||||||||
114 | */ |
||||||||
115 | public function generate() |
||||||||
116 | { |
||||||||
117 | return View::make( |
||||||||
0 ignored issues
–
show
The expression
return Illuminate\Suppor...('captcha.validator'))) returns the type Illuminate\Contracts\View\View which is incompatible with the return type mandated by Shetabit\Captcha\Contrac...erInterface::generate() of string .
In the issue above, the returned value is violating the contract defined by the mentioned interface. Let's take a look at an example: interface HasName {
/** @return string */
public function getName();
}
class Name {
public $name;
}
class User implements HasName {
/** @return string|Name */
public function getName() {
return new Name('foo'); // This is a violation of the ``HasName`` interface
// which only allows a string value to be returned.
}
}
![]() |
|||||||||
118 | 'captchaSimpleDriver::captcha', |
||||||||
119 | [ |
||||||||
120 | 'routeName' => $this->settings->route, |
||||||||
121 | 'errorsName' => config('captcha.validator'), |
||||||||
122 | ] |
||||||||
123 | ); |
||||||||
124 | } |
||||||||
125 | |||||||||
126 | /** |
||||||||
127 | * Verify token. |
||||||||
128 | * |
||||||||
129 | * @param null|$token |
||||||||
130 | * @return bool |
||||||||
131 | */ |
||||||||
132 | public function verify($token = null) |
||||||||
133 | { |
||||||||
134 | $storedToken = $this->pullFromMemory($this->settings->sessionKey); |
||||||||
135 | |||||||||
136 | if (empty($this->settings->sensitive)) { |
||||||||
137 | $storedToken = mb_strtolower($storedToken); |
||||||||
138 | $token = mb_strtolower($token); |
||||||||
139 | } |
||||||||
140 | |||||||||
141 | return $token == $storedToken; |
||||||||
142 | } |
||||||||
143 | |||||||||
144 | /** |
||||||||
145 | * Save token in memory. |
||||||||
146 | * |
||||||||
147 | * @param $key |
||||||||
148 | * @param $value |
||||||||
149 | * @return $this |
||||||||
150 | */ |
||||||||
151 | protected function pushInMemory($key, $value) |
||||||||
152 | { |
||||||||
153 | session()->put($key, $value); |
||||||||
154 | |||||||||
155 | return $this; |
||||||||
156 | } |
||||||||
157 | |||||||||
158 | /** |
||||||||
159 | * Retrieve token from memory. |
||||||||
160 | * |
||||||||
161 | * @return mixed |
||||||||
162 | */ |
||||||||
163 | protected function pullFromMemory($key) |
||||||||
164 | { |
||||||||
165 | $value = session()->pull($key); |
||||||||
166 | |||||||||
167 | if (! empty($value)) { |
||||||||
168 | session()->forget($key); |
||||||||
169 | } |
||||||||
170 | |||||||||
171 | return $value; |
||||||||
172 | } |
||||||||
173 | |||||||||
174 | /** |
||||||||
175 | * Create new canvas. |
||||||||
176 | * |
||||||||
177 | * @param $width |
||||||||
178 | * @param $height |
||||||||
179 | * @return resource |
||||||||
180 | */ |
||||||||
181 | protected function canvas($width, $height) |
||||||||
182 | { |
||||||||
183 | $canvas = imagecreatetruecolor($width, $height); |
||||||||
184 | |||||||||
185 | return $canvas; |
||||||||
186 | } |
||||||||
187 | |||||||||
188 | /** |
||||||||
189 | * Generate image |
||||||||
190 | * |
||||||||
191 | * @param $token |
||||||||
192 | * @param $width |
||||||||
193 | * @param $height |
||||||||
194 | * @param $foregroundColors |
||||||||
195 | * @param $backgroundColor |
||||||||
196 | * @param $letterSpacing |
||||||||
197 | * @param $fontSize |
||||||||
198 | * @param $fontFamily |
||||||||
199 | * @return false|string |
||||||||
200 | */ |
||||||||
201 | protected function drawImage( |
||||||||
202 | $token, |
||||||||
203 | $width, |
||||||||
204 | $height, |
||||||||
205 | $foregroundColors, |
||||||||
206 | $backgroundColor, |
||||||||
207 | $letterSpacing, |
||||||||
208 | $fontSize, |
||||||||
209 | $fontFamily |
||||||||
210 | ) { |
||||||||
211 | $canvas = $this->canvas($width, $height); |
||||||||
212 | |||||||||
213 | $this->fillWithColor($canvas, $backgroundColor); |
||||||||
214 | |||||||||
215 | $offsetX = ($width - strlen($token) * ($letterSpacing + $fontSize * 0.66)) / 2; |
||||||||
216 | $offsetY = ceil(($height) / 1.5); |
||||||||
217 | |||||||||
218 | // write token |
||||||||
219 | for ($i = 0; $i < strlen($token); $i++) { |
||||||||
220 | $randomForegroundColor = $foregroundColors[mt_rand(0, count($foregroundColors) - 1)]; |
||||||||
221 | imagettftext( |
||||||||
222 | $canvas, |
||||||||
223 | $this->settings->fontSize, |
||||||||
224 | ceil(mt_rand(0,10)), |
||||||||
225 | $offsetX, |
||||||||
0 ignored issues
–
show
$offsetX of type double is incompatible with the type integer expected by parameter $x of imagettftext() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
226 | $offsetY, |
||||||||
0 ignored issues
–
show
$offsetY of type double is incompatible with the type integer expected by parameter $y of imagettftext() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
227 | $this->prepareColor($canvas, $randomForegroundColor), |
||||||||
228 | $fontFamily, |
||||||||
229 | $token[$i] |
||||||||
230 | ); |
||||||||
231 | $offsetX += ceil($fontSize * 0.66) + $letterSpacing; |
||||||||
232 | } |
||||||||
233 | |||||||||
234 | //Scratches foreground |
||||||||
235 | for ($i = 0; $i < $this->settings->scratches[0]; $i++) { |
||||||||
236 | $randomForegroundColor = $foregroundColors[mt_rand(0, count($foregroundColors) - 1)]; |
||||||||
237 | |||||||||
238 | $this->drawScratch($canvas, $width, $height, $randomForegroundColor); |
||||||||
239 | } |
||||||||
240 | |||||||||
241 | //Scratches background |
||||||||
242 | for ($i = 0; $i < $this->settings->scratches[1]; $i++) { |
||||||||
243 | $this->drawScratch($canvas, $width, $height, $backgroundColor); |
||||||||
244 | } |
||||||||
245 | |||||||||
246 | ob_start(); |
||||||||
247 | imagepng($canvas); |
||||||||
248 | $content = ob_get_contents(); |
||||||||
249 | ob_end_clean(); |
||||||||
250 | |||||||||
251 | imagedestroy($canvas); |
||||||||
252 | |||||||||
253 | return $content; |
||||||||
254 | } |
||||||||
255 | |||||||||
256 | /** |
||||||||
257 | * Fill canvas with the given color |
||||||||
258 | * |
||||||||
259 | * @param $canvas |
||||||||
260 | * @param $color |
||||||||
261 | * @return $this |
||||||||
262 | */ |
||||||||
263 | protected function fillWithColor($canvas, $color) |
||||||||
264 | { |
||||||||
265 | $fillColor = $this->prepareColor($canvas, $color); |
||||||||
266 | |||||||||
267 | imagefill($canvas, 0, 0, $fillColor); |
||||||||
268 | |||||||||
269 | return $this; |
||||||||
270 | } |
||||||||
271 | |||||||||
272 | /** |
||||||||
273 | * Draw scratches |
||||||||
274 | * |
||||||||
275 | * @param $img |
||||||||
276 | * @param $imageWidth |
||||||||
277 | * @param $imageHeight |
||||||||
278 | * @param $hex |
||||||||
279 | */ |
||||||||
280 | private function drawScratch($img, $imageWidth, $imageHeight, $hex) |
||||||||
281 | { |
||||||||
282 | $rgb = $this->hexToRgb($hex); |
||||||||
283 | |||||||||
284 | imageline( |
||||||||
285 | $img, |
||||||||
286 | mt_rand(0, floor($imageWidth / 2)), |
||||||||
287 | mt_rand(1, $imageHeight), |
||||||||
288 | mt_rand(floor($imageWidth / 2), $imageWidth), |
||||||||
289 | mt_rand(1, $imageHeight), |
||||||||
290 | imagecolorallocate($img, $rgb['red'], $rgb['green'], $rgb['blue']) |
||||||||
0 ignored issues
–
show
It seems like
$rgb['blue'] can also be of type double ; however, parameter $blue of imagecolorallocate() does only seem to accept integer , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() It seems like
$rgb['green'] can also be of type double ; however, parameter $green of imagecolorallocate() does only seem to accept integer , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() It seems like
$rgb['red'] can also be of type double ; however, parameter $red of imagecolorallocate() does only seem to accept integer , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
291 | ); |
||||||||
292 | } |
||||||||
293 | |||||||||
294 | /** |
||||||||
295 | * prepare a color |
||||||||
296 | * |
||||||||
297 | * @param $canvas |
||||||||
298 | * @param $color |
||||||||
299 | * @return int |
||||||||
300 | */ |
||||||||
301 | private function prepareColor($canvas, $hexColor) |
||||||||
302 | { |
||||||||
303 | $rgbColor = $this->hexToRGB($hexColor); |
||||||||
304 | |||||||||
305 | return imagecolorallocate( |
||||||||
306 | $canvas, |
||||||||
307 | $rgbColor['red'], |
||||||||
0 ignored issues
–
show
It seems like
$rgbColor['red'] can also be of type double ; however, parameter $red of imagecolorallocate() does only seem to accept integer , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
308 | $rgbColor['green'], |
||||||||
0 ignored issues
–
show
It seems like
$rgbColor['green'] can also be of type double ; however, parameter $green of imagecolorallocate() does only seem to accept integer , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
309 | $rgbColor['blue'] |
||||||||
0 ignored issues
–
show
It seems like
$rgbColor['blue'] can also be of type double ; however, parameter $blue of imagecolorallocate() does only seem to accept integer , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
310 | ); |
||||||||
311 | } |
||||||||
312 | |||||||||
313 | /** |
||||||||
314 | * Create a random string |
||||||||
315 | * |
||||||||
316 | * @param string $characters |
||||||||
317 | * @param int $minLength |
||||||||
318 | * @param int $maxLength |
||||||||
319 | * @return string |
||||||||
320 | */ |
||||||||
321 | private function randomString($characters = '123456789' , $minLength = 4, $maxLength = 6) |
||||||||
322 | { |
||||||||
323 | $randomLength = mt_rand($minLength, $maxLength); |
||||||||
324 | $string = []; |
||||||||
325 | |||||||||
326 | for ($i = 0; $i < $randomLength; $i++) { |
||||||||
327 | $string[] = $characters[mt_rand(1, mb_strlen($characters) - 1)]; |
||||||||
328 | } |
||||||||
329 | |||||||||
330 | $string = implode($string); |
||||||||
331 | |||||||||
332 | return $string; |
||||||||
333 | } |
||||||||
334 | |||||||||
335 | /** |
||||||||
336 | * Convert hex color to rgb |
||||||||
337 | * |
||||||||
338 | * @param $hexColor |
||||||||
339 | * @return array |
||||||||
340 | */ |
||||||||
341 | private function hexToRGB($hexColor) |
||||||||
342 | { |
||||||||
343 | $hexColor = ($hexColor[0] == '#') ? substr($hexColor, 1) : $hexColor; |
||||||||
344 | |||||||||
345 | // Separate colors |
||||||||
346 | switch(strlen($hexColor)) { |
||||||||
347 | case 6: |
||||||||
348 | $red = $hexColor[0].$hexColor[1]; |
||||||||
349 | $green = $hexColor[2].$hexColor[3]; |
||||||||
350 | $blue = $hexColor[4].$hexColor[5]; |
||||||||
351 | break; |
||||||||
352 | case 3: |
||||||||
353 | $red = str_repeat($hexColor[0],2); |
||||||||
354 | $green = str_repeat($hexColor[1],2); |
||||||||
355 | $blue = str_repeat($hexColor[2],2); |
||||||||
356 | break; |
||||||||
357 | default: |
||||||||
358 | $red = $green = $blue = 0; |
||||||||
359 | break; |
||||||||
360 | } |
||||||||
361 | |||||||||
362 | // Convert hex to dec |
||||||||
363 | $red = hexdec($red); |
||||||||
364 | $green = hexdec($green); |
||||||||
365 | $blue = hexdec($blue); |
||||||||
366 | |||||||||
367 | return [ |
||||||||
368 | 'red' => $red, |
||||||||
369 | 'green' => $green, |
||||||||
370 | 'blue' => $blue, |
||||||||
371 | ]; |
||||||||
372 | } |
||||||||
373 | } |
||||||||
374 |