WordPress.org

Make WordPress Core

Ticket #18285: 18285.diff

File 18285.diff, 18.4 KB (added by ryan, 7 years ago)
  • wp-admin/includes/settings.php

     
     1<?php
     2/**
     3 *  Settings Page, Group, and Field API
     4 */
     5
     6class WP_Settings {
     7        private static $instance;
     8
     9        private $settings_pages;
     10
     11        /**
     12         * Returns singleton instance of api
     13         *
     14         * @return WP_Settings
     15         */
     16        public static function GetInstance() {
     17                if(!isset(self::$instance)) {
     18                        self::$instance = new WP_Settings();
     19                }
     20                return self::$instance;
     21        }
     22
     23        private function __construct() {
     24                $this->settings_pages = array();
     25        }
     26
     27        public function get_setting($setting_key, $group_key, $default = null) {
     28                if(is_array($setting_group = get_option($group_key)) && isset($setting_group[$setting_key])) {
     29                                return $setting_group[$setting_key];
     30                } elseif(($group = $this->get_group($group_key)) && isset($group->settings[$setting_key]) && !empty($group->settings[$setting_key]->default_value)) {
     31                        return $group->settings[$setting_key]->default_value;
     32                }
     33                return $default;
     34        }
     35
     36        private function get_group($group_key) {
     37                foreach($this->settings_pages as $settings_page) {
     38                        if(isset($settings_page->groups[$group_key])) {
     39                                return $settings_page->groups[$group_key];
     40                        }
     41                }
     42                return null;
     43        }
     44
     45        /**
     46         * Adds a new settings page if one doesn't already exist
     47         *
     48         * @param string $page_key
     49         * @param string $page_title
     50         * @param string $menu_title
     51         * @param string $capability
     52         * @param string $description
     53         * @param string $parent_page slug for parent page, leave empty to create new menu
     54         * @return WP_Settings_Page
     55         */
     56        public function add_page($page_title, $menu_title, $page_key, $capability = 'manage_options', $description = '', $parent_page = '') {
     57                if(!$capability) $capability = 'manage_options';
     58
     59                if ( ! $page_key ) {
     60                        $page_key = 'wp_'.sanitize_key($this->title);
     61                }
     62                if(!isset($this->settings_pages[$page_key])) {
     63                        $page = new WP_Settings_Page($page_title, $menu_title, $page_key, $capability, $description, $parent_page);
     64                        $this->settings_pages[$page_key] = $page;
     65                }
     66                return $this->settings_pages[$page_key];
     67        }
     68}
     69
     70class WP_Settings_Page {
     71
     72        public $title;
     73        public $menu_title;
     74        public $page_key;
     75        public $capability;
     76        public $description;
     77
     78        /**
     79         * Key of this page's parent page if it is a submenu item
     80         *
     81         * @var string
     82         */
     83        public $parent_page;
     84        public $groups;
     85
     86        public function __construct($title, $menu_title, $page_key, $capability = 'manage_options', $description = '', $parent_page = '') {
     87                $this->title = $title;
     88                $this->page_key = $page_key;
     89                $this->menu_title = $menu_title;
     90                $this->capability = $capability;
     91                $this->description = $description;
     92                $this->parent_page = $parent_page;
     93                $this->groups = array();
     94
     95                global $pagenow;
     96                // Quick hack to avoid adding the menu for core files.
     97                if ( 0 !== strpos( 'options-', $pagenow) )
     98                        add_action('admin_menu', array($this, 'admin_menu'));
     99                if (current_user_can($this->capability)) {
     100                        add_action('admin_head', array($this, 'admin_head'));
     101                }
     102        }
     103
     104        public function add_error($code, $message, $type = 'error') {
     105                        add_settings_error($this->page_key, $code, $message, $type);
     106        }
     107
     108        /**
     109         * Adds a new group to the page
     110         *
     111         * @param string $group_key
     112         * @param string $title
     113         * @param string $capability
     114         * @param string $description
     115         * @return WP_Settings_Group
     116         */
     117        public function add_group($title, $group_key, $capability = '', $description = '') {
     118                if(!isset($this->groups[$group_key])) {
     119                        $group = new WP_Settings_Group($this, $title, $group_key, $capability, $description);
     120                        $this->groups[$group_key] = $group;
     121                }
     122                return $this->groups[$group_key];
     123        }
     124
     125        public function admin_menu() {
     126                if(current_user_can($this->capability)) {
     127                        //only add the page if groups exist
     128                        if($this->parent_page) {
     129                                add_submenu_page($this->parent_page, $this->title, $this->menu_title, $this->capability, $this->page_key, array($this, 'display'));
     130                        } else {
     131                                add_menu_page($this->title, $this->menu_title, $this->capability, $this->page_key, array($this, 'display'));
     132                        }
     133                }
     134        }
     135
     136        public function admin_head() {
     137                register_setting($this->page_key, $this->page_key, array($this, 'sanitize_callback'));
     138        }
     139
     140        public function sanitize_callback($new_values) {
     141                if(current_user_can($this->capability)) {
     142                        $this->add_error('all', 'Your changes have been saved.', 'updated');
     143
     144                        foreach($this->groups as $group) {
     145                                $new_value = isset($new_values[$group->group_key]) ? $new_values[$group->group_key] : array();
     146                                $group->sanitize_callback($new_value);
     147                        }
     148                }
     149                /**
     150                 * return false so a new option doesn't get added for this.
     151                 */
     152                return false;
     153        }
     154
     155        public function display() {
     156                if(current_user_can($this->capability)) {
     157                        ?>
     158                        <div class="wrap">
     159                                <?php screen_icon(); ?>
     160                                <h2><?php echo $this->title ?></h2>
     161                                <?php settings_errors($this->page_key); ?>
     162                                <?php if($this->description) echo "<p>{$this->description}</p>"; ?>
     163                                <form action="options.php" method="POST">
     164                                        <?php settings_fields($this->page_key); ?>
     165                                        <?php do_settings_sections($this->page_key); ?>
     166                                        <p class="submit">
     167                                                <input type="submit" value="Save Changes" class="button-primary" name="Submit">
     168                                        </p>
     169                                </form>
     170                        </div>
     171                        <?php
     172                }
     173        }
     174}
     175
     176class WP_Settings_Group {
     177        /**
     178         * Pointer to this Section's Page
     179         *
     180         * @var WP_Settings_Page
     181         */
     182        public $page;
     183
     184        public $title;
     185        public $capability;
     186        public $group_key;
     187        public $description;
     188        public $settings;
     189
     190        public function __construct($page, $title, $group_key, $capability = '', $description = '') {
     191                $this->page = $page;
     192                $this->group_key = $group_key;
     193                $this->title = $title;
     194                $this->capability = $capability ? $capability : $this->page->capability;
     195                $this->description = $description;
     196                if(current_user_can($this->capability)) {
     197                        add_action('admin_head', array($this, 'admin_head'));
     198                }
     199        }
     200
     201        public function add_error($code, $message, $type = 'error') {
     202                        $this->page->add_error($code, $message, $type);
     203        }
     204
     205
     206        public function admin_head() {
     207                        add_settings_section($this->group_key, $this->title, array($this, 'display'), $this->page->page_key);
     208        }
     209
     210        /**
     211         * Adds a group to the group
     212         *
     213         * @param string $title
     214         * @param string $group_key
     215         * @param string $capability
     216         * @param string $description
     217         * @return WP_Setting
     218         */
     219        public function add_setting($title, $setting_key, $args = array()) {
     220                if(!isset($this->settings[$setting_key])) {
     221                        $setting = new WP_Setting($this, $title, $setting_key, $args);
     222                        $this->settings[$setting_key] = $setting;
     223                }
     224                return $this->settings[$setting_key];
     225        }
     226
     227        public function display() {
     228                if(current_user_can($this->capability)) {
     229                        if($this->description) echo "<p>{$this->description}</p>";
     230                }
     231        }
     232
     233        public function sanitize_callback($new_values) {
     234                $old_values = get_option($this->group_key, array());
     235                if(current_user_can($this->capability)) {
     236                        foreach($this->settings as $setting) {
     237                                $new_value = isset($new_values[$setting->setting_key]) ? $new_values[$setting->setting_key] : null;
     238                                $old_value = isset($old_values[$setting->setting_key]) ? $old_values[$setting->setting_key] : null;
     239                                $old_values[$setting->setting_key] = $setting->sanitize($new_value, $old_value);
     240                        }
     241                }
     242                update_option($this->group_key, $old_values);
     243        }
     244}
     245
     246class WP_Setting {
     247
     248        /**
     249         * Pointer to this settings group
     250         *
     251         * @var WP_Settings_Group
     252         */
     253        public $group;
     254        public $title;
     255        public $setting_key;
     256        public $capability;
     257        public $default_value;
     258        public $args;
     259
     260        /**
     261         * Constructor for WP Setting
     262         *
     263         * @param WP_Settings_Group $group
     264         * @param string $title
     265         * @param string $setting_key
     266         * @param array $args
     267         */
     268        public function __construct($group, $title, $setting_key, $args = array()) {
     269                $this->group = $group;
     270                $this->title = $title;
     271                $this->setting_key = $setting_key;
     272
     273                $args = wp_parse_args($args, $defaults = array(
     274                        'capability' => $this->group->capability,
     275                        'default_value' => '',
     276                        'display_callback' => '',
     277                        'sanitize_callbacks' => array(),
     278                        'description' => ''
     279                        ));
     280
     281                $this->default_value = $args['default_value'];
     282                $this->capability = $args['capability'];
     283                $this->args = $args;
     284                if(current_user_can($this->capability)) {
     285                        add_action('admin_head', array($this, 'admin_head'));
     286                }
     287        }
     288
     289        public function add_error($message, $type = 'error') {
     290                $this->group->add_error($this->setting_key, $message, $type);
     291        }
     292
     293        public function admin_head() {
     294                add_settings_field($this->setting_key, $this->title, array($this, 'display'), $this->group->page->page_key, $this->group->group_key);
     295        }
     296
     297        public function get_field_name() {
     298                return $this->group->page->page_key . '[' . $this->group->group_key . '][' . $this->setting_key . ']';
     299        }
     300
     301        public function get_field_id() {
     302                return $this->group->page->page_key . '-' . $this->group->group_key . '-' . $this->setting_key;
     303        }
     304
     305        public function display() {
     306                $value = WP_Settings::GetInstance()->get_setting($this->setting_key, $this->group->group_key, $this->default_value);
     307                if(!empty($this->args['display_callback'])) {
     308                        call_user_func_array($this->args['display_callback'], array($value, $this, $this->args));
     309                } else {
     310                        ?>
     311                        <input name="<?php echo $this->get_field_name() ?>" id="<?php echo $this->get_field_id() ?>" value="<?php echo esc_attr($value) ?>" class="regular-text" type="text">
     312                        <?php if(!empty($this->args['description'])) : ?>
     313                                <span class="description"><?php echo $this->args['description'] ?></span>
     314                        <?php endif; ?>
     315                        <?php
     316                }
     317        }
     318
     319        public function sanitize($new_value, $old_value) {
     320                if(current_user_can($this->capability)) {
     321                        $old_value = $new_value;
     322                        foreach($this->args['sanitize_callbacks'] as $callback) {
     323                                $old_value = call_user_func_array($callback, array($old_value, $this, $this->args));
     324                        }
     325                }
     326                return $old_value;
     327        }
     328}
  • wp-admin/includes/admin.php

     
    3333/** WordPress Post Administration API */
    3434require_once(ABSPATH . 'wp-admin/includes/post.php');
    3535
     36require_once(ABSPATH . 'wp-admin/includes/settings.php');
     37
    3638/** WordPress Taxonomy Administration API */
    3739require_once(ABSPATH . 'wp-admin/includes/taxonomy.php');
    3840
  • wp-admin/options-media.php

     
    2525        '<p>' . __('<a href="http://wordpress.org/support/" target="_blank">Support Forums</a>') . '</p>'
    2626);
    2727
    28 include('./admin-header.php');
    29 
    30 ?>
    31 
    32 <div class="wrap">
    33 <?php screen_icon(); ?>
    34 <h2><?php echo esc_html( $title ); ?></h2>
    35 
    36 <form action="options.php" method="post">
    37 <?php settings_fields('media'); ?>
    38 
    39 <h3><?php _e('Image sizes') ?></h3>
    40 <p><?php _e('The sizes listed below determine the maximum dimensions in pixels to use when inserting an image into the body of a post.'); ?></p>
    41 
    42 <table class="form-table">
    43 <tr valign="top">
    44 <th scope="row"><?php _e('Thumbnail size') ?></th>
    45 <td>
     28function setting_thumbnail_size() { ?>
    4629<label for="thumbnail_size_w"><?php _e('Width'); ?></label>
    4730<input name="thumbnail_size_w" type="text" id="thumbnail_size_w" value="<?php form_option('thumbnail_size_w'); ?>" class="small-text" />
    4831<label for="thumbnail_size_h"><?php _e('Height'); ?></label>
    4932<input name="thumbnail_size_h" type="text" id="thumbnail_size_h" value="<?php form_option('thumbnail_size_h'); ?>" class="small-text" /><br />
    5033<input name="thumbnail_crop" type="checkbox" id="thumbnail_crop" value="1" <?php checked('1', get_option('thumbnail_crop')); ?>/>
    5134<label for="thumbnail_crop"><?php _e('Crop thumbnail to exact dimensions (normally thumbnails are proportional)'); ?></label>
    52 </td>
    53 </tr>
     35<?php
     36}
    5437
    55 <tr valign="top">
    56 <th scope="row"><?php _e('Medium size') ?></th>
    57 <td><fieldset><legend class="screen-reader-text"><span><?php _e('Medium size'); ?></span></legend>
     38function setting_medium_size() { ?>
     39<fieldset><legend class="screen-reader-text"><span><?php _e('Medium size'); ?></span></legend>
    5840<label for="medium_size_w"><?php _e('Max Width'); ?></label>
    5941<input name="medium_size_w" type="text" id="medium_size_w" value="<?php form_option('medium_size_w'); ?>" class="small-text" />
    6042<label for="medium_size_h"><?php _e('Max Height'); ?></label>
    6143<input name="medium_size_h" type="text" id="medium_size_h" value="<?php form_option('medium_size_h'); ?>" class="small-text" />
    62 </fieldset></td>
    63 </tr>
     44</fieldset>
     45<?php
     46}
    6447
    65 <tr valign="top">
    66 <th scope="row"><?php _e('Large size') ?></th>
    67 <td><fieldset><legend class="screen-reader-text"><span><?php _e('Large size'); ?></span></legend>
     48function setting_large_size() { ?>
     49<fieldset><legend class="screen-reader-text"><span><?php _e('Large size'); ?></span></legend>
    6850<label for="large_size_w"><?php _e('Max Width'); ?></label>
    6951<input name="large_size_w" type="text" id="large_size_w" value="<?php form_option('large_size_w'); ?>" class="small-text" />
    7052<label for="large_size_h"><?php _e('Max Height'); ?></label>
    7153<input name="large_size_h" type="text" id="large_size_h" value="<?php form_option('large_size_h'); ?>" class="small-text" />
    72 </fieldset></td>
    73 </tr>
     54</fieldset>
     55<?php
     56}
    7457
    75 <?php do_settings_fields('media', 'default'); ?>
    76 </table>
    77 
    78 <h3><?php _e('Embeds') ?></h3>
    79 
    80 <table class="form-table">
    81 
    82 <tr valign="top">
    83 <th scope="row"><?php _e('Auto-embeds'); ?></th>
    84 <td><fieldset><legend class="screen-reader-text"><span><?php _e('When possible, embed the media content from a URL directly onto the page. For example: links to Flickr and YouTube.'); ?></span></legend>
     58function setting_auto_embed() { ?>
     59<fieldset><legend class="screen-reader-text"><span><?php _e('When possible, embed the media content from a URL directly onto the page. For example: links to Flickr and YouTube.'); ?></span></legend>
    8560<label for="embed_autourls"><input name="embed_autourls" type="checkbox" id="embed_autourls" value="1" <?php checked( '1', get_option('embed_autourls') ); ?>/> <?php _e('When possible, embed the media content from a URL directly onto the page. For example: links to Flickr and YouTube.'); ?></label>
    86 </fieldset></td>
    87 </tr>
     61</fieldset>
     62<?php
     63}
    8864
    89 <tr valign="top">
    90 <th scope="row"><?php _e('Maximum embed size') ?></th>
    91 <td>
     65function setting_max_embed_size() { ?>
    9266<label for="embed_size_w"><?php _e('Width'); ?></label>
    9367<input name="embed_size_w" type="text" id="embed_size_w" value="<?php form_option('embed_size_w'); ?>" class="small-text" />
    9468<label for="embed_size_h"><?php _e('Height'); ?></label>
    9569<input name="embed_size_h" type="text" id="embed_size_h" value="<?php form_option('embed_size_h'); ?>" class="small-text" />
    9670<?php if ( !empty($content_width) ) echo '<br />' . __("If the width value is left blank, embeds will default to the max width of your theme."); ?>
    97 </td>
    98 </tr>
     71<?php
     72}
    9973
    100 <?php do_settings_fields('media', 'embeds'); ?>
    101 </table>
    102 
    103 <?php if ( !is_multisite() ) : ?>
    104 <h3><?php _e('Uploading Files'); ?></h3>
    105 <table class="form-table">
    106 <tr valign="top">
    107 <th scope="row"><label for="upload_path"><?php _e('Store uploads in this folder'); ?></label></th>
    108 <td><input name="upload_path" type="text" id="upload_path" value="<?php echo esc_attr(get_option('upload_path')); ?>" class="regular-text code" />
     74function setting_upload_path() { ?>
     75<input name="upload_path" type="text" id="upload_path" value="<?php echo esc_attr(get_option('upload_path')); ?>" class="regular-text code" />
    10976<span class="description"><?php _e('Default is <code>wp-content/uploads</code>'); ?></span>
    110 </td>
    111 </tr>
     77<?php
     78}
    11279
    113 <tr valign="top">
    114 <th scope="row"><label for="upload_url_path"><?php _e('Full URL path to files'); ?></label></th>
    115 <td><input name="upload_url_path" type="text" id="upload_url_path" value="<?php echo esc_attr( get_option('upload_url_path')); ?>" class="regular-text code" />
     80function setting_upload_url_patch() { ?>
     81<input name="upload_url_path" type="text" id="upload_url_path" value="<?php echo esc_attr( get_option('upload_url_path')); ?>" class="regular-text code" />
    11682<span class="description"><?php _e('Configuring this is optional. By default, it should be blank.'); ?></span>
    117 </td>
    118 </tr>
     83<?php
     84}
    11985
    120 <tr>
    121 <th scope="row" colspan="2" class="th-full">
     86function setting_upload_use_year_month() { ?>
    12287<label for="uploads_use_yearmonth_folders">
    12388<input name="uploads_use_yearmonth_folders" type="checkbox" id="uploads_use_yearmonth_folders" value="1"<?php checked('1', get_option('uploads_use_yearmonth_folders')); ?> />
    12489<?php _e('Organize my uploads into month- and year-based folders'); ?>
    12590</label>
    126 </th>
    127 </tr>
     91<?php
     92}
    12893
    129 <?php do_settings_fields('media', 'uploads'); ?>
    130 </table>
    131 <?php endif; ?>
     94$settings_page = WP_Settings::GetInstance()->add_page( $title, __('Media'), 'media' );
    13295
    133 <?php do_settings_sections('media'); ?>
     96$group = $settings_page->add_group( __('Image sizes'), 'default', 'manage_options', __('The sizes listed below determine the maximum dimensions in pixels to use when inserting an image into the body of a post.') );
     97$group->add_setting( __('Thumbnail size'), 'thumbnail-size', array( 'display_callback' => 'setting_thumbnail_size' ) );
     98$group->add_setting( __('Medium size'), 'medium-size', array( 'display_callback' => 'setting_medium_size' ) );
     99$group->add_setting( __('Large size'), 'medium-size', array( 'display_callback' => 'setting_large_size' ) );
    134100
    135 <?php submit_button(); ?>
     101$group = $settings_page->add_group( __('Embeds'), 'embeds', 'manage_options' );
     102$group->add_setting( __('Auto-embeds'), 'embed_autourls', array( 'display_callback' => 'setting_auto_embed' ) );
     103$group->add_setting( __('Maximum embed size'), 'max-embed-size', array( 'display_callback' => 'setting_max_embed_size' ) );
    136104
    137 </form>
     105if ( ! is_multisite() ) {
     106        $group = $settings_page->add_group( __('Uploading Files'), 'uploads', 'manage_options' );
     107        $group->add_setting( __('Store uploads in this folder'), 'upload_path', array( 'display_callback' => 'setting_upload_path' ) );
     108        $group->add_setting( __('Full URL path to files'), 'upload_url_path', array( 'display_callback' => 'setting_upload_url_path' ) );
     109        $group->add_setting( '', 'uploads_use_yearmonth_folders', array( 'display_callback' => setting_upload_use_year_month ) );
     110}
    138111
    139 </div>
     112include('./admin-header.php');
    140113
    141 <?php include('./admin-footer.php'); ?>
     114$settings_page->display();
     115
     116include('./admin-footer.php');