From ae733d8971f24c572bb6283d759dd53c7c77516e Mon Sep 17 00:00:00 2001 From: Rolf Date: Thu, 12 Dec 2024 10:36:29 +0100 Subject: [PATCH 1/8] Update composer.json --- composer.json | 1 - 1 file changed, 1 deletion(-) diff --git a/composer.json b/composer.json index cc0a2b8..33aaab0 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,6 @@ { "require": { "php": "^8.2.0", - "rrze/wp": "^2.0", "johngrogg/ics-parser": "^3.4.0", "rlanvin/php-rrule": "^2.5.0", "cmb2/cmb2": "^2.11.0" From bae77486451fd3aa1eadcc2a61e8c87b3d7a0688 Mon Sep 17 00:00:00 2001 From: Rolf Date: Thu, 12 Dec 2024 10:36:46 +0100 Subject: [PATCH 2/8] Update Main.php --- includes/Main.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/includes/Main.php b/includes/Main.php index 6d191e2..fac1e31 100644 --- a/includes/Main.php +++ b/includes/Main.php @@ -10,11 +10,14 @@ class Main { - /** - * __construct - */ - public function __construct() + public function loaded() { + // Register the 'CalendarEvent' and 'CalendarFeed' custom post types. + add_action('init', fn() => [ + CalendarEvent::registerPostType(), + CalendarFeed::registerPostType(), + ]); + add_filter('plugin_action_links_' . plugin()->getBaseName(), [$this, 'settingsLink']); add_action('admin_enqueue_scripts', [$this, 'adminEnqueueScripts']); From c11f8ca83317fda541294ed06f9dca3f7809e968 Mon Sep 17 00:00:00 2001 From: Rolf Date: Thu, 12 Dec 2024 10:36:50 +0100 Subject: [PATCH 3/8] Create Plugin.php --- includes/Plugin.php | 214 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 214 insertions(+) create mode 100644 includes/Plugin.php diff --git a/includes/Plugin.php b/includes/Plugin.php new file mode 100644 index 0000000..19ccbb8 --- /dev/null +++ b/includes/Plugin.php @@ -0,0 +1,214 @@ +pluginFile = $pluginFile; + require_once ABSPATH . 'wp-admin/includes/plugin.php'; + } + + /** + * loaded method + */ + public function loaded() + { + $this->setBasename() + ->setDirectory() + ->setUrl() + ->setData(); + } + + /** + * Get the full path and filename of the plugin. + * @return string The full path and filename. + */ + public function getFile(): string + { + return $this->pluginFile; + } + + /** + * Get the basename of the plugin. + * @return string The basename. + */ + public function getBasename(): string + { + return $this->basename; + } + + /** + * Set the basename of the plugin. + * @return object This Plugin object. + */ + public function setBasename(): object + { + $this->basename = plugin_basename($this->pluginFile); + return $this; + } + + /** + * Get the filesystem directory path (with trailing slash) for the plugin. + * @return string The filesystem directory path. + */ + public function getDirectory(): string + { + return $this->directory; + } + + /** + * Set the filesystem directory path (with trailing slash) for the plugin. + * @return object This Plugin object. + */ + public function setDirectory(): object + { + $this->directory = rtrim(plugin_dir_path($this->pluginFile), '/') . '/'; + return $this; + } + + /** + * Get the filesystem directory path (with trailing slash) for the plugin. + * @param string $path The path name. + * @return string The filesystem directory path. + */ + public function getPath(string $path = ''): string + { + return $this->directory . ($path ? trim($path, '/') . '/' : ''); + } + + /** + * Get the URL directory path (with trailing slash) for the plugin. + * @param string $path The path name. + * @return string The URL directory path. + */ + public function getUrl(string $path = ''): string + { + return $this->url . ($path ? trim($path, '/') . '/' : ''); + } + + /** + * Set the URL directory path (with trailing slash) for the plugin. + * @return object This Plugin object. + */ + public function setUrl(): object + { + $this->url = rtrim(plugin_dir_url($this->pluginFile), '/') . '/'; + return $this; + } + + /** + * Get the slug of the plugin. + * @return string The slug. + */ + public function getSlug(): string + { + return sanitize_title(dirname($this->basename)); + } + + /** + * Set the data of the plugin. + * @return object This Plugin object. + */ + public function setData(): object + { + $this->data = get_plugin_data($this->pluginFile, false); + return $this; + } + + /** + * Get the data of the plugin. + * @return array The data. + */ + public function getData(): array + { + return $this->data; + } + + /** + * Get the name of the plugin. + * @return string The name. + */ + public function getName(): string + { + return $this->data['Name']; + } + + /** + * Get the version of the plugin. + * @return string The version. + */ + public function getVersion(): string + { + return $this->data['Version']; + } + + /** + * Get the required WordPress version of the plugin. + * @return string The required WordPress version. + */ + public function getRequiresWP(): string + { + return $this->data['RequiresWP']; + } + + /** + * Get the required PHP version of the plugin. + * @return string The required PHP version. + */ + public function getRequiresPHP(): string + { + return $this->data['RequiresPHP']; + } + + /** + * __call method + * Method overloading. + */ + public function __call(string $name, array $arguments) + { + if (!method_exists($this, $name)) { + $message = sprintf('Call to undefined method %1$s::%2$s', __CLASS__, $name); + if (defined('WP_DEBUG') && WP_DEBUG) { + throw new \Exception($message); + } + } + } +} From 52a735e0c72741e18c71d3c35a95eac25559f837 Mon Sep 17 00:00:00 2001 From: Rolf Date: Thu, 12 Dec 2024 10:36:59 +0100 Subject: [PATCH 4/8] Update Settings.php --- includes/Settings.php | 32 ++++++-------------------------- 1 file changed, 6 insertions(+), 26 deletions(-) diff --git a/includes/Settings.php b/includes/Settings.php index 2ab7200..3a85810 100644 --- a/includes/Settings.php +++ b/includes/Settings.php @@ -4,7 +4,8 @@ defined('ABSPATH') || exit; -use RRZE\WP\Settings\Settings as OptionsSettings; +use RRZE\Calendar\CPT\CalendarEvent; +use RRZE\Calendar\Settings\Settings as OptionsSettings; class Settings { @@ -14,7 +15,7 @@ class Settings public function __construct() { - add_action('rrze_wp_settings_after_update_option', [$this, 'flushRewriteRules']); + add_action('rrze_calendar_settings_after_update_option', [$this, 'flushRewriteRules']); } public function loaded() @@ -67,7 +68,9 @@ public function loaded() public function flushRewriteRules($optionName) { if ($optionName === self::OPTION_NAME) { - flush_rewrite_rules(false); + // Register the 'CalendarEvent' CPT again and flush rewrite rules. + CalendarEvent::registerPostType(); + flush_rewrite_rules(); } } @@ -88,27 +91,4 @@ public function getOptions() { return $this->settings->getOptions(); } - - /** - * __call method - * Method overloading. - */ - public function __call(string $name, array $arguments) - { - if (!method_exists($this, $name)) { - $message = sprintf('Call to undefined method %1$s::%2$s', __CLASS__, $name); - do_action( - 'rrze.log.error', - $message, - [ - 'class' => __CLASS__, - 'method' => $name, - 'arguments' => $arguments - ] - ); - if (defined('WP_DEBUG') && WP_DEBUG) { - throw new \Exception($message); - } - } - } } From 690d7a61e4f502e277310a89d25625a007588a25 Mon Sep 17 00:00:00 2001 From: Rolf Date: Thu, 12 Dec 2024 10:38:07 +0100 Subject: [PATCH 5/8] Add new Settings library --- includes/Settings/Builder.php | 27 ++ includes/Settings/Encryption.php | 102 ++++++ includes/Settings/Error.php | 45 +++ includes/Settings/Flash.php | 29 ++ includes/Settings/Option.php | 119 +++++++ includes/Settings/Options/Checkbox.php | 24 ++ .../Settings/Options/CheckboxMultiple.php | 31 ++ includes/Settings/Options/Password.php | 24 ++ includes/Settings/Options/RadioGroup.php | 10 + includes/Settings/Options/Select.php | 10 + includes/Settings/Options/SelectMultiple.php | 31 ++ includes/Settings/Options/Text.php | 10 + includes/Settings/Options/Textarea.php | 15 + includes/Settings/Options/Type.php | 108 ++++++ includes/Settings/README.md | 295 ++++++++++++++++ includes/Settings/Section.php | 41 +++ includes/Settings/Settings.php | 330 ++++++++++++++++++ includes/Settings/Tab.php | 88 +++++ includes/Settings/Template.php | 26 ++ includes/Settings/Worker.php | 35 ++ .../templates/options/checkbox-multiple.php | 27 ++ .../Settings/templates/options/checkbox.php | 23 ++ .../Settings/templates/options/password.php | 21 ++ .../templates/options/radio-group.php | 28 ++ .../templates/options/select-multiple.php | 25 ++ .../Settings/templates/options/select.php | 24 ++ includes/Settings/templates/options/text.php | 20 ++ .../Settings/templates/options/textarea.php | 20 ++ includes/Settings/templates/section-menu.php | 13 + includes/Settings/templates/section.php | 19 + includes/Settings/templates/sections.php | 17 + includes/Settings/templates/settings-page.php | 25 ++ includes/Settings/templates/tab-menu.php | 11 + 33 files changed, 1673 insertions(+) create mode 100644 includes/Settings/Builder.php create mode 100644 includes/Settings/Encryption.php create mode 100644 includes/Settings/Error.php create mode 100644 includes/Settings/Flash.php create mode 100644 includes/Settings/Option.php create mode 100644 includes/Settings/Options/Checkbox.php create mode 100644 includes/Settings/Options/CheckboxMultiple.php create mode 100644 includes/Settings/Options/Password.php create mode 100644 includes/Settings/Options/RadioGroup.php create mode 100644 includes/Settings/Options/Select.php create mode 100644 includes/Settings/Options/SelectMultiple.php create mode 100644 includes/Settings/Options/Text.php create mode 100644 includes/Settings/Options/Textarea.php create mode 100644 includes/Settings/Options/Type.php create mode 100644 includes/Settings/README.md create mode 100644 includes/Settings/Section.php create mode 100644 includes/Settings/Settings.php create mode 100644 includes/Settings/Tab.php create mode 100644 includes/Settings/Template.php create mode 100644 includes/Settings/Worker.php create mode 100644 includes/Settings/templates/options/checkbox-multiple.php create mode 100644 includes/Settings/templates/options/checkbox.php create mode 100644 includes/Settings/templates/options/password.php create mode 100644 includes/Settings/templates/options/radio-group.php create mode 100644 includes/Settings/templates/options/select-multiple.php create mode 100644 includes/Settings/templates/options/select.php create mode 100644 includes/Settings/templates/options/text.php create mode 100644 includes/Settings/templates/options/textarea.php create mode 100644 includes/Settings/templates/section-menu.php create mode 100644 includes/Settings/templates/section.php create mode 100644 includes/Settings/templates/sections.php create mode 100644 includes/Settings/templates/settings-page.php create mode 100644 includes/Settings/templates/tab-menu.php diff --git a/includes/Settings/Builder.php b/includes/Settings/Builder.php new file mode 100644 index 0000000..c894d22 --- /dev/null +++ b/includes/Settings/Builder.php @@ -0,0 +1,27 @@ +enqueued[$handle] = $callback; + } + + public function remove($handle) + { + unset($this->enqueued[$handle]); + } + + public function enqueue() + { + foreach ($this->enqueued as $enqueue) { + $enqueue(); + } + } +} diff --git a/includes/Settings/Encryption.php b/includes/Settings/Encryption.php new file mode 100644 index 0000000..de017e2 --- /dev/null +++ b/includes/Settings/Encryption.php @@ -0,0 +1,102 @@ +error = new \WP_Error; + $this->settings = $settings; + } + + public function getAll() + { + global $wp_settings_error; + + return $wp_settings_error[$this->settings->optionName] ?? false; + } + + public function get($key) + { + $errors = $this->getAll(); + + if (! is_wp_error($errors)) { + return; + } + + return $errors->get_error_message($key); + } + + public function add($key, $message) + { + global $wp_settings_error; + + $this->error->add($key, $message); + + $wp_settings_error[$this->settings->optionName] = $this->error; + } +} diff --git a/includes/Settings/Flash.php b/includes/Settings/Flash.php new file mode 100644 index 0000000..3c09005 --- /dev/null +++ b/includes/Settings/Flash.php @@ -0,0 +1,29 @@ +settings = $settings; + } + + public function has() + { + global $wp_settings_flash; + + return $wp_settings_flash[$this->settings->optionName] ?? null; + } + + public function set($status, $message) + { + global $wp_settings_flash; + + $wp_settings_flash[$this->settings->optionName] = compact('status', 'message'); + } +} diff --git a/includes/Settings/Option.php b/includes/Settings/Option.php new file mode 100644 index 0000000..923a652 --- /dev/null +++ b/includes/Settings/Option.php @@ -0,0 +1,119 @@ +section = $section; + $this->type = $type; + $this->args = $args; + + $typeMap = apply_filters('rrze_calendar_settings_option_type_map', [ + 'checkbox' => Checkbox::class, + 'checkbox-multiple' => CheckboxMultiple::class, + 'password' => Password::class, + 'radio-group' => RadioGroup::class, + 'select' => Select::class, + 'select-multiple' => SelectMultiple::class, + 'text' => Text::class, + 'textarea' => Textarea::class + ]); + + if (isset($typeMap[$this->type])) { + $this->implementation = new $typeMap[$this->type]($section, $args); + } else { + $this->implementation = null; + } + } + + public function getArg($key, $fallback = null) + { + return $this->args[$key] ?? $fallback; + } + + public function sanitize($value) + { + if (is_callable($this->getArg('sanitize'))) { + return $this->getArg('sanitize')($value); + } + + return is_null($this->implementation) ?: $this->implementation->sanitize($value); + } + + public function validate($value) + { + if (is_array($this->getArg('validate'))) { + foreach ($this->getArg('validate') as $validate) { + if (!is_callable($validate['callback'])) { + continue; + } + + $valid = $validate['callback']($value); + + if (!$valid) { + $this->section->tab->settings->errors->add($this->getArg('name'), $validate['feedback']); + + return false; + } + } + + return true; + } + + if (is_callable($this->getArg('validate'))) { + return $this->getArg('validate')($value); + } + + return is_null($this->implementation) ?: $this->implementation->validate($value); + } + + public function render() + { + if (is_callable($this->getArg('visible')) && $this->getArg('visible')() === false) { + return; + } + + if (is_callable($this->getArg('render'))) { + echo $this->getArg('render')($this->implementation); + + return; + } + + echo is_null($this->implementation) ?: $this->implementation->render(); + } +} diff --git a/includes/Settings/Options/Checkbox.php b/includes/Settings/Options/Checkbox.php new file mode 100644 index 0000000..b93ec4a --- /dev/null +++ b/includes/Settings/Options/Checkbox.php @@ -0,0 +1,24 @@ +section->tab->settings->optionName)[$this->getArg('name')] ?? false; + if ($value === false) { + $value = $this->getArg('default'); + } + return $value; + } + + public function isChecked() + { + return (bool) $this->getValueAttribute(); + } +} diff --git a/includes/Settings/Options/CheckboxMultiple.php b/includes/Settings/Options/CheckboxMultiple.php new file mode 100644 index 0000000..6473fe3 --- /dev/null +++ b/includes/Settings/Options/CheckboxMultiple.php @@ -0,0 +1,31 @@ +section->tab->settings->optionName)[$this->getArg('name')] ?? false; + if ($value === false) { + $value = [$this->getArg('default')]; + } + return $value; + } + + public function sanitize($value) + { + return (array) $value; + } +} diff --git a/includes/Settings/Options/Password.php b/includes/Settings/Options/Password.php new file mode 100644 index 0000000..88107de --- /dev/null +++ b/includes/Settings/Options/Password.php @@ -0,0 +1,24 @@ +section->tab->settings->optionName)[$this->getArg('name')] ?? false; + + return $value ? Encryption::decrypt($value) : null; + } + + public function sanitize($value) + { + return Encryption::encrypt($value); + } +} diff --git a/includes/Settings/Options/RadioGroup.php b/includes/Settings/Options/RadioGroup.php new file mode 100644 index 0000000..1fee3e4 --- /dev/null +++ b/includes/Settings/Options/RadioGroup.php @@ -0,0 +1,10 @@ +section->tab->settings->optionName)[$this->getArg('name')] ?? false; + if ($value === false) { + $value = [$this->getArg('default')]; + } + return $value; + } + + public function sanitize($value) + { + return (array) $value; + } +} diff --git a/includes/Settings/Options/Text.php b/includes/Settings/Options/Text.php new file mode 100644 index 0000000..45323d7 --- /dev/null +++ b/includes/Settings/Options/Text.php @@ -0,0 +1,10 @@ +section = $section; + $this->args = $args; + } + + public function render() + { + return Template::include('options/' . $this->template, ['option' => $this]); + } + + public function hasError() + { + return $this->section->tab->settings->errors->get($this->getArg('name')); + } + + public function sanitize($value) + { + return sanitize_text_field($value); + } + + public function validate($value) + { + return true; + } + + public function getArg($key, $fallback = null) + { + if (empty($this->args[$key])) { + return $fallback; + } + + if (is_callable($this->args[$key])) { + return $this->args[$key](); + } + + return $this->args[$key]; + } + + public function getLabel() + { + return esc_attr($this->getArg('label')); + } + + public function getIdAttribute() + { + return $this->getArg('id', sanitize_title(str_replace('[', '_', $this->getNameAttribute()))); + } + + public function getName() + { + return $this->getArg('name'); + } + + public function getPlaceholderAttribute() + { + $placeholder = $this->getArg('placeholder') ?? null; + + return $placeholder ?: null; + } + + public function getCss() + { + return $this->getArg('css', []); + } + + public function getInputClassAttribute() + { + $class = $this->getCss()['input_class'] ?? null; + + return !empty($class) ? 'class="' . esc_attr($class) . '"' : null; + } + + public function getLabelClassAttribute() + { + $class = $this->getCss()['label_class'] ?? null; + + return !empty($class) ? 'class="' . esc_attr($class) . '"' : null; + } + + public function getNameAttribute() + { + return $this->section->tab->settings->optionName . '[' . $this->getArg('name') . ']'; + } + + public function getValueAttribute() + { + $value = get_option($this->section->tab->settings->optionName)[$this->getArg('name')] ?? false; + + return $value ? $value : $this->args['default'] ?? null; + } +} diff --git a/includes/Settings/README.md b/includes/Settings/README.md new file mode 100644 index 0000000..532853e --- /dev/null +++ b/includes/Settings/README.md @@ -0,0 +1,295 @@ +# RRZE\Calendar\Settings + +The objective of this PHP library is to simplify the process of creating settings pages for WordPress plugins. Traditionally, developers have utilized the Settings API or custom code for this purpose. Although the Settings API functions well, it necessitates substantial setup effort. For instance, developers must manually write the HTML code for their options. Additionally, incorporating tabs and tab-sections can become rather complex. This PHP library aims to streamline these tasks and make settings page creation more straightforward. + +Based on the package `jeffreyvanrossum/wp-settings`. + +## Usage + +### Basic example + +```php +use RRZE\Calendar\Settings\Settings; + +$settings = new Settings(__('My Plugin Settings')); + +$tab = $settings->addTab(__('Tab One', 'textdomain')); + +$section = $tab->addSection(__('Section One', 'textdomain')); + +$section->addOption('text', [ + 'name' => 'title', + 'label' => __('Title', 'textdomain') +]); + +$settings->build(); +``` + +### Initializing the Settings class + +```php +use RRZE\Calendar\Settings\Settings; + +$settings = new Settings(__('Custom Settings', 'textdomain')); +``` + +The constructor supports two parameters, namely `$title` and `$slug`. By default, the page slug is generated by sanitizing the title. If there's a specific slug preference, it can be passed as the second parameter to the constructor. + +Additional methods available in this class include: + +```php +$settings->setCapability('manage_options') + ->setOptionName('my_plugin_option') + ->setMenuTitle(__('My Plugin', 'textdomain')) + ->setMenuIcon('dashicons-admin-generic') + ->setMenuPosition(5) + ->setMenuParentSlug('options-general.php'); +``` + +### Tabs + +Tabs will be displayed only if there is more than one tab available. + +```php +$settings->addTab(__('General', 'textdomain')); +``` + +### Sections + +The `addSection` method can be called from an instance of `Tab`. It can also be called from the `Settings` instance. Subsequently, it will be added to the last created `Tab`. + +```php +$tab->addSection(__('Section One', 'textdomain')); +``` + +If sections are desired to be displayed as submenu-items, the following can be done: + +```php +$tab->addSection('Section One', ['as_link' => true]); +``` + +Note that this only has an effect when there are more than one `as_link` sections. + +### Options + +To add an option, you either call the `addOption` method from an instance of `Section`. `addOption` can also be called from the `Settings` instance. The option will then be added to the last created section. + +#### Text + +```php +$section->addOption('text', [ + 'name' => 'option_1', + 'label' => __('Option 1', 'textdomain') +]); +``` + +#### Textarea + +```php +$section->addOption('textarea', [ + 'name' => 'option_1', + 'label' => __('Option 1', 'textdomain') +]); +``` + +#### Checkbox + +```php +$section->addOption('checkbox', [ + 'name' => 'option_1', + 'label' => __('Option 1', 'textdomain') +]); +``` + +#### Checkbox Multiple + +```php +$section->addOption('checkbox-multiple', [ + 'name' => 'multiple_options_1', + 'label' => __('Multiple Options 1', 'textdomain'), + 'options' => [ + 'option_1' => __('Option 1', 'rrze-calendar'), + 'option_2' => __('Option 2', 'rrze-calendar') + ], +]); +``` + +#### Radio Group + +```php +$section->addOption('radio-group', [ + 'name' => 'radio_group_1', + 'label' => __('Radio Group 1', 'textdomain'), + 'options' => [ + 'option_1' => __('Option 1', 'rrze-calendar'), + 'option_2' => __('Option 2', 'rrze-calendar') + ], +]); +``` + +#### Select + +```php +$section->addOption('select', [ + 'name' => 'option_1', + 'label' => __( 'Option 1', 'textdomain' ), + 'options' => [ + 'value_1' => 'Label 1', + 'value_2' => 'Label 2' + ] +]); +``` + +#### Select Multiple + +```php +$section->addOption('select-multiple', [ + 'name' => 'option_1', + 'label' => __('Option 1', 'textdomain'), + 'options' => [ + 'value_1' => 'Label 1', + 'value_2' => 'Label 2' + ] +] ); +``` + +#### Password + +```php +$section->addOption('password', [ + 'name' => 'password_1', + 'label' => __('Password 1', 'textdomain') +]); +``` + +### Validate + +An option can be validated, allowing for the passing of a callback and a feedback message. Multiple validation rules can be passed as well. + +```php +$section->addOption('text', [ + 'name' => 'custom_api_key', + 'label' => __('API Key', 'textdomain'), + 'validate' => [ + [ + 'feedback' => __('The API key is too short.', 'textdomain'), + 'callback' => fn($value) => strlen($value) > 35 + ] + ] +]); +``` + +### Sanitize + +A sanitize callback can be passed. + +```php +$section->addOption('text', [ + 'name' => 'custom_api_key', + 'label' => __('API Key', 'textdomain'), + 'santitize' => fn($value) => sanitize_key($value) +]); +``` + +### Additional attributes + +#### Description + +```php +$section->addOption('text', [ + 'name' => 'custom_api_key', + 'label' => __('API Key', 'textdomain'), + 'description' => __('Enter the API key here.', 'textdomain') +]); +``` + +#### Placeholder + +```php +$section->addOption('text', [ + 'name' => 'custom_api_key', + 'label' => __('API Key', 'textdomain'), + 'placeholder' => __('Enter the API key here.', 'textdomain') +]); +``` + +#### Default value + +```php +$section->addOption('text', [ + 'name' => 'custom_api_key', + 'label' => __('API Key', 'textdomain'), + 'default' => 'default_value' +]); +``` + +#### CSS classes + +```php +$section->addOption('text', [ + 'name' => 'custom_api_key', + 'label' => __('API Key', 'textdomain'), + 'css' => [ + 'label_class' => 'regular-label', + 'input_class' => 'regular-text' + ] +]); +``` + +### Hooks + +```php +apply_filters('rrze_calendar_settings_new_options', array $newOptions, array $currentOptions) +``` + +```php +apply_filters('rrze_calendar_settings_new_option_{$optionName}', mixed $value, object \RRZE\Calendar\Settings\Options\Type) +``` + +```php +apply_filters('rrze_calendar_settings_option_type_map', array $optionTypeMap) +``` + +```php +apply_filters('rrze_calendar_settings_template_include', string $fileName, array $vars) +``` + +```php +do_action('rrze_calendar_settings_after_update_option', string $optionName, array $options) +``` + +### Adding a custom option type + +To add a custom option type, the `rrze_calendar_settings_option_type_map` filter can be used. + +```php +add_filter('rrze_calendar_settings_option_type_map', function($options){ + $options['custom'] = MyCustomOption::class; + return $options; +}); +``` + +Next, the class `MyCustomOption` must be added for the custom option type. + +```php +use RRZE\Calendar\Settings\Options\Type; + +class MyCustomOption extends Type +{ + public $template = 'custom-option'; + + public function render() + { + echo 'My custom option HTML'; + } +} +``` + +Once registered, the option type can be used as follows: + +```php +$settings->addOption('custom-option', [ + 'name' => 'my_option_name', + 'label' => __('My label', 'textdomain') +]); +``` diff --git a/includes/Settings/Section.php b/includes/Settings/Section.php new file mode 100644 index 0000000..fa9c92d --- /dev/null +++ b/includes/Settings/Section.php @@ -0,0 +1,41 @@ +tab = $tab; + $this->title = $title; + $this->args = $args; + $this->slug = $this->args['slug'] ?? sanitize_title($title); + $this->description = $this->args['description'] ?? null; + $this->as_link = $this->args['as_link'] ?? false; + } + + public function addOption($type, $args = []) + { + $option = new Option($this, $type, $args); + + $this->options[] = $option; + + return $option; + } +} diff --git a/includes/Settings/Settings.php b/includes/Settings/Settings.php new file mode 100644 index 0000000..4456ee7 --- /dev/null +++ b/includes/Settings/Settings.php @@ -0,0 +1,330 @@ +title = $title; + $this->optionName = strtolower(str_replace('-', '_', sanitize_title($this->title))); + $this->slug = $slug; + + if ($this->slug === null) { + $this->slug = sanitize_title($title); + } + } + + public function setMenuParentSlug($slug) + { + $this->parentSlug = $slug; + return $this; + } + + public function setMenuTitle($title) + { + $this->menuTitle = $title; + return $this; + } + + public function getMenuTitle() + { + return $this->menuTitle ?? $this->title; + } + + public function setCapability($capability) + { + $this->capability = $capability; + return $this; + } + + public function setOptionName($name) + { + $this->optionName = $name; + return $this; + } + + public function setMenuIcon($icon) + { + $this->menuIcon = $icon; + return $this; + } + + public function setMenuPosition($position) + { + $this->menuPosition = $position; + return $this; + } + + public function addToMenu() + { + if ($this->parentSlug) { + add_submenu_page( + $this->parentSlug, + $this->title, + $this->getMenuTitle(), + $this->capability, + $this->slug, + [$this, 'render'], + $this->menuPosition + ); + } else { + add_menu_page( + $this->title, + $this->getMenuTitle(), + $this->capability, + $this->slug, + [$this, 'render'], + $this->menuIcon, + $this->menuPosition + ); + } + } + + public function build() + { + $this->errors = new Error($this); + $this->flash = new Flash($this); + + add_action('admin_init', [$this, 'save'], 20); + add_action('admin_menu', [$this, 'addToMenu'], 20); + add_action('admin_head', [$this, 'styling'], 20); + } + + public function isOnSettingsPage() + { + $screen = get_current_screen(); + if (is_null($screen)) { + return false; + } + + if ($screen->base === 'settings_page_' . $this->slug) { + return true; + } + + return false; + } + + public function styling() + { + if (!$this->isOnSettingsPage()) { + return; + } + + echo ''; + } + + public function getTabBySlug($slug) + { + foreach ($this->tabs as $tab) { + if ($tab->slug === $slug) { + return $tab; + } + } + + return false; + } + + public function getActiveTab() + { + $default = $this->tabs[0] ?? false; + + if (isset($_GET['tab'])) { + return in_array($_GET['tab'], array_map(function ($tab) { + return $tab->slug; + }, $this->tabs)) ? $this->getTabBySlug($_GET['tab']) : $default; + } + + return $default; + } + + public function addTab($title, $slug = null) + { + $tab = new Tab($this, $title, $slug); + + $this->tabs[] = $tab; + + return $tab; + } + + public function addSection($title, $args = []) + { + if (empty($this->tabs)) { + $tab = $this->addTab(__('Unnamed tab', 'rrze-calendar')); + } else { + $tab = end($this->tabs); + } + + return $tab->addSection($title, $args); + } + + public function addOption($type, $args = []) + { + $tab = end($this->tabs); + + if (!$tab instanceof Tab) { + return false; + } + + $section = end($tab->sections); + + if (!$section instanceof Section) { + return false; + } + + return $section->addOption($type, $args); + } + + public function shouldMakeTabs() + { + return count($this->tabs) > 1; + } + + public function getUrl() + { + if ($this->parentSlug && strpos($this->parentSlug, '.php') !== false) { + return add_query_arg('page', $this->slug, admin_url($this->parentSlug)); + } + + return admin_url("admin.php?page=$this->slug"); + } + + public function getFullUrl() + { + $params = []; + + if ($active_tab = $this->getActiveTab()) { + $params['tab'] = $active_tab->slug; + + if ($active_section = $active_tab->getActiveSection()) { + $params['section'] = $active_section->slug; + } + } + + return add_query_arg($params, $this->getUrl()); + } + + public function renderTabMenu() + { + if (!$this->shouldMakeTabs()) { + return; + } + + Template::include('tab-menu', ['settings' => $this]); + } + + public function renderActiveSections() + { + Template::include('sections', ['settings' => $this]); + } + + public function render() + { + Worker::setBuilder(new Builder); + + Worker::enqueue(); + + Template::include('settings-page', ['settings' => $this]); + } + + public function save() + { + if ( + !isset($_POST['rrze_calendar_settings_save']) + || !wp_verify_nonce( + $_POST['rrze_calendar_settings_save'], + 'rrze_calendar_settings_save_' . $this->optionName + ) + ) { + return; + } + + if (!current_user_can($this->capability)) { + wp_die(__('You do not have enough permissions to do that.', 'rrze-calendar')); + } + + $currentOptions = $this->getOptions(); + $submittedOptions = apply_filters('rrze_calendar_settings_new_options', $_POST[$this->optionName] ?? [], $currentOptions); + $newOptions = $currentOptions; + + foreach ($this->getActiveTab()->getActiveSections() as $section) { + foreach ($section->options as $option) { + $value = $submittedOptions[$option->implementation->getName()] ?? null; + + $valid = $option->validate($value); + + if (!$valid) { + continue; + } + + $value = apply_filters('rrze_calendar_settings_new_option_' . $option->implementation->getName(), $option->sanitize($value), $option->implementation); + + $newOptions[$option->implementation->getName()] = $value; + } + } + + $this->updateOptions($newOptions); + + $this->flash->set('success', __('Settings saved.', 'rrze-calendar')); + } + + public function defaultOptions() + { + $options = []; + foreach ($this->tabs as $tab) { + foreach ($tab->sections as $section) { + foreach ($section->options as $option) { + $options[$option->args['name']] = $option->args['default'] ?? null; + } + } + } + + return $options; + } + + public function getOptions() + { + $defaults = $this->defaultOptions(); + $options = get_option($this->optionName, []); + $options = wp_parse_args($options, $defaults); + $options = array_intersect_key($options, $defaults); + + return $options; + } + + public function getOption($option) + { + $options = $this->getOptions(); + return $options[$option] ?? null; + } + + public function updateOptions($options) + { + update_option($this->optionName, $options); + do_action('rrze_calendar_settings_after_update_option', $this->optionName, $options); + } +} diff --git a/includes/Settings/Tab.php b/includes/Settings/Tab.php new file mode 100644 index 0000000..d3b98cf --- /dev/null +++ b/includes/Settings/Tab.php @@ -0,0 +1,88 @@ +title = $title; + $this->settings = $settings; + + if ($this->slug === null) { + $this->slug = sanitize_title($title); + } + } + + public function addSection($title, $args = []) + { + $section = new Section($this, $title, $args); + + $this->sections[] = $section; + + return $section; + } + + public function getSectionLinks() + { + return array_filter($this->sections, function ($section) { + return $section->as_link; + }); + } + + public function containsOnlySectionLinks() + { + return count($this->getSectionLinks()) === count($this->sections); + } + + public function getSectionByName($name) + { + foreach ($this->sections as $section) { + if ($section->slug == $name) { + return $section; + } + } + + return false; + } + + public function getActiveSection() + { + if (empty($this->getSectionLinks())) { + return; + } + + if (isset($_REQUEST['section'])) { + return $this->getSectionByName($_REQUEST['section']); + } + + if ($this->containsOnlySectionLinks()) { + return $this->sections[0]; + } + } + + public function getActiveSections() + { + if (!isset($_REQUEST['section']) && $this->containsOnlySectionLinks()) { + return [$this->sections[0]]; + } + + return \array_filter($this->sections, function ($section) { + if (isset($_REQUEST['section'])) { + return $section->as_link && $_REQUEST['section'] == $section->slug; + } + + return !$section->as_link; + }); + } +} diff --git a/includes/Settings/Template.php b/includes/Settings/Template.php new file mode 100644 index 0000000..b081757 --- /dev/null +++ b/includes/Settings/Template.php @@ -0,0 +1,26 @@ + $value) { + ${$name} = $value; + } + + $path = __DIR__ . "/templates/{$fileName}.php"; + if (!file_exists($path)) { + return; + } + + ob_start(); + + include $path; + + echo apply_filters('rrze_calendar_settings_template_include', ob_get_clean(), $fileName, $vars); + } +} diff --git a/includes/Settings/Worker.php b/includes/Settings/Worker.php new file mode 100644 index 0000000..4719963 --- /dev/null +++ b/includes/Settings/Worker.php @@ -0,0 +1,35 @@ +add($handle, $callback); + } + + public function remove($handle) + { + static::builder()->remove($handle); + } + + public static function enqueue() + { + static::builder()->enqueue(); + } +} diff --git a/includes/Settings/templates/options/checkbox-multiple.php b/includes/Settings/templates/options/checkbox-multiple.php new file mode 100644 index 0000000..11980bc --- /dev/null +++ b/includes/Settings/templates/options/checkbox-multiple.php @@ -0,0 +1,27 @@ + + + + getLabel(); ?> + + +
+ getLabel(); ?> + getArg('options', []) as $key => $label) : ?> +
+ + getArg('description')) : ?> +

+ hasError()) : ?> +
+ + +
+ + \ No newline at end of file diff --git a/includes/Settings/templates/options/checkbox.php b/includes/Settings/templates/options/checkbox.php new file mode 100644 index 0000000..2839614 --- /dev/null +++ b/includes/Settings/templates/options/checkbox.php @@ -0,0 +1,23 @@ + + + + + + + + + + + hasError()) { ?> +
+ + + \ No newline at end of file diff --git a/includes/Settings/templates/options/password.php b/includes/Settings/templates/options/password.php new file mode 100644 index 0000000..a26f342 --- /dev/null +++ b/includes/Settings/templates/options/password.php @@ -0,0 +1,21 @@ + + + + + + + getInputClassAttribute(); ?>> + getArg('description')) { ?> +

+ + hasError()) { ?> +
+ + + \ No newline at end of file diff --git a/includes/Settings/templates/options/radio-group.php b/includes/Settings/templates/options/radio-group.php new file mode 100644 index 0000000..4d36af0 --- /dev/null +++ b/includes/Settings/templates/options/radio-group.php @@ -0,0 +1,28 @@ + + + + getLabel(); ?> + + +
+ getLabel(); ?> + getArg('options', []) as $key => $label) { ?> +
+ + getArg('description')) { ?> +

+ + hasError()) { ?> +
+ +
+ + \ No newline at end of file diff --git a/includes/Settings/templates/options/select-multiple.php b/includes/Settings/templates/options/select-multiple.php new file mode 100644 index 0000000..66db0b8 --- /dev/null +++ b/includes/Settings/templates/options/select-multiple.php @@ -0,0 +1,25 @@ + + + + + + + + getArg('description')) { ?> +

+ + + hasError()) { ?> +
+ + + \ No newline at end of file diff --git a/includes/Settings/templates/options/select.php b/includes/Settings/templates/options/select.php new file mode 100644 index 0000000..2461b73 --- /dev/null +++ b/includes/Settings/templates/options/select.php @@ -0,0 +1,24 @@ + + + + + + + + getArg('description')) { ?> +

+ + hasError()) { ?> +
+ + + \ No newline at end of file diff --git a/includes/Settings/templates/options/text.php b/includes/Settings/templates/options/text.php new file mode 100644 index 0000000..f1b3932 --- /dev/null +++ b/includes/Settings/templates/options/text.php @@ -0,0 +1,20 @@ + + + + + + + getInputClassAttribute(); ?>> + getArg('description')) { ?> +

+ + hasError()) { ?> +
+ + + \ No newline at end of file diff --git a/includes/Settings/templates/options/textarea.php b/includes/Settings/templates/options/textarea.php new file mode 100644 index 0000000..93497f6 --- /dev/null +++ b/includes/Settings/templates/options/textarea.php @@ -0,0 +1,20 @@ + + + + + + + + getArg('description')) { ?> +

+ + hasError()) { ?> +
+ + + \ No newline at end of file diff --git a/includes/Settings/templates/section-menu.php b/includes/Settings/templates/section-menu.php new file mode 100644 index 0000000..15acbea --- /dev/null +++ b/includes/Settings/templates/section-menu.php @@ -0,0 +1,13 @@ + +getActiveTab()->getSectionLinks()) { ?> + + \ No newline at end of file diff --git a/includes/Settings/templates/section.php b/includes/Settings/templates/section.php new file mode 100644 index 0000000..721bd9f --- /dev/null +++ b/includes/Settings/templates/section.php @@ -0,0 +1,19 @@ + +

title; ?>

+ +description) { ?> +
description; ?>
+ + + + + options as $option) { ?> + render(); ?> + + +
\ No newline at end of file diff --git a/includes/Settings/templates/sections.php b/includes/Settings/templates/sections.php new file mode 100644 index 0000000..f78b537 --- /dev/null +++ b/includes/Settings/templates/sections.php @@ -0,0 +1,17 @@ + +
+ + + getActiveTab()->getActiveSections() as $section) { ?> + + + + optionName, 'rrze_calendar_settings_save'); ?> + + +
\ No newline at end of file diff --git a/includes/Settings/templates/settings-page.php b/includes/Settings/templates/settings-page.php new file mode 100644 index 0000000..bc6bc68 --- /dev/null +++ b/includes/Settings/templates/settings-page.php @@ -0,0 +1,25 @@ + +
+

