Horriblesubs/fansub/class-fansub-option.php

852 lines
28 KiB
PHP

<?php
if(!function_exists('add_filter')) exit;
class HOCWP_Option {
private $menu_title;
private $page_title;
private $menu_slug;
private $heading_text;
private $is_option_page;
private $page_title_action;
private $page_header_callback;
private $page_footer_callback;
private $page_sidebar_callback;
private $disable_sidebar;
private $capability;
private $parent_slug;
private $function;
private $icon_url;
private $position;
private $option_group;
private $option_name;
private $sanitize_callback;
private $section_id;
private $section_title;
private $section_callback;
private $section_description;
private $fields;
private $sections;
private $help_tabs;
private $help_sidebar;
private $use_style_and_script;
private $use_media_upload;
private $use_color_picker;
private $use_jquery_ui;
private $use_jquery_ui_sortable;
private $exists;
private $page;
private $update_option;
private $parse_options;
public function disable_sidebar() {
$this->disable_sidebar = true;
}
public function set_parse_options($bool) {
$this->parse_options = $bool;
}
public function get_parse_options() {
return (bool)$this->parse_options;
}
public function set_update_option($bool) {
$this->update_option = $bool;
}
public function get_update_option() {
return (bool)$this->update_option;
}
public function set_page($page) {
$this->page = $page;
}
public function get_page() {
return $this->page;
}
public function set_exists($exists) {
$this->exists = $exists;
}
public function get_exists() {
return $this->exists;
}
public function set_use_style_and_script($use) {
$this->use_style_and_script = $use;
}
public function get_use_style_and_script() {
return (bool)$this->use_style_and_script;
}
public function set_use_jquery_ui_sortable($use) {
$this->use_jquery_ui_sortable = $use;
}
public function get_use_jquery_ui_sortable() {
return $this->use_jquery_ui_sortable;
}
public function set_use_jquery_ui($use) {
$this->use_jquery_ui = $use;
}
public function get_use_jquery_ui() {
return (bool)$this->use_jquery_ui;
}
public function set_use_media_upload($use) {
$this->use_media_upload = $use;
if($use) {
$this->set_use_style_and_script(true);
}
}
public function get_use_media_upload() {
return (bool)$this->use_media_upload;
}
public function set_use_color_picker($use) {
$this->use_color_picker = $use;
}
public function get_use_color_picker() {
return (bool)$this->use_color_picker;
}
public function set_help_sidebar($help_sidebar) {
$this->help_sidebar = $help_sidebar;
}
public function get_help_sidebar() {
return $this->help_sidebar;
}
public function set_help_tabs($help_tabs) {
$this->help_tabs = $help_tabs;
}
public function get_help_tabs() {
return $this->help_tabs;
}
public function set_section_description($section_description) {
$this->section_description = $section_description;
}
public function get_section_description() {
return $this->section_description;
}
public function set_fields($fields) {
$this->fields = $fields;
}
public function get_fields() {
return $this->fields;
}
public function set_sections($sections) {
$this->sections = $sections;
}
public function get_sections() {
return $this->sections;
}
public function set_section_callback($section_callback) {
$this->section_callback = $section_callback;
}
public function get_section_callback() {
if(!fansub_callback_exists($this->section_callback)) {
$this->set_section_callback(array($this, 'default_section_callback'));
}
return $this->section_callback;
}
public function set_section_id($section_id) {
$this->section_id = $section_id;
}
public function get_section_id() {
return $this->section_id;
}
public function set_section_title($section_title) {
$this->section_title = $section_title;
}
public function get_section_title() {
return $this->section_title;
}
public function set_sanitize_callback($sanitize_callback) {
$this->sanitize_callback = $sanitize_callback;
}
public function get_sanitize_callback() {
return $this->sanitize_callback;
}
public function set_option_name($option_name) {
$this->option_name = $option_name;
}
public function get_option_name() {
if(empty($this->option_name)) {
$this->option_name = $this->get_menu_slug();
}
return $this->option_name;
}
public function get_option_name_no_prefix() {
$option_name = $this->get_option_name();
$option_name = str_replace('fansub_', '', $option_name);
return $option_name;
}
public function set_option_group($option_group) {
$this->option_group = $option_group;
}
public function get_option_group() {
if(empty($this->option_group)) {
$this->option_group = $this->get_menu_slug();
}
return $this->option_group;
}
public function set_menu_title($menu_title) {
$this->menu_title = $menu_title;
}
public function get_menu_title() {
return $this->menu_title;
}
public function get_heading_text() {
return $this->heading_text;
}
public function set_heading_text($text) {
$this->heading_text = $text;
}
public function get_page_title_action() {
return $this->page_title_action;
}
public function set_page_title_action($action, $url, $text) {
$action = fansub_sanitize($action, 'html_class');
fansub_add_string_with_space_before($action, 'page-title-action');
$link = new HOCWP_HTML('a');
$link->set_class($action);
$link->set_attribute('href', $url);
$link->set_text($text);
$this->page_title_action = $link->build();
}
public function set_page_sidebar_callback($func) {
$this->page_sidebar_callback = $func;
}
public function get_page_sidebar_callback() {
return $this->page_sidebar_callback;
}
public function set_page_header_callback($func) {
$this->page_header_callback = $func;
}
public function get_page_header_callback() {
return $this->page_header_callback;
}
public function set_page_footer_callback($func) {
$this->page_footer_callback = $func;
}
public function get_page_footer_callback() {
return $this->page_footer_callback;
}
public function is_option_page() {
return (bool)$this->is_option_page;
}
public function set_is_option_page($value) {
$this->is_option_page = $value;
}
public function set_menu_slug($menu_slug) {
$this->menu_slug = $menu_slug;
}
public function get_menu_slug() {
return $this->menu_slug;
}
public function set_page_title($page_title) {
$this->page_title = $page_title;
}
public function get_page_title() {
return $this->page_title;
}
public function set_capability($capability) {
$this->capability = $capability;
}
public function get_capability() {
return $this->capability;
}
public function set_parent_slug($parent_slug) {
$this->parent_slug = $parent_slug;
}
public function get_parent_slug() {
return $this->parent_slug;
}
public function set_function($function) {
$this->function = $function;
}
public function get_function() {
if(!fansub_callback_exists($this->function)) {
$this->function = array($this, 'default_setting_page_callback');
}
return $this->function;
}
public function set_icon_url($icon_url) {
$this->icon_url = $icon_url;
}
public function get_icon_url() {
return $this->icon_url;
}
public function set_position($position) {
$this->position = $position;
}
public function get_position() {
return $this->position;
}
public function __construct($menu_title, $menu_slug) {
$this->set_menu_title($menu_title);
$this->set_page_title($menu_title);
$this->set_heading_text($menu_title);
$this->set_menu_slug($menu_slug);
$this->set_is_option_page(true);
$this->set_sanitize_callback(array($this, 'sanitize'));
$this->set_capability('manage_options');
$this->set_use_style_and_script(true);
$this->set_parent_slug('options-general.php');
$this->set_section_id('default');
$this->set_section_title('');
$this->set_sections(array());
$this->set_fields(array());
$this->set_help_tabs(array());
if(empty($menu_title)) {
$this->set_exists(true);
}
if($this->get_exists()) {
$this->set_option_name('fansub_' . fansub_sanitize_id($menu_slug));
}
}
public function settings_saved() {
$option_name = $this->get_option_name();
if(isset($_POST[$option_name])) {
$old = (array)get_option($option_name);
$new = (array)$_POST[$option_name];
$new = wp_parse_args($new, $old);
update_option($option_name, $new);
}
}
public function is_this_page() {
global $pagenow;
$page = fansub_get_current_admin_page();
if($page == $this->get_menu_slug()) {
if(($this->is_submenu() && $pagenow == $this->get_parent_slug()) || 'admin.php' == $pagenow) {
return true;
}
} elseif($pagenow == $this->get_page()) {
return true;
}
return false;
}
public function form() {
?>
<form novalidate="novalidate" action="options.php" method="post">
<?php
settings_fields($this->get_option_group());
do_settings_sections($this->get_menu_slug());
submit_button();
?>
</form>
<?php
}
public function default_setting_page_callback() {
$parent_slug = $this->get_parent_slug();
if(empty($parent_slug)) {
return;
}
$disable_sidebar = (bool)$this->disable_sidebar;
$title = $this->get_heading_text();
if($this->is_option_page() && !fansub_string_contain(strtolower($title), 'settings') && !fansub_string_contain(strtolower($title), 'options')) {
fansub_add_string_with_space_before($title, 'Settings');
}
$wrap_class = $this->get_option_name_no_prefix();
$wrap_class = fansub_sanitize($wrap_class, 'html_class');
fansub_add_string_with_space_before($wrap_class, 'wrap fansub option-page');
if(!$disable_sidebar) {
fansub_add_string_with_space_before($wrap_class, 'has-sidebar');
}
?>
<div class="<?php echo $wrap_class; ?>">
<h1 class="page-title"><?php echo esc_html($title). $this->get_page_title_action(); ?></h1>
<?php
$header_callback = $this->get_page_header_callback();
if(fansub_callback_exists($header_callback)) {
call_user_func($header_callback);
}
$page_content_class = 'page-content';
if($disable_sidebar) {
fansub_add_string_with_space_before($page_content_class, 'no-sidebar');
}
?>
<div class="<?php echo $page_content_class; ?>">
<?php
if((bool)$this->disable_sidebar) {
if($this->is_option_page()) {
if($this->is_this_page() && (isset($_REQUEST['submit']) || isset($_REQUEST['settings-updated']))) {
do_action('fansub_option_saved');
if('options-general.php' != $this->get_parent_slug() && !$this->get_exists()) {
fansub_admin_notice_setting_saved();
}
do_action($this->get_menu_slug() . '_option_saved', $this);
}
$this->form();
}
do_action('fansub_option_page_content');
do_action('fansub_option_page_' . $this->get_option_name_no_prefix() . '_content');
} else {
?>
<div class="sidebar">
<?php
$sidebar_callback = $this->get_page_sidebar_callback();
if(fansub_callback_exists($sidebar_callback)) {
call_user_func($sidebar_callback);
}
?>
</div>
<div class="main main-content">
<?php
if($this->is_option_page()) {
if($this->is_this_page() && (isset($_REQUEST['submit']) || isset($_REQUEST['settings-updated']))) {
do_action('fansub_option_saved');
if('options-general.php' != $this->get_parent_slug() && !$this->get_exists()) {
fansub_admin_notice_setting_saved();
}
do_action($this->get_menu_slug() . '_option_saved', $this);
}
$this->form();
}
do_action('fansub_option_page_content');
do_action('fansub_option_page_' . $this->get_option_name_no_prefix() . '_content');
?>
</div>
<?php
}
?>
</div>
<?php
$footer_callback = $this->get_page_footer_callback();
if(fansub_callback_exists($footer_callback)) {
call_user_func($footer_callback);
}
?>
</div>
<?php
}
public function add_option_tab(&$option_tabs) {
$option_tabs = fansub_sanitize_array($option_tabs);
$option_tabs[$this->get_option_name()] = array(
'text' => $this->get_menu_title(),
);
}
public function init() {
if($this->get_exists()) {
$this->exists_page_init();
} else {
add_action('admin_menu', array($this, 'menu_init'));
add_action('admin_init', array($this, 'setting_init'));
if($this->is_this_page()) {
add_action('admin_head', array($this, 'help_tab_init'));
add_action('admin_enqueue_scripts', array($this, 'enqueue_style_and_script'));
}
}
if($this->get_update_option()) {
$this->settings_saved();
}
}
public function enqueue_style_and_script() {
if($this->get_use_style_and_script()) {
add_filter('fansub_use_admin_style_and_script', '__return_true');
}
if($this->get_use_color_picker()) {
add_filter('fansub_use_color_picker', '__return_true');
}
if($this->get_use_media_upload()) {
add_filter('fansub_wp_enqueue_media', '__return_true');
}
if($this->get_use_jquery_ui()) {
add_filter('fansub_use_jquery_ui', '__return_true');
}
if($this->get_use_jquery_ui_sortable()) {
add_filter('fansub_use_jquery_ui_sortable', '__return_true');
}
if(!fansub_is_my_theme()) {
add_action('admin_print_scripts', 'fansub_admin_enqueue_scripts');
}
}
public function help_tab_init() {
$current_screen = get_current_screen();
foreach($this->get_help_tabs() as $args) {
$current_screen->add_help_tab($args);
}
$help_sidebar = $this->get_help_sidebar();
$current_screen->set_help_sidebar($help_sidebar);
}
public function setting_init() {
$this->register_setting();
$this->section_init();
$this->field_init();
}
public function exists_page_init() {
add_action('admin_init', array($this, 'exists_setting_page_field'));
}
public function exists_setting_page_field() {
$this->setting_init();
}
private function section_init() {
if(!$this->get_exists()) {
$this->add_settings_section_default();
}
foreach($this->get_sections() as $args) {
$id = isset($args['id']) ? $args['id'] : '';
$title = isset($args['title']) ? $args['title'] : '';
$callback = isset($args['callback']) ? $args['callback'] : '';
if(!fansub_callback_exists($callback)) {
$callback = array($this, 'default_section_callback');
}
$this->add_settings_section($id, $title, $callback);
}
}
public function section_description($text) {
$p = new HOCWP_HTML('p');
$p->set_text($text);
$p->output();
}
public function sanitize($input) {
$fields = $this->get_fields();
if(fansub_array_has_value($fields)) {
foreach($fields as $field) {
$data_type = fansub_get_value_by_key($field, 'data_type');
if('checkbox' == $data_type) {
$name = fansub_get_value_by_key($field, 'name');
if(!empty($name)) {
$input[$name] = fansub_checkbox_post_data_value($input, $name);
}
}
}
}
if($this->get_parse_options()) {
$old = (array)get_option($this->get_option_name());
$input = (array)$input;
$input = wp_parse_args($input, $old);
}
$input = apply_filters('fansub_sanitize_option_' . $this->get_option_name_no_prefix(), $input);
do_action('fansub_sanitize_' . $this->get_option_name_no_prefix() . '_option', $input);
$input = apply_filters('validate_options', $input);
return apply_filters('fansub_validate_options', $input);
}
public function field_init() {
foreach($this->get_fields() as $args) {
$id = isset($args['id']) ? $args['id'] : '';
$title = isset($args['title']) ? $args['title'] : '';
$callback = isset($args['callback']) ? $args['callback'] : '';
$section = isset($args['section']) ? $args['section'] : $this->get_section_id();
if(!fansub_callback_exists($callback)) {
$callback = array($this, 'default_field_callback');
}
if($this->get_exists()) {
$class = isset($args['class']) ? $args['class'] : '';
fansub_add_string_with_space_before($class, 'fansub');
$args['class'] = $class;
}
$this->add_settings_field($id, $title, $callback, $section, $args);
}
}
public function default_field_callback($args) {
$callback = isset($args['field_callback']) ? $args['field_callback'] : 'fansub_field_input';
if(fansub_callback_exists($callback)) {
$name = isset($args['name']) ? fansub_sanitize_array($args['name']) : array();
if(!fansub_array_has_value($name)) {
$name = isset($args['id']) ? fansub_sanitize_array($args['id']) : array();
}
if(!fansub_array_has_value($name)) {
_e('Please set name for this field.', 'fansub');
return;
}
$base_name = $name;
unset($args['class']);
if(!isset($args['value'])) {
$value = $this->get_by_key($name, fansub_get_value_by_key($args, 'default'));
if(is_array($value) && 'fansub_field_input' == $callback) {
$value = '';
}
$args['value'] = $value;
}
if('fansub_field_size' == $callback || 'fansub_field_input_size' == $callback) {
$tmp_name = $name;
$tmp_name[] = 'width';
$args['name_width'] = $this->get_field_name($tmp_name);
$args['id_width'] = $this->get_field_id($tmp_name);
$tmp_name = $name;
$tmp_name[] = 'height';
$args['name_height'] = $this->get_field_name($tmp_name);
$args['id_height'] = $this->get_field_id($tmp_name);
$tmp_sizes = $this->get_by_key($name, fansub_get_value_by_key($args, 'default'));
$sizes = array();
}
$args['name'] = $this->get_field_name($name);
$args['id'] = $this->get_field_id($name);
$options = isset($args['options']) ? $args['options'] : array();
if(fansub_array_has_value($options)) {
$tmp_options = array();
foreach($options as $option) {
$name = isset($option['name']) ? fansub_sanitize_array($option['name']) : array();
if(!fansub_array_has_value($name)) {
if(!empty($base_name)) {
$name = fansub_sanitize_array($base_name);
} else {
$name = isset($option['id']) ? fansub_sanitize_array($option['id']) : array();
}
}
if(!fansub_array_has_value($name)) {
continue;
}
if(!isset($option['value'])) {
$value = $this->get_by_key($name, fansub_get_value_by_key($option, 'default'));
if(is_array($value) && 'fansub_field_input' == $callback) {
$value = '';
}
$option['value'] = $value;
}
$option['name'] = $this->get_field_name($name);
$option['id'] = $this->get_field_id($name);
$tmp_options[] = $option;
}
$args['options'] = $tmp_options;
unset($tmp_options);
}
call_user_func($callback, $args);
} else {
_e('Please set a valid callback for this field.', 'fansub');
}
}
public function get() {
return get_option($this->get_option_name());
}
public function get_page_url() {
$url = '';
if($this->is_submenu() && strrpos($this->get_parent_slug(), '.php') !== false) {
$url .= $this->get_parent_slug();
} else {
$url .= 'admin.php';
}
$url .= '?page=' . $this->get_menu_slug();
return admin_url($url);
}
public function get_by_key($key, $default = '') {
$result = '';
$options = $this->get();
if(is_array($options)) {
$result = fansub_get_value_by_key($options, $key, $default);
} elseif('' != $options) {
$result = $options;
}
return $result;
}
public function get_field_name($field_name) {
return fansub_sanitize_field_name($this->get_option_name(), $field_name);
}
public function get_field_id($field_id) {
$id = $this->get_field_name($field_id);
$id = fansub_sanitize_id($id);
return $id;
}
private function get_section_by_id($id) {
$section = array();
$sections = $this->get_sections();
foreach($sections as $args) {
$section_id = isset($args['id']) ? $args['id'] : '';
if($id == $section_id) {
$section = $args;
break;
}
}
return $section;
}
public function default_section_callback($args) {
$id = isset($args['id']) ? $args['id'] : '';
$description = '';
if($id == $this->get_section_id()) {
$description = $this->get_section_description();
} else {
$section = $this->get_section_by_id($id);
$description = isset($section['description']) ? $section['description'] : '';
}
if(!empty($description)) {
$this->section_description($description);
}
}
public function is_submenu() {
$menu_parent = $this->get_parent_slug();
if(!empty($menu_parent) && 'admin.php' != $menu_parent) {
return true;
}
return false;
}
public function menu_init() {
if($this->is_submenu()) {
$this->add_submenu_page();
} else {
$this->add_menu_page();
}
}
public function add_menu_page() {
add_menu_page($this->get_page_title(), $this->get_menu_title(), $this->get_capability(), $this->get_menu_slug(), $this->get_function(), $this->get_icon_url(), $this->get_position());
}
public function add_submenu_page() {
add_submenu_page($this->get_parent_slug(), $this->get_page_title(), $this->get_menu_title(), $this->get_capability(), $this->get_menu_slug(), $this->get_function());
}
public function register_setting() {
register_setting($this->get_option_group(), $this->get_option_name(), $this->get_sanitize_callback());
}
public function add_settings_section($id, $title, $callback) {
if(!$this->section_exists($id)) {
add_settings_section($id, $title, $callback, $this->get_menu_slug());
}
}
public function section_exists($section) {
global $wp_settings_sections;
if(isset($wp_settings_sections[$this->get_menu_slug()][$section])) {
return true;
}
return false;
}
public function add_settings_section_default() {
$this->add_settings_section($this->get_section_id(), $this->get_section_title(), $this->get_section_callback());
}
public function add_section($args = array()) {
$this->sections[] = $args;
}
private function add_settings_field($id, $title, $callback, $section = 'default', $args = array()) {
if(!$this->field_exists($section, $id)) {
add_settings_field($id, $title, $callback, $this->get_menu_slug(), $section, $args);
}
}
public function field_exists($section, $field) {
global $wp_settings_fields;
if(isset($wp_settings_fields[$this->get_menu_slug()][$section][$field])) {
return true;
}
return false;
}
public function add_field($args = array()) {
$data_type = fansub_get_value_by_key($args, 'data_type', 'default');
$callback = fansub_get_value_by_key($args, 'field_callback');
if(fansub_callback_exists($callback)) {
if('fansub_field_input_checkbox' == $callback) {
$data_type = 'checkbox';
} elseif('fansub_field_color_picker' == $callback) {
$this->set_use_color_picker(true);
}
}
$args['data_type'] = $data_type;
$id = isset($args['id']) ? $args['id'] : '';
$name = isset($args['name']) ? $args['name'] : '';
$class = isset($args['class']) ? $args['class'] : '';
if(!isset($args['field_class'])) {
$args['field_class'] = $class;
}
fansub_transmit_id_and_name($id, $name);
$args['id'] = $id;
$args['name'] = $name;
$this->fields[] = $args;
}
public function do_settings_fields($section = 'default') {
do_settings_fields($this->get_menu_slug(), $section);
}
public function add_help_tab($args) {
$this->help_tabs[] = $args;
}
}