class-redux-metaboxes-api.php (19708B)
1 <?php // phpcs:ignore WordPress.NamingConventions.ValidFunctionName 2 /** 3 * Redux Framework Metaboxes API Class 4 * Makes instantiating a Redux Metasbox object an absolute piece of cake. 5 * 6 * @package Redux_Framework 7 * @author Dovy Paukstys 8 * @subpackage Core 9 */ 10 11 defined( 'ABSPATH' ) || exit; 12 13 // Don't duplicate me! 14 if ( ! class_exists( 'Redux_Metaboxes' ) ) { 15 16 /** 17 * Redux Metaboxes API Class 18 * Simple API for Redux Framework 19 * 20 * @since 1.0.0 21 */ 22 class Redux_Metaboxes { 23 24 /** 25 * Boxes array. 26 * 27 * @var array 28 */ 29 public static $boxes = array(); 30 31 /** 32 * Sections array. 33 * 34 * @var array 35 */ 36 public static $sections = array(); 37 38 /** 39 * Feilds array. 40 * 41 * @var array 42 */ 43 public static $fields = array(); 44 45 /** 46 * Priority array. 47 * 48 * @var array 49 */ 50 public static $priority = array(); 51 52 /** 53 * Errors array. 54 * 55 * @var array 56 */ 57 public static $errors = array(); 58 59 /** 60 * Init array. 61 * 62 * @var array 63 */ 64 public static $init = array(); 65 66 /** 67 * Args array. 68 * 69 * @var array 70 */ 71 public static $args = array(); 72 73 /** 74 * Code has run flag. 75 * 76 * @var bool 77 */ 78 public static $has_run = false; 79 80 /** 81 * Class load. 82 */ 83 public static function load() { 84 if ( version_compare( PHP_VERSION, '5.5.0', '<' ) ) { 85 include_once Redux_Core::$dir . 'inc/lib/array-column.php'; 86 } 87 88 add_action( 'init', array( 'Redux_Metaboxes', 'enqueue' ), 99 ); 89 } 90 91 /** 92 * Enqueue function. 93 */ 94 public static function enqueue() { 95 global $pagenow; 96 97 // Check and run instances of Redux where the opt_name hasn't been run. 98 $pagenows = array( 'post-new.php', 'post.php' ); 99 if ( ! empty( self::$sections ) && in_array( $pagenow, $pagenows, true ) ) { 100 $instances = ReduxFrameworkInstances::get_all_instances(); 101 102 foreach ( self::$fields as $opt_name => $fields ) { 103 if ( ! isset( $instances[ $opt_name ] ) ) { 104 Redux::setArgs( 105 $opt_name, 106 array( 107 'menu_type' => 'hidden', 108 ) 109 ); 110 111 Redux::setSections( 112 $opt_name, 113 array( 114 array( 115 'id' => 'EXTENSION_FAKE_ID' . $opt_name, 116 'fields' => $fields, 117 'title' => 'N/A', 118 ), 119 ) 120 ); 121 122 Redux::init( $opt_name ); 123 } 124 } 125 126 $instances = ReduxFrameworkInstances::get_all_instances(); 127 128 add_action( 'admin_enqueue_scripts', array( $instances[ $opt_name ], '_enqueue' ), 1 ); 129 } 130 } 131 132 /** 133 * Filter Metaboxes function. 134 * 135 * @deprecated 4.0.0 No more camelCase. 136 */ 137 public static function filterMetaboxes() { // phpcs:ignore: WordPress.NamingConventions.ValidFunctionName 138 self::filter_metaboxes(); 139 } 140 141 /** 142 * Filter Metaboxes function. 143 */ 144 public static function filter_metaboxes() { 145 if ( true === self::$has_run ) { 146 return; 147 } 148 149 if ( ! class_exists( 'ReduxFramework' ) ) { 150 echo '<div id="message" class="error"><p>Redux Framework is <strong>not installed</strong>. Please install it.</p></div>'; 151 152 return; 153 } 154 155 foreach ( self::$boxes as $opt_name => $the_boxes ) { 156 if ( ! self::$init[ $opt_name ] ) { 157 158 // phpcs:ignore WordPress.NamingConventions.ValidHookName 159 add_action( 'redux/metaboxes/' . $opt_name . '/boxes', array( 'Redux_Metaboxes', 'addMetaboxes' ), 2 ); 160 } 161 } 162 163 self::$has_run = true; 164 } 165 166 /** 167 * Constuct global args array. 168 * 169 * @param string $opt_name Panel opt_name. 170 * 171 * @return mixed 172 * @deprecated 4.0.0 No more camelCase. 173 */ 174 public static function constructArgs( string $opt_name ) { // phpcs:ignore: WordPress.NamingConventions.ValidFunctionName 175 return self::construct_args( $opt_name ); 176 } 177 178 /** 179 * Constuct global args array. 180 * 181 * @param string $opt_name Panel opt_name. 182 * 183 * @return mixed 184 */ 185 public static function construct_args( string $opt_name ) { 186 Redux_Functions_Ex::record_caller( $opt_name ); 187 188 $args = self::$args[ $opt_name ]; 189 $args['opt_name'] = $opt_name; 190 191 if ( ! isset( $args['menu_title'] ) ) { 192 $args['menu_title'] = ucfirst( $opt_name ) . ' Options'; 193 } 194 195 if ( ! isset( $args['page_title'] ) ) { 196 $args['page_title'] = ucfirst( $opt_name ) . ' Options'; 197 } 198 199 if ( ! isset( $args['page_slug'] ) ) { 200 $args['page_slug'] = $opt_name . '_options'; 201 } 202 203 return $args; 204 } 205 206 /** 207 * Construct metabox boxes array. 208 * 209 * @param string $opt_name Panel opt_name. 210 * 211 * @return array 212 * 213 * @deprecated 4.0.0 No more camelCase. 214 */ 215 public static function constructBoxes( string $opt_name ): array { // phpcs:ignore: WordPress.NamingConventions.ValidFunctionName 216 return self::construct_boxes( $opt_name ); 217 } 218 219 220 /** 221 * Construct metabox boxes array. 222 * 223 * @param string $opt_name Panel opt_name. 224 * 225 * @return array 226 */ 227 public static function construct_boxes( string $opt_name ): array { 228 Redux_Functions_Ex::record_caller( $opt_name ); 229 230 $boxes = array(); 231 if ( ! isset( self::$boxes[ $opt_name ] ) ) { 232 return $boxes; 233 } 234 235 foreach ( self::$boxes[ $opt_name ] as $box_id => $box ) { 236 $box['sections'] = self::construct_sections( $opt_name, $box['id'] ); 237 $boxes[] = $box; 238 } 239 240 ksort( $boxes ); 241 242 return $boxes; 243 } 244 245 /** 246 * Construct sections. 247 * 248 * @param string $opt_name Panel opt_name. 249 * @param string $box_id Metabox ID. 250 * 251 * @return array 252 * 253 * @deprecated 4.0.0 No more camelCase. 254 */ 255 public static function constructSections( string $opt_name, string $box_id ): array { // phpcs:ignore: WordPress.NamingConventions.ValidFunctionName 256 return self::construct_sections( $opt_name, $box_id ); 257 } 258 259 /** 260 * Construct sections. 261 * 262 * @param string $opt_name Panel opt_name. 263 * @param string $box_id Metabox ID. 264 * 265 * @return array 266 */ 267 public static function construct_sections( string $opt_name, string $box_id ): array { 268 Redux_Functions_Ex::record_caller( $opt_name ); 269 270 $sections = array(); 271 if ( ! isset( self::$sections[ $opt_name ] ) ) { 272 return $sections; 273 } 274 275 foreach ( self::$sections[ $opt_name ] as $section_id => $section ) { 276 if ( $box_id === $section['box_id'] ) { 277 $p = $section['priority']; 278 279 while ( isset( $sections[ $p ] ) ) { 280 echo esc_html( $p ++ ); 281 } 282 283 $section['fields'] = self::construct_fields( $opt_name, $section_id ); 284 $sections[ $p ] = $section; 285 } 286 } 287 288 ksort( $sections ); 289 290 return $sections; 291 } 292 293 /** 294 * Construct fields. 295 * 296 * @param string $opt_name Panel opt_name. 297 * @param string|int $section_id Section ID. 298 * 299 * @return array 300 * @deprecated 4.0.0 No moe camelCase. 301 */ 302 public static function constructFields( string $opt_name = '', $section_id = '' ): array { // phpcs:ignore: WordPress.NamingConventions.ValidFunctionName 303 return self::construct_fields( $opt_name, $section_id ); 304 } 305 306 /** 307 * Construct fields. 308 * 309 * @param string $opt_name Panel opt_name. 310 * @param string|int $section_id Section ID. 311 * 312 * @return array 313 */ 314 public static function construct_fields( string $opt_name = '', $section_id = '' ): array { 315 Redux_Functions_Ex::record_caller( $opt_name ); 316 317 $fields = array(); 318 319 if ( ! isset( self::$fields[ $opt_name ] ) ) { 320 return $fields; 321 } 322 323 foreach ( self::$fields[ $opt_name ] as $key => $field ) { 324 if ( $section_id === $field['section_id'] ) { 325 $p = $field['priority']; 326 327 while ( isset( $fields[ $p ] ) ) { 328 echo esc_html( $p ++ ); 329 } 330 331 $fields[ $p ] = $field; 332 } 333 } 334 335 ksort( $fields ); 336 337 return $fields; 338 } 339 340 /** 341 * Retrieve section array. 342 * 343 * @param string $opt_name Panel opt_name. 344 * @param string|int $id Section ID. 345 * 346 * @deprecated 4.0.0 No more camelCase. 347 * 348 * @return bool 349 */ 350 public static function getSection( string $opt_name = '', $id = '' ): bool { // phpcs:ignore: WordPress.NamingConventions.ValidFunctionName 351 return self::get_section( $opt_name, $id ); 352 } 353 354 /** 355 * Retrieve section ID. 356 * 357 * @param string $opt_name Panel opt_name. 358 * @param string|int $id Section ID. 359 * 360 * @return bool 361 */ 362 public static function get_section( string $opt_name = '', $id = '' ): bool { 363 self::check_opt_name( $opt_name ); 364 365 if ( ! empty( $opt_name ) && ! empty( $id ) ) { 366 if ( ! isset( self::$sections[ $opt_name ][ $id ] ) ) { 367 $id = strtolower( sanitize_html_class( $id ) ); 368 } 369 370 return self::$sections[ $opt_name ][ $id ] ?? false; 371 } 372 373 return false; 374 } 375 376 /** 377 * Set section array. 378 * 379 * @param string $opt_name Panel opt_name. 380 * @param array $section Section array. 381 * 382 * @deprecated 4.0.0 No more camelCase. 383 */ 384 public static function setSection( string $opt_name = '', array $section = array() ) { // phpcs:ignore: WordPress.NamingConventions.ValidFunctionName 385 self::set_section( $opt_name, $section ); 386 } 387 388 /** 389 * Set section array. 390 * 391 * @param string $opt_name Panel opt_name. 392 * @param array $section Section array. 393 */ 394 public static function set_section( string $opt_name = '', array $section = array() ) { 395 Redux_Functions_Ex::record_caller( $opt_name ); 396 397 self::check_opt_name( $opt_name ); 398 399 if ( ! empty( $opt_name ) && is_array( $section ) && ! empty( $section ) ) { 400 if ( ! isset( $section['id'] ) ) { 401 if ( isset( $section['title'] ) ) { 402 $section['id'] = strtolower( sanitize_html_class( $section['title'] ) ); 403 } else { 404 $section['id'] = 'section'; 405 } 406 407 if ( isset( self::$sections[ $opt_name ][ $section['id'] ] ) ) { 408 $orig = $section['id']; 409 $i = 0; 410 411 while ( isset( self::$sections[ $opt_name ][ $section['id'] ] ) ) { 412 $section['id'] = $orig . '_' . $i; 413 $i++; 414 } 415 } 416 } 417 418 if ( ! isset( $section['priority'] ) ) { 419 $section['priority'] = self::get_priority( $opt_name, 'sections' ); 420 } 421 422 if ( isset( $section['fields'] ) ) { 423 if ( ! empty( $section['fields'] ) && is_array( $section['fields'] ) ) { 424 self::process_fields_array( $opt_name, $section['id'], $section['fields'] ); 425 } 426 unset( $section['fields'] ); 427 } 428 self::$sections[ $opt_name ][ $section['id'] ] = $section; 429 430 } else { 431 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' ); 432 } 433 } 434 435 /** 436 * Process section arrays. 437 * 438 * @param string $opt_name Panel opt_name. 439 * @param string|int $box_id Box ID. 440 * @param array $sections Sections array. 441 */ 442 public static function process_sections_array( string $opt_name = '', $box_id = '', array $sections = array() ) { 443 if ( ! empty( $opt_name ) && ! empty( $box_id ) && is_array( $sections ) && ! empty( $sections ) ) { 444 foreach ( $sections as $section ) { 445 if ( ! is_array( $section ) ) { 446 continue; 447 } 448 449 $section['box_id'] = $box_id; 450 451 if ( ! isset( $section['fields'] ) || ! is_array( $section['fields'] ) ) { 452 $section['fields'] = array(); 453 } 454 455 self::set_section( $opt_name, $section ); 456 } 457 } 458 } 459 460 /** 461 * Process Field arrays. 462 * 463 * @param string $opt_name Panel opt_name. 464 * @param string|int $section_id Section ID. 465 * @param array $fields Field arrays. 466 * 467 * @deprecated 4.0.0 No more camelCase. 468 */ 469 public static function processFieldsArray( string $opt_name = '', $section_id = '', array $fields = array() ) { // phpcs:ignore: WordPress.NamingConventions.ValidFunctionName 470 self::process_fields_array( $opt_name, $section_id, $fields ); 471 } 472 473 /** 474 * Process Field arrays. 475 * 476 * @param string $opt_name Panel opt_name. 477 * @param string|int $section_id Section ID. 478 * @param array $fields Field arrays. 479 */ 480 public static function process_fields_array( string $opt_name = '', $section_id = '', array $fields = array() ) { 481 if ( ! empty( $opt_name ) && ! empty( $section_id ) && is_array( $fields ) && ! empty( $fields ) ) { 482 483 foreach ( $fields as $field ) { 484 if ( ! is_array( $field ) ) { 485 continue; 486 } 487 488 $field['section_id'] = $section_id; 489 490 self::set_field( $opt_name, $field ); 491 } 492 } 493 } 494 495 /** 496 * Retrives field array. 497 * 498 * @param string $opt_name Panel opt_name. 499 * @param string|int $id Field ID. 500 * 501 * @deprecated 4.0.0 No more camelCase. 502 * 503 * @return bool 504 */ 505 public static function getField( string $opt_name = '', $id = '' ): bool { // phpcs:ignore: WordPress.NamingConventions.ValidFunctionName 506 return self::get_field( $opt_name, $id ); 507 } 508 509 /** 510 * Retrives field array. 511 * 512 * @param string $opt_name Panel opt_name. 513 * @param string|int $id Field ID. 514 * 515 * @return bool 516 */ 517 public static function get_field( string $opt_name = '', $id = '' ): bool { 518 self::check_opt_name( $opt_name ); 519 520 if ( ! empty( $opt_name ) && ! empty( $id ) ) { 521 return self::$fields[ $opt_name ][ $id ] ?? false; 522 } 523 524 return false; 525 } 526 527 /** 528 * Set field array. 529 * 530 * @param string $opt_name Panel opt_name. 531 * @param array $field Field array. 532 * 533 * @deprecated 4.0.0 No more camelCase. 534 */ 535 public static function setField( string $opt_name = '', array $field = array() ) { // phpcs:ignore: WordPress.NamingConventions.ValidFunctionName 536 self::set_field( $opt_name, $field ); 537 } 538 539 /** 540 * Set field array. 541 * 542 * @param string $opt_name Panel opt_name. 543 * @param array $field Field array. 544 */ 545 public static function set_field( string $opt_name = '', array $field = array() ) { 546 Redux_Functions_Ex::record_caller( $opt_name ); 547 548 self::check_opt_name( $opt_name ); 549 550 if ( ! empty( $opt_name ) && is_array( $field ) && ! empty( $field ) ) { 551 if ( ! isset( $field['priority'] ) ) { 552 $field['priority'] = self::get_priority( $opt_name, 'fields' ); 553 } 554 555 self::$fields[ $opt_name ][ $field['id'] ] = $field; 556 } 557 } 558 559 /** 560 * Set metabox box. 561 * 562 * @param string $opt_name Panel opt_name. 563 * @param array $box Box array. 564 * 565 * @deprecated 4.0.0 No more camelCase. 566 */ 567 public static function setBox( string $opt_name = '', array $box = array() ) { // phpcs:ignore: WordPress.NamingConventions.ValidFunctionName 568 self::set_box( $opt_name, $box ); 569 } 570 571 /** 572 * Set metabox box. 573 * 574 * @param string $opt_name Panel opt_name. 575 * @param array $box Box array. 576 */ 577 public static function set_box( string $opt_name = '', array $box = array() ) { 578 Redux_Functions_Ex::record_caller( $opt_name ); 579 580 self::check_opt_name( $opt_name ); 581 582 if ( ! empty( $opt_name ) && is_array( $box ) && ! empty( $box ) ) { 583 if ( ! isset( $box['id'] ) ) { 584 if ( isset( $box['title'] ) ) { 585 $box['id'] = strtolower( sanitize_html_class( $box['title'] ) ); 586 } else { 587 $box['id'] = 'box'; 588 } 589 590 if ( isset( self::$boxes[ $opt_name ][ $box['id'] ] ) ) { 591 $orig = $box['id']; 592 $i = 0; 593 594 while ( isset( self::$boxes[ $opt_name ][ $box['id'] ] ) ) { 595 $box['id'] = $orig . '_' . $i; 596 $i++; 597 } 598 } 599 } 600 601 if ( isset( $box['sections'] ) ) { 602 if ( ! empty( $box['sections'] ) && is_array( $box['sections'] ) ) { 603 self::process_sections_array( $opt_name, $box['id'], $box['sections'] ); 604 } 605 606 unset( $box['sections'] ); 607 } 608 609 self::$boxes[ $opt_name ][ $box['id'] ] = $box; 610 } else { 611 self::$errors[ $opt_name ]['box']['empty'] = esc_html__( 'Unable to create a box due an empty box array or the box variable passed was not an array.', 'redux-framework' ); 612 } 613 } 614 615 /** 616 * Set Metaboxes. 617 * 618 * @param string $opt_name Panel opt_name. 619 * @param array $boxes Boxes array. 620 * 621 * @deprecated 4.0.0 No more camelCase. 622 */ 623 public static function setBoxes( string $opt_name = '', array $boxes = array() ) { // phpcs:ignore: WordPress.NamingConventions.ValidFunctionName 624 self::set_boxes( $opt_name, $boxes ); 625 } 626 627 /** 628 * Set Metaboxes. 629 * 630 * @param string $opt_name Panel opt_name. 631 * @param array $boxes Boxes array. 632 */ 633 public static function set_boxes( string $opt_name = '', array $boxes = array() ) { 634 Redux_Functions_Ex::record_caller( $opt_name ); 635 636 if ( ! empty( $boxes ) && is_array( $boxes ) ) { 637 foreach ( $boxes as $box ) { 638 self::set_box( $opt_name, $box ); 639 } 640 } 641 } 642 643 /** 644 * Retrieve Metabox arrays. 645 * 646 * @param string $opt_name Panel opt_name. 647 * 648 * @deprecated 4.0.0 No more camelCase. 649 * 650 * @return mixed 651 */ 652 public static function getBoxes( string $opt_name = '' ) { // phpcs:ignore: WordPress.NamingConventions.ValidFunctionName 653 return self::get_boxes( $opt_name ); 654 } 655 656 /** 657 * Retrieve Metabox arrays. 658 * 659 * @param string $opt_name Panel opt_name. 660 * 661 * @return mixed 662 */ 663 public static function get_boxes( string $opt_name = '' ) { 664 self::check_opt_name( $opt_name ); 665 666 if ( ! empty( $opt_name ) && ! empty( self::$boxes[ $opt_name ] ) ) { 667 return self::$boxes[ $opt_name ]; 668 } 669 } 670 671 /** 672 * Get Metabox box. 673 * 674 * @param string $opt_name Panel opt_name. 675 * @param string $key Box key. 676 * 677 * @deprecated 4.0.0 No more camelCase. 678 * 679 * @return mixed 680 */ 681 public static function getBox( string $opt_name = '', string $key = '' ) { // phpcs:ignore: WordPress.NamingConventions.ValidFunctionName 682 return self::get_box( $opt_name, $key ); 683 } 684 685 /** 686 * Get Metabox box. 687 * 688 * @param string $opt_name Panel opt_name. 689 * @param string $key Box key. 690 * 691 * @return mixed 692 */ 693 public static function get_box( string $opt_name = '', string $key = '' ) { 694 self::check_opt_name( $opt_name ); 695 696 if ( ! empty( $opt_name ) && ! empty( $key ) && ! empty( self::$boxes[ $opt_name ] ) && isset( self::$boxes[ $opt_name ][ $key ] ) ) { 697 return self::$boxes[ $opt_name ][ $key ]; 698 } 699 } 700 701 /** 702 * Get priority. 703 * 704 * @param string $opt_name Panel opt_name. 705 * @param string $type Type. 706 * 707 * @return mixed 708 * 709 * @deprecated 4.0.0 No more camelCase. 710 */ 711 public static function getPriority( string $opt_name, string $type ) { // phpcs:ignore: WordPress.NamingConventions.ValidFunctionName 712 return self::get_priority( $opt_name, $type ); 713 } 714 715 /** 716 * Get priority. 717 * 718 * @param string $opt_name Panel opt_name. 719 * @param string $type Type. 720 * 721 * @return mixed 722 */ 723 public static function get_priority( string $opt_name, string $type ) { 724 $priority = self::$priority[ $opt_name ][ $type ]; 725 self::$priority[ $opt_name ][ $type ] += 1; 726 727 return $priority; 728 } 729 730 /** 731 * Check opt_name. 732 * 733 * @param string $opt_name Panel opt_name. 734 */ 735 public static function check_opt_name( string $opt_name = '' ) { 736 if ( empty( $opt_name ) || is_array( $opt_name ) ) { 737 return; 738 } 739 740 if ( ! isset( self::$boxes[ $opt_name ] ) ) { 741 self::$boxes[ $opt_name ] = array(); 742 } 743 744 if ( ! isset( self::$priority[ $opt_name ] ) ) { 745 self::$priority[ $opt_name ]['args'] = 1; 746 } 747 748 if ( ! isset( self::$sections[ $opt_name ] ) ) { 749 self::$sections[ $opt_name ] = array(); 750 self::$priority[ $opt_name ]['sections'] = 1; 751 } 752 753 if ( ! isset( self::$fields[ $opt_name ] ) ) { 754 self::$fields[ $opt_name ] = array(); 755 self::$priority[ $opt_name ]['fields'] = 1; 756 } 757 758 if ( ! isset( self::$errors[ $opt_name ] ) ) { 759 self::$errors[ $opt_name ] = array(); 760 } 761 762 if ( ! isset( self::$init[ $opt_name ] ) ) { 763 self::$init[ $opt_name ] = false; 764 } 765 766 if ( ! isset( self::$args[ $opt_name ] ) ) { 767 self::$args[ $opt_name ] = false; 768 } 769 } 770 } 771 772 Redux_Metaboxes::load(); 773 }