class-redux-api.php (51267B)
1 <?php // phpcs:ignore WordPress.NamingConventions.ValidFunctionName 2 /** 3 * Redux Framework API Class 4 * Makes instantiating a Redux object an absolute piece of cake. 5 * 6 * @package Redux_Framework 7 * @author Dovy Paukstys 8 * @subpackage Core 9 */ 10 11 // Exit if accessed directly. 12 defined( 'ABSPATH' ) || exit; 13 14 // Don't duplicate me! 15 if ( ! class_exists( 'Redux', false ) ) { 16 17 /** 18 * Redux API Class 19 * Simple API for Redux Framework 20 * 21 * @since 3.0.0 22 */ 23 class Redux { 24 25 26 /** 27 * Option fields. 28 * 29 * @var array 30 */ 31 public static $fields = array(); 32 33 /** 34 * Option sections. 35 * 36 * @var array 37 */ 38 public static $sections = array(); 39 40 /** 41 * Option defaults. 42 * 43 * @var array 44 */ 45 public static $options_defaults = array(); 46 47 /** 48 * Option help array. 49 * 50 * @var array 51 */ 52 public static $help = array(); 53 54 /** 55 * Option global args. 56 * 57 * @var array 58 */ 59 public static $args = array(); 60 61 /** 62 * Option section priorities. 63 * 64 * @var array 65 */ 66 public static $priority = array(); 67 68 /** 69 * Panel validations errors. 70 * 71 * @var array 72 */ 73 public static $errors = array(); 74 75 /** 76 * Init. 77 * 78 * @var array 79 */ 80 public static $init = array(); 81 82 /** 83 * Delay Init opt_names 84 * 85 * @var array 86 */ 87 public static $delay_init = array(); 88 89 /** 90 * Extension list. 91 * 92 * @var array 93 */ 94 public static $extensions = array(); 95 96 /** 97 * Extensions in use. 98 * 99 * @var array 100 */ 101 public static $uses_extensions = array(); 102 103 /** 104 * Extension paths. 105 * 106 * @var array 107 */ 108 public static $extension_paths = array(); 109 110 /** 111 * Extension capability flag. 112 * 113 * @var boolean 114 */ 115 public static $extension_compatibility = false; 116 117 /** 118 * Code to run at creation in instance. 119 */ 120 public static function load() { 121 add_action( 'after_setup_theme', array( 'Redux', 'create_redux' ) ); 122 add_action( 'init', array( 'Redux', 'create_redux' ) ); 123 add_action( 'switch_theme', array( 'Redux', 'create_redux' ) ); 124 125 require_once Redux_Core::$dir . 'inc/extensions/metaboxes/class-redux-metaboxes-api.php'; 126 } 127 128 /** 129 * Delay init action function 130 * Delays all Redux objects from loaded before `plugins_loaded` runs. 131 */ 132 public static function delay_init() { 133 if ( ! empty( self::$delay_init ) ) { 134 135 foreach ( self::$delay_init as $opt_name ) { 136 self::init( $opt_name ); 137 $parent = Redux_Instances::get_instance( $opt_name ); 138 // translators: This is only shown to developers, should not impact users. 139 $msg = sprintf( 140 '<strong>%s</strong><br /><code>%s</code> %s', 141 esc_html__( 'Warning, Premature Initialization', 'redux-framework' ), 142 'self::init("' . esc_html( $opt_name ) . '")', 143 // translators: This is only shown to developers, should not impact users. 144 sprintf( esc_html__( 'was run before the %s hook and was delayed to avoid errors.', 'redux-framework' ), '<code>plugins_loaded</code>' ) 145 ); 146 147 if ( isset( $parent->args ) ) { 148 $data = array( 149 'parent' => $parent, 150 'type' => 'error', 151 'msg' => $msg, 152 'id' => 'redux_init', 153 'dismiss' => true, 154 ); 155 156 Redux_Admin_Notices::set_notice( $data ); 157 } 158 } 159 } 160 } 161 162 /** 163 * Init Redux object 164 * 165 * @param string $opt_name Panel opt_name. 166 */ 167 public static function init( string $opt_name = '' ) { 168 if ( ! empty( $opt_name ) ) { 169 if ( ! did_action( 'plugins_loaded' ) ) { 170 171 // We don't want to load before plugins_loaded EVER. 172 self::$delay_init[] = $opt_name; 173 add_action( 'plugins_loaded', array( 'Redux', 'delay_init' ) ); 174 } else { 175 176 // The hook `plugins_loaded` has run, let's get going! 177 self::load_redux( $opt_name ); 178 179 remove_action( 'setup_theme', array( 'Redux', 'create_redux' ) ); 180 } 181 } 182 } 183 184 /** 185 * Retrive ReduxFramework object. 186 * 187 * @param string $opt_name Panel opt_name. 188 * 189 * @return object|ReduxFramework 190 */ 191 public static function instance( string $opt_name ) { 192 return Redux_Instances::get_instance( $opt_name ); 193 } 194 195 /** 196 * Retrieve all ReduxFramework Instances. 197 * 198 * @return null|array|ReduxFramework[] 199 */ 200 public static function all_instances(): ?array { 201 return Redux_Instances::get_all_instances(); 202 } 203 204 /** 205 * Load external extensions. 206 * 207 * @param object $redux_framework ReduxFramework object. 208 * 209 * @deprecated No longer using camcelCase naming convensions. 210 */ 211 public static function loadExtensions( $redux_framework ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName 212 self::load_extensions( $redux_framework ); 213 } 214 215 /** 216 * Load external extensions. 217 * 218 * @param object $redux_framework ReduxFramework object. 219 */ 220 public static function load_extensions( $redux_framework ) { 221 $instance_extensions = self::get_extensions( $redux_framework->args['opt_name'] ); 222 223 if ( $instance_extensions ) { 224 foreach ( $instance_extensions as $name => $extension ) { 225 $old_class = str_replace( 'Redux_', 'ReduxFramework_', $extension['class'] ); 226 227 if ( ! class_exists( $extension['class'] ) && ! class_exists( $old_class ) ) { 228 // In case you wanted override your override, hah. 229 // phpcs:ignore WordPress.NamingConventions.ValidHookName 230 $extension['path'] = apply_filters( 'redux/extension/' . $redux_framework->args['opt_name'] . '/' . $name, $extension['path'] ); 231 if ( file_exists( $extension['path'] ) ) { 232 require_once $extension['path']; 233 } 234 } 235 if ( isset( $extension['field'] ) ) { 236 require_once $extension['field']; 237 } 238 239 if ( ! isset( $redux_framework->extensions[ $name ] ) ) { 240 $field_classes = array( $extension['class'], $old_class ); 241 $ext_class = Redux_Functions::class_exists_ex( $field_classes ); 242 if ( false !== $ext_class ) { 243 $redux_framework->extensions[ $name ] = new $ext_class( $redux_framework ); 244 // Backwards compatibility for extensions. 245 if ( ! is_subclass_of( $redux_framework->extensions[ $name ], 'Redux_Extension_Abstract' ) ) { 246 $new_class_name = $ext_class . '_extended'; 247 self::$extension_compatibility = true; 248 $redux_framework->extensions[ $name ] = Redux_Functions_Ex::extension_compatibility( $redux_framework, $extension['path'], $ext_class, $new_class_name, $name ); 249 } 250 } elseif ( is_admin() && true === $redux_framework->args['dev_mode'] ) { 251 echo '<div id="message" class="error"><p>No class named <strong>' . esc_html( $extension['class'] ) . '</strong> exists. Please verify your extension path.</p></div>'; 252 } 253 } 254 } 255 } 256 } 257 258 /** 259 * Deprecated function to set extension path. 260 * 261 * @param string $extension Path. 262 * @param bool $folder Set if path is a folder. 263 * 264 * @return bool|mixed 265 * @deprecated No longer using cameCase naming convensions. 266 */ 267 public static function extensionPath( string $extension, bool $folder = true ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName 268 return self::extension_path( $extension, $folder = true ); 269 } 270 271 /** 272 * Sets a path to an extension. 273 * 274 * @param string $extension Path to extension. 275 * @param bool $folder Set if path is a folder. 276 * 277 * @return bool|mixed 278 */ 279 public static function extension_path( string $extension, bool $folder = true ) { 280 if ( ! isset( self::$extensions[ $extension ] ) ) { 281 return false; 282 } 283 284 $path = end( self::$extensions[ $extension ] ); 285 286 if ( ! $folder ) { 287 return $path; 288 } 289 290 return dirname( $path ); 291 } 292 293 /** 294 * Deprecated function of Load Redux Framework. 295 * 296 * @param string $opt_name Panrl opt_name. 297 * 298 * @deprecated No longer using camelCase naming convensions. 299 */ 300 public static function loadRedux( string $opt_name = '' ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName 301 self::load_redux( $opt_name ); 302 } 303 304 /** 305 * Load defaults values for a given opt_name. 306 * 307 * @param string $opt_name Panel opt_name. 308 */ 309 public static function set_defaults( string $opt_name = '' ) { 310 // Try to load the class if in the same directory, so the user only have to include the Redux API. 311 if ( ! class_exists( 'Redux_Options_Defaults' ) ) { 312 $file_check = trailingslashit( dirname( __FILE__ ) ) . 'class-redux-options-defaults.php'; 313 314 if ( file_exists( dirname( $file_check ) ) ) { 315 include_once $file_check; 316 $file_check = trailingslashit( dirname( __FILE__ ) ) . 'class-redux-wordpress-data.php'; 317 if ( file_exists( dirname( $file_check ) ) ) { 318 include_once $file_check; 319 } 320 } 321 } 322 323 if ( class_exists( 'Redux_Options_Defaults' ) && ! isset( self::$options_defaults[ $opt_name ] ) ) { 324 $sections = self::construct_sections( $opt_name ); 325 $wordpress_data = ( ! class_exists( 'Redux_WordPress_Data' ) ) ? null : new Redux_WordPress_Data( $opt_name ); 326 $options_defaults_class = new Redux_Options_Defaults(); 327 self::$options_defaults[ $opt_name ] = $options_defaults_class->default_values( $opt_name, $sections, $wordpress_data ); 328 if ( ! isset( self::$args[ $opt_name ]['global_variable'] ) || ( '' === self::$args[ $opt_name ]['global_variable'] && false !== self::$args[ $opt_name ]['global_variable'] ) ) { 329 self::$args[ $opt_name ]['global_variable'] = str_replace( '-', '_', $opt_name ); 330 } 331 if ( isset( self::$args[ $opt_name ]['global_variable'] ) && self::$args[ $opt_name ]['global_variable'] ) { 332 $option_global = self::$args[ $opt_name ]['global_variable']; 333 334 /** 335 * Filter 'redux/options/{opt_name}/global_variable' 336 * 337 * @param array $value option value to set global_variable with 338 */ global $$option_global; 339 340 // phpcs:ignore WordPress.NamingConventions.ValidHookName 341 $$option_global = apply_filters( 'redux/options/' . $opt_name . '/global_variable', self::$options_defaults[ $opt_name ] ); 342 } 343 } 344 } 345 346 /** 347 * Load Redux Framework. 348 * 349 * @param string $opt_name Panel opt_name. 350 */ 351 public static function load_redux( string $opt_name = '' ) { 352 if ( empty( $opt_name ) ) { 353 return; 354 } 355 356 if ( class_exists( 'ReduxFramework' ) ) { 357 if ( isset( self::$init[ $opt_name ] ) && ! empty( self::$init[ $opt_name ] ) ) { 358 return; 359 } 360 } else { 361 echo '<div id="message" class="error"><p>' . esc_html__( 'Redux Framework is not installed. Please install it.', 'redux-framework' ) . '</p></div>'; 362 363 return; 364 } 365 366 $check = self::instance( $opt_name ); 367 368 Redux_Functions_Ex::record_caller( $opt_name ); 369 370 if ( isset( self::$init[ $opt_name ] ) && 1 === self::$init[ $opt_name ] ) { 371 return; 372 } 373 374 self::set_defaults( $opt_name ); 375 376 $args = self::construct_args( $opt_name ); 377 $sections = self::construct_sections( $opt_name ); 378 379 if ( isset( self::$uses_extensions[ $opt_name ] ) && ! empty( self::$uses_extensions[ $opt_name ] ) ) { 380 add_action( "redux/extensions/$opt_name/before", array( 'Redux', 'loadExtensions' ), 0 ); 381 } 382 383 $redux = new ReduxFramework( $sections, $args ); 384 self::$init[ $opt_name ] = 1; 385 386 if ( isset( $redux->args['opt_name'] ) && $redux->args['opt_name'] !== $opt_name ) { 387 self::$init[ $redux->args['opt_name'] ] = 1; 388 } 389 } 390 391 /** 392 * Deprecated Create Redux instance. 393 * 394 * @deprecated No longer using camelCase naming convention. 395 */ 396 public static function createRedux() { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName 397 self::create_redux(); 398 } 399 400 /** 401 * Create Redux instance. 402 */ 403 public static function create_redux() { 404 foreach ( self::$sections as $opt_name => $the_sections ) { 405 if ( ! empty( $the_sections ) ) { 406 if ( ! self::$init[ $opt_name ] ) { 407 self::loadRedux( $opt_name ); 408 } 409 } 410 } 411 } 412 413 /** 414 * Construct global arguments. 415 * 416 * @param string $opt_name Panel opt_name. 417 * 418 * @return array|mixed 419 */ 420 public static function construct_args( string $opt_name ) { 421 $args = self::$args[ $opt_name ] ?? array(); 422 $args['opt_name'] = $opt_name; 423 424 if ( ! isset( $args['menu_title'] ) ) { 425 $args['menu_title'] = ucfirst( $opt_name ) . ' Options'; 426 } 427 428 if ( ! isset( $args['page_title'] ) ) { 429 $args['page_title'] = ucfirst( $opt_name ) . ' Options'; 430 } 431 432 if ( ! isset( $args['page_slug'] ) ) { 433 $args['page_slug'] = $opt_name . '_options'; 434 } 435 436 return $args; 437 } 438 439 /** 440 * Construct option panel sections. 441 * 442 * @param string $opt_name Panel opt_name. 443 * 444 * @return array 445 */ 446 public static function construct_sections( string $opt_name ): array { 447 $sections = array(); 448 449 if ( ! isset( self::$sections[ $opt_name ] ) ) { 450 return $sections; 451 } 452 453 foreach ( self::$sections[ $opt_name ] as $section_id => $section ) { 454 $section['fields'] = self::construct_fields( $opt_name, $section_id ); 455 $p = $section['priority']; 456 457 while ( isset( $sections[ $p ] ) ) { 458 $p++; 459 } 460 461 $sections[ $p ] = $section; 462 } 463 464 ksort( $sections ); 465 466 return $sections; 467 } 468 469 /** 470 * Construct option panel fields. 471 * 472 * @param string $opt_name Panel opt_name. 473 * @param string $section_id ID of section. 474 * 475 * @return array 476 */ 477 public static function construct_fields( string $opt_name = '', string $section_id = '' ): array { 478 $fields = array(); 479 480 if ( ! empty( self::$fields[ $opt_name ] ) ) { 481 foreach ( self::$fields[ $opt_name ] as $key => $field ) { 482 if ( $field['section_id'] === $section_id ) { 483 $p = esc_html( $field['priority'] ); 484 485 while ( isset( $fields[ $p ] ) ) { 486 echo intval( $p++ ); 487 } 488 489 $fields[ $p ] = $field; 490 } 491 } 492 } 493 494 ksort( $fields ); 495 496 return $fields; 497 } 498 499 /** 500 * Deprecated Retrieve panel section. 501 * 502 * @param string $opt_name Panel opt_name. 503 * @param string $id Section ID. 504 * 505 * @return bool 506 * @deprecated No longer using camelCase naming convention. 507 */ 508 public static function getSection( string $opt_name = '', string $id = '' ): bool { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName 509 return self::get_section( $opt_name, $id ); 510 } 511 512 /** 513 * Retrieve panel section. 514 * 515 * @param string $opt_name Panel opt_name. 516 * @param string|int $id Section ID. 517 * 518 * @return bool|string|int 519 */ 520 public static function get_section( string $opt_name = '', $id = '' ) { 521 self::check_opt_name( $opt_name ); 522 523 if ( ! empty( $opt_name ) && ! empty( $id ) ) { 524 if ( ! isset( self::$sections[ $opt_name ][ $id ] ) ) { 525 $id = Redux_Core::strtolower( sanitize_html_class( $id ) ); 526 } 527 528 return self::$sections[ $opt_name ][ $id ] ?? false; 529 } 530 531 return false; 532 } 533 534 /** 535 * Deprecated Create a section of the option panel. 536 * 537 * @param string $opt_name Panel opt_name. 538 * @param array $sections Section ID. 539 * 540 * @deprecated No longer using camelCase naming convention. 541 */ 542 public static function setSections( string $opt_name = '', array $sections = array() ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName 543 if ( '' !== $opt_name ) { 544 Redux_Functions_Ex::record_caller( $opt_name ); 545 } 546 547 self::set_sections( $opt_name, $sections ); 548 } 549 550 /** 551 * Create multiple sections of the option panel. 552 * 553 * @param string $opt_name Panel opt_name. 554 * @param array $sections Section ID. 555 */ 556 public static function set_sections( string $opt_name = '', array $sections = array() ) { 557 if ( empty( $sections ) || '' === $opt_name ) { 558 return; 559 } 560 561 self::check_opt_name( $opt_name ); 562 563 Redux_Functions_Ex::record_caller( $opt_name ); 564 565 foreach ( $sections as $section ) { 566 self::set_section( $opt_name, $section ); 567 } 568 } 569 570 /** 571 * Deprecated Retrieve all sections from the option panel. 572 * 573 * @param string $opt_name Panel opt_name. 574 * 575 * @return array|mixed 576 * @deprecated No longer using camelCase naming convention. 577 */ 578 public static function getSections( string $opt_name = '' ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName 579 return self::get_sections( $opt_name ); 580 } 581 582 /** 583 * Retrieve all sections from the option panel. 584 * 585 * @param string $opt_name Panel opt_name. 586 * 587 * @return array|mixed 588 */ 589 public static function get_sections( string $opt_name = '' ) { 590 self::check_opt_name( $opt_name ); 591 592 if ( ! empty( self::$sections[ $opt_name ] ) ) { 593 return self::$sections[ $opt_name ]; 594 } 595 596 return array(); 597 } 598 599 /** 600 * Deprecated Remove option panel by ID. 601 * 602 * @param string $opt_name Panel opt_name. 603 * @param string|int $id Sectio ID. 604 * @param bool $fields Remove fields. 605 * 606 * @deprecated No longer using camelCase naming convention. 607 */ 608 public static function removeSection( string $opt_name = '', $id = '', bool $fields = false ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName 609 if ( '' !== $opt_name ) { 610 Redux_Functions_Ex::record_caller( $opt_name ); 611 } 612 613 self::remove_section( $opt_name, $id, $fields ); 614 } 615 616 /** 617 * Remove option panel by ID. 618 * 619 * @param string $opt_name Panel opt_name. 620 * @param string|int $id Sectio ID. 621 * @param bool $fields Remove fields. 622 */ 623 public static function remove_section( string $opt_name = '', $id = '', bool $fields = false ) { 624 if ( '' !== $opt_name && '' !== $id ) { 625 Redux_Functions_Ex::record_caller( $opt_name ); 626 627 if ( isset( self::$sections[ $opt_name ][ $id ] ) ) { 628 $priority = ''; 629 630 foreach ( self::$sections[ $opt_name ] as $key => $section ) { 631 if ( $key === $id ) { 632 $priority = $section['priority']; 633 self::$priority[ $opt_name ]['sections']--; 634 unset( self::$sections[ $opt_name ][ $id ] ); 635 continue; 636 } 637 if ( '' !== $priority ) { 638 $new_priority = $section['priority']; 639 $section['priority'] = $priority; 640 self::$sections[ $opt_name ][ $key ] = $section; 641 $priority = $new_priority; 642 } 643 } 644 645 if ( isset( self::$fields[ $opt_name ] ) && ! empty( self::$fields[ $opt_name ] ) && true === $fields ) { 646 foreach ( self::$fields[ $opt_name ] as $key => $field ) { 647 if ( $field['section_id'] === $id ) { 648 unset( self::$fields[ $opt_name ][ $key ] ); 649 } 650 } 651 } 652 } 653 } 654 } 655 656 /** 657 * Deprecated Sets a single option panel section. 658 * 659 * @param string $opt_name Panel opt_name. 660 * @param array|null $section Section data. 661 * 662 * @deprecated No longer using camelCase naming convention. 663 */ 664 public static function setSection( string $opt_name = '', ?array $section = array() ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName 665 if ( '' !== $opt_name ) { 666 Redux_Functions_Ex::record_caller( $opt_name ); 667 } 668 669 self::set_section( $opt_name, $section ); 670 } 671 672 /** 673 * Sets a single option panel section. 674 * 675 * @param string $opt_name Panel opt_name. 676 * @param array|null $section Section data. 677 * @param bool $replace Replaces section instead of creating a new one. 678 */ 679 public static function set_section( string $opt_name = '', ?array $section = array(), bool $replace = false ) { 680 if ( empty( $section ) || '' === $opt_name ) { 681 return; 682 } 683 684 self::check_opt_name( $opt_name ); 685 686 Redux_Functions_Ex::record_caller( $opt_name ); 687 688 if ( ! isset( $section['id'] ) ) { 689 if ( isset( $section['type'] ) && 'divide' === $section['type'] ) { 690 $section['id'] = time(); 691 } else { 692 if ( isset( $section['title'] ) ) { 693 $section['id'] = Redux_Core::strtolower( sanitize_title( $section['title'] ) ); 694 } else { 695 $section['id'] = time(); 696 } 697 } 698 699 if ( isset( self::$sections[ $opt_name ][ $section['id'] ] ) && ! $replace ) { 700 $orig = $section['id']; 701 $i = 0; 702 703 while ( isset( self::$sections[ $opt_name ][ $section['id'] ] ) ) { 704 $section['id'] = $orig . '_' . $i; 705 $i++; 706 } 707 } elseif ( isset( self::$sections[ $opt_name ][ $section['id'] ] ) && $replace ) { 708 // If replace is set, let's update the default values with these! 709 $fields = false; 710 if ( isset( self::$sections[ $opt_name ][ $section['id'] ]['fields'] ) && ! empty( self::$sections[ $opt_name ][ $section['id'] ]['fields'] ) ) { 711 $fields = self::$sections[ $opt_name ][ $section['id'] ]['fields']; 712 } 713 self::$sections[ $opt_name ][ $section['id'] ] = wp_parse_args( $section, self::$sections[ $opt_name ][ $section['id'] ] ); 714 if ( ! empty( $fields ) ) { 715 if ( ! isset( self::$sections[ $opt_name ][ $section['id'] ]['fields'] ) || ( isset( self::$sections[ $opt_name ][ $section['id'] ]['fields'] ) && empty( self::$sections[ $opt_name ][ $section['id'] ]['fields'] ) ) ) { 716 self::$sections[ $opt_name ][ $section['id'] ]['fields'] = $fields; 717 } 718 } 719 } 720 } 721 722 if ( ! empty( $opt_name ) && is_array( $section ) && ! empty( $section ) ) { 723 if ( ! isset( $section['id'] ) && ! isset( $section['title'] ) ) { 724 self::$errors[ $opt_name ]['section']['missing_title'] = esc_html__( 'Unable to create a section due to missing id and title.', 'redux-framework' ); 725 726 return; 727 } 728 729 if ( ! isset( $section['priority'] ) ) { 730 $section['priority'] = self::get_priority( $opt_name, 'sections' ); 731 } 732 733 if ( isset( $section['fields'] ) ) { 734 if ( ! empty( $section['fields'] ) && is_array( $section['fields'] ) ) { 735 self::process_field_array( $opt_name, $section['id'], $section['fields'] ); 736 } 737 unset( $section['fields'] ); 738 } 739 740 self::$sections[ $opt_name ][ $section['id'] ] = $section; 741 } else { 742 self::$errors[ $opt_name ]['section']['empty'] = esc_html__( 'Unable to create a section due an empty section array or the section variable passed was not an array.', 'redux-framework' ); 743 } 744 } 745 746 /** 747 * Deprecated Hides an option panel section. 748 * 749 * @param string $opt_name Panel opt_name. 750 * @param string|int $id Section ID. 751 * @param bool $hide Flag to hide/show. 752 * 753 * @deprecated No longer using camelCase naming convention. 754 */ 755 public static function hideSection( string $opt_name = '', $id = '', bool $hide = true ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName 756 if ( '' !== $opt_name ) { 757 Redux_Functions_Ex::record_caller( $opt_name ); 758 } 759 760 self::hide_section( $opt_name, $id, $hide ); 761 } 762 763 /** 764 * Hides an option panel section. 765 * 766 * @param string $opt_name Panel opt_name. 767 * @param string|int $id Section ID. 768 * @param bool $hide Flag to hide/show. 769 */ 770 public static function hide_section( string $opt_name = '', $id = '', bool $hide = true ) { 771 self::check_opt_name( $opt_name ); 772 773 if ( '' !== $opt_name && '' !== $id ) { 774 Redux_Functions_Ex::record_caller( $opt_name ); 775 776 if ( isset( self::$sections[ $opt_name ][ $id ] ) ) { 777 self::$sections[ $opt_name ][ $id ]['hidden'] = $hide; 778 } 779 } 780 } 781 782 /** 783 * Compiles field array data. 784 * 785 * @param string $opt_name Panel opt_name. 786 * @param string|int $section_id Section ID. 787 * @param array $fields Field data. 788 */ 789 private static function process_field_array( string $opt_name = '', $section_id = '', array $fields = array() ) { 790 if ( ! empty( $opt_name ) && ! empty( $section_id ) && is_array( $fields ) && ! empty( $fields ) ) { 791 foreach ( $fields as $field ) { 792 if ( ! is_array( $field ) ) { 793 continue; 794 } 795 self::set_field( $opt_name, $section_id, $field ); 796 } 797 } 798 } 799 800 /** 801 * Deprecated Retrieves an option panel field. 802 * 803 * @param string $opt_name Panel opt_name. 804 * @param string|int $id Field ID. 805 * 806 * @return int|bool 807 * @deprecated No longer using camelCase naming convention. 808 */ 809 public static function getField( string $opt_name = '', $id = '' ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName 810 return self::get_field( $opt_name, $id ); 811 } 812 813 /** 814 * Retrieves an option panel field. 815 * 816 * @param string $opt_name Panel opt_name. 817 * @param string|int $id Field ID. 818 * 819 * @return int|bool 820 */ 821 public static function get_field( string $opt_name = '', $id = '' ) { 822 self::check_opt_name( $opt_name ); 823 824 if ( ! empty( $opt_name ) && ! empty( $id ) ) { 825 return self::$fields[ $opt_name ][ $id ] ?? false; 826 } 827 828 return false; 829 } 830 831 /** 832 * Deprecated Hides an optio panel field. 833 * 834 * @param string $opt_name Panel opt_name. 835 * @param string|int $id Field ID. 836 * @param bool $hide Set hide/show. 837 * 838 * @deprecated No longer using camelCase naming convention. 839 */ 840 public static function hideField( string $opt_name = '', $id = '', bool $hide = true ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName 841 if ( '' !== $opt_name ) { 842 Redux_Functions_Ex::record_caller( $opt_name ); 843 } 844 845 self::hide_field( $opt_name, $id, $hide ); 846 } 847 848 /** 849 * Hides an option panel field. 850 * 851 * @param string $opt_name Panel opt_name. 852 * @param string|int $id Field ID. 853 * @param bool $hide Set hide/show. 854 */ 855 public static function hide_field( string $opt_name = '', $id = '', bool $hide = true ) { 856 self::check_opt_name( $opt_name ); 857 858 if ( '' !== $opt_name && '' !== $id ) { 859 if ( isset( self::$fields[ $opt_name ][ $id ] ) ) { 860 Redux_Functions_Ex::record_caller( $opt_name ); 861 862 if ( ! $hide ) { 863 self::$fields[ $opt_name ][ $id ]['class'] = str_replace( 'hidden', '', self::$fields[ $opt_name ][ $id ]['class'] ); 864 } else { 865 self::$fields[ $opt_name ][ $id ]['class'] .= 'hidden'; 866 } 867 } 868 } 869 } 870 871 /** 872 * Deprecated Creates an option panel field. 873 * 874 * @param string $opt_name Panel opt_name. 875 * @param string|int $section_id Section ID this field belongs to. 876 * @param array $field Field data. 877 * 878 * @deprecated No longer using camelCase naming convention. 879 */ 880 public static function setField( string $opt_name = '', $section_id = '', array $field = array() ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName 881 if ( '' !== $opt_name ) { 882 Redux_Functions_Ex::record_caller( $opt_name ); 883 } 884 885 self::set_field( $opt_name, $section_id, $field ); 886 } 887 888 /** 889 * Creates an option panel field and adds to a section. 890 * 891 * @param string $opt_name Panel opt_name. 892 * @param string|int $section_id Section ID this field belongs to. 893 * @param array $field Field data. 894 */ 895 public static function set_field( string $opt_name = '', $section_id = '', array $field = array() ) { 896 897 if ( ! is_array( $field ) || empty( $field ) || '' === $opt_name || '' === $section_id ) { 898 return; 899 } 900 901 self::check_opt_name( $opt_name ); 902 903 Redux_Functions_Ex::record_caller( $opt_name ); 904 905 // Shim for the old method! 906 if ( is_array( $section_id ) ) { 907 $section_id_holder = $field; 908 $field = $section_id; 909 if ( isset( $field['section_id'] ) ) { 910 $section_id = $field['section_id']; 911 } 912 } 913 914 $field['section_id'] = $section_id; 915 916 if ( ! isset( $field['priority'] ) ) { 917 $field['priority'] = self::get_priority( $opt_name, 'fields' ); 918 } 919 $field['id'] = $field['id'] ?? "{$opt_name}_{$section_id}_{$field['type']}_" . wp_rand( 1, 9999 ); 920 921 self::$fields[ $opt_name ][ $field['id'] ] = $field; 922 } 923 924 /** 925 * Create multiple fields of the option panel and apply to a section. 926 * 927 * @param string $opt_name Panel opt_name. 928 * @param int|string $section_id Section ID this field belongs to. 929 * @param array $fields Array of field arrays. 930 */ 931 public static function set_fields( string $opt_name = '', $section_id = '', array $fields = array() ) { 932 if ( ! is_array( $fields ) || empty( $fields ) || '' === $opt_name || '' === $section_id ) { 933 return; 934 } 935 936 self::check_opt_name( $opt_name ); 937 938 // phpcs:ignore WordPress.PHP.DevelopmentFunctions 939 Redux_Functions_Ex::record_caller( $opt_name ); 940 941 foreach ( $fields as $field ) { 942 if ( is_array( $field ) ) { 943 self::set_field( $opt_name, $section_id, $field ); 944 } 945 } 946 } 947 948 /** 949 * Deprecated Removes an option panel field. 950 * 951 * @param string $opt_name Panel opt_name. 952 * @param string|int $id Field ID. 953 * 954 * @return bool 955 * @deprecated No longer using camelCase naming convention. 956 */ 957 public static function removeField( string $opt_name = '', $id = '' ): bool { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName 958 if ( '' !== $opt_name ) { 959 Redux_Functions_Ex::record_caller( $opt_name ); 960 } 961 962 return self::remove_field( $opt_name, $id ); 963 } 964 965 /** 966 * Removes an option panel field. 967 * 968 * @param string $opt_name Panel opt_name. 969 * @param string|int $id Field ID. 970 * 971 * @return bool 972 */ 973 public static function remove_field( string $opt_name = '', $id = '' ): bool { 974 if ( '' !== $opt_name && '' !== $id ) { 975 self::check_opt_name( $opt_name ); 976 977 Redux_Functions_Ex::record_caller( $opt_name ); 978 979 if ( isset( self::$fields[ $opt_name ][ $id ] ) ) { 980 foreach ( self::$fields[ $opt_name ] as $key => $field ) { 981 if ( $key === $id ) { 982 $priority = $field['priority']; 983 self::$priority[ $opt_name ]['fields']--; 984 unset( self::$fields[ $opt_name ][ $id ] ); 985 continue; 986 } 987 988 if ( isset( $priority ) && '' !== $priority ) { 989 $new_priority = $field['priority']; 990 $field['priority'] = $priority; 991 self::$fields[ $opt_name ][ $key ] = $field; 992 $priority = $new_priority; 993 } 994 } 995 } 996 } 997 998 return false; 999 } 1000 1001 /** 1002 * Deprecated Sets help tabs on option panel admin page. 1003 * 1004 * @param string $opt_name Panel opt_name. 1005 * @param array $tab Tab data. 1006 * 1007 * @deprecated No longer using camelCase naming convention. 1008 */ 1009 public static function setHelpTab( string $opt_name = '', array $tab = array() ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName 1010 self::set_help_tab( $opt_name, $tab ); 1011 } 1012 1013 /** 1014 * Sets help tabs on option panel admin page. 1015 * 1016 * @param string $opt_name Panel opt_name. 1017 * @param array $tab Tab data. 1018 */ 1019 public static function set_help_tab( string $opt_name = '', array $tab = array() ) { 1020 if ( ! is_array( $tab ) && empty( $tab ) ) { 1021 return; 1022 } 1023 1024 self::check_opt_name( $opt_name ); 1025 1026 if ( '' !== $opt_name ) { 1027 if ( ! isset( self::$args[ $opt_name ]['help_tabs'] ) ) { 1028 self::$args[ $opt_name ]['help_tabs'] = array(); 1029 } 1030 1031 if ( isset( $tab['id'] ) ) { 1032 self::$args[ $opt_name ]['help_tabs'][] = $tab; 1033 } elseif ( is_array( end( $tab ) ) ) { 1034 foreach ( $tab as $tab_item ) { 1035 self::$args[ $opt_name ]['help_tabs'][] = $tab_item; 1036 } 1037 } 1038 } 1039 } 1040 1041 /** 1042 * Deprecated Sets the help sidebar content. 1043 * 1044 * @param string $opt_name Panel opt_name. 1045 * @param string $content Content. 1046 * 1047 * @deprecated No longer using camelCase naming convention. 1048 */ 1049 public static function setHelpSidebar( string $opt_name = '', string $content = '' ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName 1050 self::set_help_sidebar( $opt_name, $content ); 1051 } 1052 1053 /** 1054 * Sets the help sidebar content. 1055 * 1056 * @param string $opt_name Panel opt_name. 1057 * @param string $content Content. 1058 */ 1059 public static function set_help_sidebar( string $opt_name = '', string $content = '' ) { 1060 if ( '' === $content || '' === $opt_name ) { 1061 return; 1062 } 1063 self::check_opt_name( $opt_name ); 1064 1065 self::$args[ $opt_name ]['help_sidebar'] = $content; 1066 } 1067 1068 /** 1069 * Deprecated Sets option panel global arguments. 1070 * 1071 * @param string $opt_name Panel opt_name. 1072 * @param array $args Argument data. 1073 * 1074 * @deprecated No longer using camelCase naming convention. 1075 */ 1076 public static function setArgs( string $opt_name = '', array $args = array() ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName 1077 if ( '' !== $opt_name ) { 1078 Redux_Functions_Ex::record_caller( $opt_name ); 1079 } 1080 1081 self::set_args( $opt_name, $args ); 1082 } 1083 1084 /** 1085 * Sets option panel global arguments. 1086 * 1087 * @param string $opt_name Panel opt_name. 1088 * @param array $args Argument data. 1089 */ 1090 public static function set_args( string $opt_name = '', array $args = array() ) { 1091 if ( empty( $args ) || '' === $opt_name ) { 1092 return; 1093 } 1094 1095 self::check_opt_name( $opt_name ); 1096 1097 Redux_Functions_Ex::record_caller( $opt_name ); 1098 1099 if ( is_array( $args ) ) { 1100 if ( isset( self::$args[ $opt_name ] ) && isset( self::$args[ $opt_name ]['clearArgs'] ) ) { 1101 self::$args[ $opt_name ] = array(); 1102 } 1103 self::$args[ $opt_name ] = wp_parse_args( $args, self::$args[ $opt_name ] ); 1104 } 1105 } 1106 1107 /** 1108 * Set's developer key for premium services. 1109 * 1110 * @param string $opt_name Panel opt_name. 1111 * @param string|array $arg Args data. 1112 */ 1113 public static function set_developer( string $opt_name = '', $arg = '' ) { 1114 if ( empty( $arg ) || '' === $opt_name ) { 1115 return; 1116 } 1117 1118 self::check_opt_name( $opt_name ); 1119 1120 Redux_Functions_Ex::record_caller( $opt_name ); 1121 1122 self::$args[ $opt_name ]['developer'] = $arg; 1123 } 1124 1125 /** 1126 * Deprecated Retrives option panel global arguemnt array. 1127 * 1128 * @param string $opt_name Panel opt_name. 1129 * 1130 * @return mixed 1131 * @deprecated No longer camelCase naming convention. 1132 */ 1133 public static function getArgs( string $opt_name = '' ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName 1134 return self::get_args( $opt_name ); 1135 } 1136 1137 /** 1138 * Retrives option panel global arguemnt array. 1139 * 1140 * @param string $opt_name Panel opt_name. 1141 * @param string $key Argument key name to be returned. 1142 * 1143 * @return mixed|null|array 1144 */ 1145 public static function get_args( string $opt_name = '', string $key = '' ) { 1146 self::check_opt_name( $opt_name ); 1147 1148 if ( ! empty( $opt_name ) && ! empty( $key ) ) { 1149 if ( ! empty( self::$args[ $opt_name ] ) ) { 1150 return self::$args[ $opt_name ][ $key ]; 1151 } else { 1152 return null; 1153 } 1154 } elseif ( ! empty( $opt_name ) && ! empty( self::$args[ $opt_name ] ) ) { 1155 return self::$args[ $opt_name ]; 1156 } 1157 } 1158 1159 /** 1160 * Deprecated Retrieves a single global argument. 1161 * 1162 * @param string $opt_name Panel opt_name. 1163 * @param string $key Argument name. 1164 * 1165 * @return mixed 1166 * @deprecated No longer using camelCase naming convention and using singular function self::get_args() now. 1167 */ 1168 public static function getArg( string $opt_name = '', string $key = '' ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName 1169 return self::get_args( $opt_name, $key ); 1170 } 1171 1172 /** 1173 * Retrieves a single global argument. 1174 * 1175 * @param string $opt_name Panel opt_name. 1176 * @param string $key Argument name. 1177 * 1178 * @return mixed|array|null 1179 */ 1180 public static function get_arg( string $opt_name = '', string $key = '' ) { 1181 self::check_opt_name( $opt_name ); 1182 1183 if ( ! empty( $opt_name ) && ! empty( $key ) && ! empty( self::$args[ $opt_name ] ) ) { 1184 return self::$args[ $opt_name ][ $key ]; 1185 } else { 1186 return null; 1187 } 1188 } 1189 1190 /** 1191 * Deprecated Retrieves single option from the database. 1192 * 1193 * @param string $opt_name Panel opt_name. 1194 * @param string $key Option key. 1195 * @param string|array $default Default value. 1196 * 1197 * @return mixed 1198 * @deprecated No longer using camelCase naming convention. 1199 */ 1200 public static function getOption( string $opt_name = '', string $key = '', $default = '' ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName 1201 return self::get_option( $opt_name, $key ); 1202 } 1203 1204 /** 1205 * Retrieves meta for a given post page, IE WordPress meta values 1206 * 1207 * @param string $opt_name Panel opt_name. 1208 * @param mixed $the_post Post object to denote the current post, or custom. 1209 * @param string $key Option key. 1210 * @param mixed $default Default value. 1211 * 1212 * @return mixed 1213 */ 1214 public static function get_post_meta( string $opt_name = '', $the_post = array(), string $key = '', $default = null ) { 1215 self::check_opt_name( $opt_name ); 1216 1217 if ( empty( $opt_name ) ) { 1218 return; 1219 } 1220 1221 global $post; 1222 1223 $redux = ReduxFrameworkInstances::get_instance( $opt_name ); 1224 1225 // We don't ever need to specify advanced_metaboxes here as all function for metaboxes are core, 1226 // and thus, metabox_lite. The extension handles its own functions and is handled by this condition. - kp. 1227 $metaboxes = $redux->extensions['metaboxes']; 1228 1229 if ( null === $default || '' === $default ) { 1230 $default = self::get_option( $opt_name, $key ); 1231 } 1232 1233 if ( isset( $the_post ) && is_array( $the_post ) ) { 1234 $the_post = $post; 1235 } elseif ( ! isset( $the_post ) || 0 === $the_post ) { 1236 return $default; 1237 } elseif ( is_numeric( $the_post ) ) { 1238 $the_post = get_post( $the_post ); 1239 } elseif ( ! is_object( $the_post ) ) { 1240 $the_post = $post; 1241 } 1242 1243 $default = self::get_option( $opt_name, $key ); 1244 1245 return $metaboxes->get_values( $the_post, $key, $default ); 1246 } 1247 1248 /** 1249 * Retrieves single option from the database. 1250 * 1251 * @param string $opt_name Panel opt_name. 1252 * @param string $key Option key. 1253 * @param mixed $default Default value. 1254 * 1255 * @return mixed 1256 */ 1257 public static function get_option( string $opt_name = '', string $key = '', $default = null ) { 1258 self::check_opt_name( $opt_name ); 1259 1260 // TODO - Add metaboxes magic here! 1261 if ( ! empty( $opt_name ) && ! empty( $key ) ) { 1262 global $$opt_name; 1263 1264 if ( empty( $$opt_name ) ) { 1265 $values = get_option( $opt_name ); 1266 $$opt_name = $values; 1267 } else { 1268 $values = $$opt_name; 1269 } 1270 1271 if ( ! isset( $values[ $key ] ) ) { 1272 if ( null === $default ) { 1273 $field = self::get_field( $opt_name, $key ); 1274 1275 if ( false !== $field ) { 1276 $defaults_class = new Redux_Options_Defaults(); 1277 $sections = self::construct_sections( $opt_name ); 1278 $defaults = $defaults_class->default_values( $opt_name, $sections ); 1279 1280 if ( isset( $defaults[ $key ] ) ) { 1281 $default = $defaults[ $key ]; 1282 } 1283 } 1284 } 1285 } 1286 1287 if ( ! empty( $subkeys ) && is_array( $subkeys ) ) { 1288 $value = $default; 1289 1290 if ( isset( $values[ $key ] ) ) { 1291 $count = count( $subkeys ); 1292 1293 if ( 1 === $count ) { 1294 $value = $values[ $key ][ $subkeys[1] ] ?? $default; 1295 } elseif ( 2 === $count ) { 1296 if ( isset( $values[ $key ][ $subkeys[1] ] ) ) { 1297 $value = $values[ $key ][ $subkeys[1] ][ $subkeys[2] ] ?? $default; 1298 } 1299 } elseif ( 3 === $count ) { 1300 if ( isset( $values[ $key ][ $subkeys[1] ] ) ) { 1301 if ( isset( $values[ $key ][ $subkeys[1] ][ $subkeys[2] ] ) ) { 1302 $value = $values[ $key ][ $subkeys[1] ][ $subkeys[2] ][ $subkeys[3] ] ?? $default; 1303 } 1304 } 1305 } 1306 } 1307 } else { 1308 $value = $values[ $key ] ?? $default; 1309 } 1310 1311 return $value; 1312 } else { 1313 return false; 1314 } 1315 } 1316 1317 /** 1318 * Deprecated Sets an option into the database. 1319 * 1320 * @param string $opt_name Panel opt_name. 1321 * @param string $key Option key. 1322 * @param mixed $option Option value. 1323 * 1324 * @return bool 1325 * @deprecated No longer using camelCase naming convention. 1326 */ 1327 public static function setOption( string $opt_name = '', string $key = '', $option = '' ): bool { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName 1328 if ( '' !== $opt_name ) { 1329 Redux_Functions_Ex::record_caller( $opt_name ); 1330 } 1331 1332 return self::set_option( $opt_name, $key, $option ); 1333 } 1334 1335 /** 1336 * Sets an option into the database. 1337 * 1338 * @param string $opt_name Panel opt_name. 1339 * @param string $key Option key. 1340 * @param mixed $option Option value. 1341 * 1342 * @return bool 1343 */ 1344 public static function set_option( string $opt_name = '', string $key = '', $option = '' ): bool { 1345 if ( '' === $key ) { 1346 return false; 1347 } 1348 1349 self::check_opt_name( $opt_name ); 1350 1351 Redux_Functions_Ex::record_caller( $opt_name ); 1352 1353 if ( '' !== $opt_name ) { 1354 $redux = get_option( $opt_name ); 1355 $redux[ $key ] = $option; 1356 1357 return update_option( $opt_name, $redux ); 1358 } else { 1359 return false; 1360 } 1361 } 1362 1363 /** 1364 * Get next availablt priority for field/section. 1365 * 1366 * @param string $opt_name Panel opt_name. 1367 * @param string $type Field or section. 1368 * 1369 * @return mixed 1370 */ 1371 public static function get_priority( string $opt_name, string $type ) { 1372 $priority = self::$priority[ $opt_name ][ $type ]; 1373 self::$priority[ $opt_name ][ $type ] += 1; 1374 1375 return $priority; 1376 } 1377 1378 /** 1379 * Check opt_name integrity. 1380 * 1381 * @param string $opt_name Panel opt_name. 1382 */ 1383 public static function check_opt_name( string $opt_name = '' ) { 1384 if ( empty( $opt_name ) || is_array( $opt_name ) ) { 1385 return; 1386 } 1387 1388 if ( ! isset( self::$sections[ $opt_name ] ) ) { 1389 self::$sections[ $opt_name ] = array(); 1390 self::$priority[ $opt_name ]['sections'] = 1; 1391 } 1392 1393 if ( ! isset( self::$args[ $opt_name ] ) ) { 1394 self::$args[ $opt_name ] = array(); 1395 self::$priority[ $opt_name ]['args'] = 1; 1396 } 1397 1398 if ( ! isset( self::$fields[ $opt_name ] ) ) { 1399 self::$fields[ $opt_name ] = array(); 1400 self::$priority[ $opt_name ]['fields'] = 1; 1401 } 1402 1403 if ( ! isset( self::$help[ $opt_name ] ) ) { 1404 self::$help[ $opt_name ] = array(); 1405 self::$priority[ $opt_name ]['help'] = 1; 1406 } 1407 1408 if ( ! isset( self::$errors[ $opt_name ] ) ) { 1409 self::$errors[ $opt_name ] = array(); 1410 } 1411 1412 if ( ! isset( self::$init[ $opt_name ] ) ) { 1413 self::$init[ $opt_name ] = false; 1414 } 1415 } 1416 1417 /** 1418 * Retrieve metadata from a file. Based on WP Core's get_file_data function 1419 * 1420 * @param string $file Path to the file. 1421 * 1422 * @return string 1423 * @since 2.1.1 1424 */ 1425 public static function get_file_version( string $file ): string { 1426 $data = get_file_data( $file, array( 'version' ), 'plugin' ); 1427 1428 return $data[0]; 1429 } 1430 1431 /** 1432 * Verify extension class name. 1433 * 1434 * @param string $opt_name Panel opt_name. 1435 * @param string $name extension name. 1436 * @param string $class_file Extension class file. 1437 */ 1438 private static function check_extension_class_file( string $opt_name, string $name = '', string $class_file = '' ) { 1439 $instance = null; 1440 1441 if ( file_exists( $class_file ) ) { 1442 self::$uses_extensions[ $opt_name ] = self::$uses_extensions[ $opt_name ] ?? array(); 1443 1444 if ( ! in_array( $name, self::$uses_extensions[ $opt_name ], true ) ) { 1445 self::$uses_extensions[ $opt_name ][] = $name; 1446 } 1447 1448 self::$extensions[ $name ] = self::$extensions[ $name ] ?? array(); 1449 1450 $version = Redux_Helpers::get_template_version( $class_file ); 1451 1452 if ( empty( $version ) && ! empty( $instance ) ) { 1453 if ( isset( $instance->version ) ) { 1454 $version = $instance->version; 1455 } 1456 } 1457 self::$extensions[ $name ][ $version ] = self::$extensions[ $name ][ $version ] ?? $class_file; 1458 1459 $new_name = str_replace( '_', '-', $name ); 1460 $api_check = str_replace( 1461 array( 1462 'extension_' . $name, 1463 'class-redux-extension-' . $new_name, 1464 ), 1465 array( 1466 $name . '_api', 1467 'class-redux-' . $new_name . '-api', 1468 ), 1469 $class_file 1470 ); 1471 1472 if ( file_exists( $api_check ) && ! class_exists( 'Redux_' . ucfirst( $name ) ) ) { 1473 include_once $api_check; 1474 } 1475 } 1476 } 1477 1478 /** 1479 * Deprecated Sets all extensions in path. 1480 * 1481 * @param string $opt_name Panel opt_name. 1482 * @param string $path Path to extension folder. 1483 * 1484 * @deprecated No longer using camelCase naming convention. 1485 */ 1486 public static function setExtensions( string $opt_name, string $path ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName 1487 if ( '' !== $opt_name ) { 1488 Redux_Functions_Ex::record_caller( $opt_name ); 1489 } 1490 1491 self::set_extensions( $opt_name, $path ); 1492 } 1493 1494 /** 1495 * Sets all extensions in path. 1496 * 1497 * @param string $opt_name Panel opt_name. 1498 * @param string $path Path to extension folder. 1499 * @param bool $force Make extension reload. 1500 */ 1501 public static function set_extensions( string $opt_name, string $path, bool $force = false ) { 1502 if ( '' === $path || '' === $opt_name ) { 1503 return; 1504 } 1505 1506 if ( version_compare( PHP_VERSION, '5.5.0', '<' ) ) { 1507 include_once Redux_Core::$dir . 'inc/lib/array-column.php'; 1508 } 1509 1510 self::check_opt_name( $opt_name ); 1511 1512 Redux_Functions_Ex::record_caller( $opt_name ); 1513 1514 if ( is_dir( $path ) ) { 1515 $path = trailingslashit( $path ); 1516 $folder = str_replace( '.php', '', basename( $path ) ); 1517 1518 $folder_fix = str_replace( '_', '-', $folder ); 1519 1520 $files = array( 1521 $path . 'extension_' . $folder . '.php', 1522 $path . 'class-redux-extension-' . $folder_fix . '.php', 1523 ); 1524 1525 $ext_file = Redux_Functions::file_exists_ex( $files ); 1526 1527 if ( $ext_file ) { 1528 self::check_extension_class_file( $opt_name, $folder, $ext_file ); 1529 } else { 1530 $folders = scandir( $path, 1 ); 1531 1532 foreach ( $folders as $folder ) { 1533 if ( '.' === $folder || '..' === $folder ) { 1534 continue; 1535 } 1536 1537 if ( is_dir( $path . $folder ) ) { 1538 self::set_extensions( $opt_name, $path . $folder ); 1539 } 1540 } 1541 } 1542 } elseif ( file_exists( $path ) ) { 1543 $name = explode( 'extension_', basename( $path ) ); 1544 if ( isset( $name[1] ) && ! empty( $name[1] ) ) { 1545 $name = str_replace( '.php', '', $name[1] ); 1546 self::check_extension_class_file( $opt_name, $name, $path ); 1547 } 1548 } 1549 1550 self::$extension_paths[ $opt_name ] = $path; 1551 1552 if ( true === $force ) { 1553 if ( isset( self::$uses_extensions[ $opt_name ] ) && ! empty( self::$uses_extensions[ $opt_name ] ) ) { 1554 $redux = self::instance( $opt_name ); 1555 1556 if ( isset( $redux ) ) { 1557 self::load_extensions( $redux ); 1558 } 1559 } 1560 } 1561 } 1562 1563 /** 1564 * Retrieves all loaded extensions. 1565 */ 1566 private static function get_all_extension() { 1567 $redux = self::all_instances(); 1568 1569 foreach ( $redux as $instance ) { 1570 if ( ! empty( self::$uses_extensions[ $instance['args']['opt_name'] ] ) ) { 1571 continue; 1572 } 1573 if ( ! empty( $instance['extensions'] ) ) { 1574 self::get_instance_extension( $instance['args']['opt_name'], $instance ); 1575 } 1576 } 1577 } 1578 1579 /** 1580 * Gets all loaded extension for the passed ReduxFramework instance. 1581 * 1582 * @param string $opt_name Panel opt_name. 1583 * @param object|null $instance ReduxFramework instance. 1584 */ 1585 public static function get_instance_extension( string $opt_name, $instance ) { 1586 if ( ! empty( self::$uses_extensions[ $opt_name ] ) || empty( $opt_name ) ) { 1587 return; 1588 } 1589 1590 if ( empty( $instance ) ) { 1591 $instance = self::instance( $opt_name ); 1592 } 1593 1594 if ( empty( $instance ) || empty( $instance->extensions ) ) { 1595 return; 1596 } 1597 1598 foreach ( $instance->extensions as $name => $extension ) { 1599 if ( 'widget_areas' === $name ) { 1600 $new = new Redux_Widget_Areas( $instance ); 1601 } 1602 1603 if ( isset( self::$uses_extensions[ $opt_name ][ $name ] ) ) { 1604 continue; 1605 } 1606 1607 if ( isset( $extension->extension_dir ) ) { 1608 self::set_extensions( $opt_name, str_replace( $name, '', $extension->extension_dir ) ); 1609 } elseif ( isset( $extension->extension_dir ) ) { 1610 self::set_extensions( $opt_name, str_replace( $name, '', $extension->extension_dir ) ); 1611 } 1612 } 1613 } 1614 1615 /** 1616 * Deprecated Gets loaded extensions. 1617 * 1618 * @param string $opt_name Panel opt_name. 1619 * @param string $key Extension name. 1620 * 1621 * @return array|bool|mixed 1622 * @deprecated No longer using camelCase naming convention. 1623 */ 1624 public static function getExtensions( string $opt_name = '', string $key = '' ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName 1625 _deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'Redux 4.0.0', 'self::get_extensions( $opt_name, $key )' ); 1626 1627 return self::get_extensions( $opt_name, $key ); 1628 } 1629 1630 /** 1631 * Gets loaded extensions. 1632 * 1633 * @param string $opt_name Panel opt_name. 1634 * @param string $key Extension name. 1635 * 1636 * @return array|bool|mixed 1637 */ 1638 public static function get_extensions( string $opt_name = '', string $key = '' ) { 1639 if ( empty( $opt_name ) ) { 1640 self::get_all_extension(); 1641 1642 if ( empty( $key ) ) { 1643 return self::$extension_paths; 1644 } else { 1645 if ( isset( self::$extension_paths[ $key ] ) ) { 1646 return self::$extension_paths[ $key ]; 1647 } 1648 } 1649 } else { 1650 if ( empty( self::$uses_extensions[ $opt_name ] ) ) { 1651 self::get_instance_extension( $opt_name, null ); 1652 } 1653 1654 if ( empty( self::$uses_extensions[ $opt_name ] ) ) { 1655 return false; 1656 } 1657 1658 $instance_extensions = array(); 1659 1660 foreach ( self::$uses_extensions[ $opt_name ] as $extension ) { 1661 $class_file = end( self::$extensions[ $extension ] ); 1662 $directory = explode( DIRECTORY_SEPARATOR, $class_file ); 1663 array_pop( $directory ); 1664 $directory = trailingslashit( join( DIRECTORY_SEPARATOR, $directory ) ); 1665 $name = str_replace( '.php', '', basename( $extension ) ); 1666 $extension_class = 'Redux_Extension_' . $name; 1667 $the_data = array( 1668 'path' => $class_file, 1669 'dir' => $directory, 1670 'class' => $extension_class, 1671 'version' => Redux_Helpers::get_template_version( $class_file ), 1672 ); 1673 1674 if ( is_dir( $the_data['dir'] . $extension ) ) { 1675 $test_path = trailingslashit( $the_data['dir'] . $extension ); 1676 if ( file_exists( $test_path . 'field_' . str_replace( '-', '', $extension ) . '.php' ) ) { 1677 $the_data['field'] = $test_path . 'field_' . str_replace( '-', '', $extension ) . '.php'; 1678 } 1679 // Old extensions! 1680 if ( file_exists( $test_path . str_replace( '-', '', $extension ) . '.php' ) ) { 1681 $the_data['field'] = $test_path . str_replace( '-', '', $extension ) . '.php'; 1682 } 1683 } 1684 $instance_extensions[ $extension ] = $the_data; 1685 } 1686 1687 return $instance_extensions; 1688 } 1689 1690 return false; 1691 } 1692 1693 /** 1694 * Method to disables Redux demo mode popup. 1695 */ 1696 public static function disable_demo() { 1697 add_action( 'ReduxFrameworkPlugin_admin_notice', 'Redux::remove_demo' ); 1698 add_action( 'redux_framework_plugin_admin_notice', 'Redux::remove_demo' ); 1699 } 1700 1701 /** 1702 * Callback used by self::disable_demo() to remove the demo mode notice from Redux. 1703 */ 1704 public static function remove_demo() { 1705 update_option( 'ReduxFrameworkPlugin_ACTIVATED_NOTICES', '' ); 1706 } 1707 1708 /** 1709 * Function which forces a panel/page to render. 1710 * 1711 * @param string|object $redux Panel opt_name or Redux object. 1712 */ 1713 public static function render( $redux = '' ) { 1714 if ( is_string( $redux ) ) { 1715 $redux = Redux_Instances::get_instance( $redux ); 1716 if ( empty( $redux ) ) { 1717 return; 1718 } 1719 } 1720 $enqueue = new Redux_Enqueue( $redux ); 1721 $enqueue->init(); 1722 $panel = new \Redux_Panel( $redux ); 1723 $panel->init(); 1724 } 1725 } 1726 1727 Redux::load(); 1728 }