From 8e6476b4028e44687e10bf7fb2617a2d2fff97d2 Mon Sep 17 00:00:00 2001 From: Frédéric Guillot Date: Fri, 15 Dec 2017 13:27:25 -0800 Subject: Update composer dependencies --- vendor/gregwar/captcha/.gitignore | 1 + vendor/gregwar/captcha/.travis.yml | 4 + vendor/gregwar/captcha/CaptchaBuilder.php | 720 -------------------- vendor/gregwar/captcha/CaptchaBuilderInterface.php | 30 - vendor/gregwar/captcha/Font/captcha0.ttf | Bin 49224 -> 0 bytes vendor/gregwar/captcha/Font/captcha1.ttf | Bin 76232 -> 0 bytes vendor/gregwar/captcha/Font/captcha2.ttf | Bin 33984 -> 0 bytes vendor/gregwar/captcha/Font/captcha3.ttf | Bin 15976 -> 0 bytes vendor/gregwar/captcha/Font/captcha4.ttf | Bin 906980 -> 0 bytes vendor/gregwar/captcha/Font/captcha5.ttf | Bin 49724 -> 0 bytes vendor/gregwar/captcha/ImageFileHandler.php | 106 --- vendor/gregwar/captcha/LICENSE | 2 +- vendor/gregwar/captcha/PhraseBuilder.php | 34 - vendor/gregwar/captcha/PhraseBuilderInterface.php | 21 - vendor/gregwar/captcha/README.md | 34 +- vendor/gregwar/captcha/autoload.php | 16 - vendor/gregwar/captcha/composer.json | 9 +- vendor/gregwar/captcha/demo/demo.php | 5 +- vendor/gregwar/captcha/demo/fingerprint.php | 5 +- vendor/gregwar/captcha/demo/ocr.php | 5 +- vendor/gregwar/captcha/demo/output.php | 5 +- vendor/gregwar/captcha/phpunit.xml.dist | 15 + .../captcha/src/Gregwar/Captcha/CaptchaBuilder.php | 721 +++++++++++++++++++++ .../Gregwar/Captcha/CaptchaBuilderInterface.php | 29 + .../captcha/src/Gregwar/Captcha/Font/captcha0.ttf | Bin 0 -> 49224 bytes .../captcha/src/Gregwar/Captcha/Font/captcha1.ttf | Bin 0 -> 76232 bytes .../captcha/src/Gregwar/Captcha/Font/captcha2.ttf | Bin 0 -> 33984 bytes .../captcha/src/Gregwar/Captcha/Font/captcha3.ttf | Bin 0 -> 15976 bytes .../captcha/src/Gregwar/Captcha/Font/captcha4.ttf | Bin 0 -> 906980 bytes .../captcha/src/Gregwar/Captcha/Font/captcha5.ttf | Bin 0 -> 49724 bytes .../src/Gregwar/Captcha/ImageFileHandler.php | 105 +++ .../captcha/src/Gregwar/Captcha/PhraseBuilder.php | 59 ++ .../src/Gregwar/Captcha/PhraseBuilderInterface.php | 21 + .../gregwar/captcha/tests/CaptchaBuilderTest.php | 30 + 34 files changed, 1030 insertions(+), 947 deletions(-) delete mode 100644 vendor/gregwar/captcha/CaptchaBuilder.php delete mode 100644 vendor/gregwar/captcha/CaptchaBuilderInterface.php delete mode 100644 vendor/gregwar/captcha/Font/captcha0.ttf delete mode 100644 vendor/gregwar/captcha/Font/captcha1.ttf delete mode 100644 vendor/gregwar/captcha/Font/captcha2.ttf delete mode 100644 vendor/gregwar/captcha/Font/captcha3.ttf delete mode 100644 vendor/gregwar/captcha/Font/captcha4.ttf delete mode 100644 vendor/gregwar/captcha/Font/captcha5.ttf delete mode 100644 vendor/gregwar/captcha/ImageFileHandler.php delete mode 100644 vendor/gregwar/captcha/PhraseBuilder.php delete mode 100644 vendor/gregwar/captcha/PhraseBuilderInterface.php delete mode 100644 vendor/gregwar/captcha/autoload.php create mode 100644 vendor/gregwar/captcha/phpunit.xml.dist create mode 100644 vendor/gregwar/captcha/src/Gregwar/Captcha/CaptchaBuilder.php create mode 100644 vendor/gregwar/captcha/src/Gregwar/Captcha/CaptchaBuilderInterface.php create mode 100644 vendor/gregwar/captcha/src/Gregwar/Captcha/Font/captcha0.ttf create mode 100644 vendor/gregwar/captcha/src/Gregwar/Captcha/Font/captcha1.ttf create mode 100644 vendor/gregwar/captcha/src/Gregwar/Captcha/Font/captcha2.ttf create mode 100644 vendor/gregwar/captcha/src/Gregwar/Captcha/Font/captcha3.ttf create mode 100644 vendor/gregwar/captcha/src/Gregwar/Captcha/Font/captcha4.ttf create mode 100644 vendor/gregwar/captcha/src/Gregwar/Captcha/Font/captcha5.ttf create mode 100644 vendor/gregwar/captcha/src/Gregwar/Captcha/ImageFileHandler.php create mode 100644 vendor/gregwar/captcha/src/Gregwar/Captcha/PhraseBuilder.php create mode 100644 vendor/gregwar/captcha/src/Gregwar/Captcha/PhraseBuilderInterface.php create mode 100644 vendor/gregwar/captcha/tests/CaptchaBuilderTest.php (limited to 'vendor/gregwar') diff --git a/vendor/gregwar/captcha/.gitignore b/vendor/gregwar/captcha/.gitignore index 5a275919..5b9939b3 100644 --- a/vendor/gregwar/captcha/.gitignore +++ b/vendor/gregwar/captcha/.gitignore @@ -1,3 +1,4 @@ demo/*.jpg demo/*.pgm demo/temp/ +vendor/ diff --git a/vendor/gregwar/captcha/.travis.yml b/vendor/gregwar/captcha/.travis.yml index 9c4b7049..5d2dbf97 100644 --- a/vendor/gregwar/captcha/.travis.yml +++ b/vendor/gregwar/captcha/.travis.yml @@ -6,6 +6,10 @@ php: - 5.4 - 5.5 - 5.6 + - 7.0 + - 7.1 + - 7.2 + - hhvm script: - composer install diff --git a/vendor/gregwar/captcha/CaptchaBuilder.php b/vendor/gregwar/captcha/CaptchaBuilder.php deleted file mode 100644 index bc6173fe..00000000 --- a/vendor/gregwar/captcha/CaptchaBuilder.php +++ /dev/null @@ -1,720 +0,0 @@ - - * @author Jeremy Livingston - */ -class CaptchaBuilder implements CaptchaBuilderInterface -{ - /** - * @var array - */ - protected $fingerprint = array(); - - /** - * @var bool - */ - protected $useFingerprint = false; - - /** - * @var array - */ - protected $textColor = null; - - /** - * @var array - */ - protected $backgroundColor = null; - - /** - * @var array - */ - protected $backgroundImages = array(); - - /** - * @var resource - */ - protected $contents = null; - - /** - * @var string - */ - protected $phrase = null; - - /** - * @var PhraseBuilderInterface - */ - protected $builder; - - /** - * @var bool - */ - protected $distortion = true; - - /** - * The maximum number of lines to draw in front of - * the image. null - use default algorithm - */ - protected $maxFrontLines = null; - - /** - * The maximum number of lines to draw behind - * the image. null - use default algorithm - */ - protected $maxBehindLines = null; - - /** - * The maximum angle of char - */ - protected $maxAngle = 8; - - /** - * The maximum offset of char - */ - protected $maxOffset = 5; - - /** - * Is the interpolation enabled ? - * - * @var bool - */ - protected $interpolation = true; - - /** - * Ignore all effects - * - * @var bool - */ - protected $ignoreAllEffects = false; - - /** - * Allowed image types for the background images - * - * @var array - */ - protected $allowedBackgroundImageTypes = array('image/png', 'image/jpeg', 'image/gif'); - - /** - * The image contents - */ - public function getContents() - { - return $this->contents; - } - - /** - * Enable/Disables the interpolation - * - * @param $interpolate bool True to enable, false to disable - * - * @return CaptchaBuilder - */ - public function setInterpolation($interpolate = true) - { - $this->interpolation = $interpolate; - - return $this; - } - - /** - * Temporary dir, for OCR check - */ - public $tempDir = 'temp/'; - - public function __construct($phrase = null, PhraseBuilderInterface $builder = null) - { - if ($builder === null) { - $this->builder = new PhraseBuilder; - } else { - $this->builder = $builder; - } - - if ($phrase === null) { - $phrase = $this->builder->build(); - } - - $this->phrase = $phrase; - } - - /** - * Setting the phrase - */ - public function setPhrase($phrase) - { - $this->phrase = (string) $phrase; - } - - /** - * Enables/disable distortion - */ - public function setDistortion($distortion) - { - $this->distortion = (bool) $distortion; - - return $this; - } - - public function setMaxBehindLines($maxBehindLines) - { - $this->maxBehindLines = $maxBehindLines; - - return $this; - } - - public function setMaxFrontLines($maxFrontLines) - { - $this->maxFrontLines = $maxFrontLines; - - return $this; - } - - public function setMaxAngle($maxAngle) - { - $this->maxAngle = $maxAngle; - - return $this; - } - - public function setMaxOffset($maxOffset) - { - $this->maxOffset = $maxOffset; - - return $this; - } - - /** - * Gets the captcha phrase - */ - public function getPhrase() - { - return $this->phrase; - } - - /** - * Returns true if the given phrase is good - */ - public function testPhrase($phrase) - { - return ($this->builder->niceize($phrase) == $this->builder->niceize($this->getPhrase())); - } - - /** - * Instantiation - */ - public static function create($phrase = null) - { - return new self($phrase); - } - - /** - * Sets the text color to use - */ - public function setTextColor($r, $g, $b) - { - $this->textColor = array($r, $g, $b); - - return $this; - } - - /** - * Sets the background color to use - */ - public function setBackgroundColor($r, $g, $b) - { - $this->backgroundColor = array($r, $g, $b); - - return $this; - } - - /** - * Sets the ignoreAllEffects value - * - * @param bool $ignoreAllEffects - * @return CaptchaBuilder - */ - public function setIgnoreAllEffects($ignoreAllEffects) - { - $this->ignoreAllEffects = $ignoreAllEffects; - - return $this; - } - - /** - * Sets the list of background images to use (one image is randomly selected) - */ - public function setBackgroundImages(array $backgroundImages) - { - $this->backgroundImages = $backgroundImages; - - return $this; - } - - /** - * Draw lines over the image - */ - protected function drawLine($image, $width, $height, $tcol = null) - { - if ($tcol === null) { - $tcol = imagecolorallocate($image, $this->rand(100, 255), $this->rand(100, 255), $this->rand(100, 255)); - } - - if ($this->rand(0, 1)) { // Horizontal - $Xa = $this->rand(0, $width/2); - $Ya = $this->rand(0, $height); - $Xb = $this->rand($width/2, $width); - $Yb = $this->rand(0, $height); - } else { // Vertical - $Xa = $this->rand(0, $width); - $Ya = $this->rand(0, $height/2); - $Xb = $this->rand(0, $width); - $Yb = $this->rand($height/2, $height); - } - imagesetthickness($image, $this->rand(1, 3)); - imageline($image, $Xa, $Ya, $Xb, $Yb, $tcol); - } - - /** - * Apply some post effects - */ - protected function postEffect($image) - { - if (!function_exists('imagefilter')) { - return; - } - - if ($this->backgroundColor != null || $this->textColor != null) { - return; - } - - // Negate ? - if ($this->rand(0, 1) == 0) { - imagefilter($image, IMG_FILTER_NEGATE); - } - - // Edge ? - if ($this->rand(0, 10) == 0) { - imagefilter($image, IMG_FILTER_EDGEDETECT); - } - - // Contrast - imagefilter($image, IMG_FILTER_CONTRAST, $this->rand(-50, 10)); - - // Colorize - if ($this->rand(0, 5) == 0) { - imagefilter($image, IMG_FILTER_COLORIZE, $this->rand(-80, 50), $this->rand(-80, 50), $this->rand(-80, 50)); - } - } - - /** - * Writes the phrase on the image - */ - protected function writePhrase($image, $phrase, $font, $width, $height) - { - $length = strlen($phrase); - if ($length === 0) { - return imagecolorallocate($image, 0, 0, 0); - } - - // Gets the text size and start position - $size = $width / $length - $this->rand(0, 3) - 1; - $box = imagettfbbox($size, 0, $font, $phrase); - $textWidth = $box[2] - $box[0]; - $textHeight = $box[1] - $box[7]; - $x = ($width - $textWidth) / 2; - $y = ($height - $textHeight) / 2 + $size; - - if (!count($this->textColor)) { - $textColor = array($this->rand(0, 150), $this->rand(0, 150), $this->rand(0, 150)); - } else { - $textColor = $this->textColor; - } - $col = imagecolorallocate($image, $textColor[0], $textColor[1], $textColor[2]); - - // Write the letters one by one, with random angle - for ($i=0; $i<$length; $i++) { - $box = imagettfbbox($size, 0, $font, $phrase[$i]); - $w = $box[2] - $box[0]; - $angle = $this->rand(-$this->maxAngle, $this->maxAngle); - $offset = $this->rand(-$this->maxOffset, $this->maxOffset); - imagettftext($image, $size, $angle, $x, $y + $offset, $col, $font, $phrase[$i]); - $x += $w; - } - - return $col; - } - - /** - * Try to read the code against an OCR - */ - public function isOCRReadable() - { - if (!is_dir($this->tempDir)) { - @mkdir($this->tempDir, 0755, true); - } - - $tempj = $this->tempDir . uniqid('captcha', true) . '.jpg'; - $tempp = $this->tempDir . uniqid('captcha', true) . '.pgm'; - - $this->save($tempj); - shell_exec("convert $tempj $tempp"); - $value = trim(strtolower(shell_exec("ocrad $tempp"))); - - @unlink($tempj); - @unlink($tempp); - - return $this->testPhrase($value); - } - - /** - * Builds while the code is readable against an OCR - */ - public function buildAgainstOCR($width = 150, $height = 40, $font = null, $fingerprint = null) - { - do { - $this->build($width, $height, $font, $fingerprint); - } while ($this->isOCRReadable()); - } - - /** - * Generate the image - */ - public function build($width = 150, $height = 40, $font = null, $fingerprint = null) - { - if (null !== $fingerprint) { - $this->fingerprint = $fingerprint; - $this->useFingerprint = true; - } else { - $this->fingerprint = array(); - $this->useFingerprint = false; - } - - if ($font === null) { - $font = __DIR__ . '/Font/captcha'.$this->rand(0, 5).'.ttf'; - } - - if (empty($this->backgroundImages)) { - // if background images list is not set, use a color fill as a background - $image = imagecreatetruecolor($width, $height); - if ($this->backgroundColor == null) { - $bg = imagecolorallocate($image, $this->rand(200, 255), $this->rand(200, 255), $this->rand(200, 255)); - } else { - $color = $this->backgroundColor; - $bg = imagecolorallocate($image, $color[0], $color[1], $color[2]); - } - $this->background = $bg; - imagefill($image, 0, 0, $bg); - } else { - // use a random background image - $randomBackgroundImage = $this->backgroundImages[rand(0, count($this->backgroundImages)-1)]; - - $imageType = $this->validateBackgroundImage($randomBackgroundImage); - - $image = $this->createBackgroundImageFromType($randomBackgroundImage, $imageType); - } - - // Apply effects - if (!$this->ignoreAllEffects) { - $square = $width * $height; - $effects = $this->rand($square/3000, $square/2000); - - // set the maximum number of lines to draw in front of the text - if ($this->maxBehindLines != null && $this->maxBehindLines > 0) { - $effects = min($this->maxBehindLines, $effects); - } - - if ($this->maxBehindLines !== 0) { - for ($e = 0; $e < $effects; $e++) { - $this->drawLine($image, $width, $height); - } - } - } - - // Write CAPTCHA text - $color = $this->writePhrase($image, $this->phrase, $font, $width, $height); - - // Apply effects - if (!$this->ignoreAllEffects) { - $square = $width * $height; - $effects = $this->rand($square/3000, $square/2000); - - // set the maximum number of lines to draw in front of the text - if ($this->maxFrontLines != null && $this->maxFrontLines > 0) { - $effects = min($this->maxFrontLines, $effects); - } - - if ($this->maxFrontLines !== 0) { - for ($e = 0; $e < $effects; $e++) { - $this->drawLine($image, $width, $height, $color); - } - } - } - - // Distort the image - if ($this->distortion && !$this->ignoreAllEffects) { - $image = $this->distort($image, $width, $height, $bg); - } - - // Post effects - if (!$this->ignoreAllEffects) { - $this->postEffect($image); - } - - $this->contents = $image; - - return $this; - } - - /** - * Distorts the image - */ - public function distort($image, $width, $height, $bg) - { - $contents = imagecreatetruecolor($width, $height); - $X = $this->rand(0, $width); - $Y = $this->rand(0, $height); - $phase = $this->rand(0, 10); - $scale = 1.1 + $this->rand(0, 10000) / 30000; - for ($x = 0; $x < $width; $x++) { - for ($y = 0; $y < $height; $y++) { - $Vx = $x - $X; - $Vy = $y - $Y; - $Vn = sqrt($Vx * $Vx + $Vy * $Vy); - - if ($Vn != 0) { - $Vn2 = $Vn + 4 * sin($Vn / 30); - $nX = $X + ($Vx * $Vn2 / $Vn); - $nY = $Y + ($Vy * $Vn2 / $Vn); - } else { - $nX = $X; - $nY = $Y; - } - $nY = $nY + $scale * sin($phase + $nX * 0.2); - - if ($this->interpolation) { - $p = $this->interpolate( - $nX - floor($nX), - $nY - floor($nY), - $this->getCol($image, floor($nX), floor($nY), $bg), - $this->getCol($image, ceil($nX), floor($nY), $bg), - $this->getCol($image, floor($nX), ceil($nY), $bg), - $this->getCol($image, ceil($nX), ceil($nY), $bg) - ); - } else { - $p = $this->getCol($image, round($nX), round($nY), $bg); - } - - if ($p == 0) { - $p = $bg; - } - - imagesetpixel($contents, $x, $y, $p); - } - } - - return $contents; - } - - /** - * Saves the Captcha to a jpeg file - */ - public function save($filename, $quality = 90) - { - imagejpeg($this->contents, $filename, $quality); - } - - /** - * Gets the image GD - */ - public function getGd() - { - return $this->contents; - } - - /** - * Gets the image contents - */ - public function get($quality = 90) - { - ob_start(); - $this->output($quality); - - return ob_get_clean(); - } - - /** - * Gets the HTML inline base64 - */ - public function inline($quality = 90) - { - return 'data:image/jpeg;base64,' . base64_encode($this->get($quality)); - } - - /** - * Outputs the image - */ - public function output($quality = 90) - { - imagejpeg($this->contents, null, $quality); - } - - /** - * @return array - */ - public function getFingerprint() - { - return $this->fingerprint; - } - - /** - * Returns a random number or the next number in the - * fingerprint - */ - protected function rand($min, $max) - { - if (!is_array($this->fingerprint)) { - $this->fingerprint = array(); - } - - if ($this->useFingerprint) { - $value = current($this->fingerprint); - next($this->fingerprint); - } else { - $value = mt_rand($min, $max); - $this->fingerprint[] = $value; - } - - return $value; - } - - /** - * @param $x - * @param $y - * @param $nw - * @param $ne - * @param $sw - * @param $se - * - * @return int - */ - protected function interpolate($x, $y, $nw, $ne, $sw, $se) - { - list($r0, $g0, $b0) = $this->getRGB($nw); - list($r1, $g1, $b1) = $this->getRGB($ne); - list($r2, $g2, $b2) = $this->getRGB($sw); - list($r3, $g3, $b3) = $this->getRGB($se); - - $cx = 1.0 - $x; - $cy = 1.0 - $y; - - $m0 = $cx * $r0 + $x * $r1; - $m1 = $cx * $r2 + $x * $r3; - $r = (int) ($cy * $m0 + $y * $m1); - - $m0 = $cx * $g0 + $x * $g1; - $m1 = $cx * $g2 + $x * $g3; - $g = (int) ($cy * $m0 + $y * $m1); - - $m0 = $cx * $b0 + $x * $b1; - $m1 = $cx * $b2 + $x * $b3; - $b = (int) ($cy * $m0 + $y * $m1); - - return ($r << 16) | ($g << 8) | $b; - } - - /** - * @param $image - * @param $x - * @param $y - * - * @return int - */ - protected function getCol($image, $x, $y, $background) - { - $L = imagesx($image); - $H = imagesy($image); - if ($x < 0 || $x >= $L || $y < 0 || $y >= $H) { - return $background; - } - - return imagecolorat($image, $x, $y); - } - - /** - * @param $col - * - * @return array - */ - protected function getRGB($col) - { - return array( - (int) ($col >> 16) & 0xff, - (int) ($col >> 8) & 0xff, - (int) ($col) & 0xff, - ); - } - - /** - * Validate the background image path. Return the image type if valid - * - * @param string $backgroundImage - * @return string - * @throws Exception - */ - protected function validateBackgroundImage($backgroundImage) - { - // check if file exists - if (!file_exists($backgroundImage)) { - $backgroundImageExploded = explode('/', $backgroundImage); - $imageFileName = count($backgroundImageExploded) > 1? $backgroundImageExploded[count($backgroundImageExploded)-1] : $backgroundImage; - - throw new Exception('Invalid background image: ' . $imageFileName); - } - - // check image type - $finfo = finfo_open(FILEINFO_MIME_TYPE); // return mime type ala mimetype extension - $imageType = finfo_file($finfo, $backgroundImage); - finfo_close($finfo); - - if (!in_array ($imageType, $this->allowedBackgroundImageTypes)) { - throw new Exception('Invalid background image type! Allowed types are: ' . join(', ', $this->allowedBackgroundImageTypes)); - } - - return $imageType; - } - - /** - * Create background image from type - * - * @param string $backgroundImage - * @param string $imageType - * @return resource - * @throws Exception - */ - protected function createBackgroundImageFromType($backgroundImage, $imageType) - { - switch ($imageType) { - case 'image/jpeg': - $image = imagecreatefromjpeg($backgroundImage); - break; - case 'image/png': - $image = imagecreatefrompng($backgroundImage); - break; - case 'image/gif': - $image = imagecreatefromgif($backgroundImage); - break; - - default: - throw new Exception('Not supported file type for background image!'); - break; - } - - return $image; - } -} diff --git a/vendor/gregwar/captcha/CaptchaBuilderInterface.php b/vendor/gregwar/captcha/CaptchaBuilderInterface.php deleted file mode 100644 index bdebf38f..00000000 --- a/vendor/gregwar/captcha/CaptchaBuilderInterface.php +++ /dev/null @@ -1,30 +0,0 @@ - - * @author Jeremy Livingston - */ -class ImageFileHandler -{ - /** - * Name of folder for captcha images - * @var string - */ - protected $imageFolder; - - /** - * Absolute path to public web folder - * @var string - */ - protected $webPath; - - /** - * Frequency of garbage collection in fractions of 1 - * @var int - */ - protected $gcFreq; - - /** - * Maximum age of images in minutes - * @var int - */ - protected $expiration; - - /** - * @param $imageFolder - * @param $webPath - * @param $gcFreq - * @param $expiration - */ - public function __construct($imageFolder, $webPath, $gcFreq, $expiration) - { - $this->imageFolder = $imageFolder; - $this->webPath = $webPath; - $this->gcFreq = $gcFreq; - $this->expiration = $expiration; - } - - /** - * Saves the provided image content as a file - * - * @param string $contents - * - * @return string - */ - public function saveAsFile($contents) - { - $this->createFolderIfMissing(); - - $filename = md5(uniqid()) . '.jpg'; - $filePath = $this->webPath . '/' . $this->imageFolder . '/' . $filename; - imagejpeg($contents, $filePath, 15); - - return '/' . $this->imageFolder . '/' . $filename; - } - - /** - * Randomly runs garbage collection on the image directory - * - * @return bool - */ - public function collectGarbage() - { - if (!mt_rand(1, $this->gcFreq) == 1) { - return false; - } - - $this->createFolderIfMissing(); - - $finder = new Finder(); - $criteria = sprintf('<= now - %s minutes', $this->expiration); - $finder->in($this->webPath . '/' . $this->imageFolder) - ->date($criteria); - - foreach($finder->files() as $file) { - unlink($file->getPathname()); - } - - return true; - } - - /** - * Creates the folder if it doesn't exist - */ - protected function createFolderIfMissing() - { - if (!file_exists($this->webPath . '/' . $this->imageFolder)) { - mkdir($this->webPath . '/' . $this->imageFolder, 0755); - } - } -} - diff --git a/vendor/gregwar/captcha/LICENSE b/vendor/gregwar/captcha/LICENSE index 7db6ad8e..62f991a6 100644 --- a/vendor/gregwar/captcha/LICENSE +++ b/vendor/gregwar/captcha/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) <2012-2015> Grégoire Passault +Copyright (c) <2012-2017> Grégoire Passault Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/vendor/gregwar/captcha/PhraseBuilder.php b/vendor/gregwar/captcha/PhraseBuilder.php deleted file mode 100644 index b94bd61c..00000000 --- a/vendor/gregwar/captcha/PhraseBuilder.php +++ /dev/null @@ -1,34 +0,0 @@ - - */ -class PhraseBuilder implements PhraseBuilderInterface -{ - /** - * Generates random phrase of given length with given charset - */ - public function build($length = 5, $charset = 'abcdefghijklmnpqrstuvwxyz123456789') - { - $phrase = ''; - $chars = str_split($charset); - - for ($i = 0; $i < $length; $i++) { - $phrase .= $chars[array_rand($chars)]; - } - - return $phrase; - } - - /** - * "Niceize" a code - */ - public function niceize($str) - { - return strtr(strtolower($str), '01', 'ol'); - } -} diff --git a/vendor/gregwar/captcha/PhraseBuilderInterface.php b/vendor/gregwar/captcha/PhraseBuilderInterface.php deleted file mode 100644 index 0a4f5361..00000000 --- a/vendor/gregwar/captcha/PhraseBuilderInterface.php +++ /dev/null @@ -1,21 +0,0 @@ - - */ -interface PhraseBuilderInterface -{ - /** - * Generates random phrase of given length with given charset - */ - public function build($length, $charset); - - /** - * "Niceize" a code - */ - public function niceize($str); -} diff --git a/vendor/gregwar/captcha/README.md b/vendor/gregwar/captcha/README.md index 9f6c17a9..9f4d94b1 100644 --- a/vendor/gregwar/captcha/README.md +++ b/vendor/gregwar/captcha/README.md @@ -2,6 +2,7 @@ Captcha ======= ![Captchas examples](http://gregwar.com/captchas.png) +[![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=YUXRLWHQSWS6L) Installation ============ @@ -96,12 +97,43 @@ You can use theses functions : * **setMaxBehindLines($lines)**, sets the maximum number of lines behind the code * **setMaxFrontLines($lines)**, sets the maximum number of lines on the front of the code -Symfony 2 Bundle +If you want to change the number of character, you can call the phrase builder directly using +extra parameters: + +```php +use Gregwar\Captcha\CaptchaBuilder; +use Gregwar\Captcha\PhraseBuilder; + +// Will build phrases of 3 characters +$phraseBuilder = new PhraseBuilder(4) + +// Will build phrases of 5 characters, only digits +$phraseBuilder = new PhraseBuilder(5, '0123456789'); + +// Pass it as first argument of CaptchaBuilder, passing it the phrase +// builder +$captcha = new CaptchaBuilder(null, $phraseBuilder); +``` + +You can also pass directly the wanted phrase to the builder: + +```php +// Building a Captcha with the "hello" phrase +$captcha = new CaptchaBuilder('hello'); +``` + +Symfony Bundle ================ You can have a look at the following repository to enjoy the Symfony 2 bundle packaging this captcha generator : https://github.com/Gregwar/CaptchaBundle +Yii2 Extension +=============== + +You can use the following extension for integrating with Yii2 Framework : +https://github.com/juliardi/yii2-captcha + License ======= diff --git a/vendor/gregwar/captcha/autoload.php b/vendor/gregwar/captcha/autoload.php deleted file mode 100644 index 8b3fa392..00000000 --- a/vendor/gregwar/captcha/autoload.php +++ /dev/null @@ -1,16 +0,0 @@ -=5.3.0", - "ext-gd": "*" + "ext-gd": "*", + "ext-mbstring": "*", + "symfony/finder": "~3.0" }, "autoload": { "psr-4": { - "Gregwar\\Captcha\\": "/" + "Gregwar\\": "src/Gregwar" } + }, + "require-dev": { + "phpunit/phpunit": "^6.4" } } diff --git a/vendor/gregwar/captcha/demo/demo.php b/vendor/gregwar/captcha/demo/demo.php index 7852745f..87116cd7 100644 --- a/vendor/gregwar/captcha/demo/demo.php +++ b/vendor/gregwar/captcha/demo/demo.php @@ -1,9 +1,6 @@ + + + + + ./tests/ + + + + + + ./src + + + diff --git a/vendor/gregwar/captcha/src/Gregwar/Captcha/CaptchaBuilder.php b/vendor/gregwar/captcha/src/Gregwar/Captcha/CaptchaBuilder.php new file mode 100644 index 00000000..6db2f2c3 --- /dev/null +++ b/vendor/gregwar/captcha/src/Gregwar/Captcha/CaptchaBuilder.php @@ -0,0 +1,721 @@ + + * @author Jeremy Livingston + */ +class CaptchaBuilder implements CaptchaBuilderInterface +{ + /** + * @var array + */ + protected $fingerprint = array(); + + /** + * @var bool + */ + protected $useFingerprint = false; + + /** + * @var array + */ + protected $textColor = null; + + /** + * @var array + */ + protected $backgroundColor = null; + + /** + * @var array + */ + protected $backgroundImages = array(); + + /** + * @var resource + */ + protected $contents = null; + + /** + * @var string + */ + protected $phrase = null; + + /** + * @var PhraseBuilderInterface + */ + protected $builder; + + /** + * @var bool + */ + protected $distortion = true; + + /** + * The maximum number of lines to draw in front of + * the image. null - use default algorithm + */ + protected $maxFrontLines = null; + + /** + * The maximum number of lines to draw behind + * the image. null - use default algorithm + */ + protected $maxBehindLines = null; + + /** + * The maximum angle of char + */ + protected $maxAngle = 8; + + /** + * The maximum offset of char + */ + protected $maxOffset = 5; + + /** + * Is the interpolation enabled ? + * + * @var bool + */ + protected $interpolation = true; + + /** + * Ignore all effects + * + * @var bool + */ + protected $ignoreAllEffects = false; + + /** + * Allowed image types for the background images + * + * @var array + */ + protected $allowedBackgroundImageTypes = array('image/png', 'image/jpeg', 'image/gif'); + + /** + * The image contents + */ + public function getContents() + { + return $this->contents; + } + + /** + * Enable/Disables the interpolation + * + * @param $interpolate bool True to enable, false to disable + * + * @return CaptchaBuilder + */ + public function setInterpolation($interpolate = true) + { + $this->interpolation = $interpolate; + + return $this; + } + + /** + * Temporary dir, for OCR check + */ + public $tempDir = 'temp/'; + + public function __construct($phrase = null, PhraseBuilderInterface $builder = null) + { + if ($builder === null) { + $this->builder = new PhraseBuilder; + } else { + $this->builder = $builder; + } + + if ($phrase === null) { + $phrase = $this->builder->build(); + } + + $this->phrase = $phrase; + } + + /** + * Setting the phrase + */ + public function setPhrase($phrase) + { + $this->phrase = (string) $phrase; + } + + /** + * Enables/disable distortion + */ + public function setDistortion($distortion) + { + $this->distortion = (bool) $distortion; + + return $this; + } + + public function setMaxBehindLines($maxBehindLines) + { + $this->maxBehindLines = $maxBehindLines; + + return $this; + } + + public function setMaxFrontLines($maxFrontLines) + { + $this->maxFrontLines = $maxFrontLines; + + return $this; + } + + public function setMaxAngle($maxAngle) + { + $this->maxAngle = $maxAngle; + + return $this; + } + + public function setMaxOffset($maxOffset) + { + $this->maxOffset = $maxOffset; + + return $this; + } + + /** + * Gets the captcha phrase + */ + public function getPhrase() + { + return $this->phrase; + } + + /** + * Returns true if the given phrase is good + */ + public function testPhrase($phrase) + { + return ($this->builder->niceize($phrase) == $this->builder->niceize($this->getPhrase())); + } + + /** + * Instantiation + */ + public static function create($phrase = null) + { + return new self($phrase); + } + + /** + * Sets the text color to use + */ + public function setTextColor($r, $g, $b) + { + $this->textColor = array($r, $g, $b); + + return $this; + } + + /** + * Sets the background color to use + */ + public function setBackgroundColor($r, $g, $b) + { + $this->backgroundColor = array($r, $g, $b); + + return $this; + } + + /** + * Sets the ignoreAllEffects value + * + * @param bool $ignoreAllEffects + * @return CaptchaBuilder + */ + public function setIgnoreAllEffects($ignoreAllEffects) + { + $this->ignoreAllEffects = $ignoreAllEffects; + + return $this; + } + + /** + * Sets the list of background images to use (one image is randomly selected) + */ + public function setBackgroundImages(array $backgroundImages) + { + $this->backgroundImages = $backgroundImages; + + return $this; + } + + /** + * Draw lines over the image + */ + protected function drawLine($image, $width, $height, $tcol = null) + { + if ($tcol === null) { + $tcol = imagecolorallocate($image, $this->rand(100, 255), $this->rand(100, 255), $this->rand(100, 255)); + } + + if ($this->rand(0, 1)) { // Horizontal + $Xa = $this->rand(0, $width/2); + $Ya = $this->rand(0, $height); + $Xb = $this->rand($width/2, $width); + $Yb = $this->rand(0, $height); + } else { // Vertical + $Xa = $this->rand(0, $width); + $Ya = $this->rand(0, $height/2); + $Xb = $this->rand(0, $width); + $Yb = $this->rand($height/2, $height); + } + imagesetthickness($image, $this->rand(1, 3)); + imageline($image, $Xa, $Ya, $Xb, $Yb, $tcol); + } + + /** + * Apply some post effects + */ + protected function postEffect($image) + { + if (!function_exists('imagefilter')) { + return; + } + + if ($this->backgroundColor != null || $this->textColor != null) { + return; + } + + // Negate ? + if ($this->rand(0, 1) == 0) { + imagefilter($image, IMG_FILTER_NEGATE); + } + + // Edge ? + if ($this->rand(0, 10) == 0) { + imagefilter($image, IMG_FILTER_EDGEDETECT); + } + + // Contrast + imagefilter($image, IMG_FILTER_CONTRAST, $this->rand(-50, 10)); + + // Colorize + if ($this->rand(0, 5) == 0) { + imagefilter($image, IMG_FILTER_COLORIZE, $this->rand(-80, 50), $this->rand(-80, 50), $this->rand(-80, 50)); + } + } + + /** + * Writes the phrase on the image + */ + protected function writePhrase($image, $phrase, $font, $width, $height) + { + $length = mb_strlen($phrase); + if ($length === 0) { + return \imagecolorallocate($image, 0, 0, 0); + } + + // Gets the text size and start position + $size = $width / $length - $this->rand(0, 3) - 1; + $box = \imagettfbbox($size, 0, $font, $phrase); + $textWidth = $box[2] - $box[0]; + $textHeight = $box[1] - $box[7]; + $x = ($width - $textWidth) / 2; + $y = ($height - $textHeight) / 2 + $size; + + if (!$this->textColor) { + $textColor = array($this->rand(0, 150), $this->rand(0, 150), $this->rand(0, 150)); + } else { + $textColor = $this->textColor; + } + $col = \imagecolorallocate($image, $textColor[0], $textColor[1], $textColor[2]); + + // Write the letters one by one, with random angle + for ($i=0; $i<$length; $i++) { + $symbol = mb_substr($phrase, $i, 1); + $box = \imagettfbbox($size, 0, $font, $symbol); + $w = $box[2] - $box[0]; + $angle = $this->rand(-$this->maxAngle, $this->maxAngle); + $offset = $this->rand(-$this->maxOffset, $this->maxOffset); + \imagettftext($image, $size, $angle, $x, $y + $offset, $col, $font, $symbol); + $x += $w; + } + + return $col; + } + + /** + * Try to read the code against an OCR + */ + public function isOCRReadable() + { + if (!is_dir($this->tempDir)) { + @mkdir($this->tempDir, 0755, true); + } + + $tempj = $this->tempDir . uniqid('captcha', true) . '.jpg'; + $tempp = $this->tempDir . uniqid('captcha', true) . '.pgm'; + + $this->save($tempj); + shell_exec("convert $tempj $tempp"); + $value = trim(strtolower(shell_exec("ocrad $tempp"))); + + @unlink($tempj); + @unlink($tempp); + + return $this->testPhrase($value); + } + + /** + * Builds while the code is readable against an OCR + */ + public function buildAgainstOCR($width = 150, $height = 40, $font = null, $fingerprint = null) + { + do { + $this->build($width, $height, $font, $fingerprint); + } while ($this->isOCRReadable()); + } + + /** + * Generate the image + */ + public function build($width = 150, $height = 40, $font = null, $fingerprint = null) + { + if (null !== $fingerprint) { + $this->fingerprint = $fingerprint; + $this->useFingerprint = true; + } else { + $this->fingerprint = array(); + $this->useFingerprint = false; + } + + if ($font === null) { + $font = __DIR__ . '/Font/captcha'.$this->rand(0, 5).'.ttf'; + } + + if (empty($this->backgroundImages)) { + // if background images list is not set, use a color fill as a background + $image = imagecreatetruecolor($width, $height); + if ($this->backgroundColor == null) { + $bg = imagecolorallocate($image, $this->rand(200, 255), $this->rand(200, 255), $this->rand(200, 255)); + } else { + $color = $this->backgroundColor; + $bg = imagecolorallocate($image, $color[0], $color[1], $color[2]); + } + $this->background = $bg; + imagefill($image, 0, 0, $bg); + } else { + // use a random background image + $randomBackgroundImage = $this->backgroundImages[rand(0, count($this->backgroundImages)-1)]; + + $imageType = $this->validateBackgroundImage($randomBackgroundImage); + + $image = $this->createBackgroundImageFromType($randomBackgroundImage, $imageType); + } + + // Apply effects + if (!$this->ignoreAllEffects) { + $square = $width * $height; + $effects = $this->rand($square/3000, $square/2000); + + // set the maximum number of lines to draw in front of the text + if ($this->maxBehindLines != null && $this->maxBehindLines > 0) { + $effects = min($this->maxBehindLines, $effects); + } + + if ($this->maxBehindLines !== 0) { + for ($e = 0; $e < $effects; $e++) { + $this->drawLine($image, $width, $height); + } + } + } + + // Write CAPTCHA text + $color = $this->writePhrase($image, $this->phrase, $font, $width, $height); + + // Apply effects + if (!$this->ignoreAllEffects) { + $square = $width * $height; + $effects = $this->rand($square/3000, $square/2000); + + // set the maximum number of lines to draw in front of the text + if ($this->maxFrontLines != null && $this->maxFrontLines > 0) { + $effects = min($this->maxFrontLines, $effects); + } + + if ($this->maxFrontLines !== 0) { + for ($e = 0; $e < $effects; $e++) { + $this->drawLine($image, $width, $height, $color); + } + } + } + + // Distort the image + if ($this->distortion && !$this->ignoreAllEffects) { + $image = $this->distort($image, $width, $height, $bg); + } + + // Post effects + if (!$this->ignoreAllEffects) { + $this->postEffect($image); + } + + $this->contents = $image; + + return $this; + } + + /** + * Distorts the image + */ + public function distort($image, $width, $height, $bg) + { + $contents = imagecreatetruecolor($width, $height); + $X = $this->rand(0, $width); + $Y = $this->rand(0, $height); + $phase = $this->rand(0, 10); + $scale = 1.1 + $this->rand(0, 10000) / 30000; + for ($x = 0; $x < $width; $x++) { + for ($y = 0; $y < $height; $y++) { + $Vx = $x - $X; + $Vy = $y - $Y; + $Vn = sqrt($Vx * $Vx + $Vy * $Vy); + + if ($Vn != 0) { + $Vn2 = $Vn + 4 * sin($Vn / 30); + $nX = $X + ($Vx * $Vn2 / $Vn); + $nY = $Y + ($Vy * $Vn2 / $Vn); + } else { + $nX = $X; + $nY = $Y; + } + $nY = $nY + $scale * sin($phase + $nX * 0.2); + + if ($this->interpolation) { + $p = $this->interpolate( + $nX - floor($nX), + $nY - floor($nY), + $this->getCol($image, floor($nX), floor($nY), $bg), + $this->getCol($image, ceil($nX), floor($nY), $bg), + $this->getCol($image, floor($nX), ceil($nY), $bg), + $this->getCol($image, ceil($nX), ceil($nY), $bg) + ); + } else { + $p = $this->getCol($image, round($nX), round($nY), $bg); + } + + if ($p == 0) { + $p = $bg; + } + + imagesetpixel($contents, $x, $y, $p); + } + } + + return $contents; + } + + /** + * Saves the Captcha to a jpeg file + */ + public function save($filename, $quality = 90) + { + imagejpeg($this->contents, $filename, $quality); + } + + /** + * Gets the image GD + */ + public function getGd() + { + return $this->contents; + } + + /** + * Gets the image contents + */ + public function get($quality = 90) + { + ob_start(); + $this->output($quality); + + return ob_get_clean(); + } + + /** + * Gets the HTML inline base64 + */ + public function inline($quality = 90) + { + return 'data:image/jpeg;base64,' . base64_encode($this->get($quality)); + } + + /** + * Outputs the image + */ + public function output($quality = 90) + { + imagejpeg($this->contents, null, $quality); + } + + /** + * @return array + */ + public function getFingerprint() + { + return $this->fingerprint; + } + + /** + * Returns a random number or the next number in the + * fingerprint + */ + protected function rand($min, $max) + { + if (!is_array($this->fingerprint)) { + $this->fingerprint = array(); + } + + if ($this->useFingerprint) { + $value = current($this->fingerprint); + next($this->fingerprint); + } else { + $value = mt_rand($min, $max); + $this->fingerprint[] = $value; + } + + return $value; + } + + /** + * @param $x + * @param $y + * @param $nw + * @param $ne + * @param $sw + * @param $se + * + * @return int + */ + protected function interpolate($x, $y, $nw, $ne, $sw, $se) + { + list($r0, $g0, $b0) = $this->getRGB($nw); + list($r1, $g1, $b1) = $this->getRGB($ne); + list($r2, $g2, $b2) = $this->getRGB($sw); + list($r3, $g3, $b3) = $this->getRGB($se); + + $cx = 1.0 - $x; + $cy = 1.0 - $y; + + $m0 = $cx * $r0 + $x * $r1; + $m1 = $cx * $r2 + $x * $r3; + $r = (int) ($cy * $m0 + $y * $m1); + + $m0 = $cx * $g0 + $x * $g1; + $m1 = $cx * $g2 + $x * $g3; + $g = (int) ($cy * $m0 + $y * $m1); + + $m0 = $cx * $b0 + $x * $b1; + $m1 = $cx * $b2 + $x * $b3; + $b = (int) ($cy * $m0 + $y * $m1); + + return ($r << 16) | ($g << 8) | $b; + } + + /** + * @param $image + * @param $x + * @param $y + * + * @return int + */ + protected function getCol($image, $x, $y, $background) + { + $L = imagesx($image); + $H = imagesy($image); + if ($x < 0 || $x >= $L || $y < 0 || $y >= $H) { + return $background; + } + + return imagecolorat($image, $x, $y); + } + + /** + * @param $col + * + * @return array + */ + protected function getRGB($col) + { + return array( + (int) ($col >> 16) & 0xff, + (int) ($col >> 8) & 0xff, + (int) ($col) & 0xff, + ); + } + + /** + * Validate the background image path. Return the image type if valid + * + * @param string $backgroundImage + * @return string + * @throws Exception + */ + protected function validateBackgroundImage($backgroundImage) + { + // check if file exists + if (!file_exists($backgroundImage)) { + $backgroundImageExploded = explode('/', $backgroundImage); + $imageFileName = count($backgroundImageExploded) > 1? $backgroundImageExploded[count($backgroundImageExploded)-1] : $backgroundImage; + + throw new Exception('Invalid background image: ' . $imageFileName); + } + + // check image type + $finfo = finfo_open(FILEINFO_MIME_TYPE); // return mime type ala mimetype extension + $imageType = finfo_file($finfo, $backgroundImage); + finfo_close($finfo); + + if (!in_array($imageType, $this->allowedBackgroundImageTypes)) { + throw new Exception('Invalid background image type! Allowed types are: ' . join(', ', $this->allowedBackgroundImageTypes)); + } + + return $imageType; + } + + /** + * Create background image from type + * + * @param string $backgroundImage + * @param string $imageType + * @return resource + * @throws Exception + */ + protected function createBackgroundImageFromType($backgroundImage, $imageType) + { + switch ($imageType) { + case 'image/jpeg': + $image = imagecreatefromjpeg($backgroundImage); + break; + case 'image/png': + $image = imagecreatefrompng($backgroundImage); + break; + case 'image/gif': + $image = imagecreatefromgif($backgroundImage); + break; + + default: + throw new Exception('Not supported file type for background image!'); + break; + } + + return $image; + } +} diff --git a/vendor/gregwar/captcha/src/Gregwar/Captcha/CaptchaBuilderInterface.php b/vendor/gregwar/captcha/src/Gregwar/Captcha/CaptchaBuilderInterface.php new file mode 100644 index 00000000..bebd0704 --- /dev/null +++ b/vendor/gregwar/captcha/src/Gregwar/Captcha/CaptchaBuilderInterface.php @@ -0,0 +1,29 @@ + + * @author Jeremy Livingston + */ +class ImageFileHandler +{ + /** + * Name of folder for captcha images + * @var string + */ + protected $imageFolder; + + /** + * Absolute path to public web folder + * @var string + */ + protected $webPath; + + /** + * Frequency of garbage collection in fractions of 1 + * @var int + */ + protected $gcFreq; + + /** + * Maximum age of images in minutes + * @var int + */ + protected $expiration; + + /** + * @param $imageFolder + * @param $webPath + * @param $gcFreq + * @param $expiration + */ + public function __construct($imageFolder, $webPath, $gcFreq, $expiration) + { + $this->imageFolder = $imageFolder; + $this->webPath = $webPath; + $this->gcFreq = $gcFreq; + $this->expiration = $expiration; + } + + /** + * Saves the provided image content as a file + * + * @param string $contents + * + * @return string + */ + public function saveAsFile($contents) + { + $this->createFolderIfMissing(); + + $filename = md5(uniqid()) . '.jpg'; + $filePath = $this->webPath . '/' . $this->imageFolder . '/' . $filename; + imagejpeg($contents, $filePath, 15); + + return '/' . $this->imageFolder . '/' . $filename; + } + + /** + * Randomly runs garbage collection on the image directory + * + * @return bool + */ + public function collectGarbage() + { + if (!mt_rand(1, $this->gcFreq) == 1) { + return false; + } + + $this->createFolderIfMissing(); + + $finder = new Finder(); + $criteria = sprintf('<= now - %s minutes', $this->expiration); + $finder->in($this->webPath . '/' . $this->imageFolder) + ->date($criteria); + + foreach ($finder->files() as $file) { + unlink($file->getPathname()); + } + + return true; + } + + /** + * Creates the folder if it doesn't exist + */ + protected function createFolderIfMissing() + { + if (!file_exists($this->webPath . '/' . $this->imageFolder)) { + mkdir($this->webPath . '/' . $this->imageFolder, 0755); + } + } +} diff --git a/vendor/gregwar/captcha/src/Gregwar/Captcha/PhraseBuilder.php b/vendor/gregwar/captcha/src/Gregwar/Captcha/PhraseBuilder.php new file mode 100644 index 00000000..5cc938b6 --- /dev/null +++ b/vendor/gregwar/captcha/src/Gregwar/Captcha/PhraseBuilder.php @@ -0,0 +1,59 @@ + + */ +class PhraseBuilder implements PhraseBuilderInterface +{ + /** + * @var int + */ + public $length; + + /** + * @var string + */ + public $charset; + /** + * Constructs a PhraseBuilder with given parameters + */ + public function __construct($length = 5, $charset = 'abcdefghijklmnpqrstuvwxyz123456789') + { + $this->length = $length; + $this->charset = $charset; + } + + /** + * Generates random phrase of given length with given charset + */ + public function build($length = null, $charset = null) + { + if ($length !== null) { + $this->length = $length; + } + if ($charset !== null) { + $this->charset = $charset; + } + + $phrase = ''; + $chars = str_split($this->charset); + + for ($i = 0; $i < $this->length; $i++) { + $phrase .= $chars[array_rand($chars)]; + } + + return $phrase; + } + + /** + * "Niceize" a code + */ + public function niceize($str) + { + return strtr(strtolower($str), '01', 'ol'); + } +} diff --git a/vendor/gregwar/captcha/src/Gregwar/Captcha/PhraseBuilderInterface.php b/vendor/gregwar/captcha/src/Gregwar/Captcha/PhraseBuilderInterface.php new file mode 100644 index 00000000..62ec4b08 --- /dev/null +++ b/vendor/gregwar/captcha/src/Gregwar/Captcha/PhraseBuilderInterface.php @@ -0,0 +1,21 @@ + + */ +interface PhraseBuilderInterface +{ + /** + * Generates random phrase of given length with given charset + */ + public function build(); + + /** + * "Niceize" a code + */ + public function niceize($str); +} diff --git a/vendor/gregwar/captcha/tests/CaptchaBuilderTest.php b/vendor/gregwar/captcha/tests/CaptchaBuilderTest.php new file mode 100644 index 00000000..5325a9c1 --- /dev/null +++ b/vendor/gregwar/captcha/tests/CaptchaBuilderTest.php @@ -0,0 +1,30 @@ +build() + ->save('out.jpg') + ; + + $this->assertTrue(file_exists(__DIR__.'/../out.jpg')); + } + + public function testFingerPrint() + { + $int = count(CaptchaBuilder::create() + ->build() + ->getFingerprint() + ); + + $this->assertTrue(is_int($int)); + } +} \ No newline at end of file -- cgit v1.2.3