mirror of
https://git.d3data.de/3rdParty/captcha-module.git
synced 2024-11-21 14:13:11 +01:00
b-7.0.x tnitial commit (kudos to https://github.com/gp-itholics )
This commit is contained in:
parent
b8f1c7e8aa
commit
96b36e1c0c
5
.gitignore
vendored
5
.gitignore
vendored
@ -1 +1,4 @@
|
||||
.idea
|
||||
.idea/
|
||||
.vscode/
|
||||
vendor/
|
||||
.DS_Store
|
23
.ide-helper.php
Normal file
23
.ide-helper.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace OxidProfessionalServices\Captcha\Application\Controller{
|
||||
use OxidEsales\Eshop\Application\Controller\ArticleDetailsController;
|
||||
use OxidEsales\Eshop\Application\Controller\ContactController;
|
||||
use OxidEsales\Eshop\Application\Controller\ForgotPasswordController;
|
||||
use OxidEsales\Eshop\Application\Controller\InviteController;
|
||||
use OxidEsales\Eshop\Application\Controller\NewsletterController;
|
||||
use OxidEsales\Eshop\Application\Controller\PriceAlarmController;
|
||||
|
||||
class ContactController_parent extends ContactController
|
||||
{}
|
||||
class DetailsController_parent extends ArticleDetailsController {}
|
||||
class ForgotPasswordController_parent extends ForgotPasswordController {}
|
||||
class InviteController_parent extends InviteController {}
|
||||
class NewsletterController_parent extends NewsletterController {}
|
||||
class PricealarmController_parent extends PriceAlarmController {}
|
||||
}
|
||||
|
||||
namespace OxidProfessionalServices\Captcha\Application\Component\Widget {
|
||||
use OxidEsales\Eshop\Application\Component\Widget\ArticleDetails;
|
||||
class ArticleDetails_parent extends ArticleDetails {}
|
||||
}
|
12
Application/Component/Widget/ArticleDetails.php
Normal file
12
Application/Component/Widget/ArticleDetails.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OxidProfessionalServices\Captcha\Application\Component\Widget;
|
||||
|
||||
use OxidProfessionalServices\Captcha\Application\Shared\Captcha;
|
||||
|
||||
class ArticleDetails extends ArticleDetails_parent
|
||||
{
|
||||
use Captcha;
|
||||
}
|
21
Application/Controller/ContactController.php
Normal file
21
Application/Controller/ContactController.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OxidProfessionalServices\Captcha\Application\Controller;
|
||||
|
||||
use OxidProfessionalServices\Captcha\Application\Shared\Captcha;
|
||||
|
||||
class ContactController extends ContactController_parent
|
||||
{
|
||||
use Captcha;
|
||||
|
||||
public function send()
|
||||
{
|
||||
if (!$this->getCaptcha()->passCaptcha()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return parent::send();
|
||||
}
|
||||
}
|
23
Application/Controller/DetailsController.php
Normal file
23
Application/Controller/DetailsController.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OxidProfessionalServices\Captcha\Application\Controller;
|
||||
|
||||
use OxidProfessionalServices\Captcha\Application\Shared\Captcha;
|
||||
|
||||
class DetailsController extends DetailsController_parent
|
||||
{
|
||||
use Captcha;
|
||||
|
||||
public function addme()
|
||||
{
|
||||
if (!$this->getCaptcha()->passCaptcha(false)) {
|
||||
$this->_iPriceAlarmStatus = 2;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
return parent::addme();
|
||||
}
|
||||
}
|
21
Application/Controller/ForgotPasswordController.php
Normal file
21
Application/Controller/ForgotPasswordController.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OxidProfessionalServices\Captcha\Application\Controller;
|
||||
|
||||
use OxidProfessionalServices\Captcha\Application\Shared\Captcha;
|
||||
|
||||
class ForgotPasswordController extends ForgotPasswordController_parent
|
||||
{
|
||||
use Captcha;
|
||||
|
||||
public function forgotpassword()
|
||||
{
|
||||
if (!$this->getCaptcha()->passCaptcha()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return parent::forgotpassword();
|
||||
}
|
||||
}
|
102
Application/Controller/ImageGeneratorController.php
Normal file
102
Application/Controller/ImageGeneratorController.php
Normal file
@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OxidProfessionalServices\Captcha\Application\Controller;
|
||||
|
||||
use OxidEsales\Eshop\Application\Controller\FrontendController;
|
||||
use OxidEsales\Eshop\Core\Exception\StandardException;
|
||||
use OxidEsales\Eshop\Core\Registry;
|
||||
use OxidProfessionalServices\Captcha\Application\Shared\Options;
|
||||
use Throwable;
|
||||
|
||||
class ImageGeneratorController extends FrontendController
|
||||
{
|
||||
use Options;
|
||||
|
||||
protected $emac;
|
||||
protected int $imageHeight = 18;
|
||||
protected int $imageWidth = 80;
|
||||
protected $fontSize = 14;
|
||||
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
$this->emac = Registry::getRequest()->getRequestEscapedParameter('e_mac', null);
|
||||
if ($this->emac) {
|
||||
$this->emac = $this->decodeEmac($this->emac);
|
||||
}
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
parent::render();
|
||||
|
||||
try {
|
||||
if (!$this->emac) {
|
||||
throw new StandardException('No e_mac parameter given');
|
||||
}
|
||||
$image = $this->generateVerificationImage();
|
||||
if (!$image) {
|
||||
throw new StandardException('Image generation failed by returning NULL');
|
||||
}
|
||||
header('Content-type: image/png');
|
||||
imagepng($image);
|
||||
imagedestroy($image);
|
||||
|
||||
exit;
|
||||
} catch (Throwable $e) {
|
||||
Registry::getLogger()->error(sprintf('%s() | %s', __METHOD__, $e->getMessage()), [$e]);
|
||||
http_response_code(400);
|
||||
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
protected function decodeEmac(string $emac): string
|
||||
{
|
||||
$decryptor = new \OxidEsales\Eshop\Core\Decryptor();
|
||||
|
||||
$key = $this->getOeCaptchaKey();
|
||||
|
||||
return $decryptor->decrypt($emac, $key);
|
||||
}
|
||||
|
||||
protected function generateVerificationImage()
|
||||
{
|
||||
$image = null;
|
||||
|
||||
switch (true) {
|
||||
case function_exists('imagecreatetruecolor'):
|
||||
$image = imagecreatetruecolor($this->imageWidth, $this->imageHeight);
|
||||
|
||||
break;
|
||||
|
||||
case function_exists('imagecreate'):
|
||||
$image = imagecreate($this->imageWidth, $this->imageHeight);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
$textX = (int)ceil(($this->imageWidth - strlen($this->emac) * imagefontwidth($this->fontSize)) / 2);
|
||||
$textY = (int)ceil(($this->imageHeight - imagefontheight($this->fontSize)) / 2) - 1;
|
||||
|
||||
$colors = [
|
||||
'text' => imagecolorallocate($image, 0, 0, 0),
|
||||
'shadow1' => imagecolorallocate($image, 200, 200, 200),
|
||||
'shadow2' => imagecolorallocate($image, 100, 100, 100),
|
||||
'background' => imagecolorallocate($image, 255, 255, 255),
|
||||
'border' => imagecolorallocate($image, 0, 0, 0),
|
||||
];
|
||||
|
||||
imagefill($image, 0, 0, $colors['background']);
|
||||
imagerectangle($image, 0, 0, $this->imageWidth - 2, $this->imageHeight - 2, $colors['border']);
|
||||
imagestring($image, $this->fontSize, $textX + 1, $textY + 0, $this->emac, $colors['shadow2']);
|
||||
imagestring($image, $this->fontSize, $textX + 0, $textY + 1, $this->emac, $colors['shadow1']);
|
||||
imagestring($image, $this->fontSize, $textX, $textY, $this->emac, $colors['text']);
|
||||
|
||||
return $image;
|
||||
}
|
||||
}
|
21
Application/Controller/InviteController.php
Normal file
21
Application/Controller/InviteController.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OxidProfessionalServices\Captcha\Application\Controller;
|
||||
|
||||
use OxidProfessionalServices\Captcha\Application\Shared\Captcha;
|
||||
|
||||
class InviteController extends InviteController_parent
|
||||
{
|
||||
use Captcha;
|
||||
|
||||
public function send()
|
||||
{
|
||||
if (!$this->getCaptcha()->passCaptcha()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return parent::send();
|
||||
}
|
||||
}
|
21
Application/Controller/NewsletterController.php
Normal file
21
Application/Controller/NewsletterController.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OxidProfessionalServices\Captcha\Application\Controller;
|
||||
|
||||
use OxidProfessionalServices\Captcha\Application\Shared\Captcha;
|
||||
|
||||
class NewsletterController extends NewsletterController_parent
|
||||
{
|
||||
use Captcha;
|
||||
|
||||
public function send()
|
||||
{
|
||||
if (!$this->getCaptcha()->passCaptcha()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return parent::send();
|
||||
}
|
||||
}
|
23
Application/Controller/PricealarmController.php
Normal file
23
Application/Controller/PricealarmController.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OxidProfessionalServices\Captcha\Application\Controller;
|
||||
|
||||
use OxidProfessionalServices\Captcha\Application\Shared\Captcha;
|
||||
|
||||
class PricealarmController extends PricealarmController_parent
|
||||
{
|
||||
use Captcha;
|
||||
|
||||
public function addme()
|
||||
{
|
||||
if (!$this->getCaptcha()->passCaptcha(false)) {
|
||||
$this->_iPriceAlarmStatus = 2;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
return parent::addme();
|
||||
}
|
||||
}
|
@ -1,47 +1,55 @@
|
||||
<?php
|
||||
/**
|
||||
* #PHPHEADER_OECAPTCHA_LICENSE_INFORMATION#
|
||||
*/
|
||||
|
||||
use OxidEsales\Eshop\Core\DatabaseProvider;
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Class handling CAPTCHA image
|
||||
* This class requires utility file utils/verificationimg.php as image generator
|
||||
*
|
||||
*/
|
||||
class oeCaptcha extends oxSuperCfg
|
||||
namespace OxidProfessionalServices\Captcha\Application\Core;
|
||||
|
||||
use OxidEsales\Eshop\Core\Registry;
|
||||
use OxidEsales\Eshop\Core\UtilsObject;
|
||||
use OxidProfessionalServices\Captcha\Application\Shared\Connection;
|
||||
use OxidProfessionalServices\Captcha\Application\Shared\Options;
|
||||
|
||||
class Captcha
|
||||
{
|
||||
use Connection;
|
||||
use Options;
|
||||
public const ENCRYPT_KEY = 'fq45QS09_fqyx09239QQ';
|
||||
|
||||
/**
|
||||
* CAPTCHA length
|
||||
* CAPTCHA length.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $macLength = 5;
|
||||
|
||||
/**
|
||||
* Captcha text
|
||||
* Captcha text.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $text = null;
|
||||
protected $text;
|
||||
|
||||
/**
|
||||
* Possible CAPTCHA chars, no ambiguities
|
||||
* Possible CAPTCHA chars, no ambiguities.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $macChars = 'abcdefghijkmnpqrstuvwxyz23456789';
|
||||
|
||||
/**
|
||||
* Captcha timeout 60 * 5 = 5 minutes
|
||||
* Captcha timeout 60 * 5 = 5 minutes.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $timeout = 300;
|
||||
|
||||
public static function getInstance(): static
|
||||
{
|
||||
return oxNew(static::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns text
|
||||
* Returns text.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@ -49,7 +57,8 @@ class oeCaptcha extends oxSuperCfg
|
||||
{
|
||||
if (!$this->text) {
|
||||
$this->text = '';
|
||||
for ($i = 0; $i < $this->macLength; $i++) {
|
||||
|
||||
for ($i = 0; $i < $this->macLength; ++$i) {
|
||||
$this->text .= strtolower($this->macChars[rand(0, strlen($this->macChars) - 1)]);
|
||||
}
|
||||
}
|
||||
@ -58,38 +67,7 @@ class oeCaptcha extends oxSuperCfg
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns text hash
|
||||
*
|
||||
* @param string $text User supplie text
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getHash($text = null)
|
||||
{
|
||||
// inserting captcha record
|
||||
$time = time() + $this->timeout;
|
||||
$textHash = $this->getTextHash($text);
|
||||
|
||||
// if session is started - storing captcha info here
|
||||
$session = $this->getSession();
|
||||
if ($session->isSessionStarted()) {
|
||||
$hash = oxUtilsObject::getInstance()->generateUID();
|
||||
$hashArray = $session->getVariable('captchaHashes');
|
||||
$hashArray[$hash] = array($textHash => $time);
|
||||
$session->setVariable('captchaHashes', $hashArray);
|
||||
} else {
|
||||
$database = DatabaseProvider::getDb();
|
||||
$query = "insert into oecaptcha (oxhash, oxtime) values (" .
|
||||
$database->quote($textHash) . ", " . $database->quote($time) . ")";
|
||||
$database->execute($query);
|
||||
$hash = $database->getOne('select LAST_INSERT_ID()', false, false);
|
||||
}
|
||||
|
||||
return $hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns given string captcha hash
|
||||
* Returns given string captcha hash.
|
||||
*
|
||||
* @param string $text string to hash
|
||||
*
|
||||
@ -105,38 +83,11 @@ class oeCaptcha extends oxSuperCfg
|
||||
return md5('ox' . $text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns url to CAPTCHA image generator.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getImageUrl()
|
||||
{
|
||||
$config = \OxidEsales\Eshop\Core\Registry::getConfig();
|
||||
$url = $config->getCurrentShopUrl() . 'modules/oe/captcha/core/utils/verificationimg.php?e_mac=';
|
||||
$key = $config->getConfigParam('oecaptchakey');
|
||||
|
||||
$key = $key ? $key : $config->getConfigParam('sConfigKey');
|
||||
|
||||
$encryptor = new \OxidEsales\Eshop\Core\Encryptor();
|
||||
$url .= $encryptor->encrypt($this->getText(), $key);
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if image could be generated
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isImageVisible()
|
||||
{
|
||||
return ((function_exists('imagecreatetruecolor') || function_exists('imagecreate')) && $this->getConfig()->getConfigParam('iUseGDVersion') > 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if captcha is passed.
|
||||
*
|
||||
* @param mixed $displayError
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function passCaptcha($displayError = true)
|
||||
@ -144,8 +95,8 @@ class oeCaptcha extends oxSuperCfg
|
||||
$return = true;
|
||||
|
||||
// spam spider prevention
|
||||
$mac = $this->getConfig()->getRequestParameter('c_mac');
|
||||
$macHash = $this->getConfig()->getRequestParameter('c_mach');
|
||||
$mac = Registry::getRequest()->getRequestParameter('c_mac');
|
||||
$macHash = Registry::getRequest()->getRequestParameter('c_mach');
|
||||
|
||||
if (!$this->pass($mac, $macHash)) {
|
||||
$return = false;
|
||||
@ -153,12 +104,139 @@ class oeCaptcha extends oxSuperCfg
|
||||
|
||||
if (!$return && $displayError) {
|
||||
// even if there is no exception, use this as a default display method
|
||||
oxRegistry::get('oxUtilsView')->addErrorToDisplay('MESSAGE_WRONG_VERIFICATION_CODE');
|
||||
Registry::getUtilsView()->addErrorToDisplay('MESSAGE_WRONG_VERIFICATION_CODE');
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if image could be generated.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isImageVisible()
|
||||
{
|
||||
return (function_exists('imagecreatetruecolor') || function_exists('imagecreate')) && Registry::getConfig()->getConfigParam('iUseGDVersion') > 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns url to CAPTCHA image generator.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getImageUrl()
|
||||
{
|
||||
$config = Registry::getConfig();
|
||||
$key = $this->getOeCaptchaKey();
|
||||
$encryptor = new \OxidEsales\Eshop\Core\Encryptor();
|
||||
|
||||
return $config->getCurrentShopUrl() . sprintf('?cl=oe_captcha_generator&e_mac=%s&shp=%d', $encryptor->encrypt($this->getText(), $key), $config->getShopId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns text hash.
|
||||
*
|
||||
* @param string $text User supplie text
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getHash($text = null)
|
||||
{
|
||||
// inserting captcha record
|
||||
$time = time() + $this->timeout;
|
||||
$textHash = $this->getTextHash($text);
|
||||
|
||||
// if session is started - storing captcha info here
|
||||
$session = Registry::getSession();
|
||||
if ($session->isSessionStarted()) {
|
||||
$hash = UtilsObject::getInstance()->generateUID();
|
||||
$hashArray = $session->getVariable('captchaHashes');
|
||||
$hashArray[$hash] = [$textHash => $time];
|
||||
$session->setVariable('captchaHashes', $hashArray);
|
||||
} else {
|
||||
$q = $this->getQueryBuilder();
|
||||
$q->insert('oecaptcha')
|
||||
->values(
|
||||
[
|
||||
'oxhash' => '?',
|
||||
'oxtime' => '?',
|
||||
]
|
||||
)->setParameter(0, $textHash)->setParameter(1, $time);
|
||||
$q->execute();
|
||||
$hash = $q->getConnection()->lastInsertId();
|
||||
}
|
||||
|
||||
return $hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for DB captcha hash validity.
|
||||
*
|
||||
* @param int $macHash hash key
|
||||
* @param string $hash captcha hash
|
||||
* @param int $time check time
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function passFromDb($macHash, $hash, $time)
|
||||
{
|
||||
$q = $this->getQueryBuilder();
|
||||
$q->select('1')
|
||||
->from('oecaptcha')
|
||||
->where('oxid = :macHash')
|
||||
->andWhere('oxhash = :hash')
|
||||
->setParameter('macHash', $macHash)
|
||||
->setParameter('hash', $hash);
|
||||
$pass = (bool) $q->execute()->fetchOne();
|
||||
if ($pass) {
|
||||
// cleanup
|
||||
$q = $this->getQueryBuilder()
|
||||
->delete('oecaptcha')
|
||||
->where('oxid = :macHash')
|
||||
->andWhere('oxhash = :hash')
|
||||
->setParameter('macHash', $macHash)
|
||||
->setParameter('hash', $hash);
|
||||
$q->execute();
|
||||
}
|
||||
|
||||
// garbage cleanup
|
||||
$q = $this->getQueryBuilder()
|
||||
->delete('oecaptcha')
|
||||
->where('oxtime < :time')
|
||||
->setParameter('time', $time);
|
||||
$q->execute();
|
||||
|
||||
return $pass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for session captcha hash validity.
|
||||
*
|
||||
* @param string $macHash hash key
|
||||
* @param string $hash captcha hash
|
||||
* @param int $time check time
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function passFromSession($macHash, $hash, $time)
|
||||
{
|
||||
$pass = null;
|
||||
$session = Registry::getSession();
|
||||
|
||||
if ($hashArray = $session->getVariable('captchaHashes')) {
|
||||
$pass = (isset($hashArray[$macHash][$hash]) && $hashArray[$macHash][$hash] >= $time) ? true : false;
|
||||
unset($hashArray[$macHash]);
|
||||
if (!empty($hashArray)) {
|
||||
$session->setVariable('captchaHashes', $hashArray);
|
||||
} else {
|
||||
$session->deleteVariable('captchaHashes');
|
||||
}
|
||||
}
|
||||
|
||||
return $pass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies captcha input vs supplied hash. Returns true on success.
|
||||
*
|
||||
@ -174,67 +252,10 @@ class oeCaptcha extends oxSuperCfg
|
||||
$pass = $this->passFromSession($macHash, $hash, $time);
|
||||
|
||||
// if captcha info was NOT stored in session
|
||||
if ($pass === null) {
|
||||
if (null === $pass) {
|
||||
$pass = $this->passFromDb((int) $macHash, $hash, $time);
|
||||
}
|
||||
|
||||
return (bool) $pass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for session captcha hash validity
|
||||
*
|
||||
* @param string $macHash hash key
|
||||
* @param string $hash captcha hash
|
||||
* @param int $time check time
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function passFromSession($macHash, $hash, $time)
|
||||
{
|
||||
$pass = null;
|
||||
$session = $this->getSession();
|
||||
|
||||
if (($hashArray = $session->getVariable('captchaHashes'))) {
|
||||
$pass = (isset($hashArray[$macHash][$hash]) && $hashArray[$macHash][$hash] >= $time) ? true : false;
|
||||
unset($hashArray[$macHash]);
|
||||
if (!empty($hashArray)) {
|
||||
$session->setVariable('captchaHashes', $hashArray);
|
||||
} else {
|
||||
$session->deleteVariable('captchaHashes');
|
||||
}
|
||||
}
|
||||
|
||||
return $pass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for DB captcha hash validity
|
||||
*
|
||||
* @param int $macHash hash key
|
||||
* @param string $hash captcha hash
|
||||
* @param int $time check time
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function passFromDb($macHash, $hash, $time)
|
||||
{
|
||||
$database = DatabaseProvider::getDb();
|
||||
$where = "where oxid = " . $database->quote($macHash) . " and oxhash = " . $database->quote($hash);
|
||||
$query = "select 1 from oecaptcha " . $where;
|
||||
$pass = (bool) $database->getOne($query, false, false);
|
||||
|
||||
if ($pass) {
|
||||
// cleanup
|
||||
$query = "delete from oecaptcha " . $where;
|
||||
$database->execute($query);
|
||||
}
|
||||
|
||||
// garbage cleanup
|
||||
$query = "delete from oecaptcha where oxtime < $time";
|
||||
$database->execute($query);
|
||||
|
||||
return $pass;
|
||||
}
|
||||
|
||||
}
|
62
Application/Core/Module.php
Normal file
62
Application/Core/Module.php
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OxidProfessionalServices\Captcha\Application\Core;
|
||||
|
||||
use OxidProfessionalServices\Captcha\Application\Shared\Connection;
|
||||
|
||||
class Module
|
||||
{
|
||||
use Connection;
|
||||
|
||||
public const ID = 'oecaptcha';
|
||||
public const VERSION = '7.0.0';
|
||||
|
||||
protected static $__instance;
|
||||
|
||||
public static function getInstance()
|
||||
{
|
||||
return static::$__instance ?? (static::$__instance = oxNew(static::class));
|
||||
}
|
||||
|
||||
public static function onActivate(): void
|
||||
{
|
||||
static::getInstance()->activate();
|
||||
}
|
||||
|
||||
public static function onDeactivate(): void
|
||||
{
|
||||
static::getInstance()->deactivate();
|
||||
}
|
||||
|
||||
public function createTable(): void
|
||||
{
|
||||
$this->getDb()->executeStatement('
|
||||
CREATE TABLE IF NOT EXISTS `oecaptcha` (' .
|
||||
"`OXID` int(11) NOT NULL AUTO_INCREMENT COMMENT 'Captcha id'," .
|
||||
"`OXHASH` char(32) NOT NULL default '' COMMENT 'Hash'," .
|
||||
"`OXTIME` int(11) NOT NULL COMMENT 'Validation time'," .
|
||||
"`OXTIMESTAMP` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP COMMENT 'Timestamp'," .
|
||||
'PRIMARY KEY (`OXID`), ' .
|
||||
'KEY `OXID` (`OXID`,`OXHASH`), ' .
|
||||
'KEY `OXTIME` (`OXTIME`) ' .
|
||||
") ENGINE=MEMORY AUTO_INCREMENT=1 COMMENT 'If session is not available, this is where captcha information is stored';
|
||||
");
|
||||
}
|
||||
|
||||
public function dropTable(): void
|
||||
{
|
||||
$this->getDb()->executeStatement('DROP TABLE IF EXISTS `oecaptcha`;');
|
||||
}
|
||||
|
||||
public function activate(): void
|
||||
{
|
||||
$this->createTable();
|
||||
}
|
||||
|
||||
public function deactivate(): void
|
||||
{
|
||||
$this->dropTable();
|
||||
}
|
||||
}
|
17
Application/Shared/Captcha.php
Normal file
17
Application/Shared/Captcha.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OxidProfessionalServices\Captcha\Application\Shared;
|
||||
|
||||
use OxidProfessionalServices\Captcha\Application\Core\Captcha as CaptchaCore;
|
||||
|
||||
trait Captcha
|
||||
{
|
||||
protected ?CaptchaCore $oeCaptcha;
|
||||
|
||||
public function getCaptcha(): CaptchaCore
|
||||
{
|
||||
return $this->oeCaptcha ??= CaptchaCore::getInstance();
|
||||
}
|
||||
}
|
25
Application/Shared/Connection.php
Normal file
25
Application/Shared/Connection.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OxidProfessionalServices\Captcha\Application\Shared;
|
||||
|
||||
use Doctrine\DBAL\Query\QueryBuilder;
|
||||
use OxidEsales\EshopCommunity\Internal\Container\ContainerFactory;
|
||||
use OxidEsales\EshopCommunity\Internal\Framework\Database\ConnectionProviderInterface;
|
||||
use OxidEsales\EshopCommunity\Internal\Framework\Database\QueryBuilderFactoryInterface;
|
||||
|
||||
trait Connection
|
||||
{
|
||||
public function getQueryBuilder(): QueryBuilder
|
||||
{
|
||||
$container = ContainerFactory::getInstance()->getContainer();
|
||||
|
||||
return $container->get(QueryBuilderFactoryInterface::class)->create();
|
||||
}
|
||||
|
||||
public function getDb(): \Doctrine\DBAL\Connection
|
||||
{
|
||||
return ContainerFactory::getInstance()->getContainer()->get(ConnectionProviderInterface::class)->get();
|
||||
}
|
||||
}
|
23
Application/Shared/Options.php
Normal file
23
Application/Shared/Options.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OxidProfessionalServices\Captcha\Application\Shared;
|
||||
|
||||
use OxidEsales\EshopCommunity\Internal\Container\ContainerFactory;
|
||||
use OxidEsales\EshopCommunity\Internal\Framework\Module\Facade\ModuleSettingServiceInterface;
|
||||
use OxidProfessionalServices\Captcha\Application\Core\Captcha;
|
||||
|
||||
trait Options
|
||||
{
|
||||
public function getOeCaptchaKey(): string
|
||||
{
|
||||
$bridge = ContainerFactory::getInstance()->getContainer()->get(ModuleSettingServiceInterface::class);
|
||||
$key = $bridge->getString('oecaptchakey', 'oecaptcha')->toString();
|
||||
if (!trim($key)) {
|
||||
return Captcha::ENCRYPT_KEY;
|
||||
}
|
||||
|
||||
return $key;
|
||||
}
|
||||
}
|
16
translations/de/oecaptcha_de_lang.php → Application/translations/de/oecaptcha_de_lang.php
Executable file → Normal file
16
translations/de/oecaptcha_de_lang.php → Application/translations/de/oecaptcha_de_lang.php
Executable file → Normal file
@ -1,17 +1,17 @@
|
||||
<?php
|
||||
/**
|
||||
|
||||
*
|
||||
* @category module
|
||||
* @package captcha
|
||||
*
|
||||
* @author OXID eSales AG
|
||||
* @link http://www.oxid-esales.com/
|
||||
*
|
||||
* @see http://www.oxid-esales.com/
|
||||
*
|
||||
* @copyright (C) OXID eSales AG 2003-20162016
|
||||
*/
|
||||
|
||||
$sLangName = 'Deutsch';
|
||||
|
||||
$aLang = array(
|
||||
$aLang = [
|
||||
'charset' => 'UTF-8',
|
||||
'MESSAGE_WRONG_VERIFICATION_CODE' => 'Der Prüfcode, den Sie eingegeben haben, ist nicht korrekt. Bitte versuchen Sie es erneut!'
|
||||
);
|
||||
'MESSAGE_WRONG_VERIFICATION_CODE' => 'Der Prüfcode, den Sie eingegeben haben, ist nicht korrekt. Bitte versuchen Sie es erneut!',
|
||||
'OECAPTCHA_PLACEHOLDER' => 'Enter verification code here',
|
||||
];
|
18
Application/translations/en/oecaptcha_en_lang.php
Normal file
18
Application/translations/en/oecaptcha_en_lang.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
/**
|
||||
* @category module
|
||||
*
|
||||
* @author OXID eSales AG
|
||||
*
|
||||
* @see http://www.oxid-esales.com/
|
||||
*
|
||||
* @copyright (C) OXID eSales AG 2003-20162016
|
||||
*/
|
||||
$sLangName = 'English';
|
||||
|
||||
$aLang = [
|
||||
'charset' => 'UTF-8',
|
||||
'MESSAGE_WRONG_VERIFICATION_CODE' => 'The verification code you entered is not correct. Please try again.',
|
||||
'OECAPTCHA_PLACEHOLDER' => 'Prüfcode hier eingeben',
|
||||
|
||||
];
|
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
$sLangName = 'Deutsch';
|
||||
|
||||
$aLang = [
|
||||
'charset' => 'UTF-8',
|
||||
'SHOP_MODULE_GROUP_main' => 'Allgemein',
|
||||
'SHOP_MODULE_oecaptchakey' => 'Captcha Key',
|
||||
];
|
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
$sLangName = 'English';
|
||||
|
||||
$aLang = [
|
||||
'charset' => 'UTF-8',
|
||||
'SHOP_MODULE_GROUP_main' => 'General',
|
||||
'SHOP_MODULE_oecaptchakey' => 'Captcha Key',
|
||||
];
|
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
$sLangName = 'Deutsch';
|
||||
|
||||
$aLang = [
|
||||
'charset' => 'UTF-8',
|
||||
'SHOP_MODULE_GROUP_main' => 'Allgemein',
|
||||
'SHOP_MODULE_oecaptchakey' => 'Captcha Key',
|
||||
];
|
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
$sLangName = 'English';
|
||||
|
||||
$aLang = [
|
||||
'charset' => 'UTF-8',
|
||||
'SHOP_MODULE_GROUP_main' => 'General',
|
||||
'SHOP_MODULE_oecaptchakey' => 'Captcha Key',
|
||||
];
|
12
CHANGELOG.md
12
CHANGELOG.md
@ -19,7 +19,19 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
### Security
|
||||
|
||||
## [7.0.0] - 18 Jul 2023
|
||||
### Changed
|
||||
- PHP 8.0 compatibility
|
||||
- OXID 7.0 compatibility
|
||||
- Twig & Smarty Support
|
||||
- Major version bump to 7.0.0 to match OXID 7.0 compatibility
|
||||
|
||||
### Removed
|
||||
- Suggest dropped out
|
||||
- /docs folder (no relevant information)
|
||||
|
||||
### Deprecated
|
||||
- Tests won't work for this release and should be updated in the future.
|
||||
|
||||
## [2.0.4] - 22 Oct 2021
|
||||
|
||||
|
47
README.md
47
README.md
@ -9,8 +9,9 @@ It is used to ensure that only a user who can read the distorted characters and
|
||||
can submit the following forms:
|
||||
- contact
|
||||
- invite
|
||||
- pricealarm
|
||||
- suggest
|
||||
- pricealarm (not bound in twig)
|
||||
- newsletter (not bound in twig)
|
||||
- forgotpwd (not bound in twig)
|
||||
|
||||
The captcha module then validates the submitted value against the expected one and then decides whether to process the
|
||||
request (e.g. send contact mail to shop administrator) or refuse and show an error message instead.
|
||||
@ -24,29 +25,55 @@ Please proceed with one of the following ways to install the module:
|
||||
In order to install the module via composer, run the following commands in commandline of your shop base directory
|
||||
(where the shop's composer.json file resides).
|
||||
|
||||
```
|
||||
```bash
|
||||
composer require oxid-projects/captcha-module
|
||||
```
|
||||
|
||||
### Module installation via repository cloning
|
||||
|
||||
Clone the module to your OXID eShop **modules/oe/** directory:
|
||||
```
|
||||
```bash
|
||||
git clone https://github.com/OXIDprojects/captcha-module.git captcha
|
||||
```
|
||||
|
||||
### Module installation from zip package
|
||||
|
||||
* Make a new folder "captcha" in the **modules/oe/ directory** of your shop installation.
|
||||
* Download the https://github.com/OXIDprojects/captcha-module/archive/master.zip file and unpack it into the created folder.
|
||||
And add repository to root composer:
|
||||
```bash
|
||||
composer config repositories.oxid-projects/captcha-module path "source/modules/oe/captcha"
|
||||
```
|
||||
And install module:
|
||||
```bash
|
||||
composer require oxid-projects/captcha-module
|
||||
vendor/bin/oe-console oe:module:install source/modules/oe/captcha
|
||||
```
|
||||
|
||||
## Activate Module
|
||||
|
||||
- Activate the module in the administration panel.
|
||||
- Or use console
|
||||
```bash
|
||||
vendor/bin/oe-console oe:module:activate oecaptcha
|
||||
vendor/bin/oe-console oe:cache:clear
|
||||
```
|
||||
|
||||
## Uninstall
|
||||
|
||||
Disable the module in administration area and delete the module folder.
|
||||
Disable the module in administration area or by executing following shell command.
|
||||
```bash
|
||||
vendor/bin/oe-console oe:module:deactivate oecaptcha
|
||||
```
|
||||
If installed over composer (packagist):
|
||||
```bash
|
||||
composer remove oxid-projects/captcha-module
|
||||
vendor/bin/oe-console oe:cache:clear
|
||||
```
|
||||
else if cloned:
|
||||
```bash
|
||||
vendor/bin/oe-console oe:module:uninstall oecaptcha
|
||||
vendor/bin/oe-console oe:cache:clear
|
||||
composer remove oxid-projects/captcha-module
|
||||
composer config --unset repositories.oxid-projects/captcha-module
|
||||
# and remove the source itself
|
||||
rm -rf source/modules/oe/captcha
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
|
@ -1,30 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* #PHPHEADER_OECAPTCHA_LICENSE_INFORMATION#
|
||||
*/
|
||||
|
||||
/**
|
||||
* Article detailed information widget.
|
||||
*/
|
||||
class oeCaptchaWArticleDetails extends oeCaptchaWArticleDetails_parent
|
||||
{
|
||||
/**
|
||||
* Class handling CAPTCHA image.
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
protected $captcha = null;
|
||||
|
||||
/**
|
||||
* Template variable getter. Returns object of handling CAPTCHA image
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function getCaptcha()
|
||||
{
|
||||
if ($this->captcha === null) {
|
||||
$this->captcha = oxNew('oeCaptcha');
|
||||
}
|
||||
return $this->captcha;
|
||||
}
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* #PHPHEADER_OECAPTCHA_LICENSE_INFORMATION#
|
||||
*/
|
||||
|
||||
// -------------------------------
|
||||
// RESOURCE IDENTIFIER = STRING
|
||||
// -------------------------------
|
||||
$aLang = array(
|
||||
'charset' => 'UTF-8',
|
||||
'SHOP_MODULE_GROUP_main' => 'Allgemein',
|
||||
'SHOP_MODULE_oecaptchakey' => 'Captcha Key',
|
||||
);
|
@ -1,13 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* #PHPHEADER_OECAPTCHA_LICENSE_INFORMATION#
|
||||
*/
|
||||
|
||||
// -------------------------------
|
||||
// RESOURCE IDENTIFIER = STRING
|
||||
// -------------------------------
|
||||
$aLang = array(
|
||||
'charset' => 'UTF-8',
|
||||
'SHOP_MODULE_GROUP_main' => 'General',
|
||||
'SHOP_MODULE_oecaptchakey' => 'Captcha Key',
|
||||
);
|
@ -1,3 +0,0 @@
|
||||
[{$smarty.block.parent}]
|
||||
|
||||
[{include file="oecaptcha.tpl" labelCssClass="col-lg-2" inputCssClass="col-lg-10"}]
|
@ -1,3 +0,0 @@
|
||||
[{$smarty.block.parent}]
|
||||
|
||||
[{include file="oecaptcha.tpl" labelCssClass="col-md-3" inputCssClass="col-md-9"}]
|
@ -1,19 +0,0 @@
|
||||
[{assign var="oCaptcha" value=$oView->getCaptcha()}]
|
||||
<input type="hidden" name="c_mach" value="[{$oCaptcha->getHash()}]"/>
|
||||
|
||||
<div class="form-group verify">
|
||||
<label class="req control-label [{$labelCssClass}]" for="c_mac">[{oxmultilang ident="VERIFICATION_CODE"}]</label>
|
||||
|
||||
<div class="[{$inputCssClass}] controls">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon">
|
||||
[{if $oCaptcha->isImageVisible()}]
|
||||
<img src="[{$oCaptcha->getImageUrl()}]" alt="">
|
||||
[{else}]
|
||||
<span class="verificationCode" id="verifyTextCode">[{$oCaptcha->getText()}]</span>
|
||||
[{/if}]
|
||||
</span>
|
||||
<input type="text" data-fieldsize="verify" name="c_mac" value="" class="form-control js-oxValidate js-oxValidate_notEmpty" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
0
out/pictures/picture.png → assets/logo.png
Executable file → Normal file
0
out/pictures/picture.png → assets/logo.png
Executable file → Normal file
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 6.9 KiB |
@ -2,7 +2,13 @@
|
||||
"name": "oxid-projects/captcha-module",
|
||||
"description": "This is Captcha module for OXID eShop.",
|
||||
"type": "oxideshop-module",
|
||||
"keywords": ["oxid", "modules", "eShop", "captcha"],
|
||||
"version": "7.0.0",
|
||||
"keywords": [
|
||||
"oxid",
|
||||
"modules",
|
||||
"eShop",
|
||||
"captcha"
|
||||
],
|
||||
"homepage": "https://www.oxid-esales.com/en/home.html",
|
||||
"license": [
|
||||
"GPL-3.0",
|
||||
@ -12,5 +18,14 @@
|
||||
"oxideshop": {
|
||||
"target-directory": "oe/captcha"
|
||||
}
|
||||
},
|
||||
"require": {
|
||||
"oxid-esales/oxideshop-ce": "^7.0",
|
||||
"ext-gd": "*"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"OxidProfessionalServices\\Captcha\\": "./"
|
||||
}
|
||||
}
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* #PHPHEADER_OECAPTCHA_LICENSE_INFORMATION#
|
||||
*/
|
||||
|
||||
class oeCaptchaContact extends oeCaptchaContact_parent
|
||||
{
|
||||
/**
|
||||
* Class handling CAPTCHA image.
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
protected $captcha = null;
|
||||
|
||||
/**
|
||||
* Composes and sends user written message, returns false if some parameters
|
||||
* are missing.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function send()
|
||||
{
|
||||
if (!$this->getCaptcha()->passCaptcha()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return parent::send();
|
||||
}
|
||||
|
||||
/**
|
||||
* Template variable getter. Returns object of handling CAPTCHA image
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function getCaptcha()
|
||||
{
|
||||
if ($this->captcha === null) {
|
||||
$this->captcha = oxNew('oeCaptcha');
|
||||
}
|
||||
|
||||
return $this->captcha;
|
||||
}
|
||||
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* #PHPHEADER_OECAPTCHA_LICENSE_INFORMATION#
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class oeCaptchaDetails.
|
||||
* Extends Details.
|
||||
*
|
||||
* @see Details
|
||||
*/
|
||||
class oeCaptchaDetails extends oeCaptchaDetails_parent
|
||||
{
|
||||
/**
|
||||
* Class handling CAPTCHA image.
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
protected $captcha = null;
|
||||
|
||||
/**
|
||||
* Validates email
|
||||
* address. If email is wrong - returns false and exits. If email
|
||||
* address is OK - creates price alarm object and saves it
|
||||
* (oxpricealarm::save()). Sends price alarm notification mail
|
||||
* to shop owner.
|
||||
*
|
||||
* @return bool false on error
|
||||
*/
|
||||
public function addme()
|
||||
{
|
||||
if (!$this->getCaptcha()->passCaptcha(false)) {
|
||||
$this->_iPriceAlarmStatus = 2;
|
||||
return;
|
||||
}
|
||||
|
||||
return parent::addme();
|
||||
}
|
||||
|
||||
/**
|
||||
* Template variable getter. Returns object of handling CAPTCHA image
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function getCaptcha()
|
||||
{
|
||||
if ($this->captcha === null) {
|
||||
$this->captcha = oxNew('oeCaptcha');
|
||||
}
|
||||
return $this->captcha;
|
||||
}
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* #PHPHEADER_OECAPTCHA_LICENSE_INFORMATION#
|
||||
*/
|
||||
|
||||
class oeCaptchaForgotPwd extends oeCaptchaForgotPwd_parent
|
||||
{
|
||||
/**
|
||||
* Class handling CAPTCHA image.
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
protected $captcha = null;
|
||||
|
||||
/**
|
||||
* Composes and sends user written message, returns false if some parameters
|
||||
* are missing.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function forgotpassword()
|
||||
{
|
||||
if (!$this->getCaptcha()->passCaptcha()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return parent::forgotpassword();
|
||||
}
|
||||
|
||||
/**
|
||||
* Template variable getter. Returns object of handling CAPTCHA image
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function getCaptcha()
|
||||
{
|
||||
if ($this->captcha === null) {
|
||||
$this->captcha = oxNew('oeCaptcha');
|
||||
}
|
||||
|
||||
return $this->captcha;
|
||||
}
|
||||
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* #PHPHEADER_OECAPTCHA_LICENSE_INFORMATION#
|
||||
*/
|
||||
|
||||
/**
|
||||
* Article suggestion page.
|
||||
* Collects some article base information, sets default recommendation text,
|
||||
* sends suggestion mail to user.
|
||||
*/
|
||||
class oeCaptchaInvite extends oeCaptchaInvite_parent
|
||||
{
|
||||
/**
|
||||
* Class handling CAPTCHA image.
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
protected $captcha = null;
|
||||
|
||||
/**
|
||||
* Sends product suggestion mail and returns a URL according to
|
||||
* URL formatting rules.
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function send()
|
||||
{
|
||||
if (!$this->getCaptcha()->passCaptcha()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return parent::send();
|
||||
}
|
||||
|
||||
/**
|
||||
* Template variable getter. Returns object of handling CAPTCHA image
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function getCaptcha()
|
||||
{
|
||||
if ($this->captcha === null) {
|
||||
$this->captcha = oxNew('oeCaptcha');
|
||||
}
|
||||
|
||||
return $this->captcha;
|
||||
}
|
||||
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* #PHPHEADER_OECAPTCHA_LICENSE_INFORMATION#
|
||||
*/
|
||||
|
||||
class oeCaptchaNewsletter extends oeCaptchaNewsletter_parent
|
||||
{
|
||||
/**
|
||||
* Class handling CAPTCHA image.
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
protected $captcha = null;
|
||||
|
||||
/**
|
||||
* Composes and sends user written message, returns false if some parameters
|
||||
* are missing.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function send()
|
||||
{
|
||||
if (!$this->getCaptcha()->passCaptcha()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return parent::send();
|
||||
}
|
||||
|
||||
/**
|
||||
* Template variable getter. Returns object of handling CAPTCHA image
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function getCaptcha()
|
||||
{
|
||||
if ($this->captcha === null) {
|
||||
$this->captcha = oxNew('oeCaptcha');
|
||||
}
|
||||
|
||||
return $this->captcha;
|
||||
}
|
||||
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* #PHPHEADER_OECAPTCHA_LICENSE_INFORMATION#
|
||||
*/
|
||||
|
||||
/**
|
||||
* Pricealarm window.
|
||||
* Arranges "pricealarm" window, by sending eMail and storing into Database (etc.)
|
||||
* submission. Result - "pricealarm.tpl" template. After user correctly
|
||||
* fulfils all required fields all information is sent to shop owner by
|
||||
* email.
|
||||
* OXID eShop -> pricealarm.
|
||||
*/
|
||||
class oeCaptchaPricealarm extends oeCaptchaPricealarm_parent
|
||||
{
|
||||
/**
|
||||
* Validates email
|
||||
* address. If email is wrong - returns false and exits. If email
|
||||
* address is OK - creates prcealarm object and saves it
|
||||
* (oxpricealarm::save()). Sends pricealarm notification mail
|
||||
* to shop owner.
|
||||
*
|
||||
* @return bool false on error
|
||||
*/
|
||||
public function addme()
|
||||
{
|
||||
//control captcha
|
||||
$captcha = oxNew('oeCaptcha');
|
||||
if (!$captcha->passCaptcha(false)) {
|
||||
$this->_iPriceAlarmStatus = 2;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
return parent::addme();
|
||||
}
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* #PHPHEADER_OECAPTCHA_LICENSE_INFORMATION#
|
||||
*/
|
||||
|
||||
/**
|
||||
* Article suggestion page.
|
||||
* Collects some article base information, sets default recomendation text,
|
||||
* sends suggestion mail to user.
|
||||
*/
|
||||
class oeCaptchaSuggest extends oeCaptchaSuggest_parent
|
||||
{
|
||||
/**
|
||||
* Class handling CAPTCHA image.
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
protected $captcha = null;
|
||||
|
||||
/**
|
||||
* Sends product suggestion mail and returns a URL according to
|
||||
* URL formatting rules.
|
||||
*
|
||||
* Template variables:
|
||||
* <b>editval</b>, <b>error</b>
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function send()
|
||||
{
|
||||
// spam spider prevension
|
||||
if (!$this->getCaptcha()->passCaptcha()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return parent::send();
|
||||
}
|
||||
|
||||
/**
|
||||
* Template variable getter. Returns object of handling CAPTCHA image
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function getCaptcha()
|
||||
{
|
||||
if ($this->captcha === null) {
|
||||
$this->captcha = oxNew('oeCaptcha');
|
||||
}
|
||||
|
||||
return $this->captcha;
|
||||
}
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* #PHPHEADER_OECAPTCHA_LICENSE_INFORMATION#
|
||||
*/
|
||||
|
||||
use OxidEsales\Eshop\Core\DatabaseProvider;
|
||||
|
||||
/**
|
||||
* Class defines what module does on Shop events.
|
||||
*/
|
||||
class oeCaptchaEvents
|
||||
{
|
||||
/**
|
||||
* Add table oecaptcha.
|
||||
*/
|
||||
public static function addCaptchaTable()
|
||||
{
|
||||
$query = "CREATE TABLE IF NOT EXISTS `oecaptcha` (" .
|
||||
"`OXID` int(11) NOT NULL AUTO_INCREMENT COMMENT 'Captcha id'," .
|
||||
"`OXHASH` char(32) NOT NULL default '' COMMENT 'Hash'," .
|
||||
"`OXTIME` int(11) NOT NULL COMMENT 'Validation time'," .
|
||||
"`OXTIMESTAMP` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP COMMENT 'Timestamp'," .
|
||||
"PRIMARY KEY (`OXID`), " .
|
||||
"KEY `OXID` (`OXID`,`OXHASH`), " .
|
||||
"KEY `OXTIME` (`OXTIME`) " .
|
||||
") ENGINE=MEMORY AUTO_INCREMENT=1 COMMENT 'If session is not available, this is where captcha information is stored';";
|
||||
|
||||
DatabaseProvider::getDb()->execute($query);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove table oecaptcha.
|
||||
* NOTE: table oecaptcha contains temporary data if any and can be
|
||||
* removed without side effects on module deactivation
|
||||
*/
|
||||
public static function removeCaptchaTable()
|
||||
{
|
||||
$query = "DROP TABLE IF EXISTS `oecaptcha`";
|
||||
|
||||
DatabaseProvider::getDb()->execute($query);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute action on activate event
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public static function onActivate()
|
||||
{
|
||||
self::addCaptchaTable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute action on deactivate event
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public static function onDeactivate()
|
||||
{
|
||||
self::removeCaptchaTable();
|
||||
}
|
||||
}
|
@ -1,103 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* #PHPHEADER_OECAPTCHA_LICENSE_INFORMATION#
|
||||
*/
|
||||
|
||||
// #1428C - spam spider prevention
|
||||
if (isset($_GET['e_mac'])) {
|
||||
$emac = $_GET['e_mac'];
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
require_once '../../../../../bootstrap.php';
|
||||
|
||||
if (!function_exists('generateVerificationImg')) {
|
||||
|
||||
/**
|
||||
* Generates image
|
||||
*
|
||||
* @param string $mac verification code
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
function generateVerificationImg($mac)
|
||||
{
|
||||
$width = 80;
|
||||
$height = 18;
|
||||
$fontSize = 14;
|
||||
|
||||
if (function_exists('imagecreatetruecolor')) {
|
||||
// GD2
|
||||
$image = imagecreatetruecolor($width, $height);
|
||||
} elseif (function_exists('imagecreate')) {
|
||||
// GD1
|
||||
$image = imagecreate($width, $height);
|
||||
} else {
|
||||
// GD not found
|
||||
return;
|
||||
}
|
||||
|
||||
$textX = ($width - strlen($mac) * imagefontwidth($fontSize)) / 2;
|
||||
$textY = ($height - imagefontheight($fontSize)) / 2;
|
||||
|
||||
$colors = array();
|
||||
$colors["text"] = imagecolorallocate($image, 0, 0, 0);
|
||||
$colors["shadow1"] = imagecolorallocate($image, 200, 200, 200);
|
||||
$colors["shadow2"] = imagecolorallocate($image, 100, 100, 100);
|
||||
$colors["background"] = imagecolorallocate($image, 255, 255, 255);
|
||||
$colors["border"] = imagecolorallocate($image, 0, 0, 0);
|
||||
|
||||
imagefill($image, 0, 0, $colors["background"]);
|
||||
imagerectangle($image, 0, 0, $width - 1, $height - 1, $colors["border"]);
|
||||
imagestring($image, $fontSize, $textX + 1, $textY + 0, $mac, $colors["shadow2"]);
|
||||
imagestring($image, $fontSize, $textX + 0, $textY + 1, $mac, $colors["shadow1"]);
|
||||
imagestring($image, $fontSize, $textX, $textY, $mac, $colors["text"]);
|
||||
|
||||
header('Content-type: image/png');
|
||||
imagepng($image);
|
||||
imagedestroy($image);
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('strRem')) {
|
||||
|
||||
/**
|
||||
* OXID specific string manipulation method
|
||||
*
|
||||
* @param string $value string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function strRem($value)
|
||||
{
|
||||
$decryptor = new \OxidEsales\Eshop\Core\Decryptor();
|
||||
$config = oxRegistry::getConfig();
|
||||
|
||||
$key = $config->getConfigParam('oecaptchakey');
|
||||
if (empty($key)) {
|
||||
$key = getOxConfKey();
|
||||
}
|
||||
|
||||
return $decryptor->decrypt($value, $key);
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('getOxConfKey')) {
|
||||
|
||||
/**
|
||||
* Get default config key.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function getOxConfKey()
|
||||
{
|
||||
$config = oxRegistry::getConfig();
|
||||
$configKey = $config->getConfigParam('sConfigKey') ?: \OxidEsales\Eshop\Core\Config::DEFAULT_CONFIG_KEY;
|
||||
return $configKey;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$mac = strRem($emac);
|
||||
generateVerificationImg($mac);
|
@ -1,36 +0,0 @@
|
||||
==Title==
|
||||
OE Captcha
|
||||
|
||||
==Author==
|
||||
OXID eSales AG
|
||||
|
||||
==Prefix==
|
||||
oe
|
||||
|
||||
==Shop Version==
|
||||
6.x
|
||||
|
||||
==Version==
|
||||
1.0.0
|
||||
|
||||
==Link==
|
||||
http://www.oxid-esales.com/
|
||||
|
||||
==Mail==
|
||||
|
||||
|
||||
==Description==
|
||||
OE Captcha Module
|
||||
|
||||
==Installation==
|
||||
Activate the module in administration area.
|
||||
|
||||
==Extend==
|
||||
|
||||
|
||||
==Modules==
|
||||
|
||||
==Modified original templates==
|
||||
|
||||
==Uninstall==
|
||||
Disable the module in administration area and delete module folder.
|
121
metadata.php
Executable file → Normal file
121
metadata.php
Executable file → Normal file
@ -1,6 +1,9 @@
|
||||
<?php
|
||||
|
||||
use OxidProfessionalServices\Captcha\Application\Core\Module;
|
||||
|
||||
/**
|
||||
* #PHPHEADER_OECAPTCHA_LICENSE_INFORMATION#
|
||||
* #PHPHEADER_OECAPTCHA_LICENSE_INFORMATION#.
|
||||
*/
|
||||
/**
|
||||
* This file is part of OXID eSales Captcha module.
|
||||
@ -8,63 +11,89 @@
|
||||
* TODO: license
|
||||
*
|
||||
* @category module
|
||||
* @package captcha
|
||||
*
|
||||
* @author OXID eSales AG
|
||||
* @link http://www.oxid-esales.com/
|
||||
*
|
||||
* @see http://www.oxid-esales.com/
|
||||
*
|
||||
* @copyright (C) OXID eSales AG 2003-20162016
|
||||
*/
|
||||
|
||||
/**
|
||||
* Metadata version
|
||||
* Metadata version.
|
||||
*/
|
||||
$sMetadataVersion = '1.1';
|
||||
$sMetadataVersion = '2.1';
|
||||
|
||||
/**
|
||||
* Module information
|
||||
* Module information.
|
||||
*/
|
||||
$aModule = array(
|
||||
'id' => 'oecaptcha',
|
||||
'title' => array(
|
||||
$aModule = [
|
||||
'id' => Module::ID,
|
||||
'title' => [
|
||||
'de' => 'Simple Captcha',
|
||||
'en' => 'Simple Captcha',
|
||||
),
|
||||
'description' => array(
|
||||
],
|
||||
'description' => [
|
||||
'de' => 'OXID eSales Simple Captcha Module',
|
||||
'en' => 'OXID eSales Simple Captcha Module',
|
||||
),
|
||||
'thumbnail' => 'out/pictures/picture.png',
|
||||
'version' => '2.0.4',
|
||||
],
|
||||
'thumbnail' => 'logo.png',
|
||||
'version' => Module::VERSION,
|
||||
'author' => 'OXID eSales AG',
|
||||
'url' => 'http://www.oxid-esales.com/',
|
||||
'url' => 'https://www.oxid-esales.com/',
|
||||
'email' => '',
|
||||
'extend' => array('details' => 'oe/captcha/controllers/oecaptchadetails',
|
||||
'contact' => 'oe/captcha/controllers/oecaptchacontact',
|
||||
'forgotpwd' => 'oe/captcha/controllers/oecaptchaforgotpwd',
|
||||
'invite' => 'oe/captcha/controllers/oecaptchainvite',
|
||||
'newsletter' => 'oe/captcha/controllers/oecaptchanewsletter',
|
||||
'pricealarm' => 'oe/captcha/controllers/oecaptchapricealarm',
|
||||
'suggest' => 'oe/captcha/controllers/oecaptchasuggest',
|
||||
'oxwarticledetails' => 'oe/captcha/application/component/widget/oecaptchawarticledetails'),
|
||||
'files' => array(
|
||||
'oecaptcha' => 'oe/captcha/core/oecaptcha.php',
|
||||
'oecaptchaEvents' => 'oe/captcha/core/oecaptchaevents.php',
|
||||
),
|
||||
'templates' => array(
|
||||
'oecaptcha.tpl' => 'oe/captcha/application/views/tpl/oecaptcha.tpl',
|
||||
),
|
||||
'blocks' => array(
|
||||
array('template' => 'form/contact.tpl', 'block'=>'captcha_form', 'file'=>'/application/views/blocks/captcha_form.tpl'),
|
||||
array('template' => 'form/newsletter.tpl', 'block'=>'captcha_form', 'file'=>'/application/views/blocks/captcha_form.tpl'),
|
||||
array('template' => 'form/privatesales/invite.tpl', 'block'=>'captcha_form', 'file'=>'/application/views/blocks/captcha_form.tpl'),
|
||||
array('template' => 'form/pricealarm.tpl', 'block'=>'captcha_form', 'file'=>'/application/views/blocks/captcha_form.tpl'),
|
||||
array('template' => 'form/suggest.tpl', 'block'=>'captcha_form', 'file'=>'/application/views/blocks/captcha_form.tpl'),
|
||||
array('template' => 'form/forgotpwd_email.tpl', 'block'=>'captcha_form', 'file'=>'/application/views/blocks/captcha_form_forgotpwd.tpl'),
|
||||
),
|
||||
'settings' => array(
|
||||
array('group' => 'main', 'name' => 'oecaptchakey', 'type' => 'str', 'value' => ''),
|
||||
),
|
||||
'events' => array(
|
||||
'onActivate' => 'oecaptchaevents::onActivate',
|
||||
'onDeactivate' => 'oecaptchaevents::onDeactivate'
|
||||
),
|
||||
);
|
||||
'controllers' => [
|
||||
'oe_captcha_generator' => OxidProfessionalServices\Captcha\Application\Controller\ImageGeneratorController::class,
|
||||
],
|
||||
'extend' => [
|
||||
OxidEsales\Eshop\Application\Controller\ArticleDetailsController::class => OxidProfessionalServices\Captcha\Application\Controller\DetailsController::class,
|
||||
OxidEsales\Eshop\Application\Controller\ContactController::class => OxidProfessionalServices\Captcha\Application\Controller\ContactController::class,
|
||||
OxidEsales\Eshop\Application\Controller\ForgotPasswordController::class => OxidProfessionalServices\Captcha\Application\Controller\ForgotPasswordController::class,
|
||||
OxidEsales\Eshop\Application\Controller\InviteController::class => OxidProfessionalServices\Captcha\Application\Controller\InviteController::class,
|
||||
OxidEsales\Eshop\Application\Controller\NewsletterController::class => OxidProfessionalServices\Captcha\Application\Controller\NewsletterController::class,
|
||||
OxidEsales\Eshop\Application\Controller\PriceAlarmController::class => OxidProfessionalServices\Captcha\Application\Controller\PricealarmController::class,
|
||||
OxidEsales\Eshop\Application\Component\Widget\ArticleDetails::class => OxidProfessionalServices\Captcha\Application\Component\Widget\ArticleDetails::class,
|
||||
],
|
||||
'templates' => [
|
||||
'oe_captcha.tpl' => 'views/smarty/tpl/include/oe_captcha.tpl',
|
||||
],
|
||||
'blocks' => [
|
||||
[
|
||||
'template' => 'form/contact.tpl',
|
||||
'block' => 'captcha_form',
|
||||
'file' => 'views/smarty/blocks/oe_captcha_form.tpl',
|
||||
],
|
||||
[
|
||||
'template' => 'form/privatesales/invite.tpl',
|
||||
'block' => 'captcha_form',
|
||||
'file' => 'views/smarty/blocks/oe_captcha_form.tpl',
|
||||
],
|
||||
[
|
||||
'template' => 'form/pricealarm.tpl',
|
||||
'block' => 'captcha_form',
|
||||
'file' => 'views/smarty/blocks/oe_captcha_form.tpl',
|
||||
],
|
||||
[
|
||||
'template' => 'form/newsletter.tpl',
|
||||
'block' => 'captcha_form',
|
||||
'file' => 'views/smarty/blocks/oe_captcha_form.tpl',
|
||||
],
|
||||
[
|
||||
'template' => 'form/forgotpwd_email.tpl',
|
||||
'block' => 'captcha_form',
|
||||
'file' => 'views/smarty/blocks/oe_captcha_form.tpl',
|
||||
],
|
||||
],
|
||||
'settings' => [
|
||||
[
|
||||
'group' => 'main',
|
||||
'name' => 'oecaptchakey',
|
||||
'type' => 'str',
|
||||
'value' => '',
|
||||
],
|
||||
],
|
||||
'events' => [
|
||||
'onActivate' => Module::class . '::onActivate',
|
||||
'onDeactivate' => Module::class . '::onDeactivate',
|
||||
],
|
||||
];
|
||||
|
@ -1,17 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
|
||||
*
|
||||
* @category module
|
||||
* @package captcha
|
||||
* @author OXID eSales AG
|
||||
* @link http://www.oxid-esales.com/
|
||||
* @copyright (C) OXID eSales AG 2003-20162016
|
||||
*/
|
||||
|
||||
$sLangName = 'English';
|
||||
|
||||
$aLang = array(
|
||||
'charset' => 'UTF-8',
|
||||
'MESSAGE_WRONG_VERIFICATION_CODE' => "The verification code you entered is not correct. Please try again."
|
||||
);
|
3
views/smarty/blocks/oe_captcha_form.tpl
Normal file
3
views/smarty/blocks/oe_captcha_form.tpl
Normal file
@ -0,0 +1,3 @@
|
||||
[{$smarty.block.parent}]
|
||||
|
||||
[{include file="oe_captcha.tpl"}]
|
47
views/smarty/tpl/include/oe_captcha.tpl
Normal file
47
views/smarty/tpl/include/oe_captcha.tpl
Normal file
@ -0,0 +1,47 @@
|
||||
[{assign var="oCaptcha" value=$oView->getCaptcha()}]
|
||||
[{block name="body"}]
|
||||
[{block name="style"}]
|
||||
<style>
|
||||
.oecaptcha-group {display: flex; align-items: center; gap: 2ch;}
|
||||
.oecaptcha-container {display: grid; place-items: center;}
|
||||
</style>
|
||||
[{/block}]
|
||||
|
||||
[{block name="hidden"}]
|
||||
<input type="hidden" name="c_mach" value="[{$oCaptcha->getHash()}]" />
|
||||
[{/block}]
|
||||
|
||||
[{block name="form_group"}]
|
||||
<div class="form-group verify oecaptcha">
|
||||
[{block name="label"}]
|
||||
<label class="req control-label col-lg-2" for="c_mac">[{oxmultilang ident="VERIFICATION_CODE"}]</label>
|
||||
[{/block}]
|
||||
|
||||
[{block name="input_control"}]
|
||||
<div class="col-lg-10 controls oecaptcha-group-container">
|
||||
[{block name="input_group"}]
|
||||
<div class="input-group oecaptcha-group">
|
||||
[{block name="image_group"}]
|
||||
<span class="input-group-addon oecaptcha-container">
|
||||
[{if $oCaptcha->isImageVisible()}]
|
||||
[{block name="image_visible"}]
|
||||
<img src="[{$oCaptcha->getImageUrl()}]" alt="">
|
||||
[{/block}]
|
||||
[{else}]
|
||||
[{block name="image_hidden"}]
|
||||
<span class="verificationCode" id="verifyTextCode">[{$oCaptcha->getText()}]</span>
|
||||
[{/block}]
|
||||
[{/if}]
|
||||
</span>
|
||||
[{/block}]
|
||||
[{block name="input"}]
|
||||
<input type="text" data-fieldsize="verify" name="c_mac" value=""
|
||||
class="form-control js-oxValidate js-oxValidate_notEmpty" required>
|
||||
[{/block}]
|
||||
</div>
|
||||
[{/block}]
|
||||
</div>
|
||||
[{/block}]
|
||||
</div>
|
||||
[{/block}]
|
||||
[{/block}]
|
@ -0,0 +1,6 @@
|
||||
{% extends "form/contact.html.twig" %}
|
||||
|
||||
{% block captcha_form %}
|
||||
{{ parent() }}
|
||||
{% include "@oecaptcha/oe_captcha.html.twig" %}
|
||||
{% endblock %}
|
@ -0,0 +1,6 @@
|
||||
{% extends "form/pricealarm.html.twig" %}
|
||||
|
||||
{% block captcha_form %}
|
||||
{{ parent() }}
|
||||
{% include "@oecaptcha/oe_captcha.html.twig" %}
|
||||
{% endblock %}
|
@ -0,0 +1,6 @@
|
||||
{% extends "form/privatesales/invite.html.twig" %}
|
||||
|
||||
{% block captcha_form %}
|
||||
{{ parent() }}
|
||||
{% include "@oecaptcha/oe_captcha.html.twig" %}
|
||||
{% endblock %}
|
49
views/twig/oe_captcha.html.twig
Normal file
49
views/twig/oe_captcha.html.twig
Normal file
@ -0,0 +1,49 @@
|
||||
{% set oCaptcha = oView.getCaptcha() %}
|
||||
{% block body %}
|
||||
{% block style %}
|
||||
<style>
|
||||
.oecaptcha {padding: 0 .75rem;}
|
||||
.oecaptcha-group {display: flex; align-items: center; gap: 2ch;}
|
||||
.oecaptcha-container {display: grid; place-items: center;}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block hidden %}
|
||||
<input type="hidden" name="c_mach" value="{{ oCaptcha.getHash() }}" />
|
||||
{% endblock %}
|
||||
|
||||
{% block form_group %}
|
||||
<div class="form-group verify oecaptcha mb-3">
|
||||
{% block label %}
|
||||
<label class="req control-label col-lg-2" for="c_mac">{{ translate({ ident: "VERIFICATION_CODE" }) }}</label>
|
||||
{% endblock %}
|
||||
|
||||
{% block input_control %}
|
||||
<div class="col-lg-10 controls oecaptcha-group-container">
|
||||
{% block input_group %}
|
||||
<div class="input-group oecaptcha-group">
|
||||
{% block image_group %}
|
||||
<span class="input-group-addon oecaptcha-container">
|
||||
{% if oCaptcha.isImageVisible() %}
|
||||
{% block image_visible %}
|
||||
<img src="{{ oCaptcha.getImageUrl() }}" alt="">
|
||||
{% endblock %}
|
||||
{% else %}
|
||||
{% block image_hidden %}
|
||||
<span class="verificationCode" id="verifyTextCode">{{ oCaptcha.getText() }}</span>
|
||||
{% endblock %}
|
||||
{% endif %}
|
||||
</span>
|
||||
{% endblock %}
|
||||
|
||||
{% block input %}
|
||||
<input type="text" data-fieldsize="verify" name="c_mac" value="" placeholder="{{ translate({ ident: "OECAPTCHA_PLACEHOLDER" }) }}"
|
||||
class="form-control js-oxValidate js-oxValidate_notEmpty" required>
|
||||
{% endblock %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
Loading…
Reference in New Issue
Block a user