Files
ogre-captcha/inc/class-settings.php
T
Cooper Dalrymple 1130a6d00f
Validate Build / validate-build (push) Failing after 38s
Improvements to settings page
2026-06-04 17:26:17 -05:00

307 lines
9.7 KiB
PHP

<?php
/**
* @package ogre-captcha
* @author cleverogre
* @copyright 2026 CleverOgre
* @license GLP-3.0-or-later
* @version 0.0.0
* @since 0.0.0
*/
namespace Ogre\Captcha;
use Ogre\Singleton;
use Ogre\Captcha as Plugin;
defined('ABSPATH') || exit;
final class Settings {
use Singleton;
const CAPABILITY = 'manage_options';
const DEFAULT_INSTANCE_URL = 'https://captcha.cleverogre.com';
public const LOCATION_LOGIN_PAGE = 'login_page';
public const LOCATION_REGISTRATION_PAGE = 'registration_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';
protected function __construct() {
add_action('admin_menu', [$this, 'menu']);
add_action('admin_init', [$this, 'init']);
}
private static function get(string $key = '') {
$data = (array) get_option(Plugin::get_id(), []);
if (!empty($key)) return array_key_exists($key, $data) ? $data[$key] : null;
return $data;
}
private static function is_checked(string $name, string $value):bool {
return in_array($value, (array) self::get($name));
}
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 {
return (string) self::get('site_key');
}
public static function get_secret_key():string {
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 self::is_form_location_enabled(self::LOCATION_LOGIN_PAGE);
}
public static function is_registration_page_enabled():bool {
return self::is_form_location_enabled(self::LOCATION_REGISTRATION_PAGE);
}
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 self::is_form_location_enabled(self::LOCATION_LOGIN_FORM);
}
public static function is_comment_form_enabled():bool {
return self::is_form_location_enabled(self::LOCATION_COMMENT_FORM);
}
public static function is_post_password_form_enabled():bool {
return self::is_form_location_enabled(self::LOCATION_POST_PASSWORD_FORM);
}
public function menu() {
if (!current_user_can(self::CAPABILITY)) return;
add_options_page(
sprintf(
Plugin::__('%s Settings'),
Plugin::get_title()
),
Plugin::__('CAPTCHA'),
self::CAPABILITY,
Plugin::get_id(),
[$this, 'page']
);
}
public function init() {
register_setting(Plugin::get_id(), Plugin::get_id());
add_settings_section(
'default',
Plugin::__('Cap API Credentials'),
[$this, 'section'],
Plugin::get_id(),
[
'description' => Plugin::__('The configuration settings for your Cap CAPTCHA API connection.'),
]
);
add_settings_field(
Plugin::get_id() . '_instance_url',
Plugin::__('Instance URL'),
[$this, 'field'],
Plugin::get_id(),
args: [
'name' => 'instance_url',
'placeholder' => Plugin::__('https://captcha.cleverogre.com/'),
'description' => Plugin::__('Provide the base URL to an instance of Cap. Defaults to CleverOgre\'s CAPTCHA server.'),
]
);
add_settings_field(
Plugin::get_id() . '_site_key',
Plugin::__('Site key'),
[$this, 'field'],
Plugin::get_id(),
args: [
'name' => 'site_key',
'description' => Plugin::__('Provide your Cap site key.'),
'type' => 'password',
]
);
add_settings_field(
Plugin::get_id() . '_secret_key',
Plugin::__('Secret key'),
[$this, 'field'],
Plugin::get_id(),
args: [
'name' => 'secret_key',
'description' => Plugin::__('Provide your Cap secret key.'),
'type' => 'password',
]
);
add_settings_section(
'forms',
Plugin::__('CAPTCHA Forms'),
[$this, 'section'],
Plugin::get_id(),
[
'description' => Plugin::__('Define which forms you would like to secure with CAPTCHA.'),
]
);
add_settings_field(
Plugin::get_id() . '_form_locations',
Plugin::__('Form locations'),
[$this, 'checkbox_field'],
Plugin::get_id(),
'forms',
[
'name' => 'form_locations',
'options' => [
self::LOCATION_LOGIN_PAGE => Plugin::__('Login page'),
self::LOCATION_REGISTRATION_PAGE => Plugin::__('Registration page'),
self::LOCATION_LOST_PASSWORD_FORM => Plugin::__('Lost password page'),
self::LOCATION_LOGIN_FORM => Plugin::__('Custom login form'),
self::LOCATION_COMMENT_FORM => Plugin::__('Comment form'),
self::LOCATION_POST_PASSWORD_FORM => Plugin::__('Password-protected posts and pages'),
],
'description' => Plugin::__('Custom login form requires login page to also be enabled.'),
]
);
}
public function page() {
if (!current_user_can(self::CAPABILITY)) return;
// Show error/update messages
settings_errors(Plugin::get_id());
?>
<div class="wrap">
<h1><?php echo esc_html(get_admin_page_title()); ?></h1>
<form action="options.php" method="post"><?php
settings_fields(Plugin::get_id());
do_settings_sections(Plugin::get_id());
submit_button();
?></form>
</div>
<?php
}
public function section(array $args):void {
if (!empty($args['description'] ?? '')) {
echo wpautop($args['description']);
}
}
public function field(array $args):void {
if (empty($args['name'] ?? '')) return;
$attributes = [
'type' => $args['type'] ?? 'text',
'class' => 'regular-text',
'name' => sprintf(
'%s[%s]',
Plugin::get_id(),
$args['name']
),
'id' => $args['name'],
'value' => (string) self::get($args['name']),
];
if ($args['readonly'] ?? false) $attributes['readonly'] = 'readonly';
if ($args['required'] ?? false) $attributes['required'] = 'required';
if (!empty($args['placeholder'] ?? '')) {
$attributes['placeholder'] = $args['placeholder'];
}
if (!empty($args['description'] ?? '')) {
$attributes['describedby'] = $args['name'] . '-description';
}
if (isset($args['attributes']) && is_array($args['attributes'])) {
$attributes = array_merge($attributes, $args['attributes']);
}
printf(
'<input %s />',
implode(
' ',
array_map(
fn (string $name, string $value): string => sprintf(
'%s="%s"',
$name,
esc_attr($value)
),
array_keys($attributes),
array_values($attributes)
)
)
);
if (!empty($args['description'] ?? '')) {
printf(
'<p class="description" id="%s-description">%s</p>',
esc_attr($args['name']),
nl2br($args['description'])
);
}
}
public function checkbox_field(array $args):void {
if (empty($args['name'] ?? '') || empty($args['options'] ?? [])) return;
echo implode('<br>', array_map(
fn (string $name, string $label):string => sprintf(
'<label><input type="checkbox" name="%s[%s][]" value="%s" %s>&nbsp;%s</label>',
esc_attr(Plugin::get_id()),
esc_attr($args['name']),
esc_attr($name),
checked(self::is_checked($args['name'], $name), display: false),
esc_html($label)
),
array_keys($args['options']),
array_values($args['options'])
));
if (!empty($args['description'] ?? '')) {
printf(
'<p class="description" id="%s-description">%s</p>',
esc_attr($args['name']),
nl2br($args['description'])
);
}
}
public static function get_url():string {
return admin_url('options-general.php?page=' . Plugin::get_id());
}
}
Settings::instance();