551 lines
12 KiB
PHP
551 lines
12 KiB
PHP
<?php
|
|
/**
|
|
* Base class for handling managers. Managers are groups of sections, which are groups of
|
|
* controls + settings. Managers are output as a metabox. This essentially allows
|
|
* developers to output multiple post meta fields within a single metabox.
|
|
*
|
|
* @package ButterBean
|
|
* @author Justin Tadlock <justin@justintadlock.com>
|
|
* @copyright Copyright (c) 2015-2016, Justin Tadlock
|
|
* @link https://github.com/justintadlock/butterbean
|
|
* @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|
*/
|
|
|
|
/**
|
|
* Base manager class.
|
|
*
|
|
* @since 1.0.0
|
|
* @access public
|
|
*/
|
|
class ButterBean_Manager {
|
|
|
|
/**
|
|
* The type of manager.
|
|
*
|
|
* @since 1.0.0
|
|
* @access public
|
|
* @var string
|
|
*/
|
|
public $type = 'default';
|
|
|
|
/**
|
|
* Name of this instance of the manager.
|
|
*
|
|
* @since 1.0.0
|
|
* @access public
|
|
* @var string
|
|
*/
|
|
public $name = '';
|
|
|
|
/**
|
|
* Label for the manager.
|
|
*
|
|
* @since 1.0.0
|
|
* @access public
|
|
* @var string
|
|
*/
|
|
public $label = '';
|
|
|
|
/**
|
|
* Post type this manager is used on.
|
|
*
|
|
* @since 1.0.0
|
|
* @access public
|
|
* @var string|array
|
|
*/
|
|
public $post_type = 'post';
|
|
|
|
/**
|
|
* Location of the meta box. Accepted values: 'normal', 'advanced', 'side'.
|
|
*
|
|
* @link https://developer.wordpress.org/reference/functions/add_meta_box/
|
|
* @since 1.0.0
|
|
* @access public
|
|
* @var string
|
|
*/
|
|
public $context = 'advanced';
|
|
|
|
/**
|
|
* Priority of the meta box. Accepted values: 'high', 'core', 'default', 'low'.
|
|
*
|
|
* @link https://developer.wordpress.org/reference/functions/add_meta_box/
|
|
* @since 1.0.0
|
|
* @access public
|
|
* @var string
|
|
*/
|
|
public $priority = 'default';
|
|
|
|
/**
|
|
* Array of sections.
|
|
*
|
|
* @since 1.0.0
|
|
* @access public
|
|
* @var array
|
|
*/
|
|
public $sections = array();
|
|
|
|
/**
|
|
* Array of controls.
|
|
*
|
|
* @since 1.0.0
|
|
* @access public
|
|
* @var array
|
|
*/
|
|
public $controls = array();
|
|
|
|
/**
|
|
* Array of settings.
|
|
*
|
|
* @since 1.0.0
|
|
* @access public
|
|
* @var array
|
|
*/
|
|
public $settings = array();
|
|
|
|
/**
|
|
* A user role capability required to show the manager.
|
|
*
|
|
* @since 1.0.0
|
|
* @access public
|
|
* @var string|array
|
|
*/
|
|
public $capability = '';
|
|
|
|
/**
|
|
* A feature that the current post type must support to show the manager.
|
|
*
|
|
* @since 1.0.0
|
|
* @access public
|
|
* @var string
|
|
*/
|
|
public $post_type_supports = '';
|
|
|
|
/**
|
|
* A feature that the current theme must support to show the manager.
|
|
*
|
|
* @since 1.0.0
|
|
* @access public
|
|
* @var string|array
|
|
*/
|
|
public $theme_supports = '';
|
|
|
|
/**
|
|
* Stores the JSON data for the manager.
|
|
*
|
|
* @since 1.0.0
|
|
* @access public
|
|
* @var array()
|
|
*/
|
|
public $json = array();
|
|
|
|
/**
|
|
* ID of the post that's being edited.
|
|
*
|
|
* @since 1.0.0
|
|
* @access public
|
|
* @var int
|
|
*/
|
|
public $post_id = 0;
|
|
|
|
/**
|
|
* Sets up the manager.
|
|
*
|
|
* @since 1.0.0
|
|
* @access public
|
|
* @param string $name
|
|
* @param array $args
|
|
* @return void
|
|
*/
|
|
public function __construct( $name, $args = array() ) {
|
|
|
|
foreach ( array_keys( get_object_vars( $this ) ) as $key ) {
|
|
|
|
if ( isset( $args[ $key ] ) )
|
|
$this->$key = $args[ $key ];
|
|
}
|
|
|
|
// Make sure the post type is an array.
|
|
$this->post_type = (array) $this->post_type;
|
|
|
|
// Set the manager name.
|
|
$this->name = sanitize_key( $name );
|
|
}
|
|
|
|
/**
|
|
* Enqueue scripts/styles for the manager.
|
|
*
|
|
* @since 1.0.0
|
|
* @access public
|
|
* @return void
|
|
*/
|
|
public function enqueue() {}
|
|
|
|
/**
|
|
* Register a section.
|
|
*
|
|
* @since 1.0.0
|
|
* @access public
|
|
* @param object|string $section
|
|
* @param array $args
|
|
* @return void
|
|
*/
|
|
public function register_section( $section, $args = array() ) {
|
|
|
|
if ( ! is_object( $section ) ) {
|
|
|
|
$type = isset( $args['type'] ) ? butterbean()->get_section_type( $args['type'] ) : butterbean()->get_section_type( 'default' );
|
|
|
|
$section = new $type( $this, $section, $args );
|
|
}
|
|
|
|
if ( ! $this->section_exists( $section->name ) )
|
|
$this->sections[ $section->name ] = $section;
|
|
}
|
|
|
|
/**
|
|
* Register a control.
|
|
*
|
|
* @since 1.0.0
|
|
* @access public
|
|
* @param object|string $control
|
|
* @param array $args
|
|
* @return void
|
|
*/
|
|
public function register_control( $control, $args = array() ) {
|
|
|
|
if ( ! is_object( $control ) ) {
|
|
|
|
$type = isset( $args['type'] ) ? butterbean()->get_control_type( $args['type'] ) : butterbean()->get_control_type( 'default' );
|
|
|
|
$control = new $type( $this, $control, $args );
|
|
}
|
|
|
|
if ( ! $this->control_exists( $control->name ) )
|
|
$this->controls[ $control->name ] = $control;
|
|
}
|
|
|
|
/**
|
|
* Register a setting.
|
|
*
|
|
* @since 1.0.0
|
|
* @access public
|
|
* @param object|string $setting
|
|
* @param array $args
|
|
* @return void
|
|
*/
|
|
public function register_setting( $setting, $args = array() ) {
|
|
|
|
if ( ! is_object( $setting ) ) {
|
|
|
|
$type = isset( $args['type'] ) ? butterbean()->get_setting_type( $args['type'] ) : butterbean()->get_setting_type( 'default' );
|
|
|
|
$setting = new $type( $this, $setting, $args );
|
|
}
|
|
|
|
if ( ! $this->setting_exists( $setting->name ) )
|
|
$this->settings[ $setting->name ] = $setting;
|
|
}
|
|
|
|
/**
|
|
* Register a control and setting object.
|
|
*
|
|
* @since 1.0.0
|
|
* @access public
|
|
* @param string $name
|
|
* @param object|array $control Control object or array of control arguments.
|
|
* @param object|array $setting Setting object or array of setting arguments.
|
|
* @return void
|
|
*/
|
|
public function register_field( $name, $control, $setting ) {
|
|
|
|
is_object( $control ) ? $this->register_control( $control ) : $this->register_control( $name, $control );
|
|
is_object( $setting ) ? $this->register_setting( $setting ) : $this->register_setting( $name, $setting );
|
|
}
|
|
|
|
/**
|
|
* Unregisters a section object.
|
|
*
|
|
* @since 1.0.0
|
|
* @access public
|
|
* @param string $name
|
|
* @return void
|
|
*/
|
|
public function unregister_section( $name ) {
|
|
|
|
if ( $this->section_exists( $name ) )
|
|
unset( $this->sections[ $name ] );
|
|
}
|
|
|
|
/**
|
|
* Unregisters a control object.
|
|
*
|
|
* @since 1.0.0
|
|
* @access public
|
|
* @param string $name
|
|
* @return void
|
|
*/
|
|
public function unregister_control( $name ) {
|
|
|
|
if ( $this->control_exists( $name ) )
|
|
unset( $this->controls[ $name ] );
|
|
}
|
|
|
|
/**
|
|
* Unregisters a setting object.
|
|
*
|
|
* @since 1.0.0
|
|
* @access public
|
|
* @param string $name
|
|
* @return void
|
|
*/
|
|
public function unregister_setting( $name ) {
|
|
|
|
if ( $this->setting_exists( $name ) )
|
|
unset( $this->settings[ $name ] );
|
|
}
|
|
|
|
/**
|
|
* Unregisters a control and setting object.
|
|
*
|
|
* @since 1.0.0
|
|
* @access public
|
|
* @param string $name
|
|
* @return void
|
|
*/
|
|
public function unregister_field( $name ) {
|
|
|
|
$this->unregister_control( $name );
|
|
$this->unregister_setting( $name );
|
|
}
|
|
|
|
/**
|
|
* Returns a section object.
|
|
*
|
|
* @since 1.0.0
|
|
* @access public
|
|
* @param string $name
|
|
* @return object|bool
|
|
*/
|
|
public function get_section( $name ) {
|
|
|
|
return $this->section_exists( $name ) ? $this->sections[ $name ] : false;
|
|
}
|
|
|
|
/**
|
|
* Returns a control object.
|
|
*
|
|
* @since 1.0.0
|
|
* @access public
|
|
* @param string $name
|
|
* @return object|bool
|
|
*/
|
|
public function get_control( $name ) {
|
|
|
|
return $this->control_exists( $name ) ? $this->controls[ $name ] : false;
|
|
}
|
|
|
|
/**
|
|
* Returns a setting object.
|
|
*
|
|
* @since 1.0.0
|
|
* @access public
|
|
* @param string $name
|
|
* @return object|bool
|
|
*/
|
|
public function get_setting( $name ) {
|
|
|
|
return $this->setting_exists( $name ) ? $this->settings[ $name ] : false;
|
|
}
|
|
|
|
/**
|
|
* Returns an object that contains both the control and setting objects.
|
|
*
|
|
* @since 1.0.0
|
|
* @access public
|
|
* @param string $name
|
|
* @return object|bool
|
|
*/
|
|
public function get_field( $name ) {
|
|
|
|
$control = $this->get_control( $name );
|
|
$setting = $this->get_setting( $name );
|
|
|
|
$field = array( 'name' => $name, 'control' => $control, 'setting' => $setting );
|
|
|
|
return $control && $setting ? (object) $field : false;
|
|
}
|
|
|
|
/**
|
|
* Checks if a section exists.
|
|
*
|
|
* @since 1.0.0
|
|
* @access public
|
|
* @param string $name
|
|
* @return bool
|
|
*/
|
|
public function section_exists( $name ) {
|
|
|
|
return isset( $this->sections[ $name ] );
|
|
}
|
|
|
|
/**
|
|
* Checks if a control exists.
|
|
*
|
|
* @since 1.0.0
|
|
* @access public
|
|
* @param string $name
|
|
* @return bool
|
|
*/
|
|
public function control_exists( $name ) {
|
|
|
|
return isset( $this->controls[ $name ] );
|
|
}
|
|
|
|
/**
|
|
* Checks if a setting exists.
|
|
*
|
|
* @since 1.0.0
|
|
* @access public
|
|
* @param string $name
|
|
* @return bool
|
|
*/
|
|
public function setting_exists( $name ) {
|
|
|
|
return isset( $this->settings[ $name ] );
|
|
}
|
|
|
|
/**
|
|
* Checks if a both a control and setting exist.
|
|
*
|
|
* @since 1.0.0
|
|
* @access public
|
|
* @param string $name
|
|
* @return bool
|
|
*/
|
|
public function field_exists( $name ) {
|
|
|
|
return $this->control_exists( $name ) && $this->setting_exists( $name );
|
|
}
|
|
|
|
/**
|
|
* Returns the json array.
|
|
*
|
|
* @since 1.0.0
|
|
* @access public
|
|
* @return array
|
|
*/
|
|
public function get_json() {
|
|
$this->to_json();
|
|
|
|
return $this->json;
|
|
}
|
|
|
|
/**
|
|
* Adds custom data to the JSON array. This data is passed to the Underscore template.
|
|
*
|
|
* @since 1.0.0
|
|
* @access public
|
|
* @return void
|
|
*/
|
|
public function to_json() {
|
|
|
|
$sections_with_controls = array();
|
|
$blocked_sections = array();
|
|
|
|
$this->json['name'] = $this->name;
|
|
$this->json['type'] = $this->type;
|
|
|
|
// Get all sections that have controls.
|
|
foreach ( $this->controls as $control )
|
|
$sections_with_controls[] = $control->section;
|
|
|
|
$sections_with_controls = array_unique( $sections_with_controls );
|
|
|
|
// Get the JSON data for each section.
|
|
foreach ( $this->sections as $section ) {
|
|
|
|
$caps = $section->check_capabilities();
|
|
|
|
if ( $caps && in_array( $section->name, $sections_with_controls ) )
|
|
$this->json['sections'][] = $section->get_json();
|
|
|
|
if ( ! $caps )
|
|
$blocked_sections[] = $section->name;
|
|
}
|
|
|
|
// Get the JSON data for each control.
|
|
foreach ( $this->controls as $control ) {
|
|
|
|
if ( $control->check_capabilities() && ! in_array( $control->section, $blocked_sections ) )
|
|
$this->json['controls'][] = $control->get_json();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Saves each of the settings for the manager.
|
|
*
|
|
* @since 1.0.0
|
|
* @access public
|
|
* @return void
|
|
*/
|
|
public function save( $post_id ) {
|
|
|
|
if ( ! $this->post_id )
|
|
$this->post_id = $post_id;
|
|
|
|
// Verify the nonce for this manager.
|
|
if ( ! isset( $_POST["butterbean_{$this->name}"] ) || ! wp_verify_nonce( sanitize_key( wp_unslash($_POST["butterbean_{$this->name}"] ) ), "butterbean_{$this->name}_nonce" ) )
|
|
return;
|
|
|
|
// Loop through each setting and save it.
|
|
foreach ( $this->settings as $setting )
|
|
$setting->save();
|
|
}
|
|
|
|
/**
|
|
* Checks if the control should be allowed at all.
|
|
*
|
|
* @since 1.0.0
|
|
* @access public
|
|
* @return bool
|
|
*/
|
|
public function check_capabilities() {
|
|
|
|
if ( $this->capability && ! call_user_func_array( 'current_user_can', (array) $this->capability ) )
|
|
return false;
|
|
|
|
if ( $this->post_type_supports && ! call_user_func_array( 'post_type_supports', array( get_post_type( $this->manager->post_id ), $this->post_type_supports ) ) )
|
|
return false;
|
|
|
|
if ( $this->theme_supports && ! call_user_func_array( 'theme_supports', (array) $this->theme_supports ) )
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Prints Underscore.js template.
|
|
*
|
|
* @since 1.0.0
|
|
* @access public
|
|
* @return void
|
|
*/
|
|
public function print_template() { ?>
|
|
|
|
<script type="text/html" id="tmpl-butterbean-manager-<?php echo esc_attr( $this->type ); ?>">
|
|
<?php $this->get_template(); ?>
|
|
</script>
|
|
<?php }
|
|
|
|
/**
|
|
* Gets the Underscore.js template.
|
|
*
|
|
* @since 1.0.0
|
|
* @access public
|
|
* @return void
|
|
*/
|
|
public function get_template() {
|
|
butterbean_get_manager_template( $this->type );
|
|
}
|
|
}
|