title; ?>

+ + flash->has()) { ?> +
+

+
+ + + errors->getAll()) { ?> +
+

+
+ + + renderTabMenu(); ?> + + renderActiveSections(); ?> +
\ No newline at end of file diff --git a/includes/Settings/templates/tab-menu.php b/includes/Settings/templates/tab-menu.php new file mode 100644 index 0000000..fa6ce19 --- /dev/null +++ b/includes/Settings/templates/tab-menu.php @@ -0,0 +1,11 @@ + + \ No newline at end of file From b09b1c8f3c2b546b9ac645e70d881de4792655c4 Mon Sep 17 00:00:00 2001 From: Rolf Date: Thu, 12 Dec 2024 10:38:30 +0100 Subject: [PATCH 6/8] Update vendor files --- vendor/autoload.php | 2 +- vendor/composer/autoload_psr4.php | 1 - vendor/composer/autoload_real.php | 10 +- vendor/composer/autoload_static.php | 15 +- vendor/composer/installed.json | 48 --- vendor/composer/installed.php | 13 +- vendor/rrze/wp/.gitignore | 12 - vendor/rrze/wp/README.md | 25 -- vendor/rrze/wp/composer.json | 27 -- vendor/rrze/wp/src/Plugin/Plugin.php | 204 ----------- vendor/rrze/wp/src/Plugin/README.md | 35 -- vendor/rrze/wp/src/Settings/Builder.php | 27 -- vendor/rrze/wp/src/Settings/Encryption.php | 102 ------ vendor/rrze/wp/src/Settings/Error.php | 45 --- vendor/rrze/wp/src/Settings/Flash.php | 29 -- vendor/rrze/wp/src/Settings/Option.php | 119 ------- .../rrze/wp/src/Settings/Options/Checkbox.php | 24 -- .../src/Settings/Options/CheckboxMultiple.php | 31 -- .../rrze/wp/src/Settings/Options/Password.php | 24 -- .../wp/src/Settings/Options/RadioGroup.php | 10 - .../rrze/wp/src/Settings/Options/Select.php | 10 - .../src/Settings/Options/SelectMultiple.php | 31 -- vendor/rrze/wp/src/Settings/Options/Text.php | 10 - .../rrze/wp/src/Settings/Options/Textarea.php | 15 - vendor/rrze/wp/src/Settings/Options/Type.php | 108 ------ vendor/rrze/wp/src/Settings/README.md | 295 ---------------- vendor/rrze/wp/src/Settings/Section.php | 41 --- vendor/rrze/wp/src/Settings/Settings.php | 330 ------------------ vendor/rrze/wp/src/Settings/Tab.php | 88 ----- vendor/rrze/wp/src/Settings/Template.php | 26 -- vendor/rrze/wp/src/Settings/Worker.php | 35 -- .../languages/rrze-wp-settings-de_DE.mo | Bin 1056 -> 0 bytes .../languages/rrze-wp-settings-de_DE.po | 38 -- .../rrze-wp-settings-de_DE_formal.mo | Bin 1076 -> 0 bytes .../rrze-wp-settings-de_DE_formal.po | 39 --- .../templates/options/checkbox-multiple.php | 27 -- .../Settings/templates/options/checkbox.php | 23 -- .../Settings/templates/options/password.php | 21 -- .../templates/options/radio-group.php | 28 -- .../templates/options/select-multiple.php | 25 -- .../src/Settings/templates/options/select.php | 24 -- .../src/Settings/templates/options/text.php | 20 -- .../Settings/templates/options/textarea.php | 20 -- .../src/Settings/templates/section-menu.php | 13 - .../wp/src/Settings/templates/section.php | 19 - .../wp/src/Settings/templates/sections.php | 17 - .../src/Settings/templates/settings-page.php | 25 -- .../wp/src/Settings/templates/tab-menu.php | 11 - 48 files changed, 13 insertions(+), 2129 deletions(-) delete mode 100644 vendor/rrze/wp/.gitignore delete mode 100644 vendor/rrze/wp/README.md delete mode 100644 vendor/rrze/wp/composer.json delete mode 100644 vendor/rrze/wp/src/Plugin/Plugin.php delete mode 100644 vendor/rrze/wp/src/Plugin/README.md delete mode 100644 vendor/rrze/wp/src/Settings/Builder.php delete mode 100644 vendor/rrze/wp/src/Settings/Encryption.php delete mode 100644 vendor/rrze/wp/src/Settings/Error.php delete mode 100644 vendor/rrze/wp/src/Settings/Flash.php delete mode 100644 vendor/rrze/wp/src/Settings/Option.php delete mode 100644 vendor/rrze/wp/src/Settings/Options/Checkbox.php delete mode 100644 vendor/rrze/wp/src/Settings/Options/CheckboxMultiple.php delete mode 100644 vendor/rrze/wp/src/Settings/Options/Password.php delete mode 100644 vendor/rrze/wp/src/Settings/Options/RadioGroup.php delete mode 100644 vendor/rrze/wp/src/Settings/Options/Select.php delete mode 100644 vendor/rrze/wp/src/Settings/Options/SelectMultiple.php delete mode 100644 vendor/rrze/wp/src/Settings/Options/Text.php delete mode 100644 vendor/rrze/wp/src/Settings/Options/Textarea.php delete mode 100644 vendor/rrze/wp/src/Settings/Options/Type.php delete mode 100644 vendor/rrze/wp/src/Settings/README.md delete mode 100644 vendor/rrze/wp/src/Settings/Section.php delete mode 100644 vendor/rrze/wp/src/Settings/Settings.php delete mode 100644 vendor/rrze/wp/src/Settings/Tab.php delete mode 100644 vendor/rrze/wp/src/Settings/Template.php delete mode 100644 vendor/rrze/wp/src/Settings/Worker.php delete mode 100644 vendor/rrze/wp/src/Settings/languages/rrze-wp-settings-de_DE.mo delete mode 100644 vendor/rrze/wp/src/Settings/languages/rrze-wp-settings-de_DE.po delete mode 100644 vendor/rrze/wp/src/Settings/languages/rrze-wp-settings-de_DE_formal.mo delete mode 100644 vendor/rrze/wp/src/Settings/languages/rrze-wp-settings-de_DE_formal.po delete mode 100644 vendor/rrze/wp/src/Settings/templates/options/checkbox-multiple.php delete mode 100644 vendor/rrze/wp/src/Settings/templates/options/checkbox.php delete mode 100644 vendor/rrze/wp/src/Settings/templates/options/password.php delete mode 100644 vendor/rrze/wp/src/Settings/templates/options/radio-group.php delete mode 100644 vendor/rrze/wp/src/Settings/templates/options/select-multiple.php delete mode 100644 vendor/rrze/wp/src/Settings/templates/options/select.php delete mode 100644 vendor/rrze/wp/src/Settings/templates/options/text.php delete mode 100644 vendor/rrze/wp/src/Settings/templates/options/textarea.php delete mode 100644 vendor/rrze/wp/src/Settings/templates/section-menu.php delete mode 100644 vendor/rrze/wp/src/Settings/templates/section.php delete mode 100644 vendor/rrze/wp/src/Settings/templates/sections.php delete mode 100644 vendor/rrze/wp/src/Settings/templates/settings-page.php delete mode 100644 vendor/rrze/wp/src/Settings/templates/tab-menu.php diff --git a/vendor/autoload.php b/vendor/autoload.php index 48ef29c..ed7da0a 100644 --- a/vendor/autoload.php +++ b/vendor/autoload.php @@ -22,4 +22,4 @@ require_once __DIR__ . '/composer/autoload_real.php'; -return ComposerAutoloaderInit5b6c3334e65a54beb59683486ce33765::getLoader(); +return ComposerAutoloaderInit3edacbd9a8160b9e923dc58bd2192811::getLoader(); diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php index b621c64..28717f2 100644 --- a/vendor/composer/autoload_psr4.php +++ b/vendor/composer/autoload_psr4.php @@ -7,6 +7,5 @@ return array( 'RRule\\' => array($baseDir . '/src', $vendorDir . '/rlanvin/php-rrule/src'), - 'RRZE\\WP\\' => array($vendorDir . '/rrze/wp/src'), 'RRZE\\Calendar\\' => array($baseDir . '/includes'), ); diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php index 35a1596..98e037a 100644 --- a/vendor/composer/autoload_real.php +++ b/vendor/composer/autoload_real.php @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInit5b6c3334e65a54beb59683486ce33765 +class ComposerAutoloaderInit3edacbd9a8160b9e923dc58bd2192811 { private static $loader; @@ -24,16 +24,16 @@ public static function getLoader() require __DIR__ . '/platform_check.php'; - spl_autoload_register(array('ComposerAutoloaderInit5b6c3334e65a54beb59683486ce33765', 'loadClassLoader'), true, true); + spl_autoload_register(array('ComposerAutoloaderInit3edacbd9a8160b9e923dc58bd2192811', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__)); - spl_autoload_unregister(array('ComposerAutoloaderInit5b6c3334e65a54beb59683486ce33765', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInit3edacbd9a8160b9e923dc58bd2192811', 'loadClassLoader')); require __DIR__ . '/autoload_static.php'; - call_user_func(\Composer\Autoload\ComposerStaticInit5b6c3334e65a54beb59683486ce33765::getInitializer($loader)); + call_user_func(\Composer\Autoload\ComposerStaticInit3edacbd9a8160b9e923dc58bd2192811::getInitializer($loader)); $loader->register(true); - $filesToLoad = \Composer\Autoload\ComposerStaticInit5b6c3334e65a54beb59683486ce33765::$files; + $filesToLoad = \Composer\Autoload\ComposerStaticInit3edacbd9a8160b9e923dc58bd2192811::$files; $requireFile = \Closure::bind(static function ($fileIdentifier, $file) { if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 71e5e06..84db290 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -4,7 +4,7 @@ namespace Composer\Autoload; -class ComposerStaticInit5b6c3334e65a54beb59683486ce33765 +class ComposerStaticInit3edacbd9a8160b9e923dc58bd2192811 { public static $files = array ( 'ad901de1e5d16b81f427bfe3dc3de508' => __DIR__ . '/..' . '/cmb2/cmb2/init.php', @@ -14,7 +14,6 @@ class ComposerStaticInit5b6c3334e65a54beb59683486ce33765 'R' => array ( 'RRule\\' => 6, - 'RRZE\\WP\\' => 8, 'RRZE\\Calendar\\' => 14, ), ); @@ -25,10 +24,6 @@ class ComposerStaticInit5b6c3334e65a54beb59683486ce33765 0 => __DIR__ . '/../..' . '/src', 1 => __DIR__ . '/..' . '/rlanvin/php-rrule/src', ), - 'RRZE\\WP\\' => - array ( - 0 => __DIR__ . '/..' . '/rrze/wp/src', - ), 'RRZE\\Calendar\\' => array ( 0 => __DIR__ . '/../..' . '/includes', @@ -53,10 +48,10 @@ class ComposerStaticInit5b6c3334e65a54beb59683486ce33765 public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInit5b6c3334e65a54beb59683486ce33765::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInit5b6c3334e65a54beb59683486ce33765::$prefixDirsPsr4; - $loader->prefixesPsr0 = ComposerStaticInit5b6c3334e65a54beb59683486ce33765::$prefixesPsr0; - $loader->classMap = ComposerStaticInit5b6c3334e65a54beb59683486ce33765::$classMap; + $loader->prefixLengthsPsr4 = ComposerStaticInit3edacbd9a8160b9e923dc58bd2192811::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit3edacbd9a8160b9e923dc58bd2192811::$prefixDirsPsr4; + $loader->prefixesPsr0 = ComposerStaticInit3edacbd9a8160b9e923dc58bd2192811::$prefixesPsr0; + $loader->classMap = ComposerStaticInit3edacbd9a8160b9e923dc58bd2192811::$classMap; }, null, ClassLoader::class); } diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index ce29300..43f2b67 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -180,54 +180,6 @@ "source": "https://github.com/rlanvin/php-rrule/tree/v2.5.1" }, "install-path": "../rlanvin/php-rrule" - }, - { - "name": "rrze/wp", - "version": "2.0.0", - "version_normalized": "2.0.0.0", - "source": { - "type": "git", - "url": "https://github.com/RRZE-Webteam/rrze-wp.git", - "reference": "02076c39edcf586c1cbb5e889553bff0b24048a5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/RRZE-Webteam/rrze-wp/zipball/02076c39edcf586c1cbb5e889553bff0b24048a5", - "reference": "02076c39edcf586c1cbb5e889553bff0b24048a5", - "shasum": "" - }, - "require": { - "php": ">=8.0" - }, - "time": "2024-02-19T15:07:11+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "RRZE\\WP\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "GPL-3.0-or-later" - ], - "authors": [ - { - "name": "RRZE-Webteam", - "email": "webmaster@fau.de", - "homepage": "https://www.rrze.fau.de" - } - ], - "description": "A general purpose library for WordPress.", - "homepage": "https://github.com/RRZE-Webteam/rrze-wp", - "keywords": [ - "wordpress" - ], - "support": { - "issues": "https://github.com/RRZE-Webteam/rrze-wp/issues", - "source": "https://github.com/RRZE-Webteam/rrze-wp/tree/2.0.0" - }, - "install-path": "../rrze/wp" } ], "dev": true, diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index 4dbc4bb..882c1e8 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -3,7 +3,7 @@ 'name' => '__root__', 'pretty_version' => 'dev-master', 'version' => 'dev-master', - 'reference' => 'c9363e0bbcd5d41d384f00dfd5260c72151f3e7f', + 'reference' => '8f4387b6aa92325325194034c79ad4aac873d8b0', 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -13,7 +13,7 @@ '__root__' => array( 'pretty_version' => 'dev-master', 'version' => 'dev-master', - 'reference' => 'c9363e0bbcd5d41d384f00dfd5260c72151f3e7f', + 'reference' => '8f4387b6aa92325325194034c79ad4aac873d8b0', 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -46,14 +46,5 @@ 'aliases' => array(), 'dev_requirement' => false, ), - 'rrze/wp' => array( - 'pretty_version' => '2.0.0', - 'version' => '2.0.0.0', - 'reference' => '02076c39edcf586c1cbb5e889553bff0b24048a5', - 'type' => 'library', - 'install_path' => __DIR__ . '/../rrze/wp', - 'aliases' => array(), - 'dev_requirement' => false, - ), ), ); diff --git a/vendor/rrze/wp/.gitignore b/vendor/rrze/wp/.gitignore deleted file mode 100644 index f0602c7..0000000 --- a/vendor/rrze/wp/.gitignore +++ /dev/null @@ -1,12 +0,0 @@ -### vscode ### -.vscode/ -### NetBeans ### -**/nbproject/ -### PhpStorm ### -.idea/ -### macOS ### -.DS_Store -### Node ### -node_modules/ -### Tmp ### -_tmp/ diff --git a/vendor/rrze/wp/README.md b/vendor/rrze/wp/README.md deleted file mode 100644 index aa045ee..0000000 --- a/vendor/rrze/wp/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# RRZE WordPress Package - -The RRZE package for WordPress is a general-purpose package designed to simplify and streamline the development of plugins for WordPress. - -## Installation - -Install the latest version with - -```bash -% composer require rrze/wp -``` - -## Features - -### Plugin - -The purpose of this PHP library is to streamline the handling of files and directories within WordPress plugins. It offers methods to access various details about the plugin, including its file path, basename, directory, URL, version, and slug. - -[Read more](src/Plugin/README.md) - -### Settings - -This PHP library aims to simplify the creation of WordPress plugin settings pages, reducing reliance on the Settings API or custom code. It addresses the complexity of manual HTML coding for options and the integration of tabs and sections, streamlining the process for straightforward settings page creation. - -[Read more](src/Settings/README.md) diff --git a/vendor/rrze/wp/composer.json b/vendor/rrze/wp/composer.json deleted file mode 100644 index 6e71476..0000000 --- a/vendor/rrze/wp/composer.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "name": "rrze/wp", - "description": "A general purpose library for WordPress.", - "version": "2.0.0", - "type": "library", - "keywords": [ - "wordpress" - ], - "homepage": "https://github.com/RRZE-Webteam/rrze-wp", - "license": "GPL-3.0-or-later", - "authors": [ - { - "name": "RRZE-Webteam", - "email": "webmaster@fau.de", - "homepage": "https://www.rrze.fau.de" - } - ], - "require": { - "php": ">=8.0" - }, - "autoload": { - "psr-4": { - "RRZE\\WP\\": "src" - } - }, - "lock": false -} \ No newline at end of file diff --git a/vendor/rrze/wp/src/Plugin/Plugin.php b/vendor/rrze/wp/src/Plugin/Plugin.php deleted file mode 100644 index 76213fc..0000000 --- a/vendor/rrze/wp/src/Plugin/Plugin.php +++ /dev/null @@ -1,204 +0,0 @@ -pluginFile = $pluginFile; - } - - /** - * loaded method - */ - public function loaded() - { - $this->setBasename() - ->setDirectory() - ->setUrl() - ->setVersion(); - } - - /** - * getFile method - * Get the full path and filename of the plugin. - * @return string The full path and filename. - */ - public function getFile(): string - { - return $this->pluginFile; - } - - /** - * getBasename method - * Get the basename of the plugin. - * @return string The basename. - */ - public function getBasename(): string - { - return $this->basename; - } - - /** - * setBasename method - * Set the basename of the plugin. - * @return object This Plugin object. - */ - public function setBasename(): object - { - $this->basename = plugin_basename($this->pluginFile); - return $this; - } - - /** - * getDirectory method - * Get the filesystem directory path (with trailing slash) for the plugin. - * @return string The filesystem directory path. - */ - public function getDirectory(): string - { - return $this->directory; - } - - /** - * setDirectory method - * Set the filesystem directory path (with trailing slash) for the plugin. - * @return object This Plugin object. - */ - public function setDirectory(): object - { - $this->directory = rtrim(plugin_dir_path($this->pluginFile), '/') . '/'; - return $this; - } - - /** - * getPath method - * Get the filesystem directory path (with trailing slash) for the plugin. - * @param string $path The path name. - * @return string The filesystem directory path. - */ - public function getPath(string $path = ''): string - { - return $this->directory . ($path ? trim($path, '/') . '/' : ''); - } - - /** - * getUrl method - * Get the URL directory path (with trailing slash) for the plugin. - * @param string $path The path name. - * @return string The URL directory path. - */ - public function getUrl(string $path = ''): string - { - return $this->url . ($path ? trim($path, '/') . '/' : ''); - } - - /** - * setUrl method - * Set the URL directory path (with trailing slash) for the plugin. - * @return object This Plugin object. - */ - public function setUrl(): object - { - $this->url = rtrim(plugin_dir_url($this->pluginFile), '/') . '/'; - return $this; - } - - /** - * getSlug method - * Get the slug of the plugin. - * @return string The slug. - */ - public function getSlug(): string - { - return sanitize_title(dirname($this->basename)); - } - - /** - * getVersion method - * Get the version of the plugin. - * @return string The version. - */ - public function getVersion(): string - { - if (defined('WP_DEBUG') && WP_DEBUG) { - return bin2hex(random_bytes(4)); - } - return $this->version; - } - - /** - * getVersion method - * Set the version of the plugin. - * @return object This Plugin object. - */ - public function setVersion(): object - { - $headers = ['Version' => 'Version']; - $fileData = get_file_data($this->pluginFile, $headers, 'plugin'); - if (isset($fileData['Version'])) { - $this->version = $fileData['Version']; - }; - return $this; - } - - /** - * __call method - * Method overloading. - */ - public function __call(string $name, array $arguments) - { - if (!method_exists($this, $name)) { - $message = sprintf('Call to undefined method %1$s::%2$s', __CLASS__, $name); - do_action( - 'rrze.log.error', - $message, - [ - 'class' => __CLASS__, - 'method' => $name, - 'arguments' => $arguments - ] - ); - if (defined('WP_DEBUG') && WP_DEBUG) { - throw new \Exception($message); - } - } - } -} diff --git a/vendor/rrze/wp/src/Plugin/README.md b/vendor/rrze/wp/src/Plugin/README.md deleted file mode 100644 index 32acf51..0000000 --- a/vendor/rrze/wp/src/Plugin/README.md +++ /dev/null @@ -1,35 +0,0 @@ -# RRZE\WP\Plugin - -This PHP library is designed to simplify the management of WordPress plugin files and directories. It provides methods for retrieving information about the plugin, such as its file path, basename, directory, URL, version, and slug. - -## Usage - -To use this class, simply instantiate it with the full path and filename of the plugin: -```php -$plugin = new RRZE\WP\Plugin(__FILE__); -``` - -Then call the loaded() method to initialize the plugin properties: -```php -$plugin->loaded(); -``` - -You can now access various information about the plugin: -```php -$plugin_file = $plugin->getFile(); -$basename = $plugin->getBasename(); -$directory = $plugin->getDirectory(); -$url = $plugin->getUrl(); -$slug = $plugin->getSlug(); -$version = $plugin->getVersion(); -``` - -## Methods - -- `getFile()`: Get the full path and filename of the plugin. -- `getBasename()`: Get the basename of the plugin. -- `getDirectory()`: Get the filesystem directory path for the plugin. -- `getPath(string $path)`: Get the filesystem directory path for a specific file or directory within the plugin. -- `getUrl(string $path)`: Get the URL directory path for a specific file or directory within the plugin. -- `getSlug()`: Get the slug of the plugin. -- `getVersion()`: Get the version of the plugin. diff --git a/vendor/rrze/wp/src/Settings/Builder.php b/vendor/rrze/wp/src/Settings/Builder.php deleted file mode 100644 index c319a89..0000000 --- a/vendor/rrze/wp/src/Settings/Builder.php +++ /dev/null @@ -1,27 +0,0 @@ -enqueued[$handle] = $callback; - } - - public function remove($handle) - { - unset($this->enqueued[$handle]); - } - - public function enqueue() - { - foreach ($this->enqueued as $enqueue) { - $enqueue(); - } - } -} diff --git a/vendor/rrze/wp/src/Settings/Encryption.php b/vendor/rrze/wp/src/Settings/Encryption.php deleted file mode 100644 index dc4396f..0000000 --- a/vendor/rrze/wp/src/Settings/Encryption.php +++ /dev/null @@ -1,102 +0,0 @@ -error = new \WP_Error; - $this->settings = $settings; - } - - public function getAll() - { - global $wp_settings_error; - - return $wp_settings_error[$this->settings->optionName] ?? false; - } - - public function get($key) - { - $errors = $this->getAll(); - - if (! is_wp_error($errors)) { - return; - } - - return $errors->get_error_message($key); - } - - public function add($key, $message) - { - global $wp_settings_error; - - $this->error->add($key, $message); - - $wp_settings_error[$this->settings->optionName] = $this->error; - } -} diff --git a/vendor/rrze/wp/src/Settings/Flash.php b/vendor/rrze/wp/src/Settings/Flash.php deleted file mode 100644 index 8f4c352..0000000 --- a/vendor/rrze/wp/src/Settings/Flash.php +++ /dev/null @@ -1,29 +0,0 @@ -settings = $settings; - } - - public function has() - { - global $wp_settings_flash; - - return $wp_settings_flash[$this->settings->optionName] ?? null; - } - - public function set($status, $message) - { - global $wp_settings_flash; - - $wp_settings_flash[$this->settings->optionName] = compact('status', 'message'); - } -} diff --git a/vendor/rrze/wp/src/Settings/Option.php b/vendor/rrze/wp/src/Settings/Option.php deleted file mode 100644 index 281a843..0000000 --- a/vendor/rrze/wp/src/Settings/Option.php +++ /dev/null @@ -1,119 +0,0 @@ -section = $section; - $this->type = $type; - $this->args = $args; - - $typeMap = apply_filters('rrze_wp_settings_option_type_map', [ - 'checkbox' => Checkbox::class, - 'checkbox-multiple' => CheckboxMultiple::class, - 'password' => Password::class, - 'radio-group' => RadioGroup::class, - 'select' => Select::class, - 'select-multiple' => SelectMultiple::class, - 'text' => Text::class, - 'textarea' => Textarea::class - ]); - - if (isset($typeMap[$this->type])) { - $this->implementation = new $typeMap[$this->type]($section, $args); - } else { - $this->implementation = null; - } - } - - public function getArg($key, $fallback = null) - { - return $this->args[$key] ?? $fallback; - } - - public function sanitize($value) - { - if (is_callable($this->getArg('sanitize'))) { - return $this->getArg('sanitize')($value); - } - - return is_null($this->implementation) ?: $this->implementation->sanitize($value); - } - - public function validate($value) - { - if (is_array($this->getArg('validate'))) { - foreach ($this->getArg('validate') as $validate) { - if (!is_callable($validate['callback'])) { - continue; - } - - $valid = $validate['callback']($value); - - if (!$valid) { - $this->section->tab->settings->errors->add($this->getArg('name'), $validate['feedback']); - - return false; - } - } - - return true; - } - - if (is_callable($this->getArg('validate'))) { - return $this->getArg('validate')($value); - } - - return is_null($this->implementation) ?: $this->implementation->validate($value); - } - - public function render() - { - if (is_callable($this->getArg('visible')) && $this->getArg('visible')() === false) { - return; - } - - if (is_callable($this->getArg('render'))) { - echo $this->getArg('render')($this->implementation); - - return; - } - - echo is_null($this->implementation) ?: $this->implementation->render(); - } -} diff --git a/vendor/rrze/wp/src/Settings/Options/Checkbox.php b/vendor/rrze/wp/src/Settings/Options/Checkbox.php deleted file mode 100644 index 4399712..0000000 --- a/vendor/rrze/wp/src/Settings/Options/Checkbox.php +++ /dev/null @@ -1,24 +0,0 @@ -section->tab->settings->optionName)[$this->getArg('name')] ?? false; - if ($value === false) { - $value = $this->getArg('default'); - } - return $value; - } - - public function isChecked() - { - return (bool) $this->getValueAttribute(); - } -} diff --git a/vendor/rrze/wp/src/Settings/Options/CheckboxMultiple.php b/vendor/rrze/wp/src/Settings/Options/CheckboxMultiple.php deleted file mode 100644 index 3cedc0b..0000000 --- a/vendor/rrze/wp/src/Settings/Options/CheckboxMultiple.php +++ /dev/null @@ -1,31 +0,0 @@ -section->tab->settings->optionName)[$this->getArg('name')] ?? false; - if ($value === false) { - $value = [$this->getArg('default')]; - } - return $value; - } - - public function sanitize($value) - { - return (array) $value; - } -} diff --git a/vendor/rrze/wp/src/Settings/Options/Password.php b/vendor/rrze/wp/src/Settings/Options/Password.php deleted file mode 100644 index af9d9f0..0000000 --- a/vendor/rrze/wp/src/Settings/Options/Password.php +++ /dev/null @@ -1,24 +0,0 @@ -section->tab->settings->optionName)[$this->getArg('name')] ?? false; - - return $value ? Encryption::decrypt($value) : null; - } - - public function sanitize($value) - { - return Encryption::encrypt($value); - } -} diff --git a/vendor/rrze/wp/src/Settings/Options/RadioGroup.php b/vendor/rrze/wp/src/Settings/Options/RadioGroup.php deleted file mode 100644 index a382dcd..0000000 --- a/vendor/rrze/wp/src/Settings/Options/RadioGroup.php +++ /dev/null @@ -1,10 +0,0 @@ -section->tab->settings->optionName)[$this->getArg('name')] ?? false; - if ($value === false) { - $value = [$this->getArg('default')]; - } - return $value; - } - - public function sanitize($value) - { - return (array) $value; - } -} diff --git a/vendor/rrze/wp/src/Settings/Options/Text.php b/vendor/rrze/wp/src/Settings/Options/Text.php deleted file mode 100644 index 5336d14..0000000 --- a/vendor/rrze/wp/src/Settings/Options/Text.php +++ /dev/null @@ -1,10 +0,0 @@ -section = $section; - $this->args = $args; - } - - public function render() - { - return Template::include('options/' . $this->template, ['option' => $this]); - } - - public function hasError() - { - return $this->section->tab->settings->errors->get($this->getArg('name')); - } - - public function sanitize($value) - { - return sanitize_text_field($value); - } - - public function validate($value) - { - return true; - } - - public function getArg($key, $fallback = null) - { - if (empty($this->args[$key])) { - return $fallback; - } - - if (is_callable($this->args[$key])) { - return $this->args[$key](); - } - - return $this->args[$key]; - } - - public function getLabel() - { - return esc_attr($this->getArg('label')); - } - - public function getIdAttribute() - { - return $this->getArg('id', sanitize_title(str_replace('[', '_', $this->getNameAttribute()))); - } - - public function getName() - { - return $this->getArg('name'); - } - - public function getPlaceholderAttribute() - { - $placeholder = $this->getArg('placeholder') ?? null; - - return $placeholder ?: null; - } - - public function getCss() - { - return $this->getArg('css', []); - } - - public function getInputClassAttribute() - { - $class = $this->getCss()['input_class'] ?? null; - - return !empty($class) ? 'class="' . esc_attr($class) . '"' : null; - } - - public function getLabelClassAttribute() - { - $class = $this->getCss()['label_class'] ?? null; - - return !empty($class) ? 'class="' . esc_attr($class) . '"' : null; - } - - public function getNameAttribute() - { - return $this->section->tab->settings->optionName . '[' . $this->getArg('name') . ']'; - } - - public function getValueAttribute() - { - $value = get_option($this->section->tab->settings->optionName)[$this->getArg('name')] ?? false; - - return $value ? $value : $this->args['default'] ?? null; - } -} diff --git a/vendor/rrze/wp/src/Settings/README.md b/vendor/rrze/wp/src/Settings/README.md deleted file mode 100644 index 4074db0..0000000 --- a/vendor/rrze/wp/src/Settings/README.md +++ /dev/null @@ -1,295 +0,0 @@ -# RRZE\WP\Settings - -The objective of this PHP library is to simplify the process of creating settings pages for WordPress plugins. Traditionally, developers have utilized the Settings API or custom code for this purpose. Although the Settings API functions well, it necessitates substantial setup effort. For instance, developers must manually write the HTML code for their options. Additionally, incorporating tabs and tab-sections can become rather complex. This PHP library aims to streamline these tasks and make settings page creation more straightforward. - -Based on the package `jeffreyvanrossum/wp-settings`. - -## Usage - -### Basic example - -```php -use RRZE\WP\Settings\Settings; - -$settings = new Settings(__('My Plugin Settings')); - -$tab = $settings->addTab(__('Tab One', 'textdomain')); - -$section = $tab->addSection(__('Section One', 'textdomain')); - -$section->addOption('text', [ - 'name' => 'title', - 'label' => __('Title', 'textdomain') -]); - -$settings->build(); -``` - -### Initializing the Settings class - -```php -use RRZE\WP\Settings\Settings; - -$settings = new Settings(__('Custom Settings', 'textdomain')); -``` - -The constructor supports two parameters, namely `$title` and `$slug`. By default, the page slug is generated by sanitizing the title. If there's a specific slug preference, it can be passed as the second parameter to the constructor. - -Additional methods available in this class include: - -```php -$settings->setCapability('manage_options') - ->setOptionName('my_plugin_option') - ->setMenuTitle(__('My Plugin', 'textdomain')) - ->setMenuIcon('dashicons-admin-generic') - ->setMenuPosition(5) - ->setMenuParentSlug('options-general.php'); -``` - -### Tabs - -Tabs will be displayed only if there is more than one tab available. - -```php -$settings->addTab(__('General', 'textdomain')); -``` - -### Sections - -The `addSection` method can be called from an instance of `Tab`. It can also be called from the `Settings` instance. Subsequently, it will be added to the last created `Tab`. - -```php -$tab->addSection(__('Section One', 'textdomain')); -``` - -If sections are desired to be displayed as submenu-items, the following can be done: - -```php -$tab->addSection('Section One', ['as_link' => true]); -``` - -Note that this only has an effect when there are more than one `as_link` sections. - -### Options - -To add an option, you either call the `addOption` method from an instance of `Section`. `addOption` can also be called from the `Settings` instance. The option will then be added to the last created section. - -#### Text - -```php -$section->addOption('text', [ - 'name' => 'option_1', - 'label' => __('Option 1', 'textdomain') -]); -``` - -#### Textarea - -```php -$section->addOption('textarea', [ - 'name' => 'option_1', - 'label' => __('Option 1', 'textdomain') -]); -``` - -#### Checkbox - -```php -$section->addOption('checkbox', [ - 'name' => 'option_1', - 'label' => __('Option 1', 'textdomain') -]); -``` - -#### Checkbox Multiple - -```php -$section->addOption('checkbox-multiple', [ - 'name' => 'multiple_options_1', - 'label' => __('Multiple Options 1', 'textdomain'), - 'options' => [ - 'option_1' => __('Option 1', 'rrze-autoshare'), - 'option_2' => __('Option 2', 'rrze-autoshare') - ], -]); -``` - -#### Radio Group - -```php -$section->addOption('radio-group', [ - 'name' => 'radio_group_1', - 'label' => __('Radio Group 1', 'textdomain'), - 'options' => [ - 'option_1' => __('Option 1', 'rrze-autoshare'), - 'option_2' => __('Option 2', 'rrze-autoshare') - ], -]); -``` - -#### Select - -```php -$section->addOption('select', [ - 'name' => 'option_1', - 'label' => __( 'Option 1', 'textdomain' ), - 'options' => [ - 'value_1' => 'Label 1', - 'value_2' => 'Label 2' - ] -]); -``` - -#### Select Multiple - -```php -$section->addOption('select-multiple', [ - 'name' => 'option_1', - 'label' => __('Option 1', 'textdomain'), - 'options' => [ - 'value_1' => 'Label 1', - 'value_2' => 'Label 2' - ] -] ); -``` - -#### Password - -```php -$section->addOption('password', [ - 'name' => 'password_1', - 'label' => __('Password 1', 'textdomain') -]); -``` - -### Validate - -An option can be validated, allowing for the passing of a callback and a feedback message. Multiple validation rules can be passed as well. - -```php -$section->addOption('text', [ - 'name' => 'custom_api_key', - 'label' => __('API Key', 'textdomain'), - 'validate' => [ - [ - 'feedback' => __('The API key is too short.', 'textdomain'), - 'callback' => fn($value) => strlen($value) > 35 - ] - ] -]); -``` - -### Sanitize - -A sanitize callback can be passed. - -```php -$section->addOption('text', [ - 'name' => 'custom_api_key', - 'label' => __('API Key', 'textdomain'), - 'santitize' => fn($value) => sanitize_key($value) -]); -``` - -### Additional attributes - -#### Description - -```php -$section->addOption('text', [ - 'name' => 'custom_api_key', - 'label' => __('API Key', 'textdomain'), - 'description' => __('Enter the API key here.', 'textdomain') -]); -``` - -#### Placeholder - -```php -$section->addOption('text', [ - 'name' => 'custom_api_key', - 'label' => __('API Key', 'textdomain'), - 'placeholder' => __('Enter the API key here.', 'textdomain') -]); -``` - -#### Default value - -```php -$section->addOption('text', [ - 'name' => 'custom_api_key', - 'label' => __('API Key', 'textdomain'), - 'default' => 'default_value' -]); -``` - -#### CSS classes - -```php -$section->addOption('text', [ - 'name' => 'custom_api_key', - 'label' => __('API Key', 'textdomain'), - 'css' => [ - 'label_class' => 'regular-label', - 'input_class' => 'regular-text' - ] -]); -``` - -### Hooks - -```php -apply_filters('rrze_wp_settings_new_options', array $newOptions, array $currentOptions) -``` - -```php -apply_filters('rrze_wp_settings_new_option_{$optionName}', mixed $value, object \RRZE\WP\Settings\Options\Type) -``` - -```php -apply_filters('rrze_wp_settings_option_type_map', array $optionTypeMap) -``` - -```php -apply_filters('rrze_wp_settings_template_include', string $fileName, array $vars) -``` - -```php -do_action('rrze_wp_settings_after_update_option', string $optionName, array $options) -``` - -### Adding a custom option type - -To add a custom option type, the `rrze_wp_settings_option_type_map` filter can be used. - -```php -add_filter('rrze_wp_settings_option_type_map', function($options){ - $options['custom'] = MyCustomOption::class; - return $options; -}); -``` - -Next, the class `MyCustomOption` must be added for the custom option type. - -```php -use RRZE\WP\Settings\Options\Type; - -class MyCustomOption extends Type -{ - public $template = 'custom-option'; - - public function render() - { - echo 'My custom option HTML'; - } -} -``` - -Once registered, the option type can be used as follows: - -```php -$settings->addOption('custom-option', [ - 'name' => 'my_option_name', - 'label' => __('My label', 'textdomain') -]); -``` diff --git a/vendor/rrze/wp/src/Settings/Section.php b/vendor/rrze/wp/src/Settings/Section.php deleted file mode 100644 index cffd67a..0000000 --- a/vendor/rrze/wp/src/Settings/Section.php +++ /dev/null @@ -1,41 +0,0 @@ -tab = $tab; - $this->title = $title; - $this->args = $args; - $this->slug = $this->args['slug'] ?? sanitize_title($title); - $this->description = $this->args['description'] ?? null; - $this->as_link = $this->args['as_link'] ?? false; - } - - public function addOption($type, $args = []) - { - $option = new Option($this, $type, $args); - - $this->options[] = $option; - - return $option; - } -} diff --git a/vendor/rrze/wp/src/Settings/Settings.php b/vendor/rrze/wp/src/Settings/Settings.php deleted file mode 100644 index e3a58b4..0000000 --- a/vendor/rrze/wp/src/Settings/Settings.php +++ /dev/null @@ -1,330 +0,0 @@ -title = $title; - $this->optionName = strtolower(str_replace('-', '_', sanitize_title($this->title))); - $this->slug = $slug; - - if ($this->slug === null) { - $this->slug = sanitize_title($title); - } - } - - public function setMenuParentSlug($slug) - { - $this->parentSlug = $slug; - return $this; - } - - public function setMenuTitle($title) - { - $this->menuTitle = $title; - return $this; - } - - public function getMenuTitle() - { - return $this->menuTitle ?? $this->title; - } - - public function setCapability($capability) - { - $this->capability = $capability; - return $this; - } - - public function setOptionName($name) - { - $this->optionName = $name; - return $this; - } - - public function setMenuIcon($icon) - { - $this->menuIcon = $icon; - return $this; - } - - public function setMenuPosition($position) - { - $this->menuPosition = $position; - return $this; - } - - public function addToMenu() - { - if ($this->parentSlug) { - add_submenu_page( - $this->parentSlug, - $this->title, - $this->getMenuTitle(), - $this->capability, - $this->slug, - [$this, 'render'], - $this->menuPosition - ); - } else { - add_menu_page( - $this->title, - $this->getMenuTitle(), - $this->capability, - $this->slug, - [$this, 'render'], - $this->menuIcon, - $this->menuPosition - ); - } - } - - public function build() - { - $this->errors = new Error($this); - $this->flash = new Flash($this); - - add_action('admin_init', [$this, 'save'], 20); - add_action('admin_menu', [$this, 'addToMenu'], 20); - add_action('admin_head', [$this, 'styling'], 20); - } - - public function isOnSettingsPage() - { - $screen = get_current_screen(); - if (is_null($screen)) { - return false; - } - - if ($screen->base === 'settings_page_' . $this->slug) { - return true; - } - - return false; - } - - public function styling() - { - if (!$this->isOnSettingsPage()) { - return; - } - - echo ''; - } - - public function getTabBySlug($slug) - { - foreach ($this->tabs as $tab) { - if ($tab->slug === $slug) { - return $tab; - } - } - - return false; - } - - public function getActiveTab() - { - $default = $this->tabs[0] ?? false; - - if (isset($_GET['tab'])) { - return in_array($_GET['tab'], array_map(function ($tab) { - return $tab->slug; - }, $this->tabs)) ? $this->getTabBySlug($_GET['tab']) : $default; - } - - return $default; - } - - public function addTab($title, $slug = null) - { - $tab = new Tab($this, $title, $slug); - - $this->tabs[] = $tab; - - return $tab; - } - - public function addSection($title, $args = []) - { - if (empty($this->tabs)) { - $tab = $this->addTab(__('Unnamed tab', 'rrze-wp-settings')); - } else { - $tab = end($this->tabs); - } - - return $tab->addSection($title, $args); - } - - public function addOption($type, $args = []) - { - $tab = end($this->tabs); - - if (!$tab instanceof Tab) { - return false; - } - - $section = end($tab->sections); - - if (!$section instanceof Section) { - return false; - } - - return $section->addOption($type, $args); - } - - public function shouldMakeTabs() - { - return count($this->tabs) > 1; - } - - public function getUrl() - { - if ($this->parentSlug && strpos($this->parentSlug, '.php') !== false) { - return add_query_arg('page', $this->slug, admin_url($this->parentSlug)); - } - - return admin_url("admin.php?page=$this->slug"); - } - - public function getFullUrl() - { - $params = []; - - if ($active_tab = $this->getActiveTab()) { - $params['tab'] = $active_tab->slug; - - if ($active_section = $active_tab->getActiveSection()) { - $params['section'] = $active_section->slug; - } - } - - return add_query_arg($params, $this->getUrl()); - } - - public function renderTabMenu() - { - if (!$this->shouldMakeTabs()) { - return; - } - - Template::include('tab-menu', ['settings' => $this]); - } - - public function renderActiveSections() - { - Template::include('sections', ['settings' => $this]); - } - - public function render() - { - Worker::setBuilder(new Builder); - - Worker::enqueue(); - - Template::include('settings-page', ['settings' => $this]); - } - - public function save() - { - if ( - !isset($_POST['rrze_wp_settings_save']) - || !wp_verify_nonce( - $_POST['rrze_wp_settings_save'], - 'rrze_wp_settings_save_' . $this->optionName - ) - ) { - return; - } - - if (!current_user_can($this->capability)) { - wp_die(__('You do not have enough permissions to do that.', 'rrze-wp-settings')); - } - - $currentOptions = $this->getOptions(); - $submittedOptions = apply_filters('rrze_wp_settings_new_options', $_POST[$this->optionName] ?? [], $currentOptions); - $newOptions = $currentOptions; - - foreach ($this->getActiveTab()->getActiveSections() as $section) { - foreach ($section->options as $option) { - $value = $submittedOptions[$option->implementation->getName()] ?? null; - - $valid = $option->validate($value); - - if (!$valid) { - continue; - } - - $value = apply_filters('rrze_wp_settings_new_option_' . $option->implementation->getName(), $option->sanitize($value), $option->implementation); - - $newOptions[$option->implementation->getName()] = $value; - } - } - - $this->updateOptions($newOptions); - - $this->flash->set('success', __('Settings saved.', 'rrze-wp-settings')); - } - - public function defaultOptions() - { - $options = []; - foreach ($this->tabs as $tab) { - foreach ($tab->sections as $section) { - foreach ($section->options as $option) { - $options[$option->args['name']] = $option->args['default'] ?? null; - } - } - } - - return $options; - } - - public function getOptions() - { - $defaults = $this->defaultOptions(); - $options = get_option($this->optionName, []); - $options = wp_parse_args($options, $defaults); - $options = array_intersect_key($options, $defaults); - - return $options; - } - - public function getOption($option) - { - $options = $this->getOptions(); - return $options[$option] ?? null; - } - - public function updateOptions($options) - { - update_option($this->optionName, $options); - do_action('rrze_wp_settings_after_update_option', $this->optionName, $options); - } -} diff --git a/vendor/rrze/wp/src/Settings/Tab.php b/vendor/rrze/wp/src/Settings/Tab.php deleted file mode 100644 index cd01364..0000000 --- a/vendor/rrze/wp/src/Settings/Tab.php +++ /dev/null @@ -1,88 +0,0 @@ -title = $title; - $this->settings = $settings; - - if ($this->slug === null) { - $this->slug = sanitize_title($title); - } - } - - public function addSection($title, $args = []) - { - $section = new Section($this, $title, $args); - - $this->sections[] = $section; - - return $section; - } - - public function getSectionLinks() - { - return array_filter($this->sections, function ($section) { - return $section->as_link; - }); - } - - public function containsOnlySectionLinks() - { - return count($this->getSectionLinks()) === count($this->sections); - } - - public function getSectionByName($name) - { - foreach ($this->sections as $section) { - if ($section->slug == $name) { - return $section; - } - } - - return false; - } - - public function getActiveSection() - { - if (empty($this->getSectionLinks())) { - return; - } - - if (isset($_REQUEST['section'])) { - return $this->getSectionByName($_REQUEST['section']); - } - - if ($this->containsOnlySectionLinks()) { - return $this->sections[0]; - } - } - - public function getActiveSections() - { - if (!isset($_REQUEST['section']) && $this->containsOnlySectionLinks()) { - return [$this->sections[0]]; - } - - return \array_filter($this->sections, function ($section) { - if (isset($_REQUEST['section'])) { - return $section->as_link && $_REQUEST['section'] == $section->slug; - } - - return !$section->as_link; - }); - } -} diff --git a/vendor/rrze/wp/src/Settings/Template.php b/vendor/rrze/wp/src/Settings/Template.php deleted file mode 100644 index 74b0625..0000000 --- a/vendor/rrze/wp/src/Settings/Template.php +++ /dev/null @@ -1,26 +0,0 @@ - $value) { - ${$name} = $value; - } - - $path = __DIR__ . "/templates/{$fileName}.php"; - if (!file_exists($path)) { - return; - } - - ob_start(); - - include $path; - - echo apply_filters('rrze_wp_settings_template_include', ob_get_clean(), $fileName, $vars); - } -} diff --git a/vendor/rrze/wp/src/Settings/Worker.php b/vendor/rrze/wp/src/Settings/Worker.php deleted file mode 100644 index 77eb09e..0000000 --- a/vendor/rrze/wp/src/Settings/Worker.php +++ /dev/null @@ -1,35 +0,0 @@ -add($handle, $callback); - } - - public function remove($handle) - { - static::builder()->remove($handle); - } - - public static function enqueue() - { - static::builder()->enqueue(); - } -} diff --git a/vendor/rrze/wp/src/Settings/languages/rrze-wp-settings-de_DE.mo b/vendor/rrze/wp/src/Settings/languages/rrze-wp-settings-de_DE.mo deleted file mode 100644 index f126a662fbe234357d48d50235f96fd9e4f49dc1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1056 zcmY*Y!EVz)5H(PQWDZE2KmutvAc4plC+&ec1fe!5s%S-&rnI0+*2bRN27A}q9k(f8 zKtF&BR}Opt5?2nK`2~&~`3A;uo0OHF-gxHC%zAeB_sykG4zH_>JB&W#8Y5@a>m%bf z<`@S&F#Tr*KN;t*R>*4-0Y;}-4IUcahc0Zbss$=|W@n9w@ligZ9I& zyDx?sYqH&hMHy`j>&JPTd0qgJS*U?pnJ zlBTsF;^gVvrKXMgT!LpBv{5LD40oTKxG*oMQY!K@)y!;EGqX`Ger!!zEG4A@cnjx_ zu1tjM%~S(u#=0+FphD9eax)fK_Ex;kg*=odN{3ud`2QDN1lk<%TxXCez7=_1@f#?O zp5$2YbvEy%Qhagy8NvkxDmbo8%#@%lF^f_(tlCu*RCNNv2opY;I^PgF{feK5B~Yv+ ih`E^h`JJ+a3#_3*c4i4TM%99\n" -"Language-Team: Deutsch\n" -"Language: de_DE\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Poedit-KeywordsList: __;_e;__ngettext:1,2;_n:1,2;__ngettext_noop:1,2;" -"_n_noop:1,2;_c,_nc:4c,1,2;_x:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2;_ex:1,2c;" -"esc_attr__;esc_attr_e;esc_attr_x:1,2c;esc_html__;esc_html_e;" -"esc_html_x:1,2c\n" -"X-Poedit-Basepath: .\n" -"X-Poedit-SourceCharset: UTF-8\n" -"X-Generator: Poedit 3.4.2\n" -"X-Poedit-SearchPath-0: .\n" -"X-Poedit-SearchPath-1: ..\n" - -#: Main.php:177 -msgid "Unnamed tab" -msgstr "Unbenannte Registerkarte" - -#: Main.php:267 -msgid "You do not have enough permissions to do that." -msgstr "Du hast nicht die nötigen Berechtigungen, um das zu tun." - -#: Main.php:292 -msgid "Settings saved." -msgstr "Die Einstellungen wurden gespeichert." - -#: templates/settings-page.php:18 -msgid "Settings issues detected." -msgstr "Einstellungsprobleme erkannt." diff --git a/vendor/rrze/wp/src/Settings/languages/rrze-wp-settings-de_DE_formal.mo b/vendor/rrze/wp/src/Settings/languages/rrze-wp-settings-de_DE_formal.mo deleted file mode 100644 index 69c818d085d9717a5e010313c5f57b5c81d211b5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1076 zcmY*YO>fgc5H(PQ6b?w7KmutvAc4plC+(p)1fe!5s%S-&rnI0+*2bRN27A`pUAHN} z0JwAF$b~!CN*sFUCvfG)Z(tm^Nm%LW&F;MU@a+2c&8066ud9qZj2`0}BV$zSBjYyX z6XOQs8{<0T2g7CjWPH8sIDeV%GCp5%ocqk*nQt-wV%}o@!+eRE$ys7l^{U08_1Zye zQ;H3w#*}CvLW`lr$aQ8OBaf>6E|JVJ0xQSP8&yK2fRu%Vy?~_3IDrCn&UsQr2CS+S zHj&nK23o!2tYR|~uTfWiABMxX{e!*1!9|(I5DTTP*fwz*iM28|Vx)X%3|@&L9;H=~ z=t+w{w7vF<@YatE!S(TE3!yj@1)>{EKcm>B9kd~ zAWWn-XuG?k4Y4}cRec?z7JUj;#PjxHb)4G9AS<=Z#D>zj@qvoz)^yt)sLd|Hy)Lvm zjeRjt7^POc#FJyCBeRtn>q8K90_+3<#e9w2h2LtnI|0=+I}J#w;@q`hhs}UOeYZ8-gu_*rCG$v;7% z)i}eP-?M%%iTLIAQiKHs5*(L0Vv5len1%^zR_)RlsR}?CV$3&F#cPWWza=\n" -"Language-Team: Deutsch (Sie)\n" -"Language: de\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Poedit-KeywordsList: __;_e;__ngettext:1,2;_n:1,2;__ngettext_noop:1,2;" -"_n_noop:1,2;_c,_nc:4c,1,2;_x:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2;_ex:1,2c;" -"esc_attr__;esc_attr_e;esc_attr_x:1,2c;esc_html__;esc_html_e;" -"esc_html_x:1,2c\n" -"X-Poedit-Basepath: .\n" -"X-Poedit-SourceCharset: UTF-8\n" -"X-Generator: Poedit 3.4.2\n" -"X-Poedit-SearchPath-0: .\n" -"X-Poedit-SearchPath-1: ..\n" - -#: Main.php:177 -msgid "Unnamed tab" -msgstr "Unbenannte Registerkarte" - -#: Main.php:267 -msgid "You do not have enough permissions to do that." -msgstr "" -"Sie verfügen nicht über die erforderlichen Berechtigungen, um dies zu tun." - -#: Main.php:292 -msgid "Settings saved." -msgstr "Die Einstellungen wurden gespeichert." - -#: templates/settings-page.php:18 -msgid "Settings issues detected." -msgstr "Einstellungsprobleme erkannt." diff --git a/vendor/rrze/wp/src/Settings/templates/options/checkbox-multiple.php b/vendor/rrze/wp/src/Settings/templates/options/checkbox-multiple.php deleted file mode 100644 index db5c522..0000000 --- a/vendor/rrze/wp/src/Settings/templates/options/checkbox-multiple.php +++ /dev/null @@ -1,27 +0,0 @@ - - - - getLabel(); ?> - - -
- getLabel(); ?> - getArg('options', []) as $key => $label) : ?> -
- - getArg('description')) : ?> -

- hasError()) : ?> -
- - -
- - \ No newline at end of file diff --git a/vendor/rrze/wp/src/Settings/templates/options/checkbox.php b/vendor/rrze/wp/src/Settings/templates/options/checkbox.php deleted file mode 100644 index c3b0bcf..0000000 --- a/vendor/rrze/wp/src/Settings/templates/options/checkbox.php +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - hasError()) { ?> -
- - - \ No newline at end of file diff --git a/vendor/rrze/wp/src/Settings/templates/options/password.php b/vendor/rrze/wp/src/Settings/templates/options/password.php deleted file mode 100644 index d8b593a..0000000 --- a/vendor/rrze/wp/src/Settings/templates/options/password.php +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - getInputClassAttribute(); ?>> - getArg('description')) { ?> -

- - hasError()) { ?> -
- - - \ No newline at end of file diff --git a/vendor/rrze/wp/src/Settings/templates/options/radio-group.php b/vendor/rrze/wp/src/Settings/templates/options/radio-group.php deleted file mode 100644 index f5fe70a..0000000 --- a/vendor/rrze/wp/src/Settings/templates/options/radio-group.php +++ /dev/null @@ -1,28 +0,0 @@ - - - - getLabel(); ?> - - -
- getLabel(); ?> - getArg('options', []) as $key => $label) { ?> -
- - getArg('description')) { ?> -

- - hasError()) { ?> -
- -
- - \ No newline at end of file diff --git a/vendor/rrze/wp/src/Settings/templates/options/select-multiple.php b/vendor/rrze/wp/src/Settings/templates/options/select-multiple.php deleted file mode 100644 index 2459562..0000000 --- a/vendor/rrze/wp/src/Settings/templates/options/select-multiple.php +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - getArg('description')) { ?> -

- - - hasError()) { ?> -
- - - \ No newline at end of file diff --git a/vendor/rrze/wp/src/Settings/templates/options/select.php b/vendor/rrze/wp/src/Settings/templates/options/select.php deleted file mode 100644 index c127b67..0000000 --- a/vendor/rrze/wp/src/Settings/templates/options/select.php +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - getArg('description')) { ?> -

- - hasError()) { ?> -
- - - \ No newline at end of file diff --git a/vendor/rrze/wp/src/Settings/templates/options/text.php b/vendor/rrze/wp/src/Settings/templates/options/text.php deleted file mode 100644 index bce1be3..0000000 --- a/vendor/rrze/wp/src/Settings/templates/options/text.php +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - getInputClassAttribute(); ?>> - getArg('description')) { ?> -

- - hasError()) { ?> -
- - - \ No newline at end of file diff --git a/vendor/rrze/wp/src/Settings/templates/options/textarea.php b/vendor/rrze/wp/src/Settings/templates/options/textarea.php deleted file mode 100644 index ffb9262..0000000 --- a/vendor/rrze/wp/src/Settings/templates/options/textarea.php +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - getArg('description')) { ?> -

- - hasError()) { ?> -
- - - \ No newline at end of file diff --git a/vendor/rrze/wp/src/Settings/templates/section-menu.php b/vendor/rrze/wp/src/Settings/templates/section-menu.php deleted file mode 100644 index ac4921b..0000000 --- a/vendor/rrze/wp/src/Settings/templates/section-menu.php +++ /dev/null @@ -1,13 +0,0 @@ - -getActiveTab()->getSectionLinks()) { ?> - - \ No newline at end of file diff --git a/vendor/rrze/wp/src/Settings/templates/section.php b/vendor/rrze/wp/src/Settings/templates/section.php deleted file mode 100644 index 999aef8..0000000 --- a/vendor/rrze/wp/src/Settings/templates/section.php +++ /dev/null @@ -1,19 +0,0 @@ - -

title; ?>

- -description) { ?> -
description; ?>
- - - - - options as $option) { ?> - render(); ?> - - -
\ No newline at end of file diff --git a/vendor/rrze/wp/src/Settings/templates/sections.php b/vendor/rrze/wp/src/Settings/templates/sections.php deleted file mode 100644 index 18c4239..0000000 --- a/vendor/rrze/wp/src/Settings/templates/sections.php +++ /dev/null @@ -1,17 +0,0 @@ - -
- - - getActiveTab()->getActiveSections() as $section) { ?> - - - - optionName, 'rrze_wp_settings_save'); ?> - - -
\ No newline at end of file diff --git a/vendor/rrze/wp/src/Settings/templates/settings-page.php b/vendor/rrze/wp/src/Settings/templates/settings-page.php deleted file mode 100644 index 0c73b62..0000000 --- a/vendor/rrze/wp/src/Settings/templates/settings-page.php +++ /dev/null @@ -1,25 +0,0 @@ - -
-

title; ?>

- - flash->has()) { ?> -
-

-
- - - errors->getAll()) { ?> -
-

-
- - - renderTabMenu(); ?> - - renderActiveSections(); ?> -
\ No newline at end of file diff --git a/vendor/rrze/wp/src/Settings/templates/tab-menu.php b/vendor/rrze/wp/src/Settings/templates/tab-menu.php deleted file mode 100644 index 4c343fc..0000000 --- a/vendor/rrze/wp/src/Settings/templates/tab-menu.php +++ /dev/null @@ -1,11 +0,0 @@ - - \ No newline at end of file From 26bc4261529482d63399832964fad91c11c17109 Mon Sep 17 00:00:00 2001 From: Rolf Date: Thu, 12 Dec 2024 10:38:38 +0100 Subject: [PATCH 7/8] Update lang files --- languages/rrze-calendar-de_DE.mo | Bin 11412 -> 11405 bytes languages/rrze-calendar-de_DE.po | 164 +++++++++++------------- languages/rrze-calendar-de_DE_formal.mo | Bin 11422 -> 11415 bytes languages/rrze-calendar-de_DE_formal.po | 162 +++++++++++------------ languages/rrze-calendar.pot | 156 +++++++++++----------- 5 files changed, 219 insertions(+), 263 deletions(-) diff --git a/languages/rrze-calendar-de_DE.mo b/languages/rrze-calendar-de_DE.mo index dab5e27912cc2fdb176dff33e43970bcbda8340a..4678d3ce9762e229cc3c57979a45b27627714ebf 100644 GIT binary patch delta 4067 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 hE%fQpv`;7A`LkR?PJwnEc=EeX3 delta 4041 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\n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"POT-Creation-Date: 2024-02-19T11:20:32+00:00\n" +"POT-Creation-Date: 2024-12-12T08:43:05+00:00\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"X-Generator: WP-CLI 2.9.0\n" +"X-Generator: WP-CLI 2.11.0\n" "X-Domain: rrze-calendar\n" #. Plugin Name of the plugin +#: rrze-calendar.php msgid "RRZE Calendar" msgstr "" #. Plugin URI of the plugin +#: rrze-calendar.php msgid "https://github.com/RRZE-Webteam/rrze-calendar" msgstr "" #. Description of the plugin -msgid "Import and output of FAU public events." +#: rrze-calendar.php +msgid "Administration of local events and import of public events." msgstr "" #. Author of the plugin +#: rrze-calendar.php msgid "RRZE Webteam" msgstr "" #. Author URI of the plugin +#: rrze-calendar.php msgid "https://blogs.fau.de/webworking/" msgstr "" @@ -89,7 +94,7 @@ msgid "Parent Events:" msgstr "" #: includes/CPT/CalendarEvent.php:66 -#: includes/ICS/Events.php:48 +#: includes/ICS/Events.php:50 msgid "No events found." msgstr "" @@ -300,16 +305,14 @@ msgid "Maximum +/- 1 year." msgstr "" #: includes/CPT/CalendarEvent.php:572 -#: includes/Shortcodes/Events.php:197 -#: includes/Shortcodes/Events.php:203 +#: includes/Shortcodes/Events.php:201 +#: includes/Shortcodes/Events.php:207 msgid "Online" msgstr "" #: includes/CPT/CalendarEvent.php:610 #: includes/Shortcodes/Calendar.php:326 -#: includes/Shortcodes/Calendar.php:549 -#: includes/Shortcodes/Shortcode.php:69 -#: includes/Shortcodes/Shortcode.php:176 +#: includes/Shortcodes/Calendar.php:553 msgid "All Day" msgstr "" @@ -324,9 +327,9 @@ msgid "Time" msgstr "" #: includes/CPT/CalendarEvent.php:695 -#: includes/Shortcodes/Calendar.php:350 -#: includes/Shortcodes/Calendar.php:692 -#: includes/Shortcodes/Events.php:297 +#: includes/Shortcodes/Calendar.php:351 +#: includes/Shortcodes/Calendar.php:704 +#: includes/Shortcodes/Events.php:300 msgid "Add to calendar" msgstr "" @@ -431,7 +434,7 @@ msgstr "" #: includes/CPT/CalendarFeed.php:122 #: includes/ICS/EventsListTable.php:16 #: includes/ICS/Metabox.php:34 -#: includes/Settings.php:25 +#: includes/Settings.php:30 #: templates/cpt/archive-event.php:30 #: templates/cpt/archive-event.php:32 #: templates/cpt/themes/fau-events/archive-event.php:22 @@ -495,8 +498,8 @@ msgstr "" msgid "Invalid access" msgstr "" -#: includes/ICS/Events.php:327 -#: includes/Utils.php:828 +#: includes/ICS/Events.php:332 +#: includes/Utils.php:836 msgid "m-d-Y" msgstr "" @@ -541,74 +544,90 @@ msgstr "" msgid "Feed URL is not valid." msgstr "" -#: includes/Main.php:46 +#: includes/Main.php:45 msgid "Settings" msgstr "" -#: includes/Main.php:95 +#: includes/Main.php:94 msgid "Hide past events" msgstr "" -#: includes/Main.php:96 +#: includes/Main.php:95 msgid "Show past events" msgstr "" -#: includes/Settings.php:17 +#: includes/Settings.php:22 msgid "Calendar Settings" msgstr "" -#: includes/Settings.php:21 +#: includes/Settings.php:26 msgid "Calendar" msgstr "" -#: includes/Settings.php:26 +#: includes/Settings.php:31 msgid "ICS Feed" msgstr "" -#: includes/Settings.php:30 +#: includes/Settings.php:35 msgid "Archive Slug" msgstr "" -#: includes/Settings.php:31 +#: includes/Settings.php:36 msgid "Enter the archive slug that will display the event list." msgstr "" -#: includes/Settings.php:32 +#: includes/Settings.php:37 msgid "events" msgstr "" -#: includes/Settings.php:36 +#: includes/Settings.php:41 msgid "The archive slug can have between 4 and 32 alphanumeric characters." msgstr "" -#: includes/Settings.php:43 +#: includes/Settings.php:48 msgid "Remove Duplicates" msgstr "" -#: includes/Settings.php:44 +#: includes/Settings.php:49 msgid "If the same event (i.e. same title, date and location) is present in multiple feeds, only show one of them." msgstr "" -#: includes/Settings.php:49 +#: includes/Settings.php:54 msgid "Schedule" msgstr "" -#: includes/Settings.php:50 +#: includes/Settings.php:55 msgid "Choose the recurrence to check for new events." msgstr "" -#: includes/Settings.php:52 +#: includes/Settings.php:57 msgid "Hourly" msgstr "" -#: includes/Settings.php:53 +#: includes/Settings.php:58 msgid "Twice daily" msgstr "" -#: includes/Settings.php:54 +#: includes/Settings.php:59 msgid "Daily" msgstr "" +#: includes/Settings/Settings.php:177 +msgid "Unnamed tab" +msgstr "" + +#: includes/Settings/Settings.php:267 +msgid "You do not have enough permissions to do that." +msgstr "" + +#: includes/Settings/Settings.php:292 +msgid "Settings saved." +msgstr "" + +#: includes/Settings/templates/settings-page.php:18 +msgid "Settings issues detected." +msgstr "" + #: includes/Shortcodes/Calendar.php:213 msgid "View day" msgstr "" @@ -639,7 +658,7 @@ msgstr "" #: includes/Shortcodes/Calendar.php:265 #: includes/Shortcodes/Calendar.php:295 -#: includes/Shortcodes/Calendar.php:458 +#: includes/Shortcodes/Calendar.php:459 msgid "Previous" msgstr "" @@ -649,7 +668,7 @@ msgstr "" #: includes/Shortcodes/Calendar.php:268 #: includes/Shortcodes/Calendar.php:298 -#: includes/Shortcodes/Calendar.php:461 +#: includes/Shortcodes/Calendar.php:462 msgid "Next" msgstr "" @@ -661,28 +680,28 @@ msgstr "" msgid "Go to next day" msgstr "" -#: includes/Shortcodes/Calendar.php:353 +#: includes/Shortcodes/Calendar.php:354 msgid "There are no events scheduled for this day." msgstr "" -#: includes/Shortcodes/Calendar.php:410 +#: includes/Shortcodes/Calendar.php:411 msgid "View Details" msgstr "" -#: includes/Shortcodes/Calendar.php:458 +#: includes/Shortcodes/Calendar.php:459 msgid "Go to previous month" msgstr "" -#: includes/Shortcodes/Calendar.php:461 +#: includes/Shortcodes/Calendar.php:462 msgid "Go to next month" msgstr "" -#: includes/Shortcodes/Calendar.php:580 +#: includes/Shortcodes/Calendar.php:589 msgid "More…" msgstr "" -#: includes/Shortcodes/Calendar.php:607 -#: includes/Shortcodes/Calendar.php:664 +#: includes/Shortcodes/Calendar.php:616 +#: includes/Shortcodes/Calendar.php:676 msgid "Read more" msgstr "" @@ -690,61 +709,30 @@ msgstr "" msgid "Show All Events" msgstr "" -#: includes/Shortcodes/Events.php:290 -#: includes/Shortcodes/Events.php:328 +#: includes/Shortcodes/Events.php:293 +#: includes/Shortcodes/Events.php:331 msgid "No events scheduled." msgstr "" -#: includes/Shortcodes/Events.php:307 +#: includes/Shortcodes/Events.php:310 msgid "Add all events of this category to your calendar" msgstr "" -#: includes/Shortcodes/Events.php:314 +#: includes/Shortcodes/Events.php:317 msgid "Add all events of this tag to your calendar" msgstr "" -#: includes/Shortcodes/Shortcode.php:51 -msgid "No description" -msgstr "" - -#. translators: 1: Start date, 2: End date. -#: includes/Shortcodes/Shortcode.php:76 -#: includes/Shortcodes/Shortcode.php:181 -msgid "%1$s - %2$s" -msgstr "" - -#. translators: 1: Start date, 2: Start time, 3: End date, 4: End time. -#: includes/Shortcodes/Shortcode.php:85 -#: includes/Shortcodes/Shortcode.php:185 -msgid "%1$s %2$s - %3$s %4$s" -msgstr "" - -#. translators: 1: Start date, 2: Start time, 3: End time. -#: includes/Shortcodes/Shortcode.php:96 -#: includes/Shortcodes/Shortcode.php:189 -msgid "%1$s %2$s - %3$s" -msgstr "" - -#: includes/Shortcodes/Shortcode.php:120 -msgid "View the calendar" -msgstr "" - -#: includes/Shortcodes/Shortcode.php:125 -msgid "Subscribe to calendar" +#. translators: 1: Server WordPress version number, 2: Required WordPress version number. +#: rrze-calendar.php:110 +msgid "The server is running WordPress version %1$s. The plugin requires at least WordPress version %2$s." msgstr "" #. translators: 1: Server PHP version number, 2: Required PHP version number. -#: rrze-calendar.php:60 -msgid "The server is running PHP version %1$s. The Plugin requires at least PHP version %2$s." -msgstr "" - -#. translators: 1: Server WordPress version number, 2: Required WordPress version number. -#: rrze-calendar.php:67 -msgid "The server is running WordPress version %1$s. The Plugin requires at least WordPress version %2$s." +#: rrze-calendar.php:118 +msgid "The server is running PHP version %1$s. The plugin requires at least PHP version %2$s." msgstr "" #. translators: 1: The plugin name, 2: The error string. -#: rrze-calendar.php:86 -#: rrze-calendar.php:157 +#: rrze-calendar.php:162 msgid "Plugins: %1$s: %2$s" msgstr "" From e294be82dbb7c7facf59114ffcf9b094376d804b Mon Sep 17 00:00:00 2001 From: Rolf Date: Thu, 12 Dec 2024 10:38:44 +0100 Subject: [PATCH 8/8] Update rrze-calendar.php --- rrze-calendar.php | 184 +++++++++++++++++++++++----------------------- 1 file changed, 93 insertions(+), 91 deletions(-) diff --git a/rrze-calendar.php b/rrze-calendar.php index bf2ff92..5694b8c 100644 --- a/rrze-calendar.php +++ b/rrze-calendar.php @@ -1,111 +1,57 @@ load_plugin_textdomain('rrze-calendar', false, dirname(plugin_basename(__FILE__)) . '/languages')); -add_action('plugins_loaded', __NAMESPACE__ . '\loaded'); -add_action('init', __NAMESPACE__ . '\init'); +// Register activation hook for the plugin +register_activation_hook(__FILE__, __NAMESPACE__ . '\activation'); -/** - * loadTextdomain - */ -function loadTextdomain() -{ - load_plugin_textdomain( - 'rrze-calendar', - false, - sprintf('%s/languages/', dirname(plugin_basename(__FILE__))) - ); -} +// Register deactivation hook for the plugin +register_deactivation_hook(__FILE__, __NAMESPACE__ . '\deactivation'); /** - * System requirements verification. - * @return string Return an error message. + * Add an action hook for the 'plugins_loaded' hook. + * + * This code hooks into the 'plugins_loaded' action hook to execute a callback function when + * WordPress has fully loaded all active plugins and the theme's functions.php file. */ -function systemRequirements(): string -{ - global $wp_version; - // Strip off any -alpha, -RC, -beta, -src suffixes. - list($wpVersion) = explode('-', $wp_version); - $phpVersion = phpversion(); - $error = ''; - if (!is_php_version_compatible(RRZE_PHP_VERSION)) { - $error = sprintf( - /* translators: 1: Server PHP version number, 2: Required PHP version number. */ - __('The server is running PHP version %1$s. The Plugin requires at least PHP version %2$s.', 'rrze-calendar'), - $phpVersion, - RRZE_PHP_VERSION - ); - } elseif (!is_wp_version_compatible(RRZE_WP_VERSION)) { - $error = sprintf( - /* translators: 1: Server WordPress version number, 2: Required WordPress version number. */ - __('The server is running WordPress version %1$s. The Plugin requires at least WordPress version %2$s.', 'rrze-calendar'), - $wpVersion, - RRZE_WP_VERSION - ); - } - return $error; -} +add_action('plugins_loaded', __NAMESPACE__ . '\loaded'); /** * Activation callback function. */ function activation() { - if ($error = systemRequirements()) { - deactivate_plugins(plugin_basename(__FILE__)); - wp_die( - sprintf( - /* translators: 1: The plugin name, 2: The error string. */ - __('Plugins: %1$s: %2$s', 'rrze-calendar'), - plugin_basename(__FILE__), - $error - ) - ); - } - - add_action( - 'init', - function () { - loadTextdomain(); - CalendarEvent::registerPostType(); - CalendarFeed::registerPostType(); - flush_rewrite_rules(false); - } - ); - - flush_rewrite_rules(false); -} - -function init() { - loadTextdomain(); + settings()->loaded(); + // Register the 'CalendarEvent' and 'CalendarFeed' custom post types and flush rewrite rules. + CalendarEvent::registerPostType(); + CalendarFeed::registerPostType(); + flush_rewrite_rules(); } /** @@ -113,7 +59,7 @@ function init() { */ function deactivation() { - flush_rewrite_rules(false); + flush_rewrite_rules(); } /** @@ -143,31 +89,87 @@ function settings() } /** - * Execute on 'plugins_loaded' API/action. - * @return void + * Check system requirements for the plugin. + * + * This method checks if the server environment meets the minimum WordPress and PHP version requirements + * for the plugin to function properly. + * + * @return string An error message string if requirements are not met, or an empty string if requirements are satisfied. + */ +function systemRequirements(): string +{ + // Get the global WordPress version. + global $wp_version; + + // Get the PHP version. + $phpVersion = phpversion(); + + // Initialize an error message string. + $error = ''; + + // Check if the WordPress version is compatible with the plugin's requirement. + if (!is_wp_version_compatible(plugin()->getRequiresWP())) { + $error = sprintf( + /* translators: 1: Server WordPress version number, 2: Required WordPress version number. */ + __('The server is running WordPress version %1$s. The plugin requires at least WordPress version %2$s.', 'rrze-calendar'), + $wp_version, + plugin()->getRequiresWP() + ); + } elseif (!is_php_version_compatible(plugin()->getRequiresPHP())) { + // Check if the PHP version is compatible with the plugin's requirement. + $error = sprintf( + /* translators: 1: Server PHP version number, 2: Required PHP version number. */ + __('The server is running PHP version %1$s. The plugin requires at least PHP version %2$s.', 'rrze-calendar'), + $phpVersion, + plugin()->getRequiresPHP() + ); + } + + // Return the error message string, which will be empty if requirements are satisfied. + return $error; +} + +/** + * Handle the loading of the plugin. + * + * This function is responsible for initializing the plugin, loading text domains for localization, + * checking system requirements, and displaying error notices if necessary. */ function loaded() { + // Trigger the 'loaded' method of the main plugin instance. plugin()->loaded(); + + // Check system requirements and store any error messages. if ($error = systemRequirements()) { + // If there is an error, add an action to display an admin notice with the error message. add_action('admin_init', function () use ($error) { + // Check if the current user has the capability to activate plugins. if (current_user_can('activate_plugins')) { - $pluginData = get_plugin_data(plugin()->getFile()); - $pluginName = $pluginData['Name']; + // Get plugin data to retrieve the plugin's name. + $pluginName = plugin()->getName(); + + // Determine the admin notice tag based on network-wide activation. $tag = is_plugin_active_for_network(plugin()->getBaseName()) ? 'network_admin_notices' : 'admin_notices'; + + // Add an action to display the admin notice. add_action($tag, function () use ($pluginName, $error) { printf( '

' . /* translators: 1: The plugin name, 2: The error string. */ - __('Plugins: %1$s: %2$s', 'rrze-calendar') . + esc_html__('Plugins: %1$s: %2$s', 'rrze-calendar') . '

', - esc_html($pluginName), - esc_html($error) + $pluginName, + $error ); }); } }); + + // Return to prevent further initialization if there is an error. return; } - new Main; + + // If there are no errors, create an instance of the 'Main' class and trigger its 'loaded' method. + (new Main)->loaded(); }