/** * Generates a captcha image * * @param string $id * @param string $function */ public function captchaImage( $id, $function ) { global $_PLUGINS; if ( $id ) { $absPath = $_PLUGINS->getPluginPath( $this->getPluginId() ); $captcha = cbantispamCaptcha::getInstance( $id, ( $function != 'image' ? $function : null ) ); $code = $captcha->getCaptchaCode(); if ( $this->input( 'ver', null, GetterInterface::STRING ) ) { $code = $captcha->generateCode(); } $height = (int) $this->params->get( 'captcha_internal_height', 40 ); if ( ! $height ) { $height = 40; } $bgColor = $this->params->get( 'captcha_internal_bg_color', '255,255,255' ); if ( ! $bgColor ) { $bgColor = '255,255,255'; } $bgColors = explode( ',', $bgColor ); $imgBgColors = array(); if ( $bgColors ) for( $i = 0; $i < 3; $i++ ) { if ( isset( $bgColors[$i] ) ) { $color = (int) trim( $bgColors[$i] ); $imgBgColors[] = ( $color > 255 ? 255 : ( $color < 0 ? 0 : $color ) ); } } if ( ! $imgBgColors ) { $imgBgColors = array( 255, 255, 255 ); } elseif ( count( $imgBgColors ) < 3 ) { if ( count( $imgBgColors ) < 2 ) { $imgBgColors[] = 255; $imgBgColors[] = 255; } else { $imgBgColors[] = 255; } } $txtColor = $this->params->get( 'captcha_internal_txt_color', '20,40,100' ); if ( ! $txtColor ) { $txtColor = '20,40,100'; } $txtColors = explode( ',', $txtColor ); $imgTxtColors = array(); if ( $txtColors ) for( $i = 0; $i < 3; $i++ ) { if ( isset( $txtColors[$i] ) ) { $color = (int) trim( $txtColors[$i] ); $imgTxtColors[] = ( $color > 255 ? 255 : ( $color < 0 ? 0 : $color ) ); } } if ( ! $imgTxtColors ) { $imgTxtColors = array( 20, 40, 100 ); } elseif ( count( $imgTxtColors ) < 3 ) { if ( count( $imgTxtColors ) < 2 ) { $imgTxtColors[] = 40; $imgTxtColors[] = 100; } else { $imgTxtColors[] = 100; } } $nBgColor = $this->params->get( 'captcha_internal_bg_noise_color', '100,120,180' ); if ( ! $nBgColor ) { $nBgColor = '100,120,180'; } $nBgColors = explode( ',', $nBgColor ); $imgNoiseBgColors = array(); if ( $nBgColors ) for( $i = 0; $i < 3; $i++ ) { if ( isset( $nBgColors[$i] ) ) { $color = (int) trim( $nBgColors[$i] ); $imgNoiseBgColors[] = ( $color > 255 ? 255 : ( $color < 0 ? 0 : $color ) ); } } if ( ! $imgNoiseBgColors ) { $imgNoiseBgColors = array( 100, 120, 180 ); } elseif ( count( $imgNoiseBgColors ) < 3 ) { if ( count( $imgNoiseBgColors ) < 2 ) { $imgNoiseBgColors[] = 120; $imgNoiseBgColors[] = 180; } else { $imgNoiseBgColors[] = 180; } } $nFgColor = $this->params->get( 'captcha_internal_fg_noise_color', '100,120,120' ); if ( ! $nFgColor ) { $nFgColor = '100,120,120'; } $nFgColors = explode( ',', $nFgColor ); $imgNoiseFgColors = array(); if ( $nFgColors ) for( $i = 0; $i < 3; $i++ ) { if ( isset( $nFgColors[$i] ) ) { $color = (int) trim( $nFgColors[$i] ); $imgNoiseFgColors[] = ( $color > 255 ? 255 : ( $color < 0 ? 0 : $color ) ); } } if ( ! $imgNoiseFgColors ) { $imgNoiseFgColors = array( 100, 120, 120 ); } elseif ( count( $imgNoiseFgColors ) < 3 ) { if ( count( $imgNoiseFgColors ) < 2 ) { $imgNoiseFgColors[] = 120; $imgNoiseFgColors[] = 120; } else { $imgNoiseFgColors[] = 120; } } $font = $this->params->get( 'captcha_internal_font', 'monofont.ttf' ); if ( ! $font ) { $font = 'monofont.ttf'; } if ( ! file_exists( $absPath . '/fonts/' . $font ) ) { $imgFont = $absPath . '/fonts/monofont.ttf'; } else { $imgFont = $absPath . '/fonts/' . $font; } if ( ! file_exists( $imgFont ) ) { exit( CBTxt::T( 'failed to locate "[file]" font file', array( '[file]' => $imgFont ) ) ); } $fontSize = ( $height * 0.75 ); $textBox = imagettfbbox( $fontSize, 0, $imgFont, $code ); if ( $textBox === false ) { exit( CBTxt::T( 'imagettfbbox failed to establish image size' ) ); } $width = ( $textBox[4] + 20 ); $image = imagecreate( $width, $height ); if ( $image === false ) { exit( CBTxt::T( 'imagecreate failed to create new image' ) ); } $charRotation = (int) $this->params->get( 'captcha_internal_rotation', 13 ); if ( $charRotation < 0 ) { $charRotation = 0; } $charOffset = (int) $this->params->get( 'captcha_internal_offset', 3 ); if ( $charOffset < 0 ) { $charOffset = 0; } $colorRange = (int) $this->params->get( 'captcha_internal_color_range', 2 ); if ( $colorRange < 0 ) { $colorRange = 0; } if ( $colorRange ) { $bgColorR = mt_rand( ( ( $imgBgColors[0] - $colorRange ) < 0 ? 0 : ( $imgBgColors[0] - $colorRange ) ), ( ( $imgBgColors[0] + $colorRange ) > 255 ? 255 : ( $imgBgColors[0] + $colorRange ) ) ); $bgColorG = mt_rand( ( ( $imgBgColors[1] - $colorRange ) < 0 ? 0 : ( $imgBgColors[1] - $colorRange ) ), ( ( $imgBgColors[1] + $colorRange ) > 255 ? 255 : ( $imgBgColors[1] + $colorRange ) ) ); $bgColorB = mt_rand( ( ( $imgBgColors[2] - $colorRange ) < 0 ? 0 : ( $imgBgColors[2] - $colorRange ) ), ( ( $imgBgColors[2] + $colorRange ) > 255 ? 255 : ( $imgBgColors[2] + $colorRange ) ) ); if ( imagecolorallocate( $image, $bgColorR, $bgColorG, $bgColorB ) === false ) { exit( CBTxt::T( 'CAPTCHA_IMAGE_BG_COLOR_FAILED', 'imagecolorallocate failed to set BG colors [r], [g], [b]', array( '[r]' => $bgColorR, '[g]' => $bgColorG, '[b]' => $bgColorB ) ) ); } $textColorR = mt_rand( ( ( $imgTxtColors[0] - $colorRange ) < 0 ? 0 : ( $imgTxtColors[0] - $colorRange ) ), ( ( $imgTxtColors[0] + $colorRange ) > 255 ? 255 : ( $imgTxtColors[0] + $colorRange ) ) ); $textColorG = mt_rand( ( ( $imgTxtColors[1] - $colorRange ) < 0 ? 0 : ( $imgTxtColors[1] - $colorRange ) ), ( ( $imgTxtColors[1] + $colorRange ) > 255 ? 255 : ( $imgTxtColors[1] + $colorRange ) ) ); $textColorB = mt_rand( ( ( $imgTxtColors[2] - $colorRange ) < 0 ? 0 : ( $imgTxtColors[2] - $colorRange ) ), ( ( $imgTxtColors[2] + $colorRange ) > 255 ? 255 : ( $imgTxtColors[2] + $colorRange ) ) ); $textColor = imagecolorallocate( $image, $textColorR, $textColorG, $textColorB ); if ( $textColor === false ) { exit( CBTxt::T( 'CAPTCHA_IMAGE_TEXT_COLOR_FAILED', 'imagecolorallocate failed to set text colors [r], [g], [b]', array( '[r]' => $textColorR, '[g]' => $textColorG, '[b]' => $textColorB ) ) ); } $noiseBgColorR = mt_rand( ( ( $imgNoiseBgColors[0] - $colorRange ) < 0 ? 0 : ( $imgNoiseBgColors[0] - $colorRange ) ), ( ( $imgNoiseBgColors[0] + $colorRange ) > 255 ? 255 : ( $imgNoiseBgColors[0] + $colorRange ) ) ); $noiseBgColorG = mt_rand( ( ( $imgNoiseBgColors[1] - $colorRange ) < 0 ? 0 : ( $imgNoiseBgColors[1] - $colorRange ) ), ( ( $imgNoiseBgColors[1] + $colorRange ) > 255 ? 255 : ( $imgNoiseBgColors[1] + $colorRange ) ) ); $noiseBgColorB = mt_rand( ( ( $imgNoiseBgColors[2] - $colorRange ) < 0 ? 0 : ( $imgNoiseBgColors[2] - $colorRange ) ), ( ( $imgNoiseBgColors[2] + $colorRange ) > 255 ? 255 : ( $imgNoiseBgColors[2] + $colorRange ) ) ); $noiseBgColor = imagecolorallocate( $image, $noiseBgColorR, $noiseBgColorG, $noiseBgColorB ); if ( $noiseBgColor === false ) { exit( CBTxt::T( 'CAPTCHA_IMAGE_BG_NOISE_COLOR_FAILED', 'imagecolorallocate failed to set noise BG colors [r], [g], [b]', array( '[r]' => $noiseBgColorR, '[g]' => $noiseBgColorG, '[b]' => $noiseBgColorB ) ) ); } $noiseFgColorR = mt_rand( ( ( $imgNoiseFgColors[0] - $colorRange ) < 0 ? 0 : ( $imgNoiseFgColors[0] - $colorRange ) ), ( ( $imgNoiseFgColors[0] + $colorRange ) > 255 ? 255 : ( $imgNoiseFgColors[0] + $colorRange ) ) ); $noiseFgColorG = mt_rand( ( ( $imgNoiseFgColors[1] - $colorRange ) < 0 ? 0 : ( $imgNoiseFgColors[1] - $colorRange ) ), ( ( $imgNoiseFgColors[1] + $colorRange ) > 255 ? 255 : ( $imgNoiseFgColors[1] + $colorRange ) ) ); $noiseFgColorB = mt_rand( ( ( $imgNoiseFgColors[2] - $colorRange ) < 0 ? 0 : ( $imgNoiseFgColors[2] - $colorRange ) ), ( ( $imgNoiseFgColors[2] + $colorRange ) > 255 ? 255 : ( $imgNoiseFgColors[2] + $colorRange ) ) ); $noiseFgColor = imagecolorallocate( $image, $noiseFgColorR, $noiseFgColorG, $noiseFgColorB ); if ( $noiseFgColor === false ) { exit( CBTxt::T( 'CAPTCHA_IMAGE_FG_NOISE_COLOR_FAILED', 'imagecolorallocate failed to set noise FG colors [r], [g], [b]', array( '[r]' => $noiseFgColorR, '[g]' => $noiseFgColorG, '[b]' => $noiseFgColorB ) ) ); } } else { if ( imagecolorallocate( $image, $imgBgColors[0], $imgBgColors[1], $imgBgColors[2] ) === false ) { exit( CBTxt::T( 'CAPTCHA_IMAGE_BG_COLOR_FAILED', 'imagecolorallocate failed to set BG colors [r], [g], [b]', array( '[r]' => $imgBgColors[0], '[g]' => $imgBgColors[1], '[b]' => $imgBgColors[2] ) ) ); } $textColor = imagecolorallocate( $image, $imgTxtColors[0], $imgTxtColors[1], $imgTxtColors[2] ); if ( $textColor === false ) { exit( CBTxt::T( 'CAPTCHA_IMAGE_TEXT_COLOR_FAILED', 'imagecolorallocate failed to set text colors [r], [g], [b]', array( '[r]' => $imgTxtColors[0], '[g]' => $imgTxtColors[1], '[b]' => $imgTxtColors[2] ) ) ); } $noiseBgColor = imagecolorallocate( $image, $imgNoiseBgColors[0], $imgNoiseBgColors[1], $imgNoiseBgColors[2] ); if ( $noiseBgColor === false ) { exit( CBTxt::T( 'CAPTCHA_IMAGE_BG_NOISE_COLOR_FAILED', 'imagecolorallocate failed to set noise BG colors [r], [g], [b]', array( '[r]' => $imgNoiseBgColors[0], '[g]' => $imgNoiseBgColors[1], '[b]' => $imgNoiseBgColors[2] ) ) ); } $noiseFgColor = imagecolorallocate( $image, $imgNoiseFgColors[0], $imgNoiseFgColors[1], $imgNoiseFgColors[2] ); if ( $noiseFgColor === false ) { exit( CBTxt::T( 'CAPTCHA_IMAGE_FG_NOISE_COLOR_FAILED', 'imagecolorallocate failed to set noise FG colors [r], [g], [b]', array( '[r]' => $imgNoiseFgColors[0], '[g]' => $imgNoiseFgColors[1], '[b]' => $imgNoiseFgColors[2] ) ) ); } } if ( $this->params->get( 'captcha_internal_bg_noise', 1 ) ) { for ( $i = 0; $i < ( ( $width * $height ) / 3 ); $i++ ) { if ( imagefilledellipse( $image, mt_rand( 0, $width ), mt_rand( 0, $height ), 1, 1, $noiseBgColor ) === false ) { exit( CBTxt::T( 'imagefilledellipse failed to add BG noise to the image' ) ); } } for( $i = 1; ( $i < ( $width / 10 ) ); $i++ ) { if ( imageline( $image, ( ( $i * 10 ) - mt_rand( -20, 20 ) ), 0, ( ( $i * 10 ) + mt_rand( -20, 20 ) ), $height, $noiseBgColor ) === false ) { exit( CBTxt::T( 'imageline failed to add first pass BG noise to the image' ) ); } } for( $i = 1; ( $i < ( $height / 10 ) ); $i++ ) { if ( imageline( $image, 0, ( ( $i * 10 ) - mt_rand( -20, 20 ) ), $width, ( ( $i * 10 ) + mt_rand( -20, 20 ) ), $noiseBgColor ) === false ) { exit( CBTxt::T( 'imageline failed to add second pass BG noise to the image' ) ); } } } $x = ( ( $width - $textBox[4] ) / 2 ); $y = ( ( $height - $textBox[5] ) / 2 ); $codeSplit = cbantispamClass::UTF8_str_split( $code ); $i = 0; if ( $codeSplit ) foreach ( $codeSplit as $c ) { $result = imagettftext( $image, $fontSize, mt_rand( -$charRotation, $charRotation ), ( $x + $i ), ( $y + mt_rand( -$charOffset, $charOffset ) ), $textColor, $imgFont, $c ); if ( ! $result ) { exit( CBTxt::T( 'CAPTCHA_IMAGE_TEXT_FAILED', 'imagettftext failed to add "[text]" to the image', array( '[text]' => $c ) ) ); } $i += ( $textBox[4] / count( $codeSplit ) ); } if ( $this->params->get( 'captcha_internal_fg_noise', 1 ) ) for ( $i = 0; $i < 3; $i++ ) { if ( imageline( $image, mt_rand( 0, $width ), mt_rand( 0, $height ), mt_rand( 0, $width ), mt_rand( 0, $height ), $noiseFgColor ) === false ) { exit( CBTxt::T( 'imageline failed to add FG noise to the image' ) ); } } header( 'Expires: Mon, 26 Jul 1997 05:00:00 GMT' ); header( 'Last-Modified: ' . gmdate( 'D, d M Y H:i:s' ) . ' GMT' ); header( 'Cache-Control: no-store, no-cache, must-revalidate' ); header( 'Cache-Control: post-check=0, pre-check=0', false ); header( 'Pragma: no-cache' ); switch ( $this->params->get( 'captcha_internal_format', 'jpeg' ) ) { case 'gif': header( 'Content-Type: image/gif; charset=utf-8' ); if ( imagegif( $image ) === false ) { exit( CBTxt::T( 'imagegif failed to generate image' ) ); } break; case 'png': header( 'Content-Type: image/png; charset=utf-8' ); if ( imagepng( $image, null, 0 ) === false ) { exit( CBTxt::T( 'imagepng failed to generate image' ) ); } break; case 'jpeg': default: header( 'Content-Type: image/jpeg; charset=utf-8' ); if ( imagejpeg( $image, null, 100 ) === false ) { exit( CBTxt::T( 'imagejpeg failed to generate image' ) ); } break; } if ( imagedestroy( $image ) === false ) { exit( CBTxt::T( 'imagedestroy failed to destroy the image' ) ); } exit(); } }