From e8b8fc18718737896f286f48dcd928ace4551ec7 Mon Sep 17 00:00:00 2001 From: Cooper Dalrymple Date: Thu, 4 Jun 2026 17:05:42 -0500 Subject: [PATCH] Locations and verification --- inc/abstract-location.php | 85 +++++++++++++++++++++++ inc/class-api.php | 55 +++++++++++++++ inc/class-settings.php | 42 +++++++---- inc/class-widget.php | 46 ++++++++++++ inc/location/class-comment-form.php | 53 ++++++++++++++ inc/location/class-login-form.php | 47 +++++++++++++ inc/location/class-login-page.php | 61 ++++++++++++++++ inc/location/class-lost-password-form.php | 46 ++++++++++++ inc/location/class-post-password-form.php | 49 +++++++++++++ inc/location/class-registration-page.php | 56 +++++++++++++++ ogre-captcha.php | 11 ++- 11 files changed, 538 insertions(+), 13 deletions(-) create mode 100644 inc/abstract-location.php create mode 100644 inc/class-api.php create mode 100644 inc/class-widget.php create mode 100644 inc/location/class-comment-form.php create mode 100644 inc/location/class-login-form.php create mode 100644 inc/location/class-login-page.php create mode 100644 inc/location/class-lost-password-form.php create mode 100644 inc/location/class-post-password-form.php create mode 100644 inc/location/class-registration-page.php diff --git a/inc/abstract-location.php b/inc/abstract-location.php new file mode 100644 index 0000000..b8d57cf --- /dev/null +++ b/inc/abstract-location.php @@ -0,0 +1,85 @@ +name = $name; + add_action('init', [$this, 'init']); + } + + public function enabled():bool { + return Settings::is_form_location_enabled($this->name); + } + + public function init():void { + if (is_multisite()) { + $blog_id = get_current_blog_id(); + switch_to_blog($blog_id); + } + $enabled = $this->enabled(); + if (is_multisite()) { + restore_current_blog(); + } + if (!$enabled) return; + + $this->activate(); + } + + abstract public function activate():void; + + public function render():void { + Widget::render(); + } + + public function process(WP_Error $errors):void { + if (!Settings::is_connected()) return; + + $token = Widget::get_token(); + if (empty($token)) { + $errors->add(self::ERROR_EMPTY_TOKEN, Plugin::__('Error: Please complete CAPTCHA verification.')); + return; + } + + if (!API::verify($token)) { + $errors->add(self::ERROR_INVALID_CAPTCHA, Plugin::__('Error: Your answer was incorrect - please try again.')); + return; + } + } + + protected function print_errors(WP_Error $errors):void { + if (!$errors->has_errors()) return; + ob_start(); + echo ''; + wp_die(ob_get_clean()); + } + +} diff --git a/inc/class-api.php b/inc/class-api.php new file mode 100644 index 0000000..fd35f85 --- /dev/null +++ b/inc/class-api.php @@ -0,0 +1,55 @@ + Settings::get_secret_key(), + 'response' => $token, + ]); + + return is_bool($result) ? $result : false; + } + +} diff --git a/inc/class-settings.php b/inc/class-settings.php index 0c9a848..fd90748 100644 --- a/inc/class-settings.php +++ b/inc/class-settings.php @@ -23,7 +23,7 @@ final class Settings { public const LOCATION_LOGIN_PAGE = 'login_page'; public const LOCATION_REGISTRATION_PAGE = 'registration_page'; - public const LOCATION_LOST_PASSWORD_PAGE = 'lost_password_page'; + public const LOCATION_LOST_PASSWORD_FORM = 'lost_password_page'; public const LOCATION_LOGIN_FORM = 'login_form'; public const LOCATION_COMMENT_FORM = 'comment_form'; public const LOCATION_POST_PASSWORD_FORM = 'post_password_form'; @@ -43,8 +43,18 @@ final class Settings { return in_array($value, (array) self::get($name)); } - public static function get_instance_url():string { - return !empty($value = (string) self::get('instance_url')) ? $value : self::DEFAULT_INSTANCE_URL; + public static function get_instance_url(string $path = ''):string { + $url = (string) self::get('instance_url'); + if (empty($url)) $url = self::DEFAULT_INSTANCE_URL; + if (!wp_http_validate_url($url)) return ''; + if (!empty($path)) { + $url = sprintf( + '%s/%s', + untrailingslashit(Settings::get_instance_url()), + $path + ); + } + return $url; } public static function get_site_key():string { @@ -55,32 +65,40 @@ final class Settings { return (string) self::get('secret_key'); } + public static function is_connected():bool { + return !empty(self::get_site_key()) && !empty(self::get_secret_key()); + } + public static function get_form_locations():array { return (array) self::get('form_locations'); } + public static function is_form_location_enabled(string $name):bool { + return in_array($name, self::get_form_locations()); + } + public static function is_login_page_enabled():bool { - return in_array(self::LOCATION_LOGIN_PAGE, self::get_form_locations()); + return self::is_form_location_enabled(self::LOCATION_LOGIN_PAGE); } public static function is_registration_page_enabled():bool { - return in_array(self::LOCATION_REGISTRATION_PAGE, self::get_form_locations()); + return self::is_form_location_enabled(self::LOCATION_REGISTRATION_PAGE); } - public static function is_lost_password_page_enabled():bool { - return in_array(self::LOCATION_LOST_PASSWORD_PAGE, self::get_form_locations()); + public static function is_lost_password_form_enabled():bool { + return self::is_form_location_enabled(self::LOCATION_LOST_PASSWORD_FORM); } public static function is_login_form_enabled():bool { - return in_array(self::LOCATION_LOGIN_FORM, self::get_form_locations()); + return self::is_form_location_enabled(self::LOCATION_LOGIN_FORM); } public static function is_comment_form_enabled():bool { - return in_array(self::LOCATION_COMMENT_FORM, self::get_form_locations()); + return self::is_form_location_enabled(self::LOCATION_COMMENT_FORM); } public static function is_post_password_form_enabled():bool { - return in_array(self::LOCATION_POST_PASSWORD_FORM, self::get_form_locations()); + return self::is_form_location_enabled(self::LOCATION_POST_PASSWORD_FORM); } public function menu() { @@ -156,8 +174,8 @@ final class Settings { 'options' => [ self::LOCATION_LOGIN_PAGE => Plugin::__('Login page'), self::LOCATION_REGISTRATION_PAGE => Plugin::__('Registration page'), - self::LOCATION_LOST_PASSWORD_PAGE => Plugin::__('Lost password page'), - self::LOCATION_LOGIN_FORM => Plugin::__('Custom login form'), + self::LOCATION_LOST_PASSWORD_FORM => Plugin::__('Lost password page'), + self::LOCATION_LOGIN_FORM => Plugin::__('Custom login form (requires Login Page)'), self::LOCATION_COMMENT_FORM => Plugin::__('Comment form'), self::LOCATION_POST_PASSWORD_FORM => Plugin::__('Password-protected posts and pages'), ], diff --git a/inc/class-widget.php b/inc/class-widget.php new file mode 100644 index 0000000..7f46433 --- /dev/null +++ b/inc/class-widget.php @@ -0,0 +1,46 @@ +', + esc_attr($id), + esc_url(Settings::get_instance_url(Settings::get_site_key() . '/')) + ); + } + + public static function get_token():string { + return isset($_POST[self::TOKEN_NAME]) ? (string) $_POST[self::TOKEN_NAME] : ''; + } + +} diff --git a/inc/location/class-comment-form.php b/inc/location/class-comment-form.php new file mode 100644 index 0000000..037b8f9 --- /dev/null +++ b/inc/location/class-comment-form.php @@ -0,0 +1,53 @@ +process($errors); + $this->print_errors($errors); + + return $commentdata; + } + +} + +CommentForm::instance(); diff --git a/inc/location/class-login-form.php b/inc/location/class-login-form.php new file mode 100644 index 0000000..ce1815e --- /dev/null +++ b/inc/location/class-login-form.php @@ -0,0 +1,47 @@ +render(); + $content .= ob_get_clean(); + return $content; + } + +} + +LoginForm::instance(); diff --git a/inc/location/class-login-page.php b/inc/location/class-login-page.php new file mode 100644 index 0000000..2e1e152 --- /dev/null +++ b/inc/location/class-login-page.php @@ -0,0 +1,61 @@ +process($errors); + return $errors->has_errors() ? $errors : $user; + } + +} + +LoginPage::instance(); diff --git a/inc/location/class-lost-password-form.php b/inc/location/class-lost-password-form.php new file mode 100644 index 0000000..3c35da9 --- /dev/null +++ b/inc/location/class-lost-password-form.php @@ -0,0 +1,46 @@ +process($errors); + } + +} + +LostPasswordForm::instance(); diff --git a/inc/location/class-post-password-form.php b/inc/location/class-post-password-form.php new file mode 100644 index 0000000..c834a4b --- /dev/null +++ b/inc/location/class-post-password-form.php @@ -0,0 +1,49 @@ +render(); + $output .= ob_get_clean(); + return $output; + } + + public function process_form():void { + $errors = new WP_Error(); + $this->process($errors); + $this->print_errors($errors); + } + +} + +PostPasswordForm::instance(); diff --git a/inc/location/class-registration-page.php b/inc/location/class-registration-page.php new file mode 100644 index 0000000..63110f2 --- /dev/null +++ b/inc/location/class-registration-page.php @@ -0,0 +1,56 @@ +process($result['errors']); + return $result; + } + + public function process_form(WP_Error $errors, string $sanitized_user_login, string $user_email):WP_Error { + $this->process($errors); + return $errors; + } + +} + +RegistrationPage::instance(); diff --git a/ogre-captcha.php b/ogre-captcha.php index e1c73f3..b69cfe0 100644 --- a/ogre-captcha.php +++ b/ogre-captcha.php @@ -1,6 +1,6 @@ add_files([ 'inc/class-settings.php', + 'inc/class-api.php', + 'inc/class-widget.php', + 'inc/abstract-location.php', + 'inc/location/class-comment-form.php', + 'inc/location/class-login-form.php', + 'inc/location/class-login-page.php', + 'inc/location/class-lost-password-form.php', + 'inc/location/class-post-password-form.php', + 'inc/location/class-registration-page.php', ]); }