File Editor
Directories:
.. (Back)
Files:
class-sinatra-meta-boxes.php
Create New File
Create
Edit File: class-sinatra-meta-boxes.php
<?php /** * Meta Boxes class. * * @package Sinatra * @author Sinatra Team <hello@sinatrawp.com> * @since 1.0.0 */ /** * Do not allow direct script access. */ if ( ! defined( 'ABSPATH' ) ) { exit; } if ( ! class_exists( 'Sinatra_Meta_Boxes' ) ) : /** * Meta Boxes Class. */ class Sinatra_Meta_Boxes { /** * Singleton instance. * * @since 1.0.0 * @var object */ private static $instance; /** * Metabox settings array. * * @since 1.0.0 * @var array */ private $metabox = array(); /** * Whether this is a new post. Once the post is saved and we're * no longer on the `post-new.php` screen, this is going to be * `false`. * * @since 1.0.0 * @var bool */ public $is_new_post = false; /** * Returns the instance. * * @since 1.0.0 */ public static function get_instance() { if ( is_null( self::$instance ) ) { self::$instance = new self(); self::$instance->actions(); } return self::$instance; } /** * Primary class constructor. * * @since 1.0.0 */ private function __construct() {} /** * Sets up initial actions. * * @since 1.0.0 */ private function actions() { // Call the register function. add_action( 'load-post.php', array( $this, 'register' ) ); add_action( 'load-post-new.php', array( $this, 'register' ) ); // Load assets. add_action( 'admin_enqueue_scripts', array( $this, 'load_assets' ) ); } /** * Registration callback. * * @since 1.0.0 */ public function register() { // If this is a new post, set the new post boolean. if ( 'load-post-new.php' === current_action() ) { $this->is_new_post = true; } // Add meta boxes. add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ), 1 ); // Save settings. add_action( 'save_post', array( $this, 'update' ) ); // Config. add_action( 'pre_get_posts', array( $this, 'metabox_config' ) ); } /** * Metabox config array * * @since 1.0.0 * @return void */ public function metabox_config() { /** * Layout settings. */ $layout_settings = array(); // Sidebar position. $layout_settings['sinatra_sidebar_position'] = array( 'id' => 'sinatra_sidebar_position', 'name' => esc_html__( 'Sidebar', 'sinatra' ), 'type' => 'select', 'default' => 'default', 'choices' => array( '' => esc_html__( 'Default (from Customizer)', 'sinatra' ), 'no-sidebar' => esc_html__( 'No Sidebar', 'sinatra' ), 'left-sidebar' => esc_html__( 'Left Sidebar', 'sinatra' ), 'right-sidebar' => esc_html__( 'Right Sidebar', 'sinatra' ), ), ); // Content layout. $layout_settings['sinatra_content_layout'] = array( 'id' => 'sinatra_content_layout', 'name' => esc_html__( 'Content Layout', 'sinatra' ), 'type' => 'select', 'default' => 'default', 'choices' => array( '' => esc_html__( 'Default (from Customizer)', 'sinatra' ), 'fw-contained' => esc_html__( 'Full Width: Contained', 'sinatra' ), 'fw-stretched' => esc_html__( 'Full Width: Stretched', 'sinatra' ), 'boxed-separated' => esc_html__( 'Boxed Content', 'sinatra' ), 'boxed' => esc_html__( 'Boxed', 'sinatra' ), ), ); // Transparent header. $layout_settings['sinatra_transparent_header'] = array( 'id' => 'sinatra_transparent_header', 'name' => esc_html__( 'Transparent Header', 'sinatra' ), 'type' => 'select', 'default' => '', 'choices' => array( '' => esc_html__( 'Default (from Customizer)', 'sinatra' ), 'enable' => esc_html__( 'Enable', 'sinatra' ), 'disable' => esc_html__( 'Disable', 'sinatra' ), ), ); // Start checkbox group. $layout_settings['sinatra_page_sections'] = array( 'id' => 'sinatra_page_sections', 'type' => 'group', 'fields' => array(), ); // Disable Top Bar. if ( sinatra_option( 'top_bar_enable' ) ) { $layout_settings['sinatra_page_sections']['fields']['sinatra_disable_topbar'] = array( 'id' => 'sinatra_disable_topbar', 'name' => esc_html__( 'Disable Top Bar', 'sinatra' ), 'default' => false, 'type' => 'checkbox', ); } // Disable Header. $layout_settings['sinatra_page_sections']['fields']['sinatra_disable_header'] = array( 'id' => 'sinatra_disable_header', 'name' => esc_html__( 'Disable Main Header', 'sinatra' ), 'default' => false, 'type' => 'checkbox', ); // Disable Page Title. if ( sinatra_option( 'page_header_enable' ) ) { $layout_settings['sinatra_page_sections']['fields']['sinatra_disable_page_title'] = array( 'id' => 'sinatra_disable_page_title', 'name' => esc_html__( 'Disable Page Title', 'sinatra' ), 'default' => false, 'type' => 'checkbox', ); } // Disable Page Breadcrumbs. if ( sinatra_option( 'page_header_enable' ) && sinatra_option( 'breadcrumbs_enable' ) && ! sinatra_is_section_disabled( sinatra_option( 'breadcrumbs_hide_on' ), get_the_ID() ) ) { $layout_settings['sinatra_page_sections']['fields']['sinatra_disable_breadcrumbs'] = array( 'id' => 'sinatra_disable_breadcrumbs', 'name' => esc_html__( 'Disable Breadcrumbs', 'sinatra' ), 'default' => false, 'type' => 'checkbox', ); } // Disable Featured Image. $layout_settings['sinatra_page_sections']['fields']['sinatra_disable_thumbnail'] = array( 'id' => 'sinatra_disable_thumbnail', 'name' => esc_html__( 'Disable Featured Image', 'sinatra' ), 'default' => false, 'type' => 'checkbox', ); // Disable Prefooter. if ( sinatra_option( 'enable_pre_footer_cta' ) && ! sinatra_is_section_disabled( sinatra_option( 'pre_footer_cta_hide_on' ), get_the_ID() ) ) { $layout_settings['sinatra_page_sections']['fields']['sinatra_disable_prefooter_cta'] = array( 'id' => 'sinatra_disable_prefooter_cta', 'name' => esc_html__( 'Disable Pre Footer CTA', 'sinatra' ), 'default' => false, 'type' => 'checkbox', ); } // Disable Footer. if ( sinatra_option( 'enable_footer' ) ) { $layout_settings['sinatra_page_sections']['fields']['sinatra_disable_footer'] = array( 'id' => 'sinatra_disable_footer', 'name' => esc_html__( 'Disable Main Footer', 'sinatra' ), 'default' => false, 'type' => 'checkbox', ); } // Disable Copyright. if ( sinatra_option( 'enable_copyright' ) ) { $layout_settings['sinatra_page_sections']['fields']['sinatra_disable_copyright'] = array( 'id' => 'sinatra_disable_copyright', 'name' => esc_html__( 'Disable Copyright Bar', 'sinatra' ), 'default' => false, 'type' => 'checkbox', ); } // Set metabox options. $this->metabox = array( 'sinatra-theme-page-options' => array( 'id' => 'sinatra-theme-page-options', 'post_type' => $this->get_post_types(), 'capability' => 'edit_posts', 'label' => esc_html__( 'Theme Page Options', 'sinatra' ), 'context' => 'side', 'priority' => 'core', 'settings' => $layout_settings, ), ); $this->metabox = apply_filters( 'sinatra_metabox_options', $this->metabox ); } /** * Register Metabox. * * @since 1.0.0 * @param string $post_type Post Type of the current post page. */ public function add_meta_boxes( $post_type ) { if ( ! is_array( $this->metabox ) ) { return; } foreach ( $this->metabox as $id => $metabox ) { // If the manager is registered for the current post type, add a meta box. if ( in_array( $post_type, (array) $metabox['post_type'], true ) && $this->check_capability( $metabox['capability'] ) ) { add_meta_box( $metabox['id'], $metabox['label'], array( $this, 'render' ), $post_type, $metabox['context'], $metabox['priority'], array( 'settings' => $metabox['settings'] ) ); } } } /** * Update Metabox value. * * @since 1.0.0 * @param int $post_id Post ID. */ public function update( $post_id ) { $do_autosave = defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE; $is_autosave = wp_is_post_autosave( $post_id ); $is_revision = wp_is_post_revision( $post_id ); if ( $do_autosave || $is_autosave || $is_revision ) { return; } // Loop through all metaboxes. foreach ( $this->metabox as $id => $metabox ) { // Capability check. if ( $this->check_capability( $metabox['capability'] ) && isset( $_POST[ $metabox['id'] ] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST[ $metabox['id'] ] ) ), $metabox['id'] . '_nonce' ) ) { // phpcs:ignore // Loop through metabox settings. foreach ( $metabox['settings'] as $setting ) { // Group has nested settings. if ( 'group' === $setting['type'] ) { foreach ( $setting['fields'] as $id => $config ) { $this->save_value( $post_id, $config ); } } else { $this->save_value( $post_id, $setting ); } } } } } /** * Save the new value to postmeta database. * * @since 1.0.0 * @param object $post_id Post object ID. * @param array $setting Metabox config array. * @return void */ public function save_value( $post_id, $setting ) { // Get stored value. $old_value = $this->get_value( $post_id, $setting ); // Get new value. $new_value = $this->get_posted_value( $setting ); if ( ! $new_value && $old_value ) { delete_post_meta( $post_id, $setting['id'] ); } elseif ( $new_value !== $old_value ) { update_post_meta( $post_id, $setting['id'], $new_value ); } } /** * Print the meta box HTML Markup. * * @since 1.0.0 * @param object $post Post object. * @param array $metabox Metabox config array. * @return void */ public function render( $post, $metabox ) { if ( empty( $metabox['args']['settings'] ) ) { return; } foreach ( $metabox['args']['settings'] as $setting ) { echo '<div class="sinatra-meta-box-field">'; if ( isset( $setting['render_field_callback'] ) && function_exists( $setting['render_field_callback'] ) ) { call_user_func( $setting['render_field_callback'], $post, $setting ); } elseif ( method_exists( $this, 'render_field_' . $setting['type'] ) ) { call_user_func( array( $this, 'render_field_' . $setting['type'] ), $post, $setting ); } echo '</div>'; } // Nonce field to validate on save. wp_nonce_field( $metabox['id'] . '_nonce', $metabox['id'] ); } /** * Render select field. * * @since 1.0.0 * @param object $post Current post object. * @param array $setting Array of field settings. */ public function render_field_select( $post, $setting ) { $saved_value = get_post_meta( $post->ID, $setting['id'], true ); ?> <div class="components-base-control"> <div class="components-base-control__field"> <?php if ( isset( $setting['name'] ) ) { ?> <label class="post-attributes-label-wrapper components-base-control__label" for="<?php echo esc_attr( $setting['id'] ); ?>"> <?php echo esc_html( $setting['name'] ); ?> </label> <?php } ?> <select name="<?php echo esc_attr( $setting['id'] ); ?>" id="<?php echo esc_attr( $setting['id'] ); ?>"> <?php foreach ( $setting['choices'] as $key => $value ) { ?> <option value="<?php echo esc_attr( $key ); ?>" <?php selected( $saved_value, $key ); ?>><?php echo esc_html( $value ); ?></option> <?php } ?> </select> </div> </div> <?php if ( isset( $setting['desc'] ) ) { ?> <p class="post-attributes-description-wrapper components-base-control__help description"> <?php echo esc_html( $setting['desc'] ); ?> </p> <?php } ?> <?php } /** * Render group of fields. * * @since 1.0.0 * @param object $post Current post object. * @param array $setting Array of field settings. */ public function render_field_group( $post, $setting ) { ?> <?php if ( isset( $setting['name'] ) ) { ?> <p class="post-attributes-label-wrapper"> <strong><?php echo esc_html( $setting['name'] ); ?></strong> </p> <?php } ?> <?php if ( isset( $setting['desc'] ) ) { ?> <p class="post-attributes-description-wrapper"> <?php echo esc_html( $setting['desc'] ); ?> </p> <?php } ?> <?php foreach ( $setting['fields'] as $key => $value ) { if ( method_exists( $this, 'render_field_' . $value['type'] ) ) { call_user_func( array( $this, 'render_field_' . $value['type'] ), $post, $value ); } } } /** * Render checkbox group field. * * @since 1.0.0 * @param object $post Current post object. * @param array $setting Array of field settings. */ public function render_field_checkbox( $post, $setting ) { $saved = $this->get_value( $post->ID, $setting ); ?> <div class="components-panel__row sinatra-checkbox-row"> <div class="components-base-control"> <div class="components-base-control__field"> <span class="components-checkbox-control__input-container si-checkbox-wrapper"> <input type="checkbox" class="components-checkbox-control__input" id="<?php echo esc_attr( $setting['id'] ); ?>" name="<?php echo esc_attr( $setting['id'] ); ?>"<?php checked( $saved, true ); ?>> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" role="img" class="si-checked-icon components-checkbox-control__checked" aria-hidden="true" focusable="false"><path d="M9 18.6L3.5 13l1-1L9 16.4l9.5-9.9 1 1z"></path></svg> </span> <label class="components-checkbox-control__label" for="<?php echo esc_attr( $setting['id'] ); ?>"><?php echo esc_html( $setting['name'] ); ?></label> </div> </div> </div> <?php } /** * Render textarea field. * * @since 1.0.0 * @param object $post Current post object. * @param array $setting Array of field settings. */ public function render_field_textarea( $post, $setting ) { $saved = $this->get_value( $post->ID, $setting ); ?> <div class="components-base-control"> <div class="components-base-control__field"> <?php if ( isset( $setting['name'] ) ) { ?> <label class="post-attributes-label-wrapper components-base-control__label" for="<?php echo esc_attr( $setting['id'] ); ?>"> <?php echo esc_html( $setting['name'] ); ?> </label> <?php } ?> <textarea class="widefat" id="<?php echo esc_attr( $setting['id'] ); ?>" name="<?php echo esc_attr( $setting['id'] ); ?>" rows="5"><?php echo wp_kses_post( $saved ); ?></textarea> </div> </div> <?php if ( isset( $setting['desc'] ) ) { ?> <p class="post-attributes-description-wrapper components-base-control__help description"> <?php echo wp_kses_post( $setting['desc'] ); ?> </p> <?php } ?> <?php } /** * Render text field. * * @since 1.0.0 * @param object $post Current post object. * @param array $setting Array of field settings. */ public function render_field_text( $post, $setting ) { $saved = $this->get_value( $post->ID, $setting ); ?> <div class="components-base-control"> <div class="components-base-control__field"> <?php if ( isset( $setting['name'] ) ) { ?> <label class="post-attributes-label-wrapper components-base-control__label" for="<?php echo esc_attr( $setting['id'] ); ?>"> <?php echo esc_html( $setting['name'] ); ?> </label> <?php } ?> <input type="text" class="widefat" id="<?php echo esc_attr( $setting['id'] ); ?>" name="<?php echo esc_attr( $setting['id'] ); ?>" value="<?php echo wp_kses_post( $saved ); ?>" /> </div> </div> <?php if ( isset( $setting['desc'] ) ) { ?> <p class="post-attributes-description-wrapper components-base-control__help description"> <?php echo wp_kses_post( $setting['desc'] ); ?> </p> <?php } ?> <?php } /** * Load required assets on the admin page(s). * * @since 1.0.0 * @param string $hook Current page hook. */ public function load_assets( $hook ) { global $post; if ( 'post-new.php' === $hook || 'post.php' === $hook ) { $post_type = $post->post_type; $post_types = array(); foreach ( $this->metabox as $mb ) { $post_types = array_merge( $post_types, (array) $mb['post_type'] ); } $post_types = array_unique( $post_types ); if ( in_array( $post_type, $post_types, true ) ) { // Script debug. $sinatra_dir = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? 'dev/' : ''; $sinatra_suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min'; // Enqueue editor style. wp_enqueue_style( 'sinatra-metabox-style', SINATRA_THEME_URI . '/inc/admin/assets/css/sinatra-meta-boxes' . $sinatra_suffix . '.css', false, SINATRA_THEME_VERSION ); } } } /** * Gets the value of the setting. * * @since 1.0.0 * @param int $post_id Post ID. * @param array $setting Array of setting data. */ public function get_value( $post_id, $setting ) { $value = get_post_meta( $post_id, $setting['id'], true ); return ! $value && $this->is_new_post ? $setting['default'] : $value; } /** * Gets the posted value of the setting. * * @since 1.0.0 * @param array $setting Setting config array. */ public function get_posted_value( $setting ) { $value = ''; if ( isset( $_POST[ $setting['id'] ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing $value = wp_unslash( $_POST[ $setting['id'] ] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized } return $this->sanitize( $value, $setting ); } /** * Return array of post types for metabox. * * @since 1.0.0 * @param array $args Args for get_post_types function. */ public function get_post_types( $args = false ) { if ( ! $args ) { $args = array( 'public' => true, ); } $return = get_post_types( $args ); return $return; } /** * Sanitizes the value of the setting. * * @since 1.0.0 * @param mixed $value Value of the field to be sanitized. * @param arary $setting Setting config array. */ public function sanitize( $value, $setting ) { $filter = isset( $setting['type'] ) ? $setting['type'] : ''; switch ( $filter ) { case 'select': // Ensure input is a slug. $value = sanitize_key( $value ); // Get list of choices from the setting. $choices = $setting['choices']; // If the input is a valid key, return it; otherwise, return the default. $value = array_key_exists( $value, $choices ) ? $value : $setting['default']; break; case 'checkbox': // Ensure boolean value for $value. $value = (bool) $value; break; case 'text': $value = sanitize_text_field( $value ); break; case 'textarea': $value = wp_kses_post( $value ); break; case 'no_sanitize': default: break; } return $value; } /** * Checks if the control should be allowed at all. * * @since 1.0.0 * @param string $cap Capability. */ public function check_capability( $cap ) { if ( ! current_user_can( $cap ) ) { return false; } return true; } } endif; /** * The function which returns the one Sinatra Meta Boxes instance. * * Use this function like you would a global variable, except without needing * to declare the global. * * @since 1.0.0 * @access public * @return object */ function sinatra_meta_boxes() { return Sinatra_Meta_Boxes::get_instance(); } sinatra_meta_boxes();
Save Changes
Rename File
Rename