From 9957f738e84faf2c9e31a1985677f36d4a77fcf3 Mon Sep 17 00:00:00 2001
From: Fabian Wennink
Date: Thu, 23 Jan 2025 20:49:45 +0100
Subject: [PATCH 1/5] Fixed PHP 8.4 implicitly marked nullable parameter
warning
See https://github.com/fabianwennink/IconCaptcha-PHP/issues/51
---
src/Challenge/Challenge.php | 2 +-
src/Challenge/Hooks/InvalidHookException.php | 2 +-
src/Challenge/ValidationResult.php | 2 +-
src/Challenge/Validator.php | 2 +-
src/Exceptions/FileNotFoundException.php | 2 +-
src/Session/Drivers/KeyValueSession.php | 2 +-
src/Session/Exceptions/SessionDataParsingFailedException.php | 2 +-
src/Session/Session.php | 2 +-
src/Session/SessionFactory.php | 2 +-
src/Token/AbstractToken.php | 2 +-
src/Token/IconCaptchaToken.php | 2 +-
src/Token/TokenInterface.php | 2 +-
12 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/src/Challenge/Challenge.php b/src/Challenge/Challenge.php
index 828fb2a..5af7618 100644
--- a/src/Challenge/Challenge.php
+++ b/src/Challenge/Challenge.php
@@ -75,7 +75,7 @@ public function __construct($storage, array $options)
* @param string $widgetId The widget identifier.
* @param string|null $challengeId The challenge identifier.
*/
- public function initialize(string $widgetId, string $challengeId = null): Challenge
+ public function initialize(string $widgetId, ?string $challengeId = null): Challenge
{
// Get the visitor's current IP address.
$ipAddress = Utils::getIpAddress($this->options['ipAddress']);
diff --git a/src/Challenge/Hooks/InvalidHookException.php b/src/Challenge/Hooks/InvalidHookException.php
index ba07bf4..538cff0 100644
--- a/src/Challenge/Hooks/InvalidHookException.php
+++ b/src/Challenge/Hooks/InvalidHookException.php
@@ -20,7 +20,7 @@ class InvalidHookException extends Exception
* @param string $path The path of the non-existing file.
* @inheritDoc
*/
- public function __construct(string $hook, string $message = null, int $code = 0, Throwable $previous = null)
+ public function __construct(string $hook, ?string $message = null, int $code = 0, ?Throwable $previous = null)
{
if ($message === null) {
$message = "Hook \"$hook\" is invalid. A hook must be a class implementing the necessary interface.";
diff --git a/src/Challenge/ValidationResult.php b/src/Challenge/ValidationResult.php
index 196ce9c..f3e8acf 100644
--- a/src/Challenge/ValidationResult.php
+++ b/src/Challenge/ValidationResult.php
@@ -25,7 +25,7 @@ final class ValidationResult
* @param bool $success
* @param string|null $errorCode
*/
- public function __construct(bool $success, string $errorCode = null)
+ public function __construct(bool $success, ?string $errorCode = null)
{
$this->success = $success;
$this->errorCode = $errorCode;
diff --git a/src/Challenge/Validator.php b/src/Challenge/Validator.php
index 9f8d0b2..260139f 100644
--- a/src/Challenge/Validator.php
+++ b/src/Challenge/Validator.php
@@ -148,7 +148,7 @@ public function validate(array $request): ValidationResult
* @return bool TRUE if the captcha session token matches the given tokens or if the token option is disabled,
* FALSE if the captcha session token does not match the given tokens.
*/
- public function validateToken(string $payloadToken, string $headerToken = null): bool
+ public function validateToken(string $payloadToken, ?string $headerToken = null): bool
{
// Only validate if the token option is enabled.
if (!empty($this->options['token'])) {
diff --git a/src/Exceptions/FileNotFoundException.php b/src/Exceptions/FileNotFoundException.php
index 12e5806..9453487 100644
--- a/src/Exceptions/FileNotFoundException.php
+++ b/src/Exceptions/FileNotFoundException.php
@@ -20,7 +20,7 @@ class FileNotFoundException extends Exception
* @param string $path The path of the non-existing file.
* @inheritDoc
*/
- public function __construct(string $path, string $message = null, int $code = 0, Throwable $previous = null)
+ public function __construct(string $path, ?string $message = null, int $code = 0, ?Throwable $previous = null)
{
if ($message === null) {
$message = "File \"$path\" could not be found.";
diff --git a/src/Session/Drivers/KeyValueSession.php b/src/Session/Drivers/KeyValueSession.php
index 0f49066..10a62f1 100644
--- a/src/Session/Drivers/KeyValueSession.php
+++ b/src/Session/Drivers/KeyValueSession.php
@@ -34,7 +34,7 @@ class KeyValueSession extends Session
* @param string $widgetId The captcha widget identifier.
* @param string|null $challengeId The captcha challenge identifier.
*/
- public function __construct(KeyValueStorageInterface $storage, array $options, string $ipAddress, string $widgetId, string $challengeId = null)
+ public function __construct(KeyValueStorageInterface $storage, array $options, string $ipAddress, string $widgetId, ?string $challengeId = null)
{
parent::__construct($options, $ipAddress, $widgetId, $challengeId);
diff --git a/src/Session/Exceptions/SessionDataParsingFailedException.php b/src/Session/Exceptions/SessionDataParsingFailedException.php
index 8e6736c..12025fa 100644
--- a/src/Session/Exceptions/SessionDataParsingFailedException.php
+++ b/src/Session/Exceptions/SessionDataParsingFailedException.php
@@ -21,7 +21,7 @@ class SessionDataParsingFailedException extends Exception
*
* @inheritDoc
*/
- public function __construct(Throwable $previous = null)
+ public function __construct(?Throwable $previous = null)
{
$message = 'Failed to parse the data of a SessionData instance.';
diff --git a/src/Session/Session.php b/src/Session/Session.php
index ff83905..88fb06a 100644
--- a/src/Session/Session.php
+++ b/src/Session/Session.php
@@ -68,7 +68,7 @@ abstract class Session implements SessionInterface
* @param string $widgetId The widget unique identifier.
* @param string|null $challengeId The challenge unique identifier.
*/
- public function __construct(array $options, string $ipAddress, string $widgetId, string $challengeId = null)
+ public function __construct(array $options, string $ipAddress, string $widgetId, ?string $challengeId = null)
{
$this->options = $options;
$this->maxIdentifierTries = (int)$options['options']['identifierTries'];
diff --git a/src/Session/SessionFactory.php b/src/Session/SessionFactory.php
index da2cdca..5b72618 100644
--- a/src/Session/SessionFactory.php
+++ b/src/Session/SessionFactory.php
@@ -29,7 +29,7 @@ class SessionFactory
* @return PDOSession|KeyValueSession|SessionInterface|mixed The generated session instance.
* @throws InvalidArgumentException If the configuration contains an invalid driver.
*/
- public static function create($storage, string $driver, array $options, string $ipAddress, string $widgetId, string $challengeId = null): SessionInterface
+ public static function create($storage, string $driver, array $options, string $ipAddress, string $widgetId, ?string $challengeId = null): SessionInterface
{
if (!isset($driver)) {
throw new InvalidArgumentException('A session driver must be specified.');
diff --git a/src/Token/AbstractToken.php b/src/Token/AbstractToken.php
index fe3128f..172ba77 100644
--- a/src/Token/AbstractToken.php
+++ b/src/Token/AbstractToken.php
@@ -57,7 +57,7 @@ protected function generate(): string
* @param $headerToken string|null The token sent with the request as a header. Can be empty in certain requests.
* @return bool TRUE if the token(s) match the stored token, FALSE if it/they don't.
*/
- protected function compareToken(string $storedToken, string $payloadToken, string $headerToken = null): bool
+ protected function compareToken(string $storedToken, string $payloadToken, ?string $headerToken = null): bool
{
// If the token is empty, the token was never requested.
if (empty($storedToken)) {
diff --git a/src/Token/IconCaptchaToken.php b/src/Token/IconCaptchaToken.php
index ea329aa..fb31ee2 100644
--- a/src/Token/IconCaptchaToken.php
+++ b/src/Token/IconCaptchaToken.php
@@ -57,7 +57,7 @@ public function get(): string
/**
* @inheritDoc
*/
- public function validate(string $payloadToken, string $headerToken = null): bool
+ public function validate(string $payloadToken, ?string $headerToken = null): bool
{
$sessionToken = $this->retrieve();
diff --git a/src/Token/TokenInterface.php b/src/Token/TokenInterface.php
index 125b4b0..f524819 100644
--- a/src/Token/TokenInterface.php
+++ b/src/Token/TokenInterface.php
@@ -36,5 +36,5 @@ public function get(): string;
* value will be checked against the captcha token.
* @return bool TRUE if the captcha token matches the given tokens, FALSE if it does not match.
*/
- public function validate(string $payloadToken, string $headerToken = null): bool;
+ public function validate(string $payloadToken, ?string $headerToken = null): bool;
}
From ff02226f9afe6239edc2532425a92438ec0297f0 Mon Sep 17 00:00:00 2001
From: Fabian Wennink
Date: Thu, 23 Jan 2025 20:51:45 +0100
Subject: [PATCH 2/5] Removed unnecessary local variable
---
src/Challenge/Image/AbstractImageGenerator.php | 4 +---
src/Request.php | 2 +-
2 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/src/Challenge/Image/AbstractImageGenerator.php b/src/Challenge/Image/AbstractImageGenerator.php
index b1cff7f..0aaeed7 100644
--- a/src/Challenge/Image/AbstractImageGenerator.php
+++ b/src/Challenge/Image/AbstractImageGenerator.php
@@ -148,12 +148,10 @@ public function generate(string $iconPath, string $placeholderPath)
}
// Call the image generation hook, if provided.
- $placeholder = Hook::call(
+ return Hook::call(
'generation', GenerationHookInterface::class, 'generate',
$this->session, $this->options, $placeholder, $placeholder
);
-
- return $placeholder;
}
/**
diff --git a/src/Request.php b/src/Request.php
index 74ab44a..af9a71f 100644
--- a/src/Request.php
+++ b/src/Request.php
@@ -140,7 +140,7 @@ private function validateToken(array $payload): bool
}
/**
- * Create a error message string for the token validation error.
+ * Create an error message string for the token validation error.
*/
private function tokenError(): void
{
From d41b4afc54b9f91f3c183d9da4ca725ff5c35c3f Mon Sep 17 00:00:00 2001
From: Fabian Wennink
Date: Thu, 23 Jan 2025 20:52:15 +0100
Subject: [PATCH 3/5] Rendering PHP version on demo pages
---
examples/forms/ajax-form.php | 1 +
examples/forms/ajax/ajax-submit.php | 2 +-
examples/forms/regular-form.php | 1 +
index.php | 1 +
4 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/examples/forms/ajax-form.php b/examples/forms/ajax-form.php
index 9086a39..6aa625c 100644
--- a/examples/forms/ajax-form.php
+++ b/examples/forms/ajax-form.php
@@ -96,6 +96,7 @@
Icons made by BlendIcons .
+ Running PHP = phpversion(); ?>
diff --git a/examples/forms/ajax/ajax-submit.php b/examples/forms/ajax/ajax-submit.php
index 4a4160d..872f3ce 100644
--- a/examples/forms/ajax/ajax-submit.php
+++ b/examples/forms/ajax/ajax-submit.php
@@ -25,7 +25,7 @@
if ($validation->success()) {
echo 'Captcha: The form has been submitted!';
} else {
- echo 'Captcha: Validation failed with error code:' . $validation->getErrorCode();
+ echo 'Captcha: Validation failed with error code: ' . $validation->getErrorCode();
}
} else {
echo 'Captcha: No data posted!';
diff --git a/examples/forms/regular-form.php b/examples/forms/regular-form.php
index 2bd1ceb..34f687b 100644
--- a/examples/forms/regular-form.php
+++ b/examples/forms/regular-form.php
@@ -119,6 +119,7 @@
Icons made by BlendIcons .
+ Running PHP = phpversion(); ?>
diff --git a/index.php b/index.php
index daa905d..7c18354 100644
--- a/index.php
+++ b/index.php
@@ -63,6 +63,7 @@
Icons made by BlendIcons .
+ Running PHP = phpversion(); ?>
From e8c77d9e06fec2ee994e4c84ee672292280b3159 Mon Sep 17 00:00:00 2001
From: Fabian Wennink
Date: Thu, 23 Jan 2025 21:07:34 +0100
Subject: [PATCH 4/5] Updated widget assets to v4.0.2
---
assets/client/css/iconcaptcha.min.css | 4 ++--
assets/client/js/iconcaptcha.min.js | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/assets/client/css/iconcaptcha.min.css b/assets/client/css/iconcaptcha.min.css
index 29d5dee..a1af9ef 100644
--- a/assets/client/css/iconcaptcha.min.css
+++ b/assets/client/css/iconcaptcha.min.css
@@ -1,2 +1,2 @@
-/*! IconCaptcha v4.0.1 | (c) 2023, Fabian Wennink (fabianwennink.nl) | fabianwennink.nl/projects/IconCaptcha-Widget/license */
-.iconcaptcha-widget{position:relative;max-width:330px;min-height:50px;width:99%;height:auto;border-radius:8px;font-family:inherit;text-shadow:none;line-height:1;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased}.iconcaptcha-widget a{text-decoration:none}.iconcaptcha-widget.iconcaptcha-init{-webkit-transition:background 150ms linear;transition:background 150ms linear}.iconcaptcha-widget.iconcaptcha-init:hover{-webkit-transition:background 150ms linear;transition:background 150ms linear}.iconcaptcha-widget.iconcaptcha-init:hover .iconcaptcha-modal__body-circle{opacity:.75;-webkit-transition:opacity .1s linear;transition:opacity .1s linear}.iconcaptcha-widget.iconcaptcha-init .iconcaptcha-modal__body{cursor:pointer}.iconcaptcha-widget.iconcaptcha-init .iconcaptcha-modal__body-circle{width:28px;height:28px;border-radius:100%;border:6px solid #52b3d9;position:absolute;top:13px;left:15px;-webkit-transition:opacity .1s linear;transition:opacity .1s linear;-webkit-animation:captcha-breathing 5s infinite linear;animation:captcha-breathing 5s infinite linear}.iconcaptcha-widget.iconcaptcha-init .iconcaptcha-modal__body-circle--speed{-webkit-animation-duration:2s;animation-duration:2s}.iconcaptcha-widget.iconcaptcha-init .iconcaptcha-modal__body-title,.iconcaptcha-widget.iconcaptcha-success .iconcaptcha-modal__body-title{font-size:15px;font-weight:bold;top:19px;text-align:left;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;padding-right:20px;padding-left:60px}.iconcaptcha-widget .iconcaptcha-modal{width:100%;display:block}.iconcaptcha-widget .iconcaptcha-modal__header{height:auto;padding:0 10px;display:block}.iconcaptcha-widget .iconcaptcha-modal__header span{padding:6px 0;display:block;text-align:center;font-size:11px;line-height:14px;font-weight:bold;cursor:default}.iconcaptcha-widget .iconcaptcha-modal__header span::-moz-selection{background:none !important}.iconcaptcha-widget .iconcaptcha-modal__header span::selection{background:none !important}.iconcaptcha-widget .iconcaptcha-modal__header span::-moz-selection{background:none !important}.iconcaptcha-widget .iconcaptcha-modal__body{display:block;overflow:hidden;position:relative;height:50px;min-height:50px;padding:2px 4px;text-align:center;-webkit-box-align:center;-webkit-box-pack:center;-webkit-box-sizing:initial;box-sizing:initial}.iconcaptcha-widget .iconcaptcha-modal__body-title{font-size:20px;font-weight:700;text-transform:uppercase;display:inline-block;width:100%;position:absolute;left:0;right:0;top:8px}.iconcaptcha-widget .iconcaptcha-modal__body-subtitle{font-size:12px;display:inline-block;width:100%;position:absolute;left:0;right:0;top:35px}.iconcaptcha-widget .iconcaptcha-modal__body-icons{position:relative;height:50px;background-repeat:no-repeat;background-position:50% 50%;z-index:1}.iconcaptcha-widget .iconcaptcha-modal__body-selection{position:absolute;left:0;top:2px;bottom:0;right:0;margin:2px 4px;z-index:999;cursor:none;height:50px}.iconcaptcha-widget .iconcaptcha-modal__body-selection>i{content:"";width:14px;height:14px;border-radius:100%;background:#52b3d9;position:absolute;display:none}.iconcaptcha-widget .iconcaptcha-modal__body-info{position:absolute;right:6px;bottom:4px;font-size:9px}.iconcaptcha-widget .iconcaptcha-modal__body-info:hover{text-decoration:underline}.iconcaptcha-widget .iconcaptcha-modal__body-icons,.iconcaptcha-widget .iconcaptcha-modal__body-selection{width:100%;max-width:320px;margin:0 auto}.iconcaptcha-widget .iconcaptcha-modal__body .captcha-loader{margin:auto;position:absolute;width:34px;height:34px;border-radius:100%;border:6px solid #52b3d9;z-index:10;top:0;left:0;bottom:0;right:0;-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-animation:captcha-breathing 2s infinite ease-in-out;animation:captcha-breathing 2s infinite ease-in-out}.iconcaptcha-widget .iconcaptcha-modal__body.captcha-opacity>canvas:not(.captcha-loader){-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=20)";filter:alpha(opacity=15);-moz-opacity:.15;-khtml-opacity:.15;opacity:.15;cursor:default;pointer-events:none}.iconcaptcha-widget .iconcaptcha-modal__body.captcha-opacity>canvas:not(.captcha-loader):after,.iconcaptcha-widget .iconcaptcha-modal__body.captcha-opacity>canvas:not(.captcha-loader):hover:after{content:none}.iconcaptcha-widget .iconcaptcha-modal__body-checkmark{width:28px;height:28px;position:absolute;top:13px;left:15px}.iconcaptcha-widget .iconcaptcha-modal__footer{display:block !important;font-size:9px;padding:3px;cursor:default;text-align:center}.iconcaptcha-widget .iconcaptcha-modal__footer>span a{text-decoration:none;-webkit-transition:color .1s linear;transition:color .1s linear;text-align:center}.iconcaptcha-widget .iconcaptcha-modal__footer>span a:hover{-webkit-transition:color .1s linear;transition:color .1s linear}.iconcaptcha-widget .iconcaptcha-modal__footer--hide{visibility:hidden}.iconcaptcha-widget .iconcaptcha-modal__fields{display:none;visibility:hidden}.iconcaptcha-widget .iconcaptcha-modal__fields input[type=text]{display:none;visibility:hidden}.iconcaptcha-widget.iconcaptcha-theme-light{background:#fafafa;border:1px solid #d8d8d8}.iconcaptcha-widget.iconcaptcha-theme-light .iconcaptcha-modal__header{border-bottom:2px solid #d8d8d8}.iconcaptcha-widget.iconcaptcha-theme-light .iconcaptcha-modal__body-subtitle{color:#9e9e9e}.iconcaptcha-widget.iconcaptcha-theme-light .iconcaptcha-modal__footer{color:#a7a7a7;border-top:2px solid #d8d8d8;padding-top:6px;padding-bottom:5px}.iconcaptcha-widget.iconcaptcha-theme-light .iconcaptcha-modal__footer>span a{color:#448aff;text-transform:uppercase;font-weight:bold}.iconcaptcha-widget.iconcaptcha-theme-light .iconcaptcha-modal__footer>span a:hover{color:#74a8ff}.iconcaptcha-widget.iconcaptcha-theme-dark{background:#4c4c4c;border:1px solid #404040}.iconcaptcha-widget.iconcaptcha-theme-dark .iconcaptcha-modal__header{border-bottom:2px solid #404040}.iconcaptcha-widget.iconcaptcha-theme-dark .iconcaptcha-modal__header span{color:#dadada}.iconcaptcha-widget.iconcaptcha-theme-dark .iconcaptcha-modal__body-subtitle{color:#b1b1b1}.iconcaptcha-widget.iconcaptcha-theme-dark .iconcaptcha-modal__footer{color:#a7a7a7;border-top:2px solid #404040;padding-top:6px;padding-bottom:5px}.iconcaptcha-widget.iconcaptcha-theme-dark .iconcaptcha-modal__footer>span a{color:#fff;text-transform:uppercase;font-weight:bold}.iconcaptcha-widget.iconcaptcha-theme-dark .iconcaptcha-modal__footer>span a:hover{color:#f0f0f0}.iconcaptcha-widget.iconcaptcha-theme-light.iconcaptcha-init:hover{background:#f1f1f1}.iconcaptcha-widget.iconcaptcha-theme-light.iconcaptcha-init .iconcaptcha-modal__body-title{color:#464646}.iconcaptcha-widget.iconcaptcha-theme-light .iconcaptcha-modal__header span{color:#1d1d1d}.iconcaptcha-widget.iconcaptcha-theme-light .iconcaptcha-modal__body-info a{color:#afafaf}.iconcaptcha-widget.iconcaptcha-theme-light.iconcaptcha-success .iconcaptcha-modal__body-checkmark svg{stroke:#5bd25b}.iconcaptcha-widget.iconcaptcha-theme-light.iconcaptcha-success .iconcaptcha-modal__body-title{color:#5bd25b}.iconcaptcha-widget.iconcaptcha-theme-light.iconcaptcha-error .iconcaptcha-modal__body-title{color:#ef5858}.iconcaptcha-widget.iconcaptcha-theme-dark.iconcaptcha-init:hover{background:#454545}.iconcaptcha-widget.iconcaptcha-theme-dark.iconcaptcha-init .iconcaptcha-modal__body-title{color:#dadada}.iconcaptcha-widget.iconcaptcha-theme-dark .iconcaptcha-modal__header span{color:#dadada}.iconcaptcha-widget.iconcaptcha-theme-dark .iconcaptcha-modal__body-info a{color:#b1b1b1}.iconcaptcha-widget.iconcaptcha-theme-dark.iconcaptcha-success .iconcaptcha-modal__body-checkmark svg{stroke:#93d293}.iconcaptcha-widget.iconcaptcha-theme-dark.iconcaptcha-success .iconcaptcha-modal__body-title{color:#93d293}.iconcaptcha-widget.iconcaptcha-theme-dark.iconcaptcha-error .iconcaptcha-modal__body-title{color:#ef5858}.iconcaptcha-widget.iconcaptcha-success,.iconcaptcha-widget.iconcaptcha-error{cursor:default}.iconcaptcha-widget *{-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-tap-highlight-color:transparent;-webkit-font-smoothing:antialiased}.iconcaptcha-widget *::-moz-selection{background:none !important}.iconcaptcha-widget *::selection{background:none !important}.iconcaptcha-widget *::-moz-selection{background:none !important}@-webkit-keyframes captcha-breathing{0%,100%{-webkit-transform:scale(1) translateZ(0);transform:scale(1) translateZ(0);border-color:#52b3d9}25%{-webkit-transform:scale(0.8) translateZ(0);transform:scale(0.8) translateZ(0);border-color:#41a2c7}50%{-webkit-transform:scale(1) translateZ(0);transform:scale(1) translateZ(0);border-color:#52b3d9}75%{-webkit-transform:scale(0.8) translateZ(0);transform:scale(0.8) translateZ(0);border-color:#41a2c7}}@keyframes captcha-breathing{0%,100%{-webkit-transform:scale(1) translateZ(0);transform:scale(1) translateZ(0);border-color:#52b3d9}25%{-webkit-transform:scale(0.8) translateZ(0);transform:scale(0.8) translateZ(0);border-color:#41a2c7}50%{-webkit-transform:scale(1) translateZ(0);transform:scale(1) translateZ(0);border-color:#52b3d9}75%{-webkit-transform:scale(0.8) translateZ(0);transform:scale(0.8) translateZ(0);border-color:#41a2c7}}
\ No newline at end of file
+/*! IconCaptcha v4.0.2 | (c) 2017-2025, Fabian Wennink (fabianwennink.nl) | fabianwennink.nl/projects/IconCaptcha-Widget/license */
+.iconcaptcha-widget{position:relative;max-width:330px;min-height:50px;width:99%;height:auto;border-radius:8px;font-family:inherit;text-shadow:none;line-height:1;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased}.iconcaptcha-widget a{text-decoration:none}.iconcaptcha-widget.iconcaptcha-init{-webkit-transition:background 150ms linear;transition:background 150ms linear}.iconcaptcha-widget.iconcaptcha-init:hover{-webkit-transition:background 150ms linear;transition:background 150ms linear}.iconcaptcha-widget.iconcaptcha-init:hover .iconcaptcha-modal__body-circle{opacity:.75;-webkit-transition:opacity .1s linear;transition:opacity .1s linear}.iconcaptcha-widget.iconcaptcha-init .iconcaptcha-modal__body{cursor:pointer}.iconcaptcha-widget.iconcaptcha-init .iconcaptcha-modal__body-circle{width:28px;height:28px;border-radius:100%;border:6px solid #52b3d9;position:absolute;top:13px;left:15px;-webkit-transition:opacity .1s linear;transition:opacity .1s linear;-webkit-animation:captcha-breathing 5s infinite linear;animation:captcha-breathing 5s infinite linear}.iconcaptcha-widget.iconcaptcha-init .iconcaptcha-modal__body-circle--speed{-webkit-animation-duration:2s;animation-duration:2s}.iconcaptcha-widget.iconcaptcha-init .iconcaptcha-modal__body-title,.iconcaptcha-widget.iconcaptcha-success .iconcaptcha-modal__body-title{font-size:15px;font-weight:bold;top:19px;text-align:left;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;padding-right:20px;padding-left:60px}.iconcaptcha-widget .iconcaptcha-modal{width:100%;display:block}.iconcaptcha-widget .iconcaptcha-modal__header{height:auto;padding:0 10px;display:block}.iconcaptcha-widget .iconcaptcha-modal__header span{padding:6px 0;display:block;text-align:center;font-size:11px;line-height:14px;font-weight:bold;cursor:default}.iconcaptcha-widget .iconcaptcha-modal__header span::-moz-selection{background:none !important}.iconcaptcha-widget .iconcaptcha-modal__header span::selection{background:none !important}.iconcaptcha-widget .iconcaptcha-modal__header span::-moz-selection{background:none !important}.iconcaptcha-widget .iconcaptcha-modal__body{display:block;overflow:hidden;position:relative;height:50px;padding:2px 4px;text-align:center;-webkit-box-align:center;-webkit-box-pack:center;-webkit-box-sizing:initial;box-sizing:initial}.iconcaptcha-widget .iconcaptcha-modal__body-title{font-size:20px;font-weight:700;text-transform:uppercase;display:inline-block;width:100%;position:absolute;left:0;right:0;top:8px}.iconcaptcha-widget .iconcaptcha-modal__body-subtitle{font-size:12px;display:inline-block;width:100%;position:absolute;left:0;right:0;top:35px}.iconcaptcha-widget .iconcaptcha-modal__body-icons{position:relative;height:50px;background-repeat:no-repeat;background-position:50% 50%;z-index:1}.iconcaptcha-widget .iconcaptcha-modal__body-selection{position:absolute;left:0;top:2px;bottom:0;right:0;margin:2px 4px;z-index:999;cursor:none;height:50px}.iconcaptcha-widget .iconcaptcha-modal__body-selection>i{content:"";width:14px;height:14px;border-radius:100%;background:#52b3d9;position:absolute;display:none}.iconcaptcha-widget .iconcaptcha-modal__body-info{position:absolute;right:6px;bottom:4px;font-size:9px}.iconcaptcha-widget .iconcaptcha-modal__body-info:hover{text-decoration:underline}.iconcaptcha-widget .iconcaptcha-modal__body-icons,.iconcaptcha-widget .iconcaptcha-modal__body-selection{width:100%;max-width:320px;margin:0 auto}.iconcaptcha-widget .iconcaptcha-modal__body .captcha-loader{margin:auto;position:absolute;width:34px;height:34px;border-radius:100%;border:6px solid #52b3d9;z-index:10;top:0;left:0;bottom:0;right:0;-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-animation:captcha-breathing 2s infinite ease-in-out;animation:captcha-breathing 2s infinite ease-in-out}.iconcaptcha-widget .iconcaptcha-modal__body.captcha-opacity>canvas:not(.captcha-loader){-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=20)";filter:alpha(opacity=15);-moz-opacity:.15;-khtml-opacity:.15;opacity:.15;cursor:default;pointer-events:none}.iconcaptcha-widget .iconcaptcha-modal__body.captcha-opacity>canvas:not(.captcha-loader):after,.iconcaptcha-widget .iconcaptcha-modal__body.captcha-opacity>canvas:not(.captcha-loader):hover:after{content:none}.iconcaptcha-widget .iconcaptcha-modal__body-checkmark{width:28px;height:28px;position:absolute;top:13px;left:15px}.iconcaptcha-widget .iconcaptcha-modal__footer{display:block !important;font-size:9px;padding:3px;cursor:default;text-align:center}.iconcaptcha-widget .iconcaptcha-modal__footer>span a{text-decoration:none;-webkit-transition:color .1s linear;transition:color .1s linear;text-align:center}.iconcaptcha-widget .iconcaptcha-modal__footer>span a:hover{-webkit-transition:color .1s linear;transition:color .1s linear}.iconcaptcha-widget .iconcaptcha-modal__footer--hide{visibility:hidden}.iconcaptcha-widget .iconcaptcha-modal__fields{display:none;visibility:hidden}.iconcaptcha-widget .iconcaptcha-modal__fields input[type=text]{display:none;visibility:hidden}.iconcaptcha-widget.iconcaptcha-theme-light{background:#fafafa;border:1px solid #d8d8d8}.iconcaptcha-widget.iconcaptcha-theme-light .iconcaptcha-modal__header{border-bottom:2px solid #d8d8d8}.iconcaptcha-widget.iconcaptcha-theme-light .iconcaptcha-modal__body-subtitle{color:#9e9e9e}.iconcaptcha-widget.iconcaptcha-theme-light .iconcaptcha-modal__footer{color:#a7a7a7;border-top:2px solid #d8d8d8;padding-top:6px;padding-bottom:5px}.iconcaptcha-widget.iconcaptcha-theme-light .iconcaptcha-modal__footer>span a{color:#448aff;text-transform:uppercase;font-weight:bold}.iconcaptcha-widget.iconcaptcha-theme-light .iconcaptcha-modal__footer>span a:hover{color:#74a8ff}.iconcaptcha-widget.iconcaptcha-theme-dark{background:#4c4c4c;border:1px solid #404040}.iconcaptcha-widget.iconcaptcha-theme-dark .iconcaptcha-modal__header{border-bottom:2px solid #404040}.iconcaptcha-widget.iconcaptcha-theme-dark .iconcaptcha-modal__header span{color:#dadada}.iconcaptcha-widget.iconcaptcha-theme-dark .iconcaptcha-modal__body-subtitle{color:#b1b1b1}.iconcaptcha-widget.iconcaptcha-theme-dark .iconcaptcha-modal__footer{color:#a7a7a7;border-top:2px solid #404040;padding-top:6px;padding-bottom:5px}.iconcaptcha-widget.iconcaptcha-theme-dark .iconcaptcha-modal__footer>span a{color:#fff;text-transform:uppercase;font-weight:bold}.iconcaptcha-widget.iconcaptcha-theme-dark .iconcaptcha-modal__footer>span a:hover{color:#f0f0f0}.iconcaptcha-widget.iconcaptcha-theme-light.iconcaptcha-init:hover{background:#f1f1f1}.iconcaptcha-widget.iconcaptcha-theme-light.iconcaptcha-init .iconcaptcha-modal__body-title{color:#464646}.iconcaptcha-widget.iconcaptcha-theme-light .iconcaptcha-modal__header span{color:#1d1d1d}.iconcaptcha-widget.iconcaptcha-theme-light .iconcaptcha-modal__body-info a{color:#afafaf}.iconcaptcha-widget.iconcaptcha-theme-light.iconcaptcha-success .iconcaptcha-modal__body-checkmark svg{stroke:#5bd25b}.iconcaptcha-widget.iconcaptcha-theme-light.iconcaptcha-success .iconcaptcha-modal__body-title{color:#5bd25b}.iconcaptcha-widget.iconcaptcha-theme-light.iconcaptcha-error .iconcaptcha-modal__body-title{color:#ef5858}.iconcaptcha-widget.iconcaptcha-theme-dark.iconcaptcha-init:hover{background:#454545}.iconcaptcha-widget.iconcaptcha-theme-dark.iconcaptcha-init .iconcaptcha-modal__body-title{color:#dadada}.iconcaptcha-widget.iconcaptcha-theme-dark .iconcaptcha-modal__header span{color:#dadada}.iconcaptcha-widget.iconcaptcha-theme-dark .iconcaptcha-modal__body-info a{color:#b1b1b1}.iconcaptcha-widget.iconcaptcha-theme-dark.iconcaptcha-success .iconcaptcha-modal__body-checkmark svg{stroke:#93d293}.iconcaptcha-widget.iconcaptcha-theme-dark.iconcaptcha-success .iconcaptcha-modal__body-title{color:#93d293}.iconcaptcha-widget.iconcaptcha-theme-dark.iconcaptcha-error .iconcaptcha-modal__body-title{color:#ef5858}.iconcaptcha-widget.iconcaptcha-success,.iconcaptcha-widget.iconcaptcha-error{cursor:default}.iconcaptcha-widget *{-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-tap-highlight-color:transparent;-webkit-font-smoothing:antialiased}.iconcaptcha-widget *::-moz-selection{background:none !important}.iconcaptcha-widget *::selection{background:none !important}.iconcaptcha-widget *::-moz-selection{background:none !important}@-webkit-keyframes captcha-breathing{0%,100%{-webkit-transform:scale(1) translateZ(0);transform:scale(1) translateZ(0);border-color:#52b3d9}25%{-webkit-transform:scale(0.8) translateZ(0);transform:scale(0.8) translateZ(0);border-color:#41a2c7}50%{-webkit-transform:scale(1) translateZ(0);transform:scale(1) translateZ(0);border-color:#52b3d9}75%{-webkit-transform:scale(0.8) translateZ(0);transform:scale(0.8) translateZ(0);border-color:#41a2c7}}@keyframes captcha-breathing{0%,100%{-webkit-transform:scale(1) translateZ(0);transform:scale(1) translateZ(0);border-color:#52b3d9}25%{-webkit-transform:scale(0.8) translateZ(0);transform:scale(0.8) translateZ(0);border-color:#41a2c7}50%{-webkit-transform:scale(1) translateZ(0);transform:scale(1) translateZ(0);border-color:#52b3d9}75%{-webkit-transform:scale(0.8) translateZ(0);transform:scale(0.8) translateZ(0);border-color:#41a2c7}}
\ No newline at end of file
diff --git a/assets/client/js/iconcaptcha.min.js b/assets/client/js/iconcaptcha.min.js
index ab17013..71dd07c 100644
--- a/assets/client/js/iconcaptcha.min.js
+++ b/assets/client/js/iconcaptcha.min.js
@@ -1,2 +1,2 @@
-/*! IconCaptcha v4.0.1 | (c) 2023, Fabian Wennink (fabianwennink.nl) | fabianwennink.nl/projects/IconCaptcha-Widget/license */
-"use strict";function _typeof(e){return(_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}var IconCaptchaPolyfills=function(){var e={extend:function(e){e=e||{};for(var t=1;t=e.length?{done:!0}:{done:!1,value:e[a++]}},e:function(e){throw e},f:t}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var o,i=!0,r=!1;return{s:function(){n=n.call(e)},n:function(){var e=n.next();return i=e.done,e},e:function(e){r=!0,o=e},f:function(){try{i||null==n.return||n.return()}finally{if(r)throw o}}}}function _unsupportedIterableToArray(e,t){if(e){if("string"==typeof e)return _arrayLikeToArray(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Map"===(n="Object"===n&&e.constructor?e.constructor.name:n)||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?_arrayLikeToArray(e,t):void 0}}function _arrayLikeToArray(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,a=new Array(t);nleast amount of times",correct:"Verification complete.",incorrect:{title:"Uh oh.",subtitle:"You've selected the wrong image."},timeout:{title:"Please wait.",subtitle:"You made too many incorrect selections."}}},k="https://www.fabianwennink.nl/projects/IconCaptcha",x="IconCaptcha by Fabian Wennink";e.$init=function(e,t){return n(this,e,t)},e.init=function(e,t){e=Array.from(document.querySelectorAll(e));return n(this,e,t)},e.reset=function(t){return void 0===this.instances?console.error("IconCaptcha has not yet been initialized. Cannot use 'reset' yet."):a(this.instances,function(e){void 0!==t&&e.id!==t||null!=e&&e.reset()}),this},e.bind=function(t,n){return void 0===this.instances?console.error("IconCaptcha has not yet been initialized. Cannot use 'bind' yet."):a(this.instances,function(e){e.element.addEventListener(t,n)}),this};var n=function(e,t,n){if(void 0===e.instances||!t.some(function(e){return null!==e.querySelector(".iconcaptcha-modal")})){void 0===e.instances&&(e.instances={});var a=IconCaptchaPolyfills.extend({},r,n||{}),o=Object.values(e.instances).length;e.instances[o]=[];for(var i=0;i","","
","
".concat(i.locale.initialization.verify,"
"),"
",""],t=i.general.showCredits?"":"display: none",e.splice(4,0,""),l.classList.add("iconcaptcha-init"),l.classList.remove("iconcaptcha-error","iconcaptcha-success"),void(l.innerHTML=e.join(""));p||function(){var e=[];e.push("","","
"," ","
","","
","
");for(var n=0,a=["wid","cid","hp"];n
"))}e.push("
"),l.innerHTML=e.join(""),r=l.querySelector(".iconcaptcha-modal__body")}(),I(),i.security.loadingAnimationDuration&&0 '),n=r.querySelector(".iconcaptcha-modal__body-selection > i"),function(e){for(var t in e._ic_listeners={click:function(e){var t,n,a;new Date-f<=i.security.interactionDelay||i.security.hoverProtection&&!y||(t=IconCaptchaPolyfills.offset(e.currentTarget),n=e.pageX-t.left,a=e.pageY-t.top,n&&a&&(r.classList.contains("captcha-opacity")||(IconCaptchaPolyfills.trigger(l,"selected",{captchaId:c}),i.security.loadingAnimationDuration&&0"),m(),IconCaptchaPolyfills.trigger(l,"refreshed",{captchaId:c})}function _(e,t){void 0!==e&&void 0!==t&&(h=!0,O(),e=Math.round(e),t=Math.round(t),n.style.display="none",t=T({widgetId:c,challengeId:a,action:"SELECTION",x:e,y:t,width:u,token:o}),IconCaptchaPolyfills.ajax({url:i.general.endpoint,type:"POST",headers:L(o),data:{payload:t},success:function(e){e=j(e);e.completed?w(e):C()},error:function(){return A(-1)}}))}function w(e){r.classList.remove("captcha-opacity"),D(l.querySelector(".iconcaptcha-modal__body-selection")),null!=e&&e.expiredAt&&(o=e.expiredAt-Date.now(),d=setTimeout(S,o));var t,n=_createForOfIteratorHelper(l.querySelectorAll(".iconcaptcha-modal__header, .iconcaptcha-modal__footer, .iconcaptcha-modal__body"));try{for(n.s();!(t=n.n()).done;){var a=t.value;a.parentNode.removeChild(a)}}catch(e){n.e(e)}finally{n.f()}l.classList.add("iconcaptcha-success");var e=''+'
'.concat(i.locale.correct,"
")+'
"),o=i.general.showCredits?"":"display: none";e+="
",e+="
",l.querySelector(".iconcaptcha-modal").innerHTML+=e,h=!1,IconCaptchaPolyfills.trigger(l,"success",{captchaId:c})}function C(e,t,n){n=!(2'.concat(e,"")+''.concat(t,"
"),h=!1,IconCaptchaPolyfills.trigger(l,"error",{captchaId:c}),n&&setTimeout(b,i.security.incorrectSelectionResetDelay)}function I(){r.classList.add("captcha-opacity"),r.insertAdjacentHTML("beforeend",'
')}function S(){a=void 0,s=p=!1,b(),IconCaptchaPolyfills.trigger(l,"invalidated",{captchaId:c})}function O(){null!==d&&(clearTimeout(d),d=null)}function A(e,t){switch(e){case"too-many-attempts":C(i.locale.timeout.title,i.locale.timeout.subtitle,!1);var n=l.querySelector(".iconcaptcha-modal__header");n.parentNode.removeChild(n),IconCaptchaPolyfills.trigger(l,"timeout",{captchaId:c}),setTimeout(S,t);break;case"invalid-form-token":P(!0,"Captcha form token is missing or incorrect.","A server request was made without including a captcha token, however this option is enabled.");break;default:P(!0,"An unexpected error occurred.","An unexpected error occurred while IconCaptcha performed an action.")}}function P(e,t,n){n=2=e.length?{done:!0}:{done:!1,value:e[a++]}},e:function(e){throw e},f:t}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var o,i=!0,r=!1;return{s:function(){n=n.call(e)},n:function(){var e=n.next();return i=e.done,e},e:function(e){r=!0,o=e},f:function(){try{i||null==n.return||n.return()}finally{if(r)throw o}}}}function _unsupportedIterableToArray(e,t){if(e){if("string"==typeof e)return _arrayLikeToArray(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Map"===(n="Object"===n&&e.constructor?e.constructor.name:n)||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?_arrayLikeToArray(e,t):void 0}}function _arrayLikeToArray(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,a=new Array(t);nleast amount of times",correct:"Verification complete.",incorrect:{title:"Uh oh.",subtitle:"You've selected the wrong image."},timeout:{title:"Please wait.",subtitle:"You made too many incorrect selections."}}},q="https://www.fabianwennink.nl/projects/IconCaptcha/",k="IconCaptcha by Fabian Wennink",M=320,E=50;e.$init=function(e,t){return n(this,e,t)},e.init=function(e,t){e=Array.from(document.querySelectorAll(e));return n(this,e,t)},e.reset=function(t){return void 0===this.instances?console.error("IconCaptcha has not yet been initialized. Cannot use 'reset' yet."):a(this.instances,function(e){void 0!==t&&e.id!==t||null!=e&&e.reset()}),this},e.bind=function(t,n){return void 0===this.instances?console.error("IconCaptcha has not yet been initialized. Cannot use 'bind' yet."):a(this.instances,function(e){e.element.addEventListener(t,n)}),this};var n=function(e,t,n){if(void 0===e.instances||!t.some(function(e){return null!==e.querySelector(".iconcaptcha-modal")})){void 0===e.instances&&(e.instances={});var a=IconCaptchaPolyfills.extend({},r,n||{}),o=Object.values(e.instances).length;e.instances[o]=[];for(var i=0;i","","
","
".concat(i.locale.initialization.verify,"
"),"
",""],t=i.general.showCredits?"":"display: none",e.splice(4,0,""),l.classList.add("iconcaptcha-init"),l.classList.remove("iconcaptcha-error","iconcaptcha-success"),void(l.innerHTML=e.join(""));p||function(){var e=[];e.push("","","
"," ","
","","
","
");for(var n=0,a=["wid","cid","hp"];n
"))}e.push("
"),l.innerHTML=e.join(""),r=l.querySelector(".iconcaptcha-modal__body")}(),C(),i.security.loadingAnimationDuration&&0 '),n=r.querySelector(".iconcaptcha-modal__body-selection > i"),function(e){for(var t in e._ic_listeners={click:function(e){var t,n,a;new Date-f<=i.security.interactionDelay||i.security.hoverProtection&&!y||(t=IconCaptchaPolyfills.offset(e.currentTarget),n=e.pageX-t.left,a=e.pageY-t.top,n&&a&&(r.classList.contains("captcha-opacity")||(IconCaptchaPolyfills.trigger(l,"selected",{captchaId:c}),i.security.loadingAnimationDuration&&0"),m(),IconCaptchaPolyfills.trigger(l,"refreshed",{captchaId:c})}function _(e,t){void 0!==e&&void 0!==t&&(h=!0,O(),e=Math.round(e),t=Math.round(t),n.style.display="none",t=T({widgetId:c,challengeId:a,action:"SELECTION",x:e,y:t,width:u,token:o}),IconCaptchaPolyfills.ajax({url:i.general.endpoint,type:"POST",headers:L(o),data:{payload:t},success:function(e){e=j(e);e.completed?w(e):I()},error:function(){return A(-1)}}))}function w(e){r.classList.remove("captcha-opacity"),D(l.querySelector(".iconcaptcha-modal__body-selection")),null!=e&&e.expiredAt&&(o=e.expiredAt-Date.now(),d=setTimeout(S,o));var t,n=_createForOfIteratorHelper(l.querySelectorAll(".iconcaptcha-modal__header, .iconcaptcha-modal__footer, .iconcaptcha-modal__body"));try{for(n.s();!(t=n.n()).done;){var a=t.value;a.parentNode.removeChild(a)}}catch(e){n.e(e)}finally{n.f()}l.classList.add("iconcaptcha-success");var e=''+'
'.concat(i.locale.correct,"
")+'
"),o=i.general.showCredits?"":"display: none";e+="
",e+="
",l.querySelector(".iconcaptcha-modal").innerHTML+=e,h=!1,IconCaptchaPolyfills.trigger(l,"success",{captchaId:c})}function I(e,t,n){n=!(2'.concat(e,"")+''.concat(t,"
"),h=!1,IconCaptchaPolyfills.trigger(l,"error",{captchaId:c}),n&&setTimeout(b,i.security.incorrectSelectionResetDelay)}function C(){r.classList.add("captcha-opacity"),r.insertAdjacentHTML("beforeend",'
')}function S(){a=void 0,s=p=!1,b(),IconCaptchaPolyfills.trigger(l,"invalidated",{captchaId:c})}function O(){null!==d&&(clearTimeout(d),d=null)}function A(e,t){switch(e){case"too-many-attempts":I(i.locale.timeout.title,i.locale.timeout.subtitle,!1);var n=l.querySelector(".iconcaptcha-modal__header");n.parentNode.removeChild(n),IconCaptchaPolyfills.trigger(l,"timeout",{captchaId:c}),setTimeout(S,t);break;case"invalid-form-token":P(!0,"Captcha form token is missing or incorrect.","A server request was made without including a captcha token, however this option is enabled.");break;default:P(!0,"An unexpected error occurred.","An unexpected error occurred while IconCaptcha performed an action.")}}function P(e,t,n){n=2
Date: Thu, 23 Jan 2025 21:18:39 +0100
Subject: [PATCH 5/5] Bumped version to 4.0.4
Version not found :)
---
.github/ISSUE_TEMPLATE/1_bug_report.yml | 4 ++--
.github/ISSUE_TEMPLATE/2_blank_issue.yml | 4 ++--
CHANGELOG.md | 8 ++++++++
README.md | 2 +-
examples/forms/ajax-form.php | 4 ++--
examples/forms/regular-form.php | 4 ++--
index.php | 4 ++--
7 files changed, 19 insertions(+), 11 deletions(-)
diff --git a/.github/ISSUE_TEMPLATE/1_bug_report.yml b/.github/ISSUE_TEMPLATE/1_bug_report.yml
index d8e1c50..6201e46 100644
--- a/.github/ISSUE_TEMPLATE/1_bug_report.yml
+++ b/.github/ISSUE_TEMPLATE/1_bug_report.yml
@@ -23,7 +23,7 @@ body:
attributes:
label: IconCaptcha version
description: Please specify the version of the package that you are using.
- placeholder: "e.g. 4.0.3"
+ placeholder: "e.g. 4.0.4"
validations:
required: true
- type: input
@@ -31,7 +31,7 @@ body:
attributes:
label: PHP version
description: Please specify the version of PHP you are using.
- placeholder: e.g. 8.2.0
+ placeholder: e.g. 8.4.0
validations:
required: true
- type: dropdown
diff --git a/.github/ISSUE_TEMPLATE/2_blank_issue.yml b/.github/ISSUE_TEMPLATE/2_blank_issue.yml
index 61da860..1ca415f 100644
--- a/.github/ISSUE_TEMPLATE/2_blank_issue.yml
+++ b/.github/ISSUE_TEMPLATE/2_blank_issue.yml
@@ -12,7 +12,7 @@ body:
attributes:
label: IconCaptcha version
description: Please specify the version of the package that you are using.
- placeholder: "e.g. 4.0.3"
+ placeholder: "e.g. 4.0.4"
validations:
required: true
- type: input
@@ -20,7 +20,7 @@ body:
attributes:
label: PHP version
description: Please specify the version of PHP you are using.
- placeholder: e.g. 8.2.0
+ placeholder: e.g. 8.4.0
validations:
required: true
- type: textarea
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f37e85a..6899ea8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,14 @@
All notable changes will be documented in this file. Only changes starting at IconCaptcha 2.0.2 have been recorded.
+## 4.0.4 - January 23, 2025
+Release: [View tag 4.0.4](https://github.com/fabianwennink/IconCaptcha-PHP/releases/tag/4.0.4)
+
+### Fixed
+- Fixed a compatibility issue with PHP 8.4 caused by a deprecation warning for "implicitly marked nullable parameters", which was breaking the code.
+
+For a full list of commits and changes, please refer to the [full commit changelog](https://github.com/fabianwennink/IconCaptcha-PHP/compare/4.0.3...4.0.4).
+
## 4.0.3 - Dec 19, 2023
Release: [View tag 4.0.3](https://github.com/fabianwennink/IconCaptcha-PHP/releases/tag/4.0.3)
diff --git a/README.md b/README.md
index 6df9a68..593ec23 100644
--- a/README.md
+++ b/README.md
@@ -12,7 +12,7 @@
-
+
diff --git a/examples/forms/ajax-form.php b/examples/forms/ajax-form.php
index 6aa625c..9257ef2 100644
--- a/examples/forms/ajax-form.php
+++ b/examples/forms/ajax-form.php
@@ -11,7 +11,7 @@
- IconCaptcha v4.0.3 - By Fabian Wennink
+ IconCaptcha v4.0.4 - By Fabian Wennink
@@ -38,7 +38,7 @@