diff --git a/src/admin/layout/class-engine.php b/src/admin/layout/class-engine.php
index a4e20cb..5aa289b 100644
--- a/src/admin/layout/class-engine.php
+++ b/src/admin/layout/class-engine.php
@@ -99,18 +99,21 @@ abstract class Engine {
*
* @since 1.5.0
*/
- public function register_sections(): void {
- foreach ( $this->get_sections() as $section ) {
+ public function add_settings_sections(): void {
+ $this->sections[Includes\Settings::instance()->general_settings->get_section_slug()] = Includes\Settings::instance()->general_settings;
+
+ /*foreach ( $this->get_sections() as $section ) {
// Append tab to the tab-array.
$this->sections[ $section['id'] ] = $section;
add_settings_section(
$section['id'],
'',
fn() => $this->description(),
- $section['id']
+ 'footnotes'
);
- $this->register_meta_boxes( $section['id'] );
- }
+ $this->add_settings_fields();
+ //$this->register_meta_boxes( $section['id'] );
+ }*/
}
// phpcs:disable WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
/**
@@ -120,7 +123,68 @@ abstract class Engine {
* @todo Review nonce verification.
*/
public function display_content(): void {
- $this->append_scripts();
+ // check user capabilities
+ if ( ! current_user_can( 'manage_options' ) ) {
+ return;
+ }
+
+ $active_section_id = isset( $_GET['t'] ) ? wp_unslash( $_GET['t'] ) : array_key_first( $this->sections );
+ $active_section = $this->sections[ $active_section_id ];
+
+ ?>
+
+ append_scripts();
$active_section_id = isset( $_GET['t'] ) ? wp_unslash( $_GET['t'] ) : array_key_first( $this->sections );
$active_section = $this->sections[ $active_section_id ];
@@ -163,16 +227,7 @@ abstract class Engine {
submit_button();
}
echo '';
- echo '';
-
- // Echo JavaScript for the expand/collapse function of the meta boxes.
- echo '';
+ echo '';*/
}
// phpcs:enable WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
/**
@@ -182,7 +237,7 @@ abstract class Engine {
* @todo Required? Should be `abstract`?
*/
public function description(): void {
- // Default no description will be displayed.
+ // Nothing yet.
}
/**
@@ -224,6 +279,9 @@ abstract class Engine {
* @since 1.5.0
*/
abstract protected function get_meta_boxes(): array;
+
+
+ abstract protected function add_settings_fields(): void;
/**
* Returns an array describing a sub-page section.
@@ -368,21 +426,32 @@ abstract class Engine {
*/
protected function add_text_box( string $setting_name, int $max_length = 999, bool $readonly = false, bool $hidden = false ): string {
$style = '';
- // Collect data for given settings field.
- $data = $this->load_setting( $setting_name );
if ( $hidden ) {
$style .= 'display:none;';
}
return sprintf(
'',
- $data['name'],
- $data['id'],
+ $setting_name,
+ $setting_name,
$max_length,
$style,
- $data['value'],
+ get_option($setting_name),
$readonly ? 'readonly="readonly"' : ''
);
}
+ public function new_add_text_box( array $args ): void {
+ extract( $args );
+
+ echo ( sprintf(
+ '',
+ $name,
+ $name,
+ $max_length ?? 999,
+ $style ?? '',
+ $value,
+ isset($readonly) ? 'readonly="readonly"' : ''
+ ) );
+ }
/**
* Constructs the HTML for a checkbox 'input' element.
@@ -438,7 +507,32 @@ abstract class Engine {
$select_options
);
}
+ public function new_add_select_box( array $args ): void {
+ $select_options = '';
+ $setting_value = ( !isset( $options[$args['name']] ) )
+ ? null : $options[$args['name']];
+ // Loop through all array keys.
+ foreach ( $args['options'] as $option_value => $caption ) {
+ $select_options .= sprintf(
+ '',
+ $option_value,
+ // Only check for equality, not identity, WRT backlink symbol arrows.
+ // phpcs:disable WordPress.PHP.StrictComparisons.LooseComparison
+ $option_value == $setting_value ? 'selected' : '',
+ // phpcs:enable WordPress.PHP.StrictComparisons.LooseComparison
+ $caption
+ );
+ }
+
+ echo ( sprintf(
+ '',
+ $args['name'],
+ $args['name'],
+ $select_options
+ ) );
+ }
+
/**
* Constructs the HTML for a 'textarea' element.
*
diff --git a/src/admin/layout/class-init.php b/src/admin/layout/class-init.php
index 6a54e9e..08a0dee 100644
--- a/src/admin/layout/class-init.php
+++ b/src/admin/layout/class-init.php
@@ -93,7 +93,10 @@ class Init {
*/
public function initialize_settings(): void {
Includes\Settings::instance()->register_settings();
- $this->settings->register_sections();
+
+ Includes\Settings::instance()->general_settings->add_settings_section();
+ $this->settings->add_settings_sections();
+ $this->settings->add_settings_fields();
}
/**
@@ -103,8 +106,7 @@ class Init {
* @see http://codex.wordpress.org/Function_Reference/add_menu_page
*/
public function register_options_submenu(): void {
- add_submenu_page(
- 'options-general.php',
+ add_options_page(
'footnotes Settings',
\footnotes\includes\Config::PLUGIN_PUBLIC_NAME,
'manage_options',
diff --git a/src/admin/layout/class-settings.php b/src/admin/layout/class-settings.php
index 61905a1..8b04d95 100644
--- a/src/admin/layout/class-settings.php
+++ b/src/admin/layout/class-settings.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
namespace footnotes\admin\layout;
+require_once plugin_dir_path( dirname( __FILE__, 2 ) ) . 'includes/class-settings.php';
+
use footnotes\includes as Includes;
use footnotes\general as General;
@@ -56,6 +58,165 @@ class Settings extends Engine {
public function get_priority(): int {
return 10;
}
+
+ public function add_settings_fields(): void {
+ $active_section_id = isset( $_GET['t'] ) ? wp_unslash( $_GET['t'] ) : array_key_first( $this->sections );
+ $active_section = $this->sections[ $active_section_id ];
+
+ switch ($active_section->get_section_slug()) {
+ case 'footnotes-settings':
+ $this->add_general_settings_fields();
+ break;
+ case 'footnotes-customize':
+ $this->add_customize_settings_fields();
+ break;
+ case 'footnotes-expert':
+ $this->add_expert_settings_fields();
+ break;
+ case 'footnotes-customcss':
+ $this->add_customcss_settings_fields();
+ break;
+ case 'footnotes-how-to':
+ print_r("Demo goes here");
+ break;
+ default: print_r("ERR: section not found");
+ }
+ }
+
+ public function add_general_settings_fields(): void {
+ // Options for the label element.
+ $label_element_options = array(
+ 'p' => __( 'paragraph', 'footnotes' ),
+ 'h2' => __( 'heading 2', 'footnotes' ),
+ 'h3' => __( 'heading 3', 'footnotes' ),
+ 'h4' => __( 'heading 4', 'footnotes' ),
+ 'h5' => __( 'heading 5', 'footnotes' ),
+ 'h6' => __( 'heading 6', 'footnotes' ),
+ );
+ // Options for the positioning of the reference container.
+ $positions_options = array(
+ 'post_end' => __( 'at the end of the post', 'footnotes' ),
+ 'widget' => __( 'in the widget area', 'footnotes' ),
+ 'footer' => __( 'in the footer', 'footnotes' ),
+ );
+ // Basic responsive page layout options.
+ $page_layout_options = array(
+ 'none' => __( 'No', 'footnotes' ),
+ 'reference-container' => __( 'to the reference container exclusively', 'footnotes' ),
+ 'entry-content' => __( 'to the div element starting below the post title', 'footnotes' ),
+ 'main-content' => __( 'to the main element including the post title', 'footnotes' ),
+ );
+
+ // Options for the separating punctuation between backlinks.
+ $separators_options = array(
+ // Unicode character names are conventionally uppercase.
+ 'comma' => __( 'COMMA', 'footnotes' ),
+ 'semicolon' => __( 'SEMICOLON', 'footnotes' ),
+ 'en_dash' => __( 'EN DASH', 'footnotes' ),
+ );
+
+ /*
+ * Options for the terminating punctuation after backlinks.
+ * The Unicode name of RIGHT PARENTHESIS was originally more accurate because.
+ * This character is bidi-mirrored. Let's use the Unicode 1.0 name.
+ * The wrong names were enforced in spite of Unicode, that subsequently scrambled to correct.
+ */
+ $terminators_options = array(
+ 'period' => __( 'FULL STOP', 'footnotes' ),
+ // Unicode 1.0 name of RIGHT PARENTHESIS (represented as a left parenthesis in right-to-left scripts).
+ 'parenthesis' => __( 'CLOSING PARENTHESIS', 'footnotes' ),
+ 'colon' => __( 'COLON', 'footnotes' ),
+ );
+ // Options for the first column width (per cent is a ratio, not a unit).
+ $width_units_options = array(
+ '%' => __( 'per cent', 'footnotes' ),
+ 'px' => __( 'pixels', 'footnotes' ),
+ 'rem' => __( 'root em', 'footnotes' ),
+ 'em' => __( 'em', 'footnotes' ),
+ 'vw' => __( 'viewport width', 'footnotes' ),
+ );
+ // Options for reference container script mode.
+ $script_mode_options = array(
+ 'jquery' => __( 'jQuery', 'footnotes' ),
+ 'js' => __( 'plain JavaScript', 'footnotes' ),
+ );
+ // Options for Yes/No select box.
+ $enabled_options = array(
+ 'yes' => __( 'Yes', 'footnotes' ),
+ 'no' => __( 'No', 'footnotes' ),
+ );
+
+ Includes\Settings::instance()->general_settings->add_settings_fields($this);
+
+ /*
+ add_settings_field(
+ \footnotes\includes\Settings::REFERENCE_CONTAINER_LABEL_ELEMENT,
+ __( 'Heading\'s HTML element', 'footnotes' ),
+ array ($this, 'new_add_select_box'),
+ 'footnotes',
+ 'footnotes-settings',
+ array(
+ 'name' => \footnotes\includes\Settings::REFERENCE_CONTAINER_LABEL_ELEMENT,
+ 'label_for' => \footnotes\includes\Settings::REFERENCE_CONTAINER_LABEL_ELEMENT,
+ 'value' => get_option(\footnotes\includes\Settings::REFERENCE_CONTAINER_LABEL_ELEMENT),
+ 'options' => $label_element_options
+ )
+ );
+
+ add_settings_field(
+ \footnotes\includes\Settings::REFERENCE_CONTAINER_LABEL_BOTTOM_BORDER,
+ __( 'Border under the heading', 'footnotes' ),
+ array ($this, 'new_add_select_box'),
+ 'footnotes',
+ 'footnotes-settings',
+ array(
+ 'name' => \footnotes\includes\Settings::REFERENCE_CONTAINER_LABEL_BOTTOM_BORDER,
+ 'label_for' => \footnotes\includes\Settings::REFERENCE_CONTAINER_LABEL_BOTTOM_BORDER,
+ 'value' => get_option(\footnotes\includes\Settings::REFERENCE_CONTAINER_LABEL_BOTTOM_BORDER),
+ 'options' => $enabled_options
+ )
+ );
+
+ add_settings_field(
+ \footnotes\includes\Settings::REFERENCE_CONTAINER_COLLAPSE,
+ __( 'Collapse by default', 'footnotes' ),
+ array ($this, 'new_add_select_box'),
+ 'footnotes',
+ 'footnotes-settings',
+ array(
+ 'name' => \footnotes\includes\Settings::REFERENCE_CONTAINER_COLLAPSE,
+ 'label_for' => \footnotes\includes\Settings::REFERENCE_CONTAINER_COLLAPSE,
+ 'value' => get_option(\footnotes\includes\Settings::REFERENCE_CONTAINER_COLLAPSE),
+ 'options' => $enabled_options
+ )
+ );
+
+ add_settings_field(
+ \footnotes\includes\Settings::FOOTNOTES_REFERENCE_CONTAINER_SCRIPT_MODE,
+ __( 'Script mode', 'footnotes' ),
+ array ($this, 'new_add_select_box'),
+ 'footnotes',
+ 'footnotes-settings',
+ array(
+ 'name' => \footnotes\includes\Settings::FOOTNOTES_REFERENCE_CONTAINER_SCRIPT_MODE,
+ 'label_for' => \footnotes\includes\Settings::FOOTNOTES_REFERENCE_CONTAINER_SCRIPT_MODE,
+ 'value' => get_option(\footnotes\includes\Settings::FOOTNOTES_REFERENCE_CONTAINER_SCRIPT_MODE),
+ 'options' => $script_mode_options,
+ 'description' => __( 'The plain JavaScript mode will enable hard links with configurable scroll offset', 'footnotes')
+ )
+ );*/
+ }
+
+ public function setting_field_callback( array $args ): void {
+ if (isset($args['type'])) {
+ switch($args['type']) {
+ case 'text':
+ $this->new_add_text_box($args);
+ return;
+ default: return;
+ }
+ } else return;
+ }
/**
* Displays the AMP compatibility mode option.
@@ -90,91 +251,17 @@ class Settings extends Engine {
* @since 1.5.0
*/
public function reference_container(): void {
-
- // Options for the label element.
- $label_element = array(
- 'p' => __( 'paragraph', 'footnotes' ),
- 'h2' => __( 'heading 2', 'footnotes' ),
- 'h3' => __( 'heading 3', 'footnotes' ),
- 'h4' => __( 'heading 4', 'footnotes' ),
- 'h5' => __( 'heading 5', 'footnotes' ),
- 'h6' => __( 'heading 6', 'footnotes' ),
- );
- // Options for the positioning of the reference container.
- $positions = array(
- 'post_end' => __( 'at the end of the post', 'footnotes' ),
- 'widget' => __( 'in the widget area', 'footnotes' ),
- 'footer' => __( 'in the footer', 'footnotes' ),
- );
- // Basic responsive page layout options.
- $page_layout_options = array(
- 'none' => __( 'No', 'footnotes' ),
- 'reference-container' => __( 'to the reference container exclusively', 'footnotes' ),
- 'entry-content' => __( 'to the div element starting below the post title', 'footnotes' ),
- 'main-content' => __( 'to the main element including the post title', 'footnotes' ),
- );
- // Options for the separating punctuation between backlinks.
- $separators = array(
- // Unicode character names are conventionally uppercase.
- 'comma' => __( 'COMMA', 'footnotes' ),
- 'semicolon' => __( 'SEMICOLON', 'footnotes' ),
- 'en_dash' => __( 'EN DASH', 'footnotes' ),
- );
-
- /*
- * Options for the terminating punctuation after backlinks.
- * The Unicode name of RIGHT PARENTHESIS was originally more accurate because.
- * This character is bidi-mirrored. Let's use the Unicode 1.0 name.
- * The wrong names were enforced in spite of Unicode, that subsequently scrambled to correct.
- */
- $terminators = array(
- 'period' => __( 'FULL STOP', 'footnotes' ),
- // Unicode 1.0 name of RIGHT PARENTHESIS (represented as a left parenthesis in right-to-left scripts).
- 'parenthesis' => __( 'CLOSING PARENTHESIS', 'footnotes' ),
- 'colon' => __( 'COLON', 'footnotes' ),
- );
- // Options for the first column width (per cent is a ratio, not a unit).
- $width_units = array(
- '%' => __( 'per cent', 'footnotes' ),
- 'px' => __( 'pixels', 'footnotes' ),
- 'rem' => __( 'root em', 'footnotes' ),
- 'em' => __( 'em', 'footnotes' ),
- 'vw' => __( 'viewport width', 'footnotes' ),
- );
- // Options for reference container script mode.
- $script_mode = array(
- 'jquery' => __( 'jQuery', 'footnotes' ),
- 'js' => __( 'plain JavaScript', 'footnotes' ),
- );
- // Options for Yes/No select box.
- $enabled = array(
- 'yes' => __( 'Yes', 'footnotes' ),
- 'no' => __( 'No', 'footnotes' ),
- );
-
+
+
+
+
// Load template file.
$template = new Includes\Template( \footnotes\includes\Template::DASHBOARD, 'settings-reference-container' );
// Replace all placeholders.
$template->replace(
array(
- 'label-name' => $this->add_label( \footnotes\includes\Settings::REFERENCE_CONTAINER_NAME, __( 'Heading:', 'footnotes' ) ),
- 'name' => $this->add_text_box( \footnotes\includes\Settings::REFERENCE_CONTAINER_NAME ),
-
- 'label-element' => $this->add_label( \footnotes\includes\Settings::REFERENCE_CONTAINER_LABEL_ELEMENT, __( 'Heading\'s HTML element:', 'footnotes' ) ),
- 'element' => $this->add_select_box( \footnotes\includes\Settings::REFERENCE_CONTAINER_LABEL_ELEMENT, $label_element ),
-
- 'label-border' => $this->add_label( \footnotes\includes\Settings::REFERENCE_CONTAINER_LABEL_BOTTOM_BORDER, __( 'Border under the heading:', 'footnotes' ) ),
- 'border' => $this->add_select_box( \footnotes\includes\Settings::REFERENCE_CONTAINER_LABEL_BOTTOM_BORDER, $enabled ),
-
- 'label-collapse' => $this->add_label( \footnotes\includes\Settings::REFERENCE_CONTAINER_COLLAPSE, __( 'Collapse by default:', 'footnotes' ) ),
- 'collapse' => $this->add_select_box( \footnotes\includes\Settings::REFERENCE_CONTAINER_COLLAPSE, $enabled ),
-
- 'label-script' => $this->add_label( \footnotes\includes\Settings::FOOTNOTES_REFERENCE_CONTAINER_SCRIPT_MODE, __( 'Script mode:', 'footnotes' ) ),
- 'script' => $this->add_select_box( \footnotes\includes\Settings::FOOTNOTES_REFERENCE_CONTAINER_SCRIPT_MODE, $script_mode ),
- 'notice-script' => __( 'The plain JavaScript mode will enable hard links with configurable scroll offset.', 'footnotes' ),
-
'label-position' => $this->add_label( \footnotes\includes\Settings::REFERENCE_CONTAINER_POSITION, __( 'Default position:', 'footnotes' ) ),
- 'position' => $this->add_select_box( \footnotes\includes\Settings::REFERENCE_CONTAINER_POSITION, $positions ),
+ 'position' => $this->add_select_box( \footnotes\includes\Settings::REFERENCE_CONTAINER_POSITION, $positions_options ),
// Translators: %s: at the end of the post.
'notice-position' => sprintf( __( 'To use the position or section shortcode, please set the position to: %s', 'footnotes' ), '' . __( 'at the end of the post', 'footnotes' ) . '' ),
@@ -187,7 +274,7 @@ class Settings extends Engine {
'notice-section' => __( 'If present in the content, any shortcode in this text box will delimit a section terminated by a reference container.', 'footnotes' ),
'label-startpage' => $this->add_label( \footnotes\includes\Settings::REFERENCE_CONTAINER_START_PAGE_ENABLE, __( 'Display on start page too:', 'footnotes' ) ),
- 'startpage' => $this->add_select_box( \footnotes\includes\Settings::REFERENCE_CONTAINER_START_PAGE_ENABLE, $enabled ),
+ 'startpage' => $this->add_select_box( \footnotes\includes\Settings::REFERENCE_CONTAINER_START_PAGE_ENABLE, $enabled_options ),
'label-margin-top' => $this->add_label( \footnotes\includes\Settings::REFERENCE_CONTAINER_TOP_MARGIN, __( 'Top margin:', 'footnotes' ) ),
'margin-top' => $this->add_num_box( \footnotes\includes\Settings::REFERENCE_CONTAINER_TOP_MARGIN, -500, 500 ),
@@ -202,53 +289,53 @@ class Settings extends Engine {
'notice-page-layout' => __( 'Most themes don\'t need this fix.', 'footnotes' ),
'label-url-wrap' => $this->add_label( \footnotes\includes\Settings::FOOTNOTE_URL_WRAP_ENABLED, __( 'Allow URLs to line-wrap anywhere:', 'footnotes' ) ),
- 'url-wrap' => $this->add_select_box( \footnotes\includes\Settings::FOOTNOTE_URL_WRAP_ENABLED, $enabled ),
+ 'url-wrap' => $this->add_select_box( \footnotes\includes\Settings::FOOTNOTE_URL_WRAP_ENABLED, $enabled_options ),
'notice-url-wrap' => __( 'Unicode-conformant browsers don\'t need this fix.', 'footnotes' ),
'label-symbol' => $this->add_label( \footnotes\includes\Settings::REFERENCE_CONTAINER_BACKLINK_SYMBOL_ENABLE, __( 'Display a backlink symbol:', 'footnotes' ) ),
- 'symbol-enable' => $this->add_select_box( \footnotes\includes\Settings::REFERENCE_CONTAINER_BACKLINK_SYMBOL_ENABLE, $enabled ),
+ 'symbol-enable' => $this->add_select_box( \footnotes\includes\Settings::REFERENCE_CONTAINER_BACKLINK_SYMBOL_ENABLE, $enabled_options ),
'notice-symbol' => __( 'Please choose or input the symbol at the top of the next dashboard tab.', 'footnotes' ),
'label-switch' => $this->add_label( \footnotes\includes\Settings::REFERENCE_CONTAINER_BACKLINK_SYMBOL_SWITCH, __( 'Symbol appended, not prepended:', 'footnotes' ) ),
- 'switch' => $this->add_select_box( \footnotes\includes\Settings::REFERENCE_CONTAINER_BACKLINK_SYMBOL_SWITCH, $enabled ),
+ 'switch' => $this->add_select_box( \footnotes\includes\Settings::REFERENCE_CONTAINER_BACKLINK_SYMBOL_SWITCH, $enabled_options ),
'label-3column' => $this->add_label( \footnotes\includes\Settings::REFERENCE_CONTAINER_3COLUMN_LAYOUT_ENABLE, __( 'Backlink symbol in an extra column:', 'footnotes' ) ),
- '3column' => $this->add_select_box( \footnotes\includes\Settings::REFERENCE_CONTAINER_3COLUMN_LAYOUT_ENABLE, $enabled ),
+ '3column' => $this->add_select_box( \footnotes\includes\Settings::REFERENCE_CONTAINER_3COLUMN_LAYOUT_ENABLE, $enabled_options ),
'notice-3column' => __( 'This legacy layout is available if identical footnotes are not combined.', 'footnotes' ),
'label-row-borders' => $this->add_label( \footnotes\includes\Settings::REFERENCE_CONTAINER_ROW_BORDERS_ENABLE, __( 'Borders around the table rows:', 'footnotes' ) ),
- 'row-borders' => $this->add_select_box( \footnotes\includes\Settings::REFERENCE_CONTAINER_ROW_BORDERS_ENABLE, $enabled ),
+ 'row-borders' => $this->add_select_box( \footnotes\includes\Settings::REFERENCE_CONTAINER_ROW_BORDERS_ENABLE, $enabled_options ),
'label-separator' => $this->add_label( \footnotes\includes\Settings::BACKLINKS_SEPARATOR_ENABLED, __( 'Add a separator when enumerating backlinks:', 'footnotes' ) ),
- 'separator-enable' => $this->add_select_box( \footnotes\includes\Settings::BACKLINKS_SEPARATOR_ENABLED, $enabled ),
- 'separator-options' => $this->add_select_box( \footnotes\includes\Settings::BACKLINKS_SEPARATOR_OPTION, $separators ),
+ 'separator-enable' => $this->add_select_box( \footnotes\includes\Settings::BACKLINKS_SEPARATOR_ENABLED, $enabled_options ),
+ 'separator-options' => $this->add_select_box( \footnotes\includes\Settings::BACKLINKS_SEPARATOR_OPTION, $separators_options ),
'separator-custom' => $this->add_text_box( \footnotes\includes\Settings::BACKLINKS_SEPARATOR_CUSTOM ),
'notice-separator' => __( 'Your input overrides the selection.', 'footnotes' ),
'label-terminator' => $this->add_label( \footnotes\includes\Settings::BACKLINKS_TERMINATOR_ENABLED, __( 'Add a terminal punctuation to backlinks:', 'footnotes' ) ),
- 'terminator-enable' => $this->add_select_box( \footnotes\includes\Settings::BACKLINKS_TERMINATOR_ENABLED, $enabled ),
- 'terminator-options' => $this->add_select_box( \footnotes\includes\Settings::BACKLINKS_TERMINATOR_OPTION, $terminators ),
+ 'terminator-enable' => $this->add_select_box( \footnotes\includes\Settings::BACKLINKS_TERMINATOR_ENABLED, $enabled_options ),
+ 'terminator-options' => $this->add_select_box( \footnotes\includes\Settings::BACKLINKS_TERMINATOR_OPTION, $terminators_options ),
'terminator-custom' => $this->add_text_box( \footnotes\includes\Settings::BACKLINKS_TERMINATOR_CUSTOM ),
'notice-terminator' => __( 'Your input overrides the selection.', 'footnotes' ),
'label-width' => $this->add_label( \footnotes\includes\Settings::BACKLINKS_COLUMN_WIDTH_ENABLED, __( 'Set backlinks column width:', 'footnotes' ) ),
- 'width-enable' => $this->add_select_box( \footnotes\includes\Settings::BACKLINKS_COLUMN_WIDTH_ENABLED, $enabled ),
+ 'width-enable' => $this->add_select_box( \footnotes\includes\Settings::BACKLINKS_COLUMN_WIDTH_ENABLED, $enabled_options ),
'width-scalar' => $this->add_num_box( \footnotes\includes\Settings::BACKLINKS_COLUMN_WIDTH_SCALAR, 0, 500, true ),
- 'width-unit' => $this->add_select_box( \footnotes\includes\Settings::BACKLINKS_COLUMN_WIDTH_UNIT, $width_units ),
+ 'width-unit' => $this->add_select_box( \footnotes\includes\Settings::BACKLINKS_COLUMN_WIDTH_UNIT, $width_units_options ),
'notice-width' => __( 'Absolute width in pixels doesn\'t need to be accurate to the tenth, but relative width in rem or em may.', 'footnotes' ),
'label-max-width' => $this->add_label( \footnotes\includes\Settings::BACKLINKS_COLUMN_MAX_WIDTH_ENABLED, __( 'Set backlinks column maximum width:', 'footnotes' ) ),
- 'max-width-enable' => $this->add_select_box( \footnotes\includes\Settings::BACKLINKS_COLUMN_MAX_WIDTH_ENABLED, $enabled ),
+ 'max-width-enable' => $this->add_select_box( \footnotes\includes\Settings::BACKLINKS_COLUMN_MAX_WIDTH_ENABLED, $enabled_options ),
'max-width-scalar' => $this->add_num_box( \footnotes\includes\Settings::BACKLINKS_COLUMN_MAX_WIDTH_SCALAR, 0, 500, true ),
- 'max-width-unit' => $this->add_select_box( \footnotes\includes\Settings::BACKLINKS_COLUMN_MAX_WIDTH_UNIT, $width_units ),
+ 'max-width-unit' => $this->add_select_box( \footnotes\includes\Settings::BACKLINKS_COLUMN_MAX_WIDTH_UNIT, $width_units_options ),
'notice-max-width' => __( 'Absolute width in pixels doesn\'t need to be accurate to the tenth, but relative width in rem or em may.', 'footnotes' ),
'label-line-break' => $this->add_label( \footnotes\includes\Settings::BACKLINKS_LINE_BREAKS_ENABLED, __( 'Stack backlinks when enumerating:', 'footnotes' ) ),
- 'line-break' => $this->add_select_box( \footnotes\includes\Settings::BACKLINKS_LINE_BREAKS_ENABLED, $enabled ),
+ 'line-break' => $this->add_select_box( \footnotes\includes\Settings::BACKLINKS_LINE_BREAKS_ENABLED, $enabled_options ),
'notice-line-break' => __( 'This option adds a line break before each added backlink when identical footnotes are combined.', 'footnotes' ),
'label-link' => $this->add_label( \footnotes\includes\Settings::LINK_ELEMENT_ENABLED, __( 'Use the link element for referrers and backlinks:', 'footnotes' ) ),
- 'link' => $this->add_select_box( \footnotes\includes\Settings::LINK_ELEMENT_ENABLED, $enabled ),
+ 'link' => $this->add_select_box( \footnotes\includes\Settings::LINK_ELEMENT_ENABLED, $enabled_options ),
'notice-link' => __( 'The link element is needed to apply the theme\'s link color.', 'footnotes' ),
'description-link' => __( 'If the link element is not desired for styling, a simple span is used instead when the above is set to No.', 'footnotes' ),
)
diff --git a/src/includes/class-core.php b/src/includes/class-core.php
index 048b547..2c1ed31 100644
--- a/src/includes/class-core.php
+++ b/src/includes/class-core.php
@@ -157,6 +157,7 @@ class Core {
* @return void
*/
private function load_dependencies() {
+ require_once plugin_dir_path( __DIR__ ) . 'includes/class-settings.php';
/**
* The class responsible for orchestrating the actions and filters of the
@@ -175,7 +176,6 @@ class Core {
*/
require_once plugin_dir_path( __DIR__ ) . 'includes/class-config.php';
require_once plugin_dir_path( __DIR__ ) . 'includes/class-convert.php';
- require_once plugin_dir_path( __DIR__ ) . 'includes/class-settings.php';
require_once plugin_dir_path( __DIR__ ) . 'includes/class-template.php';
/**
diff --git a/src/includes/class-settings.php b/src/includes/class-settings.php
index 42fff9f..587597a 100644
--- a/src/includes/class-settings.php
+++ b/src/includes/class-settings.php
@@ -1,6 +1,6 @@
array(
@@ -1164,7 +1167,21 @@ class Settings {
self::FOOTNOTES_BACKLINK_TOOLTIP_TEXT => 'Alt+ ←',
// Reference container.
- self::REFERENCE_CONTAINER_NAME => 'References',
+ self::REFERENCE_CONTAINER_NAME => array(
+ 'title' => 'Reference container title',
+ 'setting_args' => array (
+ 'type' => 'string',
+ 'description' => 'The title of the reference container',
+ 'default' => 'References',
+ ),
+ 'field_args' => array (
+ 'name' => self::REFERENCE_CONTAINER_NAME,
+ 'label_for' => self::REFERENCE_CONTAINER_NAME,
+ 'type' => 'text',
+ 'value' => 'References',
+ 'description' => 'The title of the reference container',
+ ),
+ ),
self::REFERENCE_CONTAINER_LABEL_ELEMENT => 'p',
self::REFERENCE_CONTAINER_LABEL_BOTTOM_BORDER => 'yes',
self::REFERENCE_CONTAINER_COLLAPSE => 'no',
@@ -1281,7 +1298,7 @@ class Settings {
'footnotes_storage_expert' => array(
// WordPress hooks with priority level.
- self::EXPERT_LOOKUP_THE_TITLE => '',
+ self::EXPERT_LOOKUP_THE_TITLE => "",
self::EXPERT_LOOKUP_THE_TITLE_PRIORITY_LEVEL => PHP_INT_MAX,
self::EXPERT_LOOKUP_THE_CONTENT => 'checked',
@@ -1319,7 +1336,10 @@ class Settings {
* @since 1.5.0
* @todo Create `PreferencesSet` class.
*/
- private array $settings = array();
+ public array $settings = array();
+
+ public GeneralSettingsSection $general_settings;
+
/**********************************************************************
* SETTINGS STORAGE.
**********************************************************************/
@@ -1336,7 +1356,11 @@ class Settings {
* @since 1.5.0
*/
private function __construct() {
- $this->load_all();
+ $this->load_options();
+
+ require_once plugin_dir_path( __DIR__ ) . 'includes/settings/class-general-settings-section.php';
+
+ $this->general_settings = new GeneralSettingsSection('footnotes_storage', 'footnotes-settings', 'General Settings');
}
/**
@@ -1348,7 +1372,7 @@ class Settings {
* @since 1.5.0
*/
public function get_container( int $index ): string {
- return $this->container[ $index ];
+ return $this->option_groups[ $index ];
}
/**
@@ -1360,7 +1384,7 @@ class Settings {
* @since 1.5.6
*/
public function get_defaults( int $index ): array {
- return $this->default[ $this->container[ $index ] ];
+ return $this->default[ $this->option_groups[ $index ] ];
}
/**
@@ -1398,14 +1422,21 @@ class Settings {
* The Settings Container label will be the same as the Settings Container name.
*
* @since 1.5.0
+ * @todo Only register current tab?
*/
public function register_settings(): void {
- // Register all settings.
- $num_settings = count( $this->container );
- for ( $i = 0; $i < $num_settings; $i++ ) {
- register_setting( $this->get_container( $i ), $this->get_container( $i ) );
+ // Register all settings.
+ foreach ($this->default_settings as $option_groups_name => $option_groups_values) {
+ foreach ($option_groups_values as $setting_name => $setting_value) {
+ if (!is_array($setting_value)) {
+ register_setting( $option_groups_name, $setting_name );
+ } else {
+ register_setting( $option_groups_name, $setting_name, $setting_value['setting_args']);
+ }
+ }
}
}
+
/**
* Returns a singleton of this class.
*
@@ -1421,46 +1452,46 @@ class Settings {
return self::$instance;
}
/**
- * Loads all Settings from each Settings container.
+ * Loads all settings from each option group.
*
* @since 1.5.0
+ * @since 2.8.0 Renamed from `load_all()` to `load_options()`.
*/
- private function load_all(): void {
+ private function load_options(): void {
// Clear current settings.
$this->settings = array();
- $num_settings = count( $this->container );
- for ( $i = 0; $i < $num_settings; $i++ ) {
- // Load settings.
- $this->settings = array_merge( $this->settings, $this->load( $i ) );
+
+ foreach ($this->option_groups as $option_group) {
+ $this->settings[$option_group] = $this->load_option( $option_group );
}
}
+
/**
- * Loads all settings from specified Settings Containers.
+ * Loads all settings from a given option group.
*
- * @param int $index Settings container index.
- * @return (string|int)[] Loaded settings (or defaults if specified container is empty).
+ * @param string $option_group Option group slug.
+ * @return (string|int)[] Loaded settings (or defaults if specified option group is empty).
*
* @since 1.5.0
+ * @since 2.8.0 Renamed from `load()` to `load_option()`.
*/
- private function load( int $index ): array {
- // Load all settings from container.
- $options = get_option( $this->get_container( $index ) );
- // Load all default settings.
- $default = $this->default[ $this->get_container( $index ) ];
-
+ private function load_option(string $option_group): array {
+ // Load all settings from option group.
+ $options = get_option( $option_group );
+
// No settings found, set them to their default value.
if ( empty( $options ) ) {
- return $default;
+ return $this->default_settings[$option_group];
}
- // Iterate through all available settings ( = default values).
- foreach ( $default as $key => $value ) {
- // Available setting not found in the container.
- if ( ! array_key_exists( $key, $options ) ) {
+
+ foreach ( $this->default_settings[$option_group] as $setting_name => $setting_value ) {
+ // Available setting not found in the option group.
+ if ( ! array_key_exists( $setting_name, $options ) ) {
// Define the setting with its default value.
- $options[ $key ] = $value;
+ $options[ $setting_name ] = $setting_value;
}
}
- // Return settings loaded from Container.
+ // Return settings loaded from option group.
return $options;
}
}
diff --git a/src/includes/settings/class-general-settings-section.php b/src/includes/settings/class-general-settings-section.php
new file mode 100644
index 0000000..cc7fc14
--- /dev/null
+++ b/src/includes/settings/class-general-settings-section.php
@@ -0,0 +1,56 @@
+options_group_slug = $options_group_slug;
+ $this->section_slug = $section_slug;
+ $this->title = $title;
+
+ $this->load_dependencies();
+
+ $this->add_settings_groups(get_option( $this->options_group_slug ));
+ }
+
+ protected function load_dependencies(): void {
+ require_once plugin_dir_path( __DIR__ ) . 'settings/general/class-reference-container-settings-group.php';
+ }
+
+ protected function add_settings_groups(): void {
+ $this->settings_groups = array (
+ ReferenceContainerSettingsGroup::GROUP_ID => new ReferenceContainerSettingsGroup($this->options_group_slug, $this->section_slug),
+ );
+ }
+}
diff --git a/src/includes/settings/class-setting.php b/src/includes/settings/class-setting.php
new file mode 100644
index 0000000..0ca69f0
--- /dev/null
+++ b/src/includes/settings/class-setting.php
@@ -0,0 +1,137 @@
+options_group_slug, $this->key, $this->get_setting_args());
+ }
+
+ public function get_setting_args(): array {
+ return array (
+ 'type' => $this->type,
+ 'description' => $this->description,
+ 'default' => $this->default_value,
+ );
+ }
+
+ public function get_setting_field_args(): array {
+ return array (
+ 'name' => $this->key,
+ 'label_for' => $this->key,
+ 'type' => $this->input_type,
+ 'value' => $this->value,
+ 'description' => $this->description,
+ );
+ }
+
+ public function get_options_group_slug(): string {
+ return $this->options_group_slug;
+ }
+
+ public function get_section_slug(): string {
+ return $this->section_slug;
+ }
+}
diff --git a/src/includes/settings/class-settings-group.php b/src/includes/settings/class-settings-group.php
new file mode 100644
index 0000000..ceb7191
--- /dev/null
+++ b/src/includes/settings/class-settings-group.php
@@ -0,0 +1,71 @@
+section_slug,
+ $this->title,
+ array($this, 'setting_section_callback'),
+ 'footnotes'
+ );
+ }
+
+ public function add_settings_fields($component): void {
+ foreach($this->settings_groups as $settings_group) {
+ $settings_group->add_settings_fields($component);
+ }
+ }
+
+ public function setting_section_callback(): void {
+ echo "
";
+ }
+
+ protected abstract function add_settings_groups(): void;
+
+ public function get_options_group_slug(): string {
+ return $this->options_group_slug;
+ }
+
+ public function get_section_slug(): string {
+ return $this->section_slug;
+ }
+
+ public function get_title(): string {
+ return $this->title;
+ }
+
+ public function get_settings_group(string $group_id) {
+ return $this->settings_groups[$group_id];
+ }
+}
diff --git a/src/includes/settings/general/class-reference-container-settings-group.php b/src/includes/settings/general/class-reference-container-settings-group.php
new file mode 100644
index 0000000..5580b9c
--- /dev/null
+++ b/src/includes/settings/general/class-reference-container-settings-group.php
@@ -0,0 +1,122 @@
+ 'footnote_inputfield_references_label',
+ 'name' => 'Reference Container Name',
+ 'description' => 'The title of the reference container.',
+ 'default_value' => 'Reference',
+ 'type' => 'string',
+ 'input_type' => 'text'
+ );
+
+ /**
+ * The general settings.
+ *
+ * @var Setting[]
+ *
+ * @since 2.8.0
+ */
+ protected array $settings;
+
+ public function __construct(
+ /**
+ * Setting options group slug.
+ *
+ * @var string
+ *
+ * @since 2.8.0
+ */
+ protected string $options_group_slug,
+
+ /**
+ * Setting section slug.
+ *
+ * @var string
+ *
+ * @since 2.8.0
+ */
+ protected string $section_slug
+ ) {
+ $this->load_dependencies();
+
+ $this->add_settings(get_option( $this->options_group_slug ));
+ }
+
+ protected function load_dependencies(): void {
+ require_once plugin_dir_path( __DIR__ ) . 'class-setting.php';
+ }
+
+ protected function add_settings(array $options): void {
+ $this->settings = array(
+ self::REFERENCE_CONTAINER_NAME['key'] => $this->add_setting(self::REFERENCE_CONTAINER_NAME)
+ );
+ }
+
+ private function add_setting(array $setting): Setting {
+ extract( $setting );
+
+ return new Setting(
+ self::GROUP_ID,
+ $this->options_group_slug,
+ $this->section_slug,
+ $key,
+ $name,
+ $description,
+ $default_value,
+ $type,
+ $input_type
+ );
+ }
+
+ public function add_settings_fields($component): void {
+ foreach ($this->settings as $setting) {
+ add_settings_field(
+ $setting->key,
+ __( $setting->name, 'footnotes' ),
+ array ($component, 'setting_field_callback'),
+ 'footnotes',
+ $setting->get_section_slug(),
+ $setting->get_setting_field_args()
+ );
+ }
+ }
+}
diff --git a/src/includes/settings/general/reference-container/class-reference-container-name-setting.php b/src/includes/settings/general/reference-container/class-reference-container-name-setting.php
new file mode 100644
index 0000000..8794351
--- /dev/null
+++ b/src/includes/settings/general/reference-container/class-reference-container-name-setting.php
@@ -0,0 +1,106 @@
+options_group_slug, self::NAME, $this->get_setting_args());
+ }
+}