| 1 |
<?php |
| 2 |
/** |
| 3 |
* WordPress Settings Framework |
| 4 |
* |
| 5 |
* @link https://github.com/gilbitron/WordPress-Settings-Framework |
| 6 |
* @version 1.6.11 |
| 7 |
* |
| 8 |
* @package wordpress-settings-framework |
| 9 |
*/ |
| 10 |
|
| 11 |
if ( ! class_exists( 'Orderable_Settings_Framework' ) ) { |
| 12 |
/** |
| 13 |
* Orderable_Settings_Framework class |
| 14 |
*/ |
| 15 |
class Orderable_Settings_Framework { |
| 16 |
/** |
| 17 |
* Settings wrapper. |
| 18 |
* |
| 19 |
* @var array |
| 20 |
*/ |
| 21 |
private $settings_wrapper; |
| 22 |
|
| 23 |
/** |
| 24 |
* Settings. |
| 25 |
* |
| 26 |
* @var array |
| 27 |
*/ |
| 28 |
private $settings; |
| 29 |
|
| 30 |
/** |
| 31 |
* Tabs. |
| 32 |
* |
| 33 |
* @var array |
| 34 |
*/ |
| 35 |
private $tabs; |
| 36 |
|
| 37 |
/** |
| 38 |
* Option group. |
| 39 |
* |
| 40 |
* @var string |
| 41 |
*/ |
| 42 |
private $option_group; |
| 43 |
|
| 44 |
/** |
| 45 |
* Settings page. |
| 46 |
* |
| 47 |
* @var array |
| 48 |
*/ |
| 49 |
public $settings_page = array(); |
| 50 |
|
| 51 |
/** |
| 52 |
* Options path. |
| 53 |
* |
| 54 |
* @var string |
| 55 |
*/ |
| 56 |
private $options_path; |
| 57 |
|
| 58 |
/** |
| 59 |
* Options URL. |
| 60 |
* |
| 61 |
* @var string |
| 62 |
*/ |
| 63 |
private $options_url; |
| 64 |
|
| 65 |
/** |
| 66 |
* Setting defaults. |
| 67 |
* |
| 68 |
* @var array |
| 69 |
*/ |
| 70 |
protected $setting_defaults = array( |
| 71 |
'id' => 'default_field', |
| 72 |
'title' => 'Default Field', |
| 73 |
'desc' => '', |
| 74 |
'std' => '', |
| 75 |
'type' => 'text', |
| 76 |
'placeholder' => '', |
| 77 |
'choices' => array(), |
| 78 |
'class' => '', |
| 79 |
'subfields' => array(), |
| 80 |
'autocomplete' => '', |
| 81 |
'attributes' => array(), |
| 82 |
'custom_args' => array(), |
| 83 |
); |
| 84 |
|
| 85 |
/** |
| 86 |
* Orderable_Settings_Framework constructor. |
| 87 |
* |
| 88 |
* @param null|string $settings_file Path to a settings file, or null if you pass the option_group manually and construct your settings with a filter. |
| 89 |
* @param bool|string $option_group Option group name, usually a short slug. |
| 90 |
*/ |
| 91 |
public function __construct( $settings_file = null, $option_group = false ) { |
| 92 |
$this->option_group = $option_group; |
| 93 |
|
| 94 |
if ( $settings_file ) { |
| 95 |
if ( ! is_file( $settings_file ) ) { |
| 96 |
return; |
| 97 |
} |
| 98 |
|
| 99 |
require_once $settings_file; |
| 100 |
|
| 101 |
if ( ! $this->option_group ) { |
| 102 |
$this->option_group = preg_replace( '/[^a-z0-9]+/i', '', basename( $settings_file, '.php' ) ); |
| 103 |
} |
| 104 |
} |
| 105 |
|
| 106 |
if ( empty( $this->option_group ) ) { |
| 107 |
return; |
| 108 |
} |
| 109 |
|
| 110 |
$this->options_path = plugin_dir_path( __FILE__ ); |
| 111 |
$this->options_url = plugin_dir_url( __FILE__ ); |
| 112 |
|
| 113 |
$this->construct_settings(); |
| 114 |
|
| 115 |
if ( is_admin() ) { |
| 116 |
global $pagenow; |
| 117 |
|
| 118 |
add_action( 'admin_init', array( $this, 'admin_init' ) ); |
| 119 |
add_action( 'wpsf_do_settings_sections_' . $this->option_group, array( $this, 'do_tabless_settings_sections' ), 10 ); |
| 120 |
|
| 121 |
if ( filter_input( INPUT_GET, 'page' ) && filter_input( INPUT_GET, 'page' ) === $this->settings_page['slug'] ) { |
| 122 |
if ( 'options-general.php' !== $pagenow ) { |
| 123 |
add_action( 'admin_notices', array( $this, 'admin_notices' ) ); |
| 124 |
} |
| 125 |
add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) ); |
| 126 |
} |
| 127 |
|
| 128 |
if ( $this->has_tabs() ) { |
| 129 |
add_action( 'wpsf_before_settings_' . $this->option_group, array( $this, 'tab_links' ) ); |
| 130 |
|
| 131 |
remove_action( 'wpsf_do_settings_sections_' . $this->option_group, array( $this, 'do_tabless_settings_sections' ), 10 ); |
| 132 |
add_action( 'wpsf_do_settings_sections_' . $this->option_group, array( $this, 'do_tabbed_settings_sections' ), 10 ); |
| 133 |
} |
| 134 |
|
| 135 |
add_action( 'wp_ajax_wpsf_export_settings', array( $this, 'export_settings' ) ); |
| 136 |
add_action( 'wp_ajax_wpsf_import_settings', array( $this, 'import_settings' ) ); |
| 137 |
} |
| 138 |
} |
| 139 |
|
| 140 |
/** |
| 141 |
* Construct Settings. |
| 142 |
*/ |
| 143 |
public function construct_settings() { |
| 144 |
/** |
| 145 |
* Filter: modify settings for a given option group. |
| 146 |
* |
| 147 |
* @filter wpsf_register_settings_<option_group> |
| 148 |
* @since 1.6.9 |
| 149 |
* @param array |
| 150 |
*/ |
| 151 |
$this->settings_wrapper = apply_filters( 'wpsf_register_settings_' . $this->option_group, array() ); |
| 152 |
|
| 153 |
if ( ! is_array( $this->settings_wrapper ) ) { |
| 154 |
return new WP_Error( 'broke', esc_html__( 'WPSF settings must be an array', 'wpsf' ) ); |
| 155 |
} |
| 156 |
|
| 157 |
// If "sections" is set, this settings group probably has tabs. |
| 158 |
if ( isset( $this->settings_wrapper['sections'] ) ) { |
| 159 |
$this->tabs = ( isset( $this->settings_wrapper['tabs'] ) ) ? $this->settings_wrapper['tabs'] : array(); |
| 160 |
$this->settings = $this->settings_wrapper['sections']; |
| 161 |
// If not, it's probably just an array of settings. |
| 162 |
} else { |
| 163 |
$this->settings = $this->settings_wrapper; |
| 164 |
} |
| 165 |
|
| 166 |
$this->settings_page['slug'] = sprintf( '%s-settings', str_replace( '_', '-', $this->option_group ) ); |
| 167 |
} |
| 168 |
|
| 169 |
/** |
| 170 |
* Get the option group for this instance |
| 171 |
* |
| 172 |
* @return string the "option_group" |
| 173 |
*/ |
| 174 |
public function get_option_group() { |
| 175 |
return $this->option_group; |
| 176 |
} |
| 177 |
|
| 178 |
/** |
| 179 |
* Registers the internal WordPress settings |
| 180 |
*/ |
| 181 |
public function admin_init() { |
| 182 |
register_setting( $this->option_group, $this->option_group . '_settings', array( $this, 'settings_validate' ) ); |
| 183 |
$this->process_settings(); |
| 184 |
} |
| 185 |
|
| 186 |
/** |
| 187 |
* Add Settings Page |
| 188 |
* |
| 189 |
* @param array $args Settings page arguments. |
| 190 |
*/ |
| 191 |
public function add_settings_page( $args ) { |
| 192 |
if ( ! $this->settings_page ) { |
| 193 |
return; |
| 194 |
} |
| 195 |
|
| 196 |
$defaults = array( |
| 197 |
'parent_slug' => false, |
| 198 |
'page_slug' => '', |
| 199 |
'page_title' => '', |
| 200 |
'menu_title' => '', |
| 201 |
'capability' => 'manage_options', |
| 202 |
); |
| 203 |
|
| 204 |
$args = wp_parse_args( $args, $defaults ); |
| 205 |
|
| 206 |
$this->settings_page['title'] = $args['page_title']; |
| 207 |
$this->settings_page['capability'] = $args['capability']; |
| 208 |
|
| 209 |
if ( $args['parent_slug'] ) { |
| 210 |
add_submenu_page( |
| 211 |
$args['parent_slug'], |
| 212 |
$this->settings_page['title'], |
| 213 |
$args['menu_title'], |
| 214 |
$args['capability'], |
| 215 |
$this->settings_page['slug'], |
| 216 |
array( $this, 'settings_page_content' ) |
| 217 |
); |
| 218 |
} else { |
| 219 |
add_menu_page( |
| 220 |
$this->settings_page['title'], |
| 221 |
$args['menu_title'], |
| 222 |
$args['capability'], |
| 223 |
$this->settings_page['slug'], |
| 224 |
array( $this, 'settings_page_content' ), |
| 225 |
/** |
| 226 |
* Filter: modify icon URL for a given option group. |
| 227 |
* |
| 228 |
* @filter wpsf_menu_icon_url_<option_group> |
| 229 |
* @since 1.6.9 |
| 230 |
* @param string |
| 231 |
*/ |
| 232 |
apply_filters( 'wpsf_menu_icon_url_' . $this->option_group, '' ), |
| 233 |
/** |
| 234 |
* Filter: modify menu position for a given option group. |
| 235 |
* |
| 236 |
* @filter wpsf_menu_position_<option_group> |
| 237 |
* @since 1.6.9 |
| 238 |
* @param int|null |
| 239 |
*/ |
| 240 |
apply_filters( 'wpsf_menu_position_' . $this->option_group, null ) |
| 241 |
); |
| 242 |
} |
| 243 |
} |
| 244 |
|
| 245 |
/** |
| 246 |
* Settings Page Content |
| 247 |
*/ |
| 248 |
public function settings_page_content() { |
| 249 |
if ( ! current_user_can( $this->settings_page['capability'] ) ) { |
| 250 |
wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'wpsf' ) ); |
| 251 |
} |
| 252 |
?> |
| 253 |
<div class="wpsf-settings wpsf-settings--<?php echo esc_attr( $this->option_group ); ?>"> |
| 254 |
<?php $this->settings_header(); ?> |
| 255 |
<div class="wpsf-settings__content"> |
| 256 |
<?php $this->settings(); ?> |
| 257 |
</div> |
| 258 |
</div> |
| 259 |
<?php |
| 260 |
} |
| 261 |
|
| 262 |
/** |
| 263 |
* Settings Header. |
| 264 |
*/ |
| 265 |
public function settings_header() { |
| 266 |
?> |
| 267 |
<div class="wpsf-settings__header"> |
| 268 |
<h2> |
| 269 |
<?php |
| 270 |
global $allowedposttags; |
| 271 |
$protocols = wp_allowed_protocols(); |
| 272 |
$protocols[] = 'data'; |
| 273 |
|
| 274 |
echo wp_kses( |
| 275 |
/** |
| 276 |
* Filter: modify title for a given option group. |
| 277 |
* |
| 278 |
* @filter wpsf_title_<option_group> |
| 279 |
* @since 1.6.9 |
| 280 |
* @param string $title Title for the group settings header. |
| 281 |
*/ |
| 282 |
apply_filters( 'wpsf_title_' . $this->option_group, $this->settings_page['title'] ), |
| 283 |
$allowedposttags, |
| 284 |
$protocols |
| 285 |
); |
| 286 |
?> |
| 287 |
</h2> |
| 288 |
<?php |
| 289 |
/** |
| 290 |
* Hook: execute a callback after the option group title. |
| 291 |
* |
| 292 |
* @hook wpsf_after_title_<option_group> |
| 293 |
* @since 1.6.9 |
| 294 |
*/ |
| 295 |
do_action( 'wpsf_after_title_' . $this->option_group ); |
| 296 |
?> |
| 297 |
</div> |
| 298 |
<?php |
| 299 |
} |
| 300 |
|
| 301 |
/** |
| 302 |
* Displays any errors from the WordPress settings API |
| 303 |
*/ |
| 304 |
public function admin_notices() { |
| 305 |
settings_errors(); |
| 306 |
} |
| 307 |
|
| 308 |
/** |
| 309 |
* Enqueue scripts and styles |
| 310 |
*/ |
| 311 |
public function admin_enqueue_scripts() { |
| 312 |
// Scripts. |
| 313 |
$jqtimepicker_js_path = 'assets/vendor/jquery-timepicker/jquery.ui.timepicker.js'; |
| 314 |
wp_register_script( |
| 315 |
'jquery-ui-timepicker', |
| 316 |
$this->options_url . $jqtimepicker_js_path, |
| 317 |
array( 'jquery', 'jquery-ui-core' ), |
| 318 |
filemtime( $this->options_path . $jqtimepicker_js_path ), |
| 319 |
true |
| 320 |
); |
| 321 |
|
| 322 |
$wpsf_js_path = 'assets/js/main.js'; |
| 323 |
wp_register_script( |
| 324 |
'wpsf', |
| 325 |
$this->options_url . $wpsf_js_path, |
| 326 |
array( 'jquery' ), |
| 327 |
filemtime( $this->options_path . $wpsf_js_path ), |
| 328 |
true |
| 329 |
); |
| 330 |
|
| 331 |
wp_enqueue_script( 'jquery' ); |
| 332 |
wp_enqueue_script( 'farbtastic' ); |
| 333 |
wp_enqueue_media(); |
| 334 |
wp_enqueue_script( 'media-upload' ); |
| 335 |
wp_enqueue_script( 'thickbox' ); |
| 336 |
wp_enqueue_script( 'jquery-ui-core' ); |
| 337 |
wp_enqueue_script( 'jquery-ui-datepicker' ); |
| 338 |
wp_enqueue_script( 'jquery-ui-timepicker' ); |
| 339 |
wp_enqueue_script( 'wpsf' ); |
| 340 |
|
| 341 |
$data = array( |
| 342 |
'select_file' => esc_html__( 'Please select a file to import', 'wpsf' ), |
| 343 |
'invalid_file' => esc_html__( 'Invalid file', 'wpsf' ), |
| 344 |
'something_went_wrong' => esc_html__( 'Something went wrong', 'wpsf' ), |
| 345 |
); |
| 346 |
wp_localize_script( 'wpsf', 'wpsf_vars', $data ); |
| 347 |
|
| 348 |
// Styles. |
| 349 |
$jqtimepicker_css_path = 'assets/vendor/jquery-timepicker/jquery.ui.timepicker.css'; |
| 350 |
wp_register_style( |
| 351 |
'jquery-ui-timepicker', |
| 352 |
$this->options_url . $jqtimepicker_css_path, |
| 353 |
array(), |
| 354 |
filemtime( $this->options_path . $jqtimepicker_css_path ) |
| 355 |
); |
| 356 |
|
| 357 |
$wpsf_css_path = 'assets/css/main.css'; |
| 358 |
wp_register_style( |
| 359 |
'wpsf', |
| 360 |
$this->options_url . $wpsf_css_path, |
| 361 |
array(), |
| 362 |
filemtime( $this->options_path . $wpsf_css_path ) |
| 363 |
); |
| 364 |
|
| 365 |
$jqui_css_path = 'assets/vendor/jquery-ui/jquery-ui.css'; |
| 366 |
wp_register_style( |
| 367 |
'jquery-ui-css', |
| 368 |
$this->options_url . $jqui_css_path, |
| 369 |
array(), |
| 370 |
filemtime( $this->options_path . $jqui_css_path ) |
| 371 |
); |
| 372 |
|
| 373 |
wp_enqueue_style( 'farbtastic' ); |
| 374 |
wp_enqueue_style( 'thickbox' ); |
| 375 |
wp_enqueue_style( 'jquery-ui-timepicker' ); |
| 376 |
wp_enqueue_style( 'jquery-ui-css' ); |
| 377 |
wp_enqueue_style( 'wpsf' ); |
| 378 |
|
| 379 |
// Dequeue global style inlined by WordPress since WP 5.9. |
| 380 |
wp_dequeue_style( 'global-styles' ); |
| 381 |
} |
| 382 |
|
| 383 |
/** |
| 384 |
* Adds a filter for settings validation. |
| 385 |
* |
| 386 |
* @param mixed $input Input data. |
| 387 |
* |
| 388 |
* @return array |
| 389 |
*/ |
| 390 |
public function settings_validate( $input ) { |
| 391 |
/** |
| 392 |
* Filter: validate field input for a given option group. |
| 393 |
* |
| 394 |
* @filter <option_group>_settings_validate |
| 395 |
* @since 1.6.9 |
| 396 |
* @param mixed |
| 397 |
*/ |
| 398 |
return apply_filters( $this->option_group . '_settings_validate', $input ); |
| 399 |
} |
| 400 |
|
| 401 |
/** |
| 402 |
* Displays the "section_description" if specified in $this->settings |
| 403 |
* |
| 404 |
* @param array $args callback args from add_settings_section(). |
| 405 |
*/ |
| 406 |
public function section_intro( $args ) { |
| 407 |
if ( ! empty( $this->settings ) ) { |
| 408 |
foreach ( $this->settings as $section ) { |
| 409 |
if ( $section['section_id'] === $args['id'] ) { |
| 410 |
$render_class = ''; |
| 411 |
|
| 412 |
$render_class .= self::add_show_hide_classes( $section ); |
| 413 |
|
| 414 |
if ( $render_class ) { |
| 415 |
echo '<span class="' . esc_attr( $render_class ) . '"></span>'; |
| 416 |
} |
| 417 |
if ( isset( $section['section_description'] ) && $section['section_description'] ) { |
| 418 |
echo '<div class="wpsf-section-description wpsf-section-description--' . esc_attr( $section['section_id'] ) . '">' . wp_kses_post( $section['section_description'] ) . '</div>'; |
| 419 |
} |
| 420 |
break; |
| 421 |
} |
| 422 |
} |
| 423 |
} |
| 424 |
} |
| 425 |
|
| 426 |
/** |
| 427 |
* Processes $this->settings and adds the sections and fields via the WordPress settings API |
| 428 |
*/ |
| 429 |
private function process_settings() { |
| 430 |
if ( ! empty( $this->settings ) ) { |
| 431 |
usort( $this->settings, array( $this, 'sort_array' ) ); |
| 432 |
|
| 433 |
foreach ( $this->settings as $section ) { |
| 434 |
if ( isset( $section['section_id'] ) && $section['section_id'] && isset( $section['section_title'] ) ) { |
| 435 |
$page_name = ( $this->has_tabs() ) ? sprintf( '%s_%s', $this->option_group, $section['tab_id'] ) : $this->option_group; |
| 436 |
|
| 437 |
add_settings_section( $section['section_id'], $section['section_title'], array( $this, 'section_intro' ), $page_name ); |
| 438 |
|
| 439 |
if ( isset( $section['fields'] ) && is_array( $section['fields'] ) && ! empty( $section['fields'] ) ) { |
| 440 |
foreach ( $section['fields'] as $field ) { |
| 441 |
if ( isset( $field['id'] ) && $field['id'] && isset( $field['title'] ) ) { |
| 442 |
$tooltip = ''; |
| 443 |
|
| 444 |
if ( isset( $field['link'] ) && is_array( $field['link'] ) ) { |
| 445 |
$link_url = ( isset( $field['link']['url'] ) ) ? esc_html( $field['link']['url'] ) : ''; |
| 446 |
$link_text = ( isset( $field['link']['text'] ) ) ? esc_html( $field['link']['text'] ) : esc_html__( 'Learn More', 'wpsf' ); |
| 447 |
$link_external = ( isset( $field['link']['external'] ) ) ? (bool) $field['link']['external'] : true; |
| 448 |
$link_type = ( isset( $field['link']['type'] ) ) ? esc_attr( $field['link']['type'] ) : 'tooltip'; |
| 449 |
$link_target = ( $link_external ) ? ' target="_blank"' : ''; |
| 450 |
|
| 451 |
if ( 'tooltip' === $link_type ) { |
| 452 |
$link_text = sprintf( '<i class="dashicons dashicons-info wpsf-link-icon" title="%s"><span class="screen-reader-text">%s</span></i>', $link_text, $link_text ); |
| 453 |
} |
| 454 |
|
| 455 |
$link = ( $link_url ) ? sprintf( '<a class="wpsf-label__link" href="%s"%s>%s</a>', $link_url, $link_target, $link_text ) : ''; |
| 456 |
|
| 457 |
if ( $link && 'tooltip' === $link_type ) { |
| 458 |
$tooltip = $link; |
| 459 |
} elseif ( $link ) { |
| 460 |
$field['subtitle'] .= ( empty( $field['subtitle'] ) ) ? $link : sprintf( '<br/><br/>%s', $link ); |
| 461 |
} |
| 462 |
} |
| 463 |
|
| 464 |
$title = sprintf( '<span class="wpsf-label">%s %s</span>', $field['title'], $tooltip ); |
| 465 |
|
| 466 |
if ( ! empty( $field['subtitle'] ) ) { |
| 467 |
$title .= sprintf( '<span class="wpsf-subtitle">%s</span>', $field['subtitle'] ); |
| 468 |
} |
| 469 |
|
| 470 |
add_settings_field( |
| 471 |
$field['id'], |
| 472 |
$title, |
| 473 |
array( $this, 'generate_setting' ), |
| 474 |
$page_name, |
| 475 |
$section['section_id'], |
| 476 |
array( |
| 477 |
'section' => $section, |
| 478 |
'field' => $field, |
| 479 |
) |
| 480 |
); |
| 481 |
} |
| 482 |
} |
| 483 |
} |
| 484 |
} |
| 485 |
} |
| 486 |
} |
| 487 |
} |
| 488 |
|
| 489 |
/** |
| 490 |
* Usort callback. Sorts $this->settings by "section_order" |
| 491 |
* |
| 492 |
* @param array $a Sortable Array. |
| 493 |
* @param array $b Sortable Array. |
| 494 |
* |
| 495 |
* @return array |
| 496 |
*/ |
| 497 |
public function sort_array( $a, $b ) { |
| 498 |
if ( ! isset( $a['section_order'] ) ) { |
| 499 |
return 0; |
| 500 |
} |
| 501 |
|
| 502 |
return ( $a['section_order'] > $b['section_order'] ) ? 1 : 0; |
| 503 |
} |
| 504 |
|
| 505 |
/** |
| 506 |
* Generates the HTML output of the settings fields |
| 507 |
* |
| 508 |
* @param array $args callback args from add_settings_field(). |
| 509 |
*/ |
| 510 |
public function generate_setting( $args ) { |
| 511 |
$section = $args['section']; |
| 512 |
/** |
| 513 |
* Filter: filter the default setting values for a given option group. |
| 514 |
* |
| 515 |
* @filter wpsf_defaults_<option_group> |
| 516 |
* @since 1.6.9 |
| 517 |
* @param mixed $setting_defaults Default values for settings. |
| 518 |
*/ |
| 519 |
$this->setting_defaults = apply_filters( 'wpsf_defaults_' . $this->option_group, $this->setting_defaults ); |
| 520 |
|
| 521 |
$args = wp_parse_args( $args['field'], $this->setting_defaults ); |
| 522 |
|
| 523 |
$options = get_option( $this->option_group . '_settings' ); |
| 524 |
|
| 525 |
$args['id'] = ( $this->has_tabs() ) ? sprintf( '%s_%s_%s', $section['tab_id'], $section['section_id'], $args['id'] ) : sprintf( '%s_%s', $section['section_id'], $args['id'] ); |
| 526 |
$field_name = isset( $args['name'] ) ? $args['name'] : $args['id']; |
| 527 |
$args['name'] = $this->generate_field_name( $field_name ); |
| 528 |
$args['value'] = ( isset( $options[ $field_name ] ) ) ? $options[ $field_name ] : ( isset( $args['default'] ) ? $args['default'] : '' ); |
| 529 |
|
| 530 |
$args['class'] .= self::add_show_hide_classes( $args ); |
| 531 |
|
| 532 |
/** |
| 533 |
* Hook: execute callback before a given group. |
| 534 |
* |
| 535 |
* @hook wpsf_before_field_<option_group> |
| 536 |
* @since 1.6.9 |
| 537 |
*/ |
| 538 |
do_action( 'wpsf_before_field_' . $this->option_group ); |
| 539 |
|
| 540 |
/** |
| 541 |
* Hook: execute callback before a specific field in a given group. |
| 542 |
* |
| 543 |
* @hook wpsf_before_field_<option_group>_<field_id> |
| 544 |
* @since 1.6.9 |
| 545 |
*/ |
| 546 |
do_action( 'wpsf_before_field_' . $this->option_group . '_' . $args['id'] ); |
| 547 |
|
| 548 |
$this->do_field_method( $args ); |
| 549 |
|
| 550 |
/** |
| 551 |
* Hook: execute callback after a given group. |
| 552 |
* |
| 553 |
* @hook wpsf_after_field_<option_group> |
| 554 |
* @since 1.6.9 |
| 555 |
*/ |
| 556 |
do_action( 'wpsf_after_field_' . $this->option_group ); |
| 557 |
|
| 558 |
/** |
| 559 |
* Hook: execute callback after a specific field in a given group. |
| 560 |
* |
| 561 |
* @hook wpsf_after_field_<option_group>_<field_id> |
| 562 |
* @since 1.6.9 |
| 563 |
*/ |
| 564 |
do_action( 'wpsf_after_field_' . $this->option_group . '_' . $args['id'] ); |
| 565 |
} |
| 566 |
|
| 567 |
/** |
| 568 |
* Do field method, if it exists |
| 569 |
* |
| 570 |
* @param array $args Field arguments. |
| 571 |
*/ |
| 572 |
public function do_field_method( $args ) { |
| 573 |
$generate_field_method = sprintf( 'generate_%s_field', $args['type'] ); |
| 574 |
|
| 575 |
if ( method_exists( $this, $generate_field_method ) ) { |
| 576 |
$this->$generate_field_method( $args ); |
| 577 |
} |
| 578 |
} |
| 579 |
|
| 580 |
/** |
| 581 |
* Generate: Text field |
| 582 |
* |
| 583 |
* @param array $args Field arguments. |
| 584 |
*/ |
| 585 |
public function generate_text_field( $args ) { |
| 586 |
$args['value'] = esc_attr( stripslashes( $args['value'] ) ); |
| 587 |
|
| 588 |
echo '<input type="text" name="' . esc_attr( $args['name'] ) . '" id="' . esc_attr( $args['id'] ) . '" value="' . esc_attr( $args['value'] ) . '" placeholder="' . esc_attr( $args['placeholder'] ) . '" class="regular-text ' . esc_attr( $args['class'] ) . '" ' . $this->array_to_html_atts( $args['attributes'] ) . '/>'; |
| 589 |
|
| 590 |
$this->generate_description( $args ); |
| 591 |
} |
| 592 |
|
| 593 |
/** |
| 594 |
* Generate: Hidden field. |
| 595 |
* |
| 596 |
* @param array $args Field arguments. |
| 597 |
*/ |
| 598 |
public function generate_hidden_field( $args ) { |
| 599 |
$args['value'] = esc_attr( stripslashes( $args['value'] ) ); |
| 600 |
|
| 601 |
echo '<input type="hidden" name="' . esc_attr( $args['name'] ) . '" id="' . esc_attr( $args['id'] ) . '" value="' . esc_attr( $args['value'] ) . '" class="hidden-field ' . esc_attr( $args['class'] ) . '" ' . $this->array_to_html_atts( $args['attributes'] ) . '/>'; |
| 602 |
} |
| 603 |
|
| 604 |
/** |
| 605 |
* Generate: Number field |
| 606 |
* |
| 607 |
* @param array $args Field arguments. |
| 608 |
*/ |
| 609 |
public function generate_number_field( $args ) { |
| 610 |
$args['value'] = esc_attr( stripslashes( $args['value'] ) ); |
| 611 |
|
| 612 |
echo '<input type="number" name="' . esc_attr( $args['name'] ) . '" id="' . esc_attr( $args['id'] ) . '" value="' . esc_attr( $args['value'] ) . '" placeholder="' . esc_attr( $args['placeholder'] ) . '" class="regular-text ' . esc_attr( $args['class'] ) . '" ' . $this->array_to_html_atts( $args['attributes'] ) . '/>'; |
| 613 |
|
| 614 |
$this->generate_description( $args ); |
| 615 |
} |
| 616 |
|
| 617 |
/** |
| 618 |
* Generate: Time field |
| 619 |
* |
| 620 |
* @param array $args Field arguments. |
| 621 |
*/ |
| 622 |
public function generate_time_field( $args ) { |
| 623 |
$args['value'] = esc_attr( stripslashes( $args['value'] ) ); |
| 624 |
|
| 625 |
$timepicker = ( ! empty( $args['timepicker'] ) ) ? htmlentities( wp_json_encode( $args['timepicker'] ) ) : null; |
| 626 |
|
| 627 |
echo '<input type="text" name="' . esc_attr( $args['name'] ) . '" id="' . esc_attr( $args['id'] ) . '" value="' . esc_attr( $args['value'] ) . '" class="timepicker regular-text ' . esc_attr( $args['class'] ) . '" data-timepicker="' . esc_attr( $timepicker ) . '" ' . $this->array_to_html_atts( $args['attributes'] ) . '/>'; |
| 628 |
|
| 629 |
$this->generate_description( $args ); |
| 630 |
} |
| 631 |
|
| 632 |
/** |
| 633 |
* Generate: Date field |
| 634 |
* |
| 635 |
* @param array $args Field arguments. |
| 636 |
*/ |
| 637 |
public function generate_date_field( $args ) { |
| 638 |
$args['value'] = esc_attr( stripslashes( $args['value'] ) ); |
| 639 |
|
| 640 |
$datepicker = ( ! empty( $args['datepicker'] ) ) ? htmlentities( wp_json_encode( $args['datepicker'] ) ) : null; |
| 641 |
|
| 642 |
echo '<input type="text" name="' . esc_attr( $args['name'] ) . '" id="' . esc_attr( $args['id'] ) . '" value="' . esc_attr( $args['value'] ) . '" class="datepicker regular-text ' . esc_attr( $args['class'] ) . '" data-datepicker="' . esc_attr( $datepicker ) . '" ' . $this->array_to_html_atts( $args['attributes'] ) . '/>'; |
| 643 |
|
| 644 |
$this->generate_description( $args ); |
| 645 |
} |
| 646 |
|
| 647 |
/** |
| 648 |
* Generate Export Field. |
| 649 |
* |
| 650 |
* @param array $args Field arguments. |
| 651 |
*/ |
| 652 |
public function generate_export_field( $args ) { |
| 653 |
$args['value'] = esc_attr( stripslashes( $args['value'] ) ); |
| 654 |
$args['value'] = empty( $args['value'] ) ? esc_html__( 'Export Settings', 'wpsf' ) : $args['value']; |
| 655 |
$option_group = $this->option_group; |
| 656 |
$export_url = site_url() . '/wp-admin/admin-ajax.php?action=wpsf_export_settings&_wpnonce=' . wp_create_nonce( 'wpsf_export_settings' ) . '&option_group=' . $option_group; |
| 657 |
|
| 658 |
echo '<a target=_blank href="' . esc_url( $export_url ) . '" class="button" name="' . esc_attr( $args['name'] ) . '" id="' . esc_attr( $args['id'] ) . '">' . esc_html( $args['value'] ) . '</a>'; |
| 659 |
|
| 660 |
$options = get_option( $option_group . '_settings' ); |
| 661 |
$this->generate_description( $args ); |
| 662 |
} |
| 663 |
|
| 664 |
/** |
| 665 |
* Generate Import Field. |
| 666 |
* |
| 667 |
* @param array $args Field rguments. |
| 668 |
*/ |
| 669 |
public function generate_import_field( $args ) { |
| 670 |
$args['value'] = esc_attr( stripslashes( $args['value'] ) ); |
| 671 |
$args['value'] = empty( $args['value'] ) ? esc_html__( 'Import Settings', 'wpsf' ) : $args['value']; |
| 672 |
$option_group = $this->option_group; |
| 673 |
|
| 674 |
echo sprintf( |
| 675 |
' |
| 676 |
<div class="wpsf-import"> |
| 677 |
<div class="wpsf-import__false_btn"> |
| 678 |
<input type="file" name="wpsf-import-field" class="wpsf-import__file_field" id="%s" accept=".json"/> |
| 679 |
<button type="button" name="wpsf_import_button" class="button wpsf-import__button" id="%s">%s</button> |
| 680 |
<input type="hidden" class="wpsf_import_nonce" value="%s"></input> |
| 681 |
<input type="hidden" class="wpsf_import_option_group" value="%s"></input> |
| 682 |
</div> |
| 683 |
<span class="spinner"></span> |
| 684 |
</div>', |
| 685 |
esc_attr( $args['id'] ), |
| 686 |
esc_attr( $args['id'] ), |
| 687 |
esc_attr( $args['value'] ), |
| 688 |
esc_attr( wp_create_nonce( 'wpsf_import_settings' ) ), |
| 689 |
esc_attr( $this->option_group ) |
| 690 |
); |
| 691 |
|
| 692 |
$this->generate_description( $args ); |
| 693 |
} |
| 694 |
|
| 695 |
/** |
| 696 |
* Generate: Group field |
| 697 |
* |
| 698 |
* Generates a table of subfields, and a javascript template for create new repeatable rows |
| 699 |
* |
| 700 |
* @param array $args Field arguments. |
| 701 |
*/ |
| 702 |
public function generate_group_field( $args ) { |
| 703 |
$value = (array) $args['value']; |
| 704 |
$row_count = ( ! empty( $value ) ) ? count( $value ) : 1; |
| 705 |
|
| 706 |
echo '<table id="group-' . esc_attr( str_replace( '_', '-', $args['id'] ) ) . '" class="' . esc_attr( $args['class'] ) . ' widefat wpsf-group" cellspacing="0">'; |
| 707 |
|
| 708 |
echo '<tbody>'; |
| 709 |
|
| 710 |
for ( $row = 0; $row < $row_count; $row ++ ) { |
| 711 |
// @codingStandardsIgnoreStart |
| 712 |
echo $this->generate_group_row_template( $args, false, $row ); |
| 713 |
// @codingStandardsIgnoreEnd |
| 714 |
} |
| 715 |
|
| 716 |
echo '</tbody>'; |
| 717 |
|
| 718 |
echo '</table>'; |
| 719 |
|
| 720 |
$this->generate_description( $args ); |
| 721 |
|
| 722 |
printf( |
| 723 |
'<script type="text/html" id="%s_template">%s</script>', |
| 724 |
esc_attr( $args['id'] ), |
| 725 |
// @codingStandardsIgnoreStart |
| 726 |
$this->generate_group_row_template( $args, true ) |
| 727 |
// @codingStandardsIgnoreEnd |
| 728 |
); |
| 729 |
|
| 730 |
$this->generate_description( $args ); |
| 731 |
} |
| 732 |
|
| 733 |
|
| 734 |
/** |
| 735 |
* Generate Image Checkboxes. |
| 736 |
* |
| 737 |
* @param array $args Field arguments. |
| 738 |
* |
| 739 |
* @return void |
| 740 |
*/ |
| 741 |
public function generate_image_checkboxes_field( $args ) { |
| 742 |
|
| 743 |
echo '<input type="hidden" name="' . esc_attr( $args['name'] ) . '" value="0" />'; |
| 744 |
|
| 745 |
echo '<ul class="wpsf-visual-field wpsf-visual-field--image-checkboxes wpsf-visual-field--grid wpsf-visual-field--cols">'; |
| 746 |
|
| 747 |
foreach ( $args['choices'] as $value => $choice ) { |
| 748 |
$field_id = sprintf( '%s_%s', $args['id'], $value ); |
| 749 |
$is_checked = is_array( $args['value'] ) && in_array( $value, $args['value'], true ); |
| 750 |
$checked_class = $is_checked ? 'wpsf-visual-field__item--checked' : ''; |
| 751 |
|
| 752 |
echo sprintf( |
| 753 |
'<li class="wpsf-visual-field__item %s"> |
| 754 |
<label> |
| 755 |
<div class="wpsf-visual-field-image-radio__img_wrap"> |
| 756 |
<img src="%s"> |
| 757 |
</div> |
| 758 |
<div class="wpsf-visual-field__item-footer"> |
| 759 |
<input type="checkbox" name="%s[]" id="%s" value="%s" class="%s" %s> |
| 760 |
<span class="wpsf-visual-field__item-text">%s</span> |
| 761 |
</div> |
| 762 |
</label> |
| 763 |
</li>', |
| 764 |
esc_attr( $checked_class ), |
| 765 |
esc_url( $choice['image'] ), |
| 766 |
esc_attr( $args['name'] ), |
| 767 |
esc_attr( $field_id ), |
| 768 |
esc_attr( $value ), |
| 769 |
esc_attr( $args['class'] ), |
| 770 |
checked( true, $is_checked, false ), |
| 771 |
esc_attr( $choice['text'] ) |
| 772 |
); |
| 773 |
} |
| 774 |
|
| 775 |
echo '</ul>'; |
| 776 |
|
| 777 |
$this->generate_description( $args ); |
| 778 |
} |
| 779 |
|
| 780 |
/** |
| 781 |
* Generate: Image Radio field |
| 782 |
* |
| 783 |
* @param array $args Field arguments. |
| 784 |
*/ |
| 785 |
public function generate_image_radio_field( $args ) { |
| 786 |
$args['value'] = esc_html( esc_attr( $args['value'] ) ); |
| 787 |
$count = count( $args['choices'] ); |
| 788 |
|
| 789 |
echo sprintf( '<ul class="wpsf-visual-field wpsf-visual-field--image-radio wpsf-visual-field--grid wpsf-visual-field--cols wpsf-visual-field--col-%s ">', esc_attr( $count ) ); |
| 790 |
|
| 791 |
foreach ( $args['choices'] as $value => $choice ) { |
| 792 |
$field_id = sprintf( '%s_%s', $args['id'], $value ); |
| 793 |
$checked = $value === $args['value'] ? 'checked="checked"' : ''; |
| 794 |
|
| 795 |
echo sprintf( |
| 796 |
'<li class="wpsf-visual-field__item %s"> |
| 797 |
<label> |
| 798 |
<div class="wpsf-visual-field-image-radio__img_wrap"> |
| 799 |
<img src="%s"> |
| 800 |
</div> |
| 801 |
<div class="wpsf-visual-field__item-footer"> |
| 802 |
<input type="radio" name="%s" id="%s" value="%s" class="%s" %s> |
| 803 |
<span class="wpsf-visual-field__item-text">%s</span> |
| 804 |
</div> |
| 805 |
</label> |
| 806 |
</li>', |
| 807 |
( $checked ? 'wpsf-visual-field__item--checked' : '' ), |
| 808 |
esc_attr( $choice['image'] ), |
| 809 |
esc_attr( $args['name'] ), |
| 810 |
esc_attr( $field_id ), |
| 811 |
esc_attr( $value ), |
| 812 |
esc_attr( $args['class'] ), |
| 813 |
esc_html( $checked ), |
| 814 |
esc_attr( $choice['text'] ) |
| 815 |
); |
| 816 |
} |
| 817 |
echo '</ul>'; |
| 818 |
|
| 819 |
$this->generate_description( $args ); |
| 820 |
} |
| 821 |
|
| 822 |
/** |
| 823 |
* Generate group row template |
| 824 |
* |
| 825 |
* @param array $args Field arguments. |
| 826 |
* @param bool $blank Blank values. |
| 827 |
* @param int $row Iterator. |
| 828 |
* |
| 829 |
* @return string|bool |
| 830 |
*/ |
| 831 |
public function generate_group_row_template( $args, $blank = false, $row = 0 ) { |
| 832 |
$row_template = false; |
| 833 |
$row_id = ( ! empty( $args['value'][ $row ]['row_id'] ) ) ? $args['value'][ $row ]['row_id'] : $row; |
| 834 |
$row_id_value = ( $blank ) ? '' : $row_id; |
| 835 |
|
| 836 |
if ( $args['subfields'] ) { |
| 837 |
$row_class = ( 0 === $row % 2 ) ? 'alternate' : ''; |
| 838 |
|
| 839 |
$row_template .= sprintf( '<tr class="wpsf-group__row %s">', $row_class ); |
| 840 |
|
| 841 |
$row_template .= sprintf( '<td class="wpsf-group__row-index"><span>%d</span></td>', $row ); |
| 842 |
|
| 843 |
$row_template .= '<td class="wpsf-group__row-fields">'; |
| 844 |
|
| 845 |
$row_template .= '<input type="hidden" class="wpsf-group__row-id" name="' . sprintf( '%s[%d][row_id]', esc_attr( $args['name'] ), esc_attr( $row ) ) . '" value="' . esc_attr( $row_id_value ) . '" />'; |
| 846 |
|
| 847 |
foreach ( $args['subfields'] as $subfield ) { |
| 848 |
$subfield = wp_parse_args( $subfield, $this->setting_defaults ); |
| 849 |
|
| 850 |
$subfield['value'] = ( $blank ) ? '' : ( isset( $args['value'][ $row ][ $subfield['id'] ] ) ? $args['value'][ $row ][ $subfield['id'] ] : '' ); |
| 851 |
$subfield['name'] = sprintf( '%s[%d][%s]', $args['name'], $row, $subfield['id'] ); |
| 852 |
$subfield['id'] = sprintf( '%s_%d_%s', $args['id'], $row, $subfield['id'] ); |
| 853 |
|
| 854 |
$class = sprintf( 'wpsf-group__field-wrapper--%s', $subfield['type'] ); |
| 855 |
|
| 856 |
$row_template .= sprintf( '<div class="wpsf-group__field-wrapper %s">', $class ); |
| 857 |
$row_template .= sprintf( '<label for="%s" class="wpsf-group__field-label">%s</label>', $subfield['id'], $subfield['title'] ); |
| 858 |
|
| 859 |
ob_start(); |
| 860 |
$this->do_field_method( $subfield ); |
| 861 |
$row_template .= ob_get_clean(); |
| 862 |
|
| 863 |
$row_template .= '</div>'; |
| 864 |
} |
| 865 |
|
| 866 |
$row_template .= '</td>'; |
| 867 |
|
| 868 |
$row_template .= '<td class="wpsf-group__row-actions">'; |
| 869 |
|
| 870 |
$row_template .= sprintf( '<a href="javascript: void(0);" class="wpsf-group__row-add" data-template="%s_template"><span class="dashicons dashicons-plus-alt"></span></a>', $args['id'] ); |
| 871 |
$row_template .= '<a href="javascript: void(0);" class="wpsf-group__row-remove"><span class="dashicons dashicons-trash"></span></a>'; |
| 872 |
|
| 873 |
$row_template .= '</td>'; |
| 874 |
|
| 875 |
$row_template .= '</tr>'; |
| 876 |
} |
| 877 |
|
| 878 |
return $row_template; |
| 879 |
} |
| 880 |
|
| 881 |
/** |
| 882 |
* Generate: Select field |
| 883 |
* |
| 884 |
* @param array $args Field rguments. |
| 885 |
*/ |
| 886 |
public function generate_select_field( $args ) { |
| 887 |
$is_multiple = isset( $args['multiple'] ) && filter_var( $args['multiple'], FILTER_VALIDATE_BOOLEAN ); |
| 888 |
$multiple = $is_multiple ? ' multiple="true" ' : ' '; |
| 889 |
|
| 890 |
if ( $is_multiple ) { |
| 891 |
$args['name'] .= '[]'; |
| 892 |
} |
| 893 |
|
| 894 |
$values = (array) $args['value']; |
| 895 |
$values = array_map( 'strval', $values ); |
| 896 |
|
| 897 |
echo '<select ' . esc_html( $multiple ) . ' name="' . esc_attr( $args['name'] ) . '" id="' . esc_attr( $args['id'] ) . '" class="' . esc_attr( $args['class'] ) . '" ' . $this->array_to_html_atts( $args['attributes'] ) . '>'; |
| 898 |
|
| 899 |
foreach ( $args['choices'] as $value => $text ) { |
| 900 |
if ( is_array( $text ) ) { |
| 901 |
echo sprintf( '<optgroup label="%s">', esc_html( $value ) ); |
| 902 |
foreach ( $text as $group_value => $group_text ) { |
| 903 |
$selected = in_array( (string) $group_value, $values, true ) ? ' selected="selected" ' : ''; |
| 904 |
echo sprintf( '<option value="%s" %s>%s</option>', esc_attr( $group_value ), esc_html( $selected ), esc_html( $group_text ) ); |
| 905 |
} |
| 906 |
echo '</optgroup>'; |
| 907 |
continue; |
| 908 |
} |
| 909 |
|
| 910 |
$selected = in_array( (string) $value, $values, true ) ? ' selected="selected" ' : ''; |
| 911 |
echo sprintf( '<option value="%s" %s>%s</option>', esc_attr( $value ), esc_html( $selected ), esc_html( $text ) ); |
| 912 |
} |
| 913 |
|
| 914 |
echo '</select>'; |
| 915 |
|
| 916 |
$this->generate_description( $args ); |
| 917 |
} |
| 918 |
|
| 919 |
/** |
| 920 |
* Generate: Password field |
| 921 |
* |
| 922 |
* @param array $args Field arguments. |
| 923 |
*/ |
| 924 |
public function generate_password_field( $args ) { |
| 925 |
$args['value'] = esc_attr( stripslashes( $args['value'] ) ); |
| 926 |
|
| 927 |
echo '<input type="password" name="' . esc_attr( $args['name'] ) . '" id="' . esc_attr( $args['id'] ) . '" value="' . esc_attr( $args['value'] ) . '" placeholder="' . esc_attr( $args['placeholder'] ) . '" class="regular-text ' . esc_attr( $args['class'] ) . '" autocomplete="' . esc_attr( $args['autocomplete'] ) . '" ' . $this->array_to_html_atts( $args['attributes'] ) . '/>'; |
| 928 |
|
| 929 |
$this->generate_description( $args ); |
| 930 |
} |
| 931 |
|
| 932 |
/** |
| 933 |
* Generate: Textarea field |
| 934 |
* |
| 935 |
* @param array $args Field arguments. |
| 936 |
*/ |
| 937 |
public function generate_textarea_field( $args ) { |
| 938 |
$args['value'] = esc_html( esc_attr( $args['value'] ) ); |
| 939 |
$rows = ( ! empty( $args['attributes']['rows'] ) ) ? absint( $args['attributes']['rows'] ) : 5; |
| 940 |
$cols = ( ! empty( $args['attributes']['cols'] ) ) ? absint( $args['attributes']['cols'] ) : 60; |
| 941 |
|
| 942 |
echo '<textarea name="' . esc_attr( $args['name'] ) . '" id="' . esc_attr( $args['id'] ) . '" placeholder="' . esc_attr( $args['placeholder'] ) . '" rows="' . esc_attr( $rows ) . '" cols="' . esc_attr( $cols ) . '" class="' . esc_attr( $args['class'] ) . '" ' . $this->array_to_html_atts( $args['attributes'] ) . '>' . esc_html( $args['value'] ) . '</textarea>'; |
| 943 |
|
| 944 |
$this->generate_description( $args ); |
| 945 |
} |
| 946 |
|
| 947 |
/** |
| 948 |
* Generate: Radio field |
| 949 |
* |
| 950 |
* @param array $args Field arguments. |
| 951 |
*/ |
| 952 |
public function generate_radio_field( $args ) { |
| 953 |
$args['value'] = esc_html( esc_attr( $args['value'] ) ); |
| 954 |
|
| 955 |
foreach ( $args['choices'] as $value => $text ) { |
| 956 |
$field_id = sprintf( '%s_%s', $args['id'], $value ); |
| 957 |
$checked = ( $value === $args['value'] ) ? 'checked="checked"' : ''; |
| 958 |
|
| 959 |
echo sprintf( '<label><input type="radio" name="%s" id="%s" value="%s" class="%s" %s> %s</label><br />', esc_attr( $args['name'] ), esc_attr( $field_id ), esc_html( $value ), esc_attr( $args['class'] ), esc_html( $checked ), esc_html( $text ) ); |
| 960 |
} |
| 961 |
|
| 962 |
$this->generate_description( $args ); |
| 963 |
} |
| 964 |
|
| 965 |
/** |
| 966 |
* Generate: Checkbox field |
| 967 |
* |
| 968 |
* @param array $args Field arguments. |
| 969 |
*/ |
| 970 |
public function generate_checkbox_field( $args ) { |
| 971 |
$args['value'] = esc_attr( stripslashes( $args['value'] ) ); |
| 972 |
$checked = ( $args['value'] ) ? 'checked="checked"' : ''; |
| 973 |
|
| 974 |
echo '<input type="hidden" name="' . esc_attr( $args['name'] ) . '" value="0" />'; |
| 975 |
echo '<label><input type="checkbox" name="' . esc_attr( $args['name'] ) . '" id="' . esc_attr( $args['id'] ) . '" value="1" class="' . esc_attr( $args['class'] ) . '" ' . esc_html( $checked ) . '> ' . esc_attr( $args['desc'] ) . '</label>'; |
| 976 |
} |
| 977 |
|
| 978 |
/** |
| 979 |
* Generate: Toggle field |
| 980 |
* |
| 981 |
* @param array $args Field arguments. |
| 982 |
*/ |
| 983 |
public function generate_toggle_field( $args ) { |
| 984 |
$args['value'] = esc_attr( stripslashes( $args['value'] ) ); |
| 985 |
$checked = ( $args['value'] ) ? 'checked="checked"' : ''; |
| 986 |
|
| 987 |
echo '<input type="hidden" name="' . esc_attr( $args['name'] ) . '" value="0" />'; |
| 988 |
echo '<label class="switch"><input type="checkbox" name="' . esc_attr( $args['name'] ) . '" id="' . esc_attr( $args['id'] ) . '" value="1" class="' . esc_attr( $args['class'] ) . '" ' . esc_html( $checked ) . '> ' . esc_html( $args['desc'] ) . '<span class="slider"></span></label>'; |
| 989 |
} |
| 990 |
|
| 991 |
/** |
| 992 |
* Generate: Checkboxes field |
| 993 |
* |
| 994 |
* @param array $args Field arguments. |
| 995 |
*/ |
| 996 |
public function generate_checkboxes_field( $args ) { |
| 997 |
echo '<input type="hidden" name="' . esc_attr( $args['name'] ) . '" value="0" />'; |
| 998 |
|
| 999 |
echo '<ul class="wpsf-list wpsf-list--checkboxes">'; |
| 1000 |
|
| 1001 |
foreach ( $args['choices'] as $value => $text ) { |
| 1002 |
$checked = ( is_array( $args['value'] ) && in_array( strval( $value ), array_map( 'strval', $args['value'] ), true ) ) ? 'checked="checked"' : ''; |
| 1003 |
$field_id = sprintf( '%s_%s', $args['id'], $value ); |
| 1004 |
|
| 1005 |
echo sprintf( '<li><label><input type="checkbox" name="%s[]" id="%s" value="%s" class="%s" %s> %s</label></li>', esc_attr( $args['name'] ), esc_attr( $field_id ), esc_html( $value ), esc_attr( $args['class'] ), esc_html( $checked ), esc_html( $text ) ); |
| 1006 |
} |
| 1007 |
|
| 1008 |
echo '</ul>'; |
| 1009 |
|
| 1010 |
$this->generate_description( $args ); |
| 1011 |
} |
| 1012 |
|
| 1013 |
/** |
| 1014 |
* Generate: Color field |
| 1015 |
* |
| 1016 |
* @param array $args Field arguments. |
| 1017 |
*/ |
| 1018 |
public function generate_color_field( $args ) { |
| 1019 |
$color_picker_id = sprintf( '%s_cp', $args['id'] ); |
| 1020 |
$args['value'] = esc_attr( stripslashes( $args['value'] ) ); |
| 1021 |
|
| 1022 |
echo '<div style="position:relative;">'; |
| 1023 |
|
| 1024 |
echo sprintf( '<input type="text" name="%s" id="%s" value="%s" class="%s">', esc_attr( $args['name'] ), esc_attr( $args['id'] ), esc_attr( $args['value'] ), esc_attr( $args['class'] ) ); |
| 1025 |
|
| 1026 |
echo sprintf( '<div id="%s" style="position:absolute;top:0;left:190px;background:#fff;z-index:9999;"></div>', esc_attr( $color_picker_id ) ); |
| 1027 |
|
| 1028 |
$this->generate_description( $args ); |
| 1029 |
|
| 1030 |
echo '<script type="text/javascript"> |
| 1031 |
jQuery(document).ready(function($){ |
| 1032 |
var colorPicker = $("#' . esc_attr( $color_picker_id ) . '"); |
| 1033 |
colorPicker.farbtastic("#' . esc_attr( $args['id'] ) . '"); |
| 1034 |
colorPicker.hide(); |
| 1035 |
$("#' . esc_attr( $args['id'] ) . '").on("focus", function(){ |
| 1036 |
colorPicker.show(); |
| 1037 |
}); |
| 1038 |
$("#' . esc_attr( $args['id'] ) . '").on("blur", function(){ |
| 1039 |
colorPicker.hide(); |
| 1040 |
if($(this).val() == "") $(this).val("#"); |
| 1041 |
}); |
| 1042 |
}); |
| 1043 |
</script>'; |
| 1044 |
|
| 1045 |
echo '</div>'; |
| 1046 |
} |
| 1047 |
|
| 1048 |
/** |
| 1049 |
* Generate: File field |
| 1050 |
* |
| 1051 |
* @param array $args Field arguments. |
| 1052 |
*/ |
| 1053 |
public function generate_file_field( $args ) { |
| 1054 |
$args['value'] = esc_attr( $args['value'] ); |
| 1055 |
$button_id = sprintf( '%s_button', $args['id'] ); |
| 1056 |
|
| 1057 |
/** |
| 1058 |
* Hook in to generate a file preview e.g. image thumbnail. |
| 1059 |
*/ |
| 1060 |
do_action( 'wpsf_file_field_preview', $args['value'], $args ); |
| 1061 |
|
| 1062 |
echo sprintf( '<input type="text" name="%s" id="%s" value="%s" class="regular-text %s"> ', esc_attr( $args['name'] ), esc_attr( $args['id'] ), esc_html( $args['value'] ), esc_attr( $args['class'] ) ); |
| 1063 |
|
| 1064 |
echo sprintf( '<input type="button" class="button wpsf-browse" id="%s" value="%s" />', esc_attr( $button_id ), esc_html__( 'Browse', 'wpsf' ) ); |
| 1065 |
|
| 1066 |
$this->generate_description( $args ); |
| 1067 |
?> |
| 1068 |
<script type='text/javascript'> |
| 1069 |
jQuery( document ).ready( function( $ ) { |
| 1070 |
|
| 1071 |
// Uploading files |
| 1072 |
var file_frame; |
| 1073 |
var wp_media_post_id = wp.media.model.settings.post.id; // Store the old id. |
| 1074 |
var set_to_post_id = 0; |
| 1075 |
|
| 1076 |
jQuery( document.body ).on('click', '#<?php echo esc_attr( $button_id ); ?>', function( event ){ |
| 1077 |
|
| 1078 |
event.preventDefault(); |
| 1079 |
|
| 1080 |
// If the media frame already exists, reopen it. |
| 1081 |
if ( file_frame ) { |
| 1082 |
// Set the post ID to what we want |
| 1083 |
file_frame.uploader.uploader.param( 'post_id', set_to_post_id ); |
| 1084 |
// Open frame |
| 1085 |
file_frame.open(); |
| 1086 |
return; |
| 1087 |
} else { |
| 1088 |
// Set the wp.media post id so the uploader grabs the ID we want when initialised. |
| 1089 |
wp.media.model.settings.post.id = set_to_post_id; |
| 1090 |
} |
| 1091 |
|
| 1092 |
// Create the media frame. |
| 1093 |
file_frame = wp.media.frames.file_frame = wp.media({ |
| 1094 |
title: '<?php echo esc_html__( 'Select a image to upload', 'wpsf' ); ?>', |
| 1095 |
button: { |
| 1096 |
text: '<?php echo esc_html__( 'Use this image', 'wpsf' ); ?>', |
| 1097 |
}, |
| 1098 |
multiple: false // Set to true to allow multiple files to be selected |
| 1099 |
}); |
| 1100 |
|
| 1101 |
// When an image is selected, run a callback. |
| 1102 |
file_frame.on( 'select', function() { |
| 1103 |
// We set multiple to false so only get one image from the uploader |
| 1104 |
attachment = file_frame.state().get('selection').first().toJSON(); |
| 1105 |
|
| 1106 |
// Do something with attachment.id and/or attachment.url here |
| 1107 |
$( '#image-preview' ).attr( 'src', attachment.url ).css( 'width', 'auto' ); |
| 1108 |
$( '#image_attachment_id' ).val( attachment.id ); |
| 1109 |
$( '#<?php echo esc_attr( $args['id'] ); ?>' ).val( attachment.url ); |
| 1110 |
|
| 1111 |
// Restore the main post ID |
| 1112 |
wp.media.model.settings.post.id = wp_media_post_id; |
| 1113 |
}); |
| 1114 |
|
| 1115 |
// Finally, open the modal |
| 1116 |
file_frame.open(); |
| 1117 |
}); |
| 1118 |
|
| 1119 |
// Restore the main ID when the add media button is pressed |
| 1120 |
jQuery( 'a.add_media' ).on( 'click', function() { |
| 1121 |
wp.media.model.settings.post.id = wp_media_post_id; |
| 1122 |
}); |
| 1123 |
}); |
| 1124 |
</script> |
| 1125 |
<?php |
| 1126 |
} |
| 1127 |
|
| 1128 |
/** |
| 1129 |
* Generate: Editor field |
| 1130 |
* |
| 1131 |
* @param array $args Field arguments. |
| 1132 |
*/ |
| 1133 |
public function generate_editor_field( $args ) { |
| 1134 |
$settings = ( isset( $args['editor_settings'] ) && is_array( $args['editor_settings'] ) ) ? $args['editor_settings'] : array(); |
| 1135 |
$settings['textarea_name'] = $args['name']; |
| 1136 |
|
| 1137 |
wp_editor( $args['value'], $args['id'], $settings ); |
| 1138 |
|
| 1139 |
$this->generate_description( $args ); |
| 1140 |
} |
| 1141 |
|
| 1142 |
/** |
| 1143 |
* Generate: Code editor field |
| 1144 |
* |
| 1145 |
* @param array $args Field arguments. |
| 1146 |
*/ |
| 1147 |
public function generate_code_editor_field( $args ) { |
| 1148 |
printf( |
| 1149 |
'<textarea |
| 1150 |
name="%s" |
| 1151 |
id="%s" |
| 1152 |
placeholder="%s" |
| 1153 |
rows="5" |
| 1154 |
cols="60" |
| 1155 |
class="%s" |
| 1156 |
>%s</textarea>', |
| 1157 |
esc_attr( $args['name'] ), |
| 1158 |
esc_attr( $args['id'] ), |
| 1159 |
esc_attr( $args['placeholder'] ), |
| 1160 |
esc_attr( $args['class'] ), |
| 1161 |
esc_html( $args['value'] ) |
| 1162 |
); |
| 1163 |
|
| 1164 |
$settings = wp_enqueue_code_editor( array( 'type' => esc_attr( $args['mimetype'] ) ) ); |
| 1165 |
|
| 1166 |
wp_add_inline_script( |
| 1167 |
'code-editor', |
| 1168 |
sprintf( |
| 1169 |
'jQuery( function() { wp.codeEditor.initialize( "%s", %s ); } );', |
| 1170 |
esc_attr( $args['id'] ), |
| 1171 |
wp_json_encode( $settings ) |
| 1172 |
) |
| 1173 |
); |
| 1174 |
|
| 1175 |
$this->generate_description( $args ); |
| 1176 |
} |
| 1177 |
|
| 1178 |
/** |
| 1179 |
* Generate: Custom field |
| 1180 |
* |
| 1181 |
* @param array $args Field arguments. |
| 1182 |
*/ |
| 1183 |
public function generate_custom_field( $args ) { |
| 1184 |
if ( isset( $args['output'] ) && is_callable( $args['output'] ) ) { |
| 1185 |
call_user_func( $args['output'], $args ); |
| 1186 |
return; |
| 1187 |
} |
| 1188 |
|
| 1189 |
// @codingStandardsIgnoreStart |
| 1190 |
echo ( isset( $args['output'] ) ) ? $args['output'] : $args['default']; // This output isn't easily escaped. |
| 1191 |
// @codingStandardsIgnoreEnd |
| 1192 |
} |
| 1193 |
|
| 1194 |
/** |
| 1195 |
* Generate: Multi Inputs field |
| 1196 |
* |
| 1197 |
* @param array $args Field arguments. |
| 1198 |
*/ |
| 1199 |
public function generate_multiinputs_field( $args ) { |
| 1200 |
$field_titles = array_keys( $args['default'] ); |
| 1201 |
$values = array_values( $args['value'] ); |
| 1202 |
|
| 1203 |
echo '<div class="wpsf-multifields">'; |
| 1204 |
|
| 1205 |
$i = 0; |
| 1206 |
$c = count( $values ); |
| 1207 |
while ( $i < $c ) : |
| 1208 |
|
| 1209 |
$field_id = sprintf( '%s_%s', $args['id'], $i ); |
| 1210 |
$value = esc_attr( stripslashes( $values[ $i ] ) ); |
| 1211 |
|
| 1212 |
echo '<div class="wpsf-multifields__field">'; |
| 1213 |
echo '<input type="text" name="' . esc_attr( $args['name'] ) . '[]" id="' . esc_attr( $field_id ) . '" value="' . esc_attr( $value ) . '" class="regular-text ' . esc_attr( $args['class'] ) . '" placeholder="' . esc_attr( $args['placeholder'] ) . '" />'; |
| 1214 |
echo '<br><span>' . esc_html( $field_titles[ $i ] ) . '</span>'; |
| 1215 |
echo '</div>'; |
| 1216 |
|
| 1217 |
$i ++; |
| 1218 |
endwhile; |
| 1219 |
|
| 1220 |
echo '</div>'; |
| 1221 |
|
| 1222 |
$this->generate_description( $args ); |
| 1223 |
} |
| 1224 |
|
| 1225 |
/** |
| 1226 |
* Generate: Field ID |
| 1227 |
* |
| 1228 |
* @param mixed $id Field ID. |
| 1229 |
* |
| 1230 |
* @return string |
| 1231 |
*/ |
| 1232 |
public function generate_field_name( $id ) { |
| 1233 |
return sprintf( '%s_settings[%s]', $this->option_group, $id ); |
| 1234 |
} |
| 1235 |
|
| 1236 |
/** |
| 1237 |
* Generate: Description |
| 1238 |
* |
| 1239 |
* @param mixed $description Field description. |
| 1240 |
*/ |
| 1241 |
public function generate_description( $args ) { |
| 1242 |
$classes = 'wpsf-description'; |
| 1243 |
$description = ( ! empty( $args['desc'] ) ) ? $args['desc'] : false; |
| 1244 |
$descriptions = array(); |
| 1245 |
|
| 1246 |
// Add the main description. |
| 1247 |
if ( $description ) { |
| 1248 |
$descriptions[] = array( |
| 1249 |
'classes' => $classes, |
| 1250 |
// Serialize group field data to prevent errors. |
| 1251 |
'value' => ( is_array( $args['value'] ) ) ? serialize( $args['value'] ) : $args['value'], |
| 1252 |
'description' => $description, |
| 1253 |
); |
| 1254 |
} |
| 1255 |
|
| 1256 |
// Output any conditional descriptions that exist. |
| 1257 |
if ( 'select' === $args['type'] && ! empty( $args['conditional_desc'] ) && is_array( $args['conditional_desc'] ) ) { |
| 1258 |
|
| 1259 |
foreach ( $args['conditional_desc'] as $value => $conditional_description ) { |
| 1260 |
|
| 1261 |
if ( $conditional_description ) { |
| 1262 |
// Add a class to hide descriptions for other values. |
| 1263 |
if ( $args['value'] !== $value ) { |
| 1264 |
$classes .= ' wpsf-hide-description'; |
| 1265 |
} |
| 1266 |
|
| 1267 |
$descriptions[] = array( |
| 1268 |
'classes' => $classes, |
| 1269 |
'value' => $value, |
| 1270 |
'description' => $conditional_description, |
| 1271 |
); |
| 1272 |
} |
| 1273 |
} |
| 1274 |
} |
| 1275 |
|
| 1276 |
// Output all descriptions. |
| 1277 |
foreach ( $descriptions as $description_data ) { |
| 1278 |
printf( |
| 1279 |
'<p class="%s" data-value="%s">%s</p>', |
| 1280 |
esc_attr( $description_data['classes'] ), |
| 1281 |
esc_attr( $description_data['value'] ), |
| 1282 |
wp_kses_post( $description_data['description'] ) |
| 1283 |
); |
| 1284 |
} |
| 1285 |
} |
| 1286 |
|
| 1287 |
/** |
| 1288 |
* Output the settings form |
| 1289 |
*/ |
| 1290 |
public function settings() { |
| 1291 |
/** |
| 1292 |
* Hook: execute callback before the settings form for a given group. |
| 1293 |
* |
| 1294 |
* @hook wpsf_before_settings_<option_group> |
| 1295 |
* @since 1.6.9 |
| 1296 |
*/ |
| 1297 |
do_action( 'wpsf_before_settings_' . $this->option_group ); |
| 1298 |
?> |
| 1299 |
<form action="options.php" method="post" novalidate enctype="multipart/form-data"> |
| 1300 |
<?php |
| 1301 |
/** |
| 1302 |
* Hook: execute callback before the settings fields for a given group. |
| 1303 |
* |
| 1304 |
* @hook wpsf_before_settings_fields_<option_group> |
| 1305 |
* @since 1.6.9 |
| 1306 |
*/ |
| 1307 |
do_action( 'wpsf_before_settings_fields_' . $this->option_group ); |
| 1308 |
?> |
| 1309 |
<?php settings_fields( $this->option_group ); ?> |
| 1310 |
|
| 1311 |
<?php |
| 1312 |
/** |
| 1313 |
* Hook: execute callback to output the settings sections for a given group. |
| 1314 |
* |
| 1315 |
* @hook wpsf_do_settings_sections_<option_group> |
| 1316 |
* @since 1.6.9 |
| 1317 |
*/ |
| 1318 |
do_action( 'wpsf_do_settings_sections_' . $this->option_group ); |
| 1319 |
?> |
| 1320 |
|
| 1321 |
<?php |
| 1322 |
/** |
| 1323 |
* Filter: control whether the save changes button should be visible or not for a given option group. |
| 1324 |
* |
| 1325 |
* @filter wpsf_show_save_changes_button_<option_group> |
| 1326 |
* @since 1.6.9 |
| 1327 |
* @param boolean |
| 1328 |
*/ |
| 1329 |
if ( apply_filters( 'wpsf_show_save_changes_button_' . $this->option_group, true ) ) { |
| 1330 |
?> |
| 1331 |
<p class="submit"> |
| 1332 |
<input type="submit" class="button-primary" value="<?php esc_attr_e( 'Save Changes' ); ?>" /> |
| 1333 |
</p> |
| 1334 |
<?php } ?> |
| 1335 |
</form> |
| 1336 |
<?php |
| 1337 |
/** |
| 1338 |
* Hook: execute callback after the settings form for a given group. |
| 1339 |
* |
| 1340 |
* @hook wpsf_after_settings_<option_group> |
| 1341 |
* @since 1.6.9 |
| 1342 |
*/ |
| 1343 |
do_action( 'wpsf_after_settings_' . $this->option_group ); |
| 1344 |
} |
| 1345 |
|
| 1346 |
/** |
| 1347 |
* Helper: Get Settings |
| 1348 |
* |
| 1349 |
* @return array |
| 1350 |
*/ |
| 1351 |
public function get_settings() { |
| 1352 |
$settings_name = $this->option_group . '_settings'; |
| 1353 |
|
| 1354 |
static $settings = array(); |
| 1355 |
|
| 1356 |
if ( isset( $settings[ $settings_name ] ) ) { |
| 1357 |
return $settings[ $settings_name ]; |
| 1358 |
} |
| 1359 |
|
| 1360 |
$saved_settings = get_option( $this->option_group . '_settings' ); |
| 1361 |
$settings[ $settings_name ] = array(); |
| 1362 |
|
| 1363 |
if ( ! $this->settings ) { |
| 1364 |
return $settings[ $settings_name ]; |
| 1365 |
} |
| 1366 |
|
| 1367 |
foreach ( $this->settings as $section ) { |
| 1368 |
if ( empty( $section['fields'] ) ) { |
| 1369 |
continue; |
| 1370 |
} |
| 1371 |
|
| 1372 |
foreach ( $section['fields'] as $field ) { |
| 1373 |
if ( ! empty( $field['default'] ) && is_array( $field['default'] ) ) { |
| 1374 |
$field['default'] = array_values( $field['default'] ); |
| 1375 |
} |
| 1376 |
|
| 1377 |
// If a field name override has been provided, use it. |
| 1378 |
if ( ! empty( $field['name'] ) ) { |
| 1379 |
$setting_key = $field['name']; |
| 1380 |
} else { |
| 1381 |
$setting_key = ( $this->has_tabs() ) ? sprintf( '%s_%s_%s', $section['tab_id'], $section['section_id'], $field['id'] ) : sprintf( '%s_%s', $section['section_id'], $field['id'] ); |
| 1382 |
} |
| 1383 |
|
| 1384 |
if ( isset( $saved_settings[ $setting_key ] ) ) { |
| 1385 |
$settings[ $settings_name ][ $setting_key ] = $saved_settings[ $setting_key ]; |
| 1386 |
} else { |
| 1387 |
$settings[ $settings_name ][ $setting_key ] = ( isset( $field['default'] ) ) ? $field['default'] : false; |
| 1388 |
} |
| 1389 |
} |
| 1390 |
} |
| 1391 |
|
| 1392 |
return $settings[ $settings_name ]; |
| 1393 |
} |
| 1394 |
|
| 1395 |
/** |
| 1396 |
* Tabless Settings sections |
| 1397 |
*/ |
| 1398 |
public function do_tabless_settings_sections() { |
| 1399 |
?> |
| 1400 |
<div class="wpsf-section wpsf-tabless"> |
| 1401 |
<?php do_settings_sections( $this->option_group ); ?> |
| 1402 |
</div> |
| 1403 |
<?php |
| 1404 |
} |
| 1405 |
|
| 1406 |
/** |
| 1407 |
* Tabbed Settings sections |
| 1408 |
*/ |
| 1409 |
public function do_tabbed_settings_sections() { |
| 1410 |
$i = 0; |
| 1411 |
foreach ( $this->tabs as $tab_data ) { |
| 1412 |
?> |
| 1413 |
<div id="tab-<?php echo esc_attr( $tab_data['id'] ); ?>" class="wpsf-section wpsf-tab wpsf-tab--<?php echo esc_attr( $tab_data['id'] ); ?> <?php |
| 1414 |
if ( 0 === $i ) { |
| 1415 |
echo 'wpsf-tab--active'; |
| 1416 |
} |
| 1417 |
?> |
| 1418 |
"> |
| 1419 |
<div class="postbox"> |
| 1420 |
<?php do_settings_sections( sprintf( '%s_%s', $this->option_group, $tab_data['id'] ) ); ?> |
| 1421 |
</div> |
| 1422 |
</div> |
| 1423 |
<?php |
| 1424 |
$i ++; |
| 1425 |
} |
| 1426 |
} |
| 1427 |
|
| 1428 |
/** |
| 1429 |
* Output the tab links |
| 1430 |
*/ |
| 1431 |
public function tab_links() { |
| 1432 |
/** |
| 1433 |
* Filter: control whether the tab links should be visible or not for a given option group. |
| 1434 |
* |
| 1435 |
* @filter wpsf_show_tab_links_<option_group> |
| 1436 |
* @since 1.6.9 |
| 1437 |
* @param boolean |
| 1438 |
*/ |
| 1439 |
if ( ! apply_filters( 'wpsf_show_tab_links_' . $this->option_group, true ) ) { |
| 1440 |
return; |
| 1441 |
} |
| 1442 |
|
| 1443 |
/** |
| 1444 |
* Hook: execute callback before the tab links for a given option group. |
| 1445 |
* |
| 1446 |
* @hook wpsf_before_tab_links_<option_group> |
| 1447 |
* @since 1.6.9 |
| 1448 |
*/ |
| 1449 |
do_action( 'wpsf_before_tab_links_' . $this->option_group ); |
| 1450 |
?> |
| 1451 |
<ul class="wpsf-nav"> |
| 1452 |
<?php |
| 1453 |
$i = 0; |
| 1454 |
foreach ( $this->tabs as $tab_data ) { |
| 1455 |
if ( ! $this->tab_has_settings( $tab_data['id'] ) ) { |
| 1456 |
continue; |
| 1457 |
} |
| 1458 |
|
| 1459 |
if ( ! isset( $tab_data['class'] ) ) { |
| 1460 |
$tab_data['class'] = ''; |
| 1461 |
} |
| 1462 |
|
| 1463 |
$tab_data['class'] .= self::add_show_hide_classes( $tab_data ); |
| 1464 |
|
| 1465 |
$active = ( 0 === $i ) ? 'wpsf-nav__item--active' : ''; |
| 1466 |
?> |
| 1467 |
<li class="wpsf-nav__item <?php echo esc_attr( $active ); ?>"> |
| 1468 |
<a class="wpsf-nav__item-link <?php echo esc_attr( $tab_data['class'] ); ?>" href="#tab-<?php echo esc_attr( $tab_data['id'] ); ?>"><?php echo wp_kses_post( $tab_data['title'] ); ?></a> |
| 1469 |
</li> |
| 1470 |
<?php |
| 1471 |
$i ++; |
| 1472 |
} |
| 1473 |
?> |
| 1474 |
<li class="wpsf-nav__item wpsf-nav__item--last"> |
| 1475 |
<input type="submit" class="button-primary wpsf-button-submit" value="<?php esc_attr_e( 'Save Changes' ); ?>"> |
| 1476 |
</li> |
| 1477 |
</ul> |
| 1478 |
|
| 1479 |
<?php // Add this here so notices are moved. ?> |
| 1480 |
<div class="wrap wpsf-notices"><h2> </h2></div> |
| 1481 |
<?php |
| 1482 |
/** |
| 1483 |
* Hook: execute callback after the tab links for a given option group. |
| 1484 |
* |
| 1485 |
* @hook wpsf_after_tab_links_<option_group> |
| 1486 |
* @since 1.6.9 |
| 1487 |
*/ |
| 1488 |
do_action( 'wpsf_after_tab_links_' . $this->option_group ); |
| 1489 |
} |
| 1490 |
|
| 1491 |
/** |
| 1492 |
* Does this tab have settings? |
| 1493 |
* |
| 1494 |
* @param string $tab_id Tab ID. |
| 1495 |
* |
| 1496 |
* @return bool |
| 1497 |
*/ |
| 1498 |
public function tab_has_settings( $tab_id ) { |
| 1499 |
if ( empty( $this->settings ) ) { |
| 1500 |
return false; |
| 1501 |
} |
| 1502 |
|
| 1503 |
foreach ( $this->settings as $settings_section ) { |
| 1504 |
if ( $tab_id !== $settings_section['tab_id'] ) { |
| 1505 |
continue; |
| 1506 |
} |
| 1507 |
|
| 1508 |
return true; |
| 1509 |
} |
| 1510 |
|
| 1511 |
return false; |
| 1512 |
} |
| 1513 |
|
| 1514 |
/** |
| 1515 |
* Check if this settings instance has tabs |
| 1516 |
*/ |
| 1517 |
public function has_tabs() { |
| 1518 |
if ( ! empty( $this->tabs ) ) { |
| 1519 |
return true; |
| 1520 |
} |
| 1521 |
|
| 1522 |
return false; |
| 1523 |
} |
| 1524 |
|
| 1525 |
/** |
| 1526 |
* Add Show Hide Classes. |
| 1527 |
* |
| 1528 |
* @param array $args Field arguments. |
| 1529 |
* @param string $type Type. |
| 1530 |
*/ |
| 1531 |
public static function add_show_hide_classes( $args, $type = 'show_if' ) { |
| 1532 |
$class = ''; |
| 1533 |
$slug = ' ' . str_replace( '_', '-', $type ); |
| 1534 |
if ( isset( $args[ $type ] ) && is_array( $args[ $type ] ) ) { |
| 1535 |
$class .= $slug; |
| 1536 |
foreach ( $args[ $type ] as $condition ) { |
| 1537 |
if ( isset( $condition['field'] ) && $condition['value'] ) { |
| 1538 |
$value_string = ''; |
| 1539 |
foreach ( $condition['value'] as $value ) { |
| 1540 |
if ( ! empty( $value_string ) ) { |
| 1541 |
$value_string .= '||'; |
| 1542 |
} |
| 1543 |
$value_string .= $value; |
| 1544 |
} |
| 1545 |
|
| 1546 |
if ( ! empty( $value_string ) ) { |
| 1547 |
$class .= $slug . '--' . $condition['field'] . '===' . $value_string; |
| 1548 |
} |
| 1549 |
} else { |
| 1550 |
$and_string = ''; |
| 1551 |
foreach ( $condition as $and_condition ) { |
| 1552 |
if ( ! isset( $and_condition['field'] ) || ! isset( $and_condition['value'] ) ) { |
| 1553 |
continue; |
| 1554 |
} |
| 1555 |
|
| 1556 |
if ( ! empty( $and_string ) ) { |
| 1557 |
$and_string .= '&&'; |
| 1558 |
} |
| 1559 |
|
| 1560 |
$value_string = ''; |
| 1561 |
foreach ( $and_condition['value'] as $value ) { |
| 1562 |
if ( ! empty( $value_string ) ) { |
| 1563 |
$value_string .= '||'; |
| 1564 |
} |
| 1565 |
$value_string .= $value; |
| 1566 |
} |
| 1567 |
|
| 1568 |
if ( ! empty( $value_string ) ) { |
| 1569 |
$and_string .= $and_condition['field'] . '===' . $value_string; |
| 1570 |
} |
| 1571 |
} |
| 1572 |
|
| 1573 |
if ( ! empty( $and_string ) ) { |
| 1574 |
$class .= $slug . '--' . $and_string; |
| 1575 |
} |
| 1576 |
} |
| 1577 |
} |
| 1578 |
} |
| 1579 |
|
| 1580 |
// Run the function again with hide if. |
| 1581 |
if ( 'hide_if' !== $type ) { |
| 1582 |
$class .= self::add_show_hide_classes( $args, 'hide_if' ); |
| 1583 |
} |
| 1584 |
|
| 1585 |
return $class; |
| 1586 |
} |
| 1587 |
|
| 1588 |
/** |
| 1589 |
* Handle export settings action. |
| 1590 |
*/ |
| 1591 |
public static function export_settings() { |
| 1592 |
$_wpnonce = filter_input( INPUT_GET, '_wpnonce' ); |
| 1593 |
$option_group = filter_input( INPUT_GET, 'option_group' ); |
| 1594 |
|
| 1595 |
if ( empty( $_wpnonce ) || ! wp_verify_nonce( $_wpnonce, 'wpsf_export_settings' ) ) { |
| 1596 |
wp_die( esc_html__( 'Action failed.', 'wpsf' ) ); |
| 1597 |
} |
| 1598 |
|
| 1599 |
if ( empty( $option_group ) ) { |
| 1600 |
wp_die( esc_html__( 'No option group specified.', 'wpsf' ) ); |
| 1601 |
} |
| 1602 |
|
| 1603 |
$options = get_option( $option_group . '_settings' ); |
| 1604 |
|
| 1605 |
header( 'Content-Disposition: attachment; filename=wpsf-settings-' . $option_group . '.json' ); |
| 1606 |
|
| 1607 |
wp_send_json( $options ); |
| 1608 |
} |
| 1609 |
|
| 1610 |
/** |
| 1611 |
* Import settings. |
| 1612 |
*/ |
| 1613 |
public function import_settings() { |
| 1614 |
$_wpnonce = filter_input( INPUT_POST, '_wpnonce' ); |
| 1615 |
$option_group = filter_input( INPUT_POST, 'option_group' ); |
| 1616 |
$settings = filter_input( INPUT_POST, 'settings' ); |
| 1617 |
|
| 1618 |
if ( $option_group !== $this->option_group ) { |
| 1619 |
return; |
| 1620 |
} |
| 1621 |
|
| 1622 |
// verify nonce. |
| 1623 |
if ( empty( $_wpnonce ) || ! wp_verify_nonce( $_wpnonce, 'wpsf_import_settings' ) ) { |
| 1624 |
wp_send_json_error(); |
| 1625 |
} |
| 1626 |
|
| 1627 |
// check if $settings is a valid json. |
| 1628 |
if ( ! is_string( $settings ) || ! is_array( json_decode( $settings, true ) ) ) { |
| 1629 |
wp_send_json_error(); |
| 1630 |
} |
| 1631 |
|
| 1632 |
$settings_data = json_decode( $settings, true ); |
| 1633 |
update_option( $option_group . '_settings', $settings_data ); |
| 1634 |
|
| 1635 |
wp_send_json_success(); |
| 1636 |
} |
| 1637 |
|
| 1638 |
/** |
| 1639 |
* Helper: Array to HTML Attributes |
| 1640 |
*/ |
| 1641 |
public static function array_to_html_atts( $array = array() ) { |
| 1642 |
if ( ! is_array( $array ) || empty( $array ) ) { |
| 1643 |
return false; |
| 1644 |
} |
| 1645 |
|
| 1646 |
$return = ''; |
| 1647 |
|
| 1648 |
foreach ( $array as $key => $value ) { |
| 1649 |
if ( '' === $value ) { |
| 1650 |
continue; |
| 1651 |
} |
| 1652 |
|
| 1653 |
$return .= sprintf( '%s="%s" ', $key, esc_attr( $value ) ); |
| 1654 |
} |
| 1655 |
|
| 1656 |
return $return; |
| 1657 |
} |
| 1658 |
} |
| 1659 |
} |
| 1660 |
|
| 1661 |
if ( ! function_exists( 'wpsf_get_setting' ) ) { |
| 1662 |
/** |
| 1663 |
* Get a setting from an option group |
| 1664 |
* |
| 1665 |
* @param string $option_group Option group. |
| 1666 |
* @param string $section_id May also be prefixed with tab ID. |
| 1667 |
* @param string $field_id Field ID. |
| 1668 |
* |
| 1669 |
* @return mixed |
| 1670 |
*/ |
| 1671 |
function wpsf_get_setting( $option_group, $section_id, $field_id ) { |
| 1672 |
$options = get_option( $option_group . '_settings' ); |
| 1673 |
if ( isset( $options[ $section_id . '_' . $field_id ] ) ) { |
| 1674 |
return $options[ $section_id . '_' . $field_id ]; |
| 1675 |
} |
| 1676 |
|
| 1677 |
return false; |
| 1678 |
} |
| 1679 |
} |
| 1680 |
|
| 1681 |
if ( ! function_exists( 'wpsf_delete_settings' ) ) { |
| 1682 |
/** |
| 1683 |
* Delete all the saved settings from a settings file/option group |
| 1684 |
* |
| 1685 |
* @param string $option_group Option group. |
| 1686 |
*/ |
| 1687 |
function wpsf_delete_settings( $option_group ) { |
| 1688 |
delete_option( $option_group . '_settings' ); |
| 1689 |
} |
| 1690 |
} |
| 1691 |
|