York 3 лет назад
Родитель
Сommit
52edf75d53
2 измененных файлов с 157 добавлено и 158 удалено
  1. 0 2
      common/components/Controller.php
  2. 157 156
      common/helpers/CaptchaAction.php

+ 0 - 2
common/components/Controller.php

@@ -23,8 +23,6 @@ class Controller extends \yii\web\Controller {
         return [
             'captcha' =>  [
                 'class' => 'common\helpers\CaptchaAction',
-                'backColor' => 0x000000,//背景颜色
-                'foreColor' => 0xffffff,     //字体颜色
                 'width' => 120,
                 'height' => 40,
                 'padding' => 0,

+ 157 - 156
common/helpers/CaptchaAction.php

@@ -1,157 +1,158 @@
-<?php
-namespace common\helpers;
-
-use Yii;
-use yii\helpers\Url;
-use yii\web\Response;
-
-/**
- * 验证码扩展类
- * @author   Leo
- * @copyright  Copyright (c) 2016 (http://www.LeoCode.net)
- */
-class CaptchaAction extends \yii\captcha\CaptchaAction
-{
-
-    const CAPTCHA_CODE = 'ak:captcha_code_%s';
-
-    /**
-     * GD库方式渲染
-     * @param string $code
-     * @return string
-     */
-    protected function renderImageByGD($code)
-    {
-        $this->fontFile = Yii::getAlias('@common/helpers/font/DroidSansMono.ttf');
-        $image = imagecreatetruecolor($this->width, $this->height);
-        $backColor = imagecolorallocate(
-            $image,
-            (int)($this->backColor % 0x1000000 / 0x10000),
-            (int)($this->backColor % 0x10000 / 0x100),
-            $this->backColor % 0x100
-        );
-        imagefilledrectangle($image, 0, 0, $this->width - 1, $this->height - 1, $backColor);
-        imagecolordeallocate($image, $backColor);
-        $this->transparent = true;
-        if ($this->transparent) {
-            imagecolortransparent($image, $backColor);
-        }
-
-        $foreColor = imagecolorallocate(
-            $image,
-            (int)($this->foreColor % 0x1000000 / 0x10000),
-            (int)($this->foreColor % 0x10000 / 0x100),
-            $this->foreColor % 0x100
-        );
-
-        $length = strlen($code);
-        $box = imagettfbbox(30, 0, $this->fontFile, $code);
-        $w = $box[4] - $box[0] + $this->offset * ($length - 1);
-        $h = $box[1] - $box[5];
-        $scale = min(($this->width - $this->padding * 2) / $w, ($this->height - $this->padding * 2) / $h);
-        $x = 10;
-        $y = round($this->height * 27 / 40);
-
-        // 添加彩色乱字符
-        $chartDictionary = 'abcdefghjkmnopqrstuvwxyzABCDEFGHJKMNOPQRSTUVWXYZ2345679';
-        for ($i = 0; $i < 50; $i++) {
-            $chartPosition = rand(0, strlen($chartDictionary));
-            $chartContent = substr($chartDictionary, $chartPosition, 1);
-            $chartColor = imagecolorallocate($image, mt_rand(150, 255), mt_rand(150, 255), mt_rand(150, 255));
-            $chartAngle = rand(-10, 10);
-            imagettftext($image, 10, $chartAngle, rand(0, ($this->width - $this->padding * 2) - 10), rand(0, ($this->height - $this->padding * 2) - 10), $chartColor, $this->fontFile, $chartContent);
-        }
-
-        // 设置文字
-        for ($i = 0; $i < $length; ++$i) {
-            $fontSize = (int)(rand(26, 32) * $scale * 0.8);
-            $angle = rand(-10, 10);
-            $letter = $code[$i];
-            $box = imagettftext($image, $fontSize, $angle, $x, $y, $foreColor, $this->fontFile, $letter);
-            $x = $box[2] + $this->offset;
-        }
-
-        // 验证码添加线条
-        for ($i = 0; $i < 10; $i++) {
-            $lineColor = imagecolorallocate($image, rand(0, 255), rand(0, 255), rand(0, 255));
-            imageline($image, rand(0, 2), rand(0, ($this->width - $this->height * 2) - 2), rand(0, ($this->width - $this->padding * 2) - 2), rand(0, ($this->width - $this->height * 2) - 2), $lineColor);
-        }
-
-        // 验证码添加噪点
-        for ($i = 0; $i < 300; $i++) {
-            //设置点的颜色
-            $pointColor = imagecolorallocate($image, rand(0, 255), rand(0, 255), rand(0, 255));
-            imagesetpixel($image, rand(0, ($this->width - $this->padding * 2)), rand(0, ($this->width - $this->height * 2) - 10), $pointColor);
-        }
-
-        imagecolordeallocate($image, $foreColor);
-
-        ob_start();
-        imagepng($image);
-        imagedestroy($image);
-
-        return ob_get_clean();
-    }
-
-    /**
-     * Runs the action.
-     */
-    public function run()
-    {
-        if (Yii::$app->request->getQueryParam(self::REFRESH_GET_VAR) !== null) {
-            // AJAX request for regenerating code
-            $code = $this->getVerifyCode(true);
-            Yii::$app->response->format = Response::FORMAT_JSON;
-            return [
-                'hash1' => $this->generateValidationHash($code),
-                'hash2' => $this->generateValidationHash(strtolower($code)),
-                // we add a random 'v' parameter so that FireFox can refresh the image
-                // when src attribute of image tag is changed
-                'url' => Url::to([$this->id, 'v' => uniqid()]),
-            ];
-        } else {
-            $this->setHttpHeaders();
-            Yii::$app->response->format = Response::FORMAT_RAW;
-            return $this->renderImage($this->getVerifyCode(true));
-        }
-    }
-
-    /**
-     * @param bool $regenerate
-     * @return int|mixed|string|null
-     */
-    public function getVerifyCode($regenerate = false)
-    {
-        if ($this->fixedVerifyCode !== null) {
-            return $this->fixedVerifyCode;
-        }
-//        $name = $this->getSessionKey();
-        $pageId = \Yii::$app->request->get('page_id');
-        if( !$pageId ) {
-            throw new \Exception('no page id');
-        }
-
-        $cacheRedis = Yii::$app->cache;
-        $key = sprintf(self::CAPTCHA_CODE, $pageId);
-        if( !$regenerate ) {
-            $code = $cacheRedis->get($key);
-            if ( $code ) return $code;
-        }
-
-        $code = $this->generateVerifyCode();
-        $cacheRedis->set($key, $code, 300);
-
-        return $code;
-    }
-
-    public function validate($input, $caseSensitive)
-    {
-        $code = $this->getVerifyCode();
-        $valid = $caseSensitive ? ($input === $code) : strcasecmp($input, $code) === 0;
-        if ( $valid ) {
-            $this->getVerifyCode(true);
-        }
-
-        return $valid;
-    }
+<?php
+namespace common\helpers;
+
+use Yii;
+use yii\helpers\Url;
+use yii\web\Response;
+
+/**
+ * 验证码扩展类
+ * @author   Leo
+ * @copyright  Copyright (c) 2016 (http://www.LeoCode.net)
+ */
+class CaptchaAction extends \yii\captcha\CaptchaAction
+{
+
+    const CAPTCHA_CODE = 'ak:captcha_code_%s';
+
+    /**
+     * GD库方式渲染
+     * @param string $code
+     * @return string
+     */
+    protected function renderImageByGD($code)
+    {
+        $this->fontFile = Yii::getAlias('@common/helpers/font/DroidSansMono.ttf');
+        $image = imagecreatetruecolor($this->width, $this->height);
+        $backColor = imagecolorallocate(
+            $image,
+            (int)($this->backColor % 0x1000000 / 0x10000),
+            (int)($this->backColor % 0x10000 / 0x100),
+            $this->backColor % 0x100
+        );
+        imagefilledrectangle($image, 0, 0, $this->width - 1, $this->height - 1, $backColor);
+        imagecolordeallocate($image, $backColor);
+        $this->transparent = true;
+        if ($this->transparent) {
+            imagecolortransparent($image, $backColor);
+        }
+
+        $foreColor = imagecolorallocate(
+            $image,
+            (int)($this->foreColor % 0x1000000 / 0x10000),
+            (int)($this->foreColor % 0x10000 / 0x100),
+            $this->foreColor % 0x100
+        );
+
+        $length = strlen($code);
+        $box = imagettfbbox(30, 0, $this->fontFile, $code);
+        $w = $box[4] - $box[0] + $this->offset * ($length - 1);
+        $h = $box[1] - $box[5];
+        $scale = min(($this->width - $this->padding * 2) / $w, ($this->height - $this->padding * 2) / $h);
+        $x = 10;
+        $y = round($this->height * 27 / 40);
+
+        // 添加彩色乱字符
+        $chartDictionary = 'abcdefghjkmnopqrstuvwxyzABCDEFGHJKMNOPQRSTUVWXYZ2345679';
+        for ($i = 0; $i < 50; $i++) {
+            $chartPosition = rand(0, strlen($chartDictionary));
+            $chartContent = substr($chartDictionary, $chartPosition, 1);
+            $chartColor = imagecolorallocate($image, mt_rand(150, 255), mt_rand(150, 255), mt_rand(150, 255));
+            $chartAngle = rand(-10, 10);
+            imagettftext($image, 10, $chartAngle, rand(0, ($this->width - $this->padding * 2) - 10), rand(0, ($this->height - $this->padding * 2) - 10), $chartColor, $this->fontFile, $chartContent);
+        }
+
+        // 设置文字
+        for ($i = 0; $i < $length; ++$i) {
+            $fontSize = (int)(rand(26, 32) * $scale * 0.8);
+            //$angle = rand(-10, 10);
+            $angle = rand(-100, 10);
+            $letter = $code[$i];
+            $box = imagettftext($image, $fontSize, $angle, $x, $y, $foreColor, $this->fontFile, $letter);
+            $x = $box[2] + $this->offset;
+        }
+
+        // 验证码添加线条
+        for ($i = 0; $i < 10; $i++) {
+            $lineColor = imagecolorallocate($image, rand(0, 255), rand(0, 255), rand(0, 255));
+            imageline($image, rand(0, 2), rand(0, ($this->width - $this->height * 2) - 2), rand(0, ($this->width - $this->padding * 2) - 2), rand(0, ($this->width - $this->height * 2) - 2), $lineColor);
+        }
+
+        // 验证码添加噪点
+        for ($i = 0; $i < 300; $i++) {
+            //设置点的颜色
+            $pointColor = imagecolorallocate($image, rand(0, 255), rand(0, 255), rand(0, 255));
+            imagesetpixel($image, rand(0, ($this->width - $this->padding * 2)), rand(0, ($this->width - $this->height * 2) - 10), $pointColor);
+        }
+
+        imagecolordeallocate($image, $foreColor);
+
+        ob_start();
+        imagepng($image);
+        imagedestroy($image);
+
+        return ob_get_clean();
+    }
+
+    /**
+     * Runs the action.
+     */
+    public function run()
+    {
+        if (Yii::$app->request->getQueryParam(self::REFRESH_GET_VAR) !== null) {
+            // AJAX request for regenerating code
+            $code = $this->getVerifyCode(true);
+            Yii::$app->response->format = Response::FORMAT_JSON;
+            return [
+                'hash1' => $this->generateValidationHash($code),
+                'hash2' => $this->generateValidationHash(strtolower($code)),
+                // we add a random 'v' parameter so that FireFox can refresh the image
+                // when src attribute of image tag is changed
+                'url' => Url::to([$this->id, 'v' => uniqid()]),
+            ];
+        } else {
+            $this->setHttpHeaders();
+            Yii::$app->response->format = Response::FORMAT_RAW;
+            return $this->renderImage($this->getVerifyCode(true));
+        }
+    }
+
+    /**
+     * @param bool $regenerate
+     * @return int|mixed|string|null
+     */
+    public function getVerifyCode($regenerate = false)
+    {
+        if ($this->fixedVerifyCode !== null) {
+            return $this->fixedVerifyCode;
+        }
+//        $name = $this->getSessionKey();
+        $pageId = \Yii::$app->request->get('page_id');
+        if( !$pageId ) {
+            throw new \Exception('no page id');
+        }
+
+        $cacheRedis = Yii::$app->cache;
+        $key = sprintf(self::CAPTCHA_CODE, $pageId);
+        if( !$regenerate ) {
+            $code = $cacheRedis->get($key);
+            if ( $code ) return $code;
+        }
+
+        $code = $this->generateVerifyCode();
+        $cacheRedis->set($key, $code, 300);
+
+        return $code;
+    }
+
+    public function validate($input, $caseSensitive)
+    {
+        $code = $this->getVerifyCode();
+        $valid = $caseSensitive ? ($input === $code) : strcasecmp($input, $code) === 0;
+        if ( $valid ) {
+            $this->getVerifyCode(true);
+        }
+
+        return $valid;
+    }
 }