554 lines
12 KiB
PHP
554 lines
12 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Admin View Base
|
|
* Core functionality Admin UI components
|
|
* @package Simple Lightbox
|
|
* @subpackage Admin
|
|
* @author Archetyped
|
|
*/
|
|
class SLB_Admin_View extends SLB_Base_Object {
|
|
/* Properties */
|
|
|
|
/**
|
|
* Labels
|
|
* @var array (Associative)
|
|
*/
|
|
protected $labels = array();
|
|
|
|
/**
|
|
* Function to handle building UI
|
|
* @var callback
|
|
*/
|
|
protected $callback = null;
|
|
|
|
/**
|
|
* Capability for access control
|
|
* @var string
|
|
*/
|
|
protected $capability = 'manage_options';
|
|
|
|
/**
|
|
* Icon to use
|
|
* @var string
|
|
*/
|
|
protected $icon = null;
|
|
|
|
/**
|
|
* View parent ID/Slug
|
|
* @var string
|
|
*/
|
|
protected $parent = null;
|
|
|
|
/**
|
|
* Whether parent is a custom view or a default WP one
|
|
* @var bool
|
|
*/
|
|
protected $parent_custom = true;
|
|
|
|
/**
|
|
* If view requires a parent
|
|
* @var bool
|
|
*/
|
|
protected $parent_required = false;
|
|
|
|
/**
|
|
* WP-Generated hook name for view
|
|
* @var string
|
|
*/
|
|
protected $hookname = null;
|
|
|
|
/**
|
|
* Raw content parameters
|
|
* Stores pre-rendered content parameters
|
|
* Items stored by ID (key)
|
|
* @var array
|
|
*/
|
|
protected $content_raw = array();
|
|
|
|
/**
|
|
* Parsed content parameters
|
|
* @var array
|
|
*/
|
|
protected $content = array();
|
|
|
|
/**
|
|
* Messages to be displayed
|
|
* Indexed Array
|
|
* @var array
|
|
*/
|
|
protected $messages = array();
|
|
|
|
/**
|
|
* Required properties
|
|
* Associative array
|
|
* > Key: Property name
|
|
* > Value: Required data type
|
|
* @var array
|
|
*/
|
|
private $required = array();
|
|
|
|
/**
|
|
* Default required properties
|
|
* Merged into $required array with this->init_required()
|
|
* @see this->required for more information
|
|
* @var array
|
|
*/
|
|
private $_required = array(
|
|
'id' => 'string',
|
|
'labels' => 'array',
|
|
);
|
|
|
|
/* Init */
|
|
|
|
/**
|
|
* Constructor
|
|
* @return obj Current instance
|
|
*/
|
|
public function __construct( $id, $labels, $callback = null, $capability = null, $icon = null ) {
|
|
$props = array(
|
|
'labels' => $labels,
|
|
'callback' => $callback,
|
|
'capability' => $capability,
|
|
'icon' => $icon,
|
|
);
|
|
parent::__construct( $id, $props );
|
|
$this->init_required();
|
|
return $this;
|
|
}
|
|
|
|
protected function init_required() {
|
|
$this->required = array_merge( $this->_required, $this->required );
|
|
// Check for parent requirement
|
|
if ( $this->parent_required ) {
|
|
$this->required['parent'] = 'string';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set required feature
|
|
* @param string $feature Required feature
|
|
*/
|
|
protected function _require( $feature ) {
|
|
if ( ! isset( $this->_required[ $feature ] ) ) {
|
|
$this->_required[ $feature ] = true;
|
|
}
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Check if feature is required
|
|
* @param string $feature Feature to check for
|
|
* @return bool TRUE if feature required
|
|
*/
|
|
protected function _is_required( $feature ) {
|
|
return ( isset( $this->_required[ $feature ] ) ) ? true : false;
|
|
}
|
|
|
|
/* Property Methods */
|
|
|
|
/**
|
|
* Retrieve ID (Formatted by default)
|
|
* @param bool $formatted (optional) Whether ID should be formatted for external use or not
|
|
* @return string ID
|
|
*/
|
|
public function get_id( $formatted = true ) {
|
|
$id = parent::get_id();
|
|
if ( $formatted ) {
|
|
$this->add_prefix_ref( $id );
|
|
}
|
|
return $id;
|
|
}
|
|
|
|
/**
|
|
* Retrieve raw ID
|
|
* @return string Raw ID
|
|
*/
|
|
public function get_id_raw() {
|
|
return $this->get_id( false );
|
|
}
|
|
|
|
/**
|
|
* Retrieve label
|
|
* Uses first label (or default if defined) if specified type does not exist
|
|
* @param string $type Label type to retrieve
|
|
* @param string $default (optional) Default value if label type does not exist
|
|
* @return string Label text
|
|
*/
|
|
public function get_label( $type, $default = null ) {
|
|
// Retrieve existing label type
|
|
if ( $this->has_label( $type ) ) {
|
|
return $this->labels[ $type ];
|
|
}
|
|
// Use default label if type is not set
|
|
if ( empty( $default ) && ! empty( $this->labels ) ) {
|
|
reset( $this->labels );
|
|
$default = current( $this->labels );
|
|
}
|
|
|
|
return ( empty( $default ) ) ? '' : $default;
|
|
}
|
|
|
|
/**
|
|
* Set text labels
|
|
* @param array|string $labels
|
|
* @return obj Current instance
|
|
*/
|
|
public function set_labels( $labels ) {
|
|
if ( empty( $labels ) ) {
|
|
return this;
|
|
}
|
|
// Single string
|
|
if ( is_string( $labels ) ) {
|
|
$labels = array( $labels );
|
|
}
|
|
|
|
// Array
|
|
if ( is_array( $labels ) ) {
|
|
// Merge with existing labels
|
|
if ( empty( $this->labels ) || ! is_array( $this->labels ) ) {
|
|
$this->labels = array();
|
|
}
|
|
$this->labels = array_merge( $this->labels, $labels );
|
|
}
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Set single text label
|
|
* @uses this->set_labels()
|
|
* @param string $type Label type to set
|
|
* @param string $value Label value
|
|
* @return obj Current instance
|
|
*/
|
|
public function set_label( $type, $value ) {
|
|
if ( is_string( $type ) && is_string( $value ) ) {
|
|
$label = array( $type => $value );
|
|
$this->set_labels( $label );
|
|
}
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Checks if specified label is set on view
|
|
* @param string $type Label type
|
|
* @return bool TRUE if label exists, FALSE otherwise
|
|
*/
|
|
public function has_label( $type ) {
|
|
return ( isset( $this->labels[ $type ] ) );
|
|
}
|
|
|
|
/* Content */
|
|
|
|
/**
|
|
* Add content block to view
|
|
* Child classes define method functionality
|
|
* @param string $id Content block ID
|
|
* @param array $args Content arguments (Defined by child class), converted to an object
|
|
* @return obj Current View instance
|
|
*/
|
|
public function add_content( $id, $args ) {
|
|
// Save parameters
|
|
$this->content_raw[ $id ] = (object) $args;
|
|
// Clear parsed content
|
|
$this->content = array();
|
|
// Return instance reference
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Retrieve content
|
|
*/
|
|
protected function get_content( $parsed = true ) {
|
|
// Return raw content.
|
|
if ( ! $parsed ) {
|
|
return $this->content_raw;
|
|
}
|
|
|
|
// Return parsed content.
|
|
if ( empty( $this->content ) && ! empty( $this->content_raw ) ) {
|
|
$this->content = $this->parse_content();
|
|
}
|
|
|
|
return $this->content;
|
|
}
|
|
|
|
/**
|
|
* Parse content
|
|
* Child classes define functionality
|
|
* @return array Parsed content
|
|
*/
|
|
protected function parse_content() {
|
|
return $this->get_content( false );
|
|
}
|
|
|
|
/**
|
|
* Check if content has been added to view
|
|
* @return bool TRUE if content added
|
|
*/
|
|
protected function has_content() {
|
|
$raw = $this->get_content( false );
|
|
return ! empty( $raw );
|
|
}
|
|
|
|
/**
|
|
* Render content
|
|
*/
|
|
protected function render_content( $context = 'default' ) {}
|
|
|
|
/**
|
|
* Retrieve view messages
|
|
* @return array Messages
|
|
*/
|
|
protected function &get_messages() {
|
|
if ( ! is_array( $this->messages ) ) {
|
|
$this->messages = array();
|
|
}
|
|
return $this->messages;
|
|
}
|
|
|
|
/**
|
|
* Save message
|
|
* @param string $text Message text
|
|
* @return obj Current instance
|
|
*/
|
|
public function set_message( $text ) {
|
|
$msgs =& $this->get_messages();
|
|
$text = trim( $text );
|
|
if ( empty( $msgs ) && ! empty( $text ) ) {
|
|
$this->util->add_filter( 'admin_messages', $this->m( 'do_messages' ), 10, 1, false );
|
|
}
|
|
$msgs[] = $text;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Add messages to array
|
|
* Called by internal `admin_messages` filter hook
|
|
* @param array $msgs Aggregated messages
|
|
* @return array Merged messages array
|
|
*/
|
|
public function do_messages( $msgs = array() ) {
|
|
$m =& $this->get_messages();
|
|
if ( ! empty( $m ) ) {
|
|
$msgs = array_merge( $msgs, $m );
|
|
}
|
|
return $msgs;
|
|
}
|
|
|
|
/**
|
|
* Retrieve view callback
|
|
* @return callback Callback (Default: standard handler method)
|
|
*/
|
|
public function get_callback() {
|
|
return ( $this->has_callback() ) ? $this->callback : $this->m( 'handle' );
|
|
}
|
|
|
|
/**
|
|
* Set callback function for building item
|
|
* @param callback $callback Callback function to use
|
|
* @return obj Current instance
|
|
*/
|
|
public function set_callback( $callback ) {
|
|
$this->callback = ( is_callable( $callback ) ) ? $callback : null;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Check if callback set
|
|
* @return bool TRUE if callback is set
|
|
*/
|
|
protected function has_callback() {
|
|
return ( ! empty( $this->callback ) ) ? true : false;
|
|
}
|
|
|
|
/**
|
|
* Run callback
|
|
*/
|
|
public function do_callback() {
|
|
call_user_func( $this->get_callback() );
|
|
}
|
|
|
|
/**
|
|
* Retrieve capability
|
|
* @return string Capability
|
|
*/
|
|
public function get_capability() {
|
|
return $this->capability;
|
|
}
|
|
|
|
/**
|
|
* Set capability for access control
|
|
* @param string $capability Capability
|
|
* @return obj Current instance
|
|
*/
|
|
public function set_capability( $capability ) {
|
|
if ( is_string( $capability ) && ! empty( $capability ) ) {
|
|
$this->capability = $capability;
|
|
}
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Set icon
|
|
* @param string $icon Icon URI
|
|
* @return obj Current instance
|
|
*/
|
|
public function set_icon( $icon ) {
|
|
if ( ! empty( $icon ) && is_string( $icon ) ) {
|
|
$this->icon = $icon;
|
|
}
|
|
return $this;
|
|
}
|
|
|
|
protected function get_hookname() {
|
|
return ( empty( $this->hookname ) ) ? '' : $this->hookname;
|
|
}
|
|
|
|
/**
|
|
* Set hookname
|
|
* @param string $hookname Hookname value
|
|
* @return obj Current instance
|
|
*/
|
|
public function set_hookname( $hookname ) {
|
|
if ( ! empty( $hookname ) && is_string( $hookname ) ) {
|
|
$this->hookname = $hookname;
|
|
}
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Retrieve parent
|
|
* Formats parent ID for custom parents
|
|
* @uses parent::get_parent()
|
|
* @return string Parent ID
|
|
*/
|
|
public function get_parent() {
|
|
$parent = parent::get_parent();
|
|
return ( $this->is_parent_custom() ) ? $this->add_prefix( $parent ) : $parent;
|
|
}
|
|
|
|
/**
|
|
* Set parent for view
|
|
* @param string $parent Parent ID
|
|
* @return obj Current instance
|
|
*/
|
|
public function set_parent( $parent ) {
|
|
if ( $this->parent_required ) {
|
|
if ( ! empty( $parent ) && is_string( $parent ) ) {
|
|
$this->parent = $parent;
|
|
}
|
|
} else {
|
|
$this->parent = null;
|
|
}
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Specify whether parent is a custom view or a WP view
|
|
* @param bool $custom (optional) TRUE if custom, FALSE if WP
|
|
* @return obj Current instance
|
|
*/
|
|
protected function set_parent_custom( $custom = true ) {
|
|
if ( $this->parent_required ) {
|
|
$this->parent_custom = ! ! $custom;
|
|
}
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Set parent as WP view
|
|
* @uses this->set_parent_custom()
|
|
* @return obj Current instance
|
|
*/
|
|
public function set_parent_wp() {
|
|
$this->set_parent_custom( false );
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Get view URI
|
|
* URI Structures:
|
|
* > Top Level Menus: admin.php?page={menu_id}
|
|
* > Pages: [parent_page_file.php|admin.php]?page={page_id}
|
|
* > Section: [parent_menu_uri]#{section_id}
|
|
*
|
|
* @uses $admin_page_hooks to determine if page is child of default WP page
|
|
* @param string $file (optional) Base file name
|
|
* @param string $format (optional) Format string for URI
|
|
* @return string Object URI
|
|
*/
|
|
public function get_uri( $file = null, $format = null ) {
|
|
static $page_hooks = null;
|
|
$uri = '';
|
|
if ( empty( $file ) ) {
|
|
$file = 'admin.php';
|
|
}
|
|
if ( $this->is_child() ) {
|
|
$parent = str_replace( '_page_' . $this->get_id(), '', $this->get_hookname() );
|
|
if ( is_null( $page_hooks ) ) {
|
|
$page_hooks = array_flip( $GLOBALS['admin_page_hooks'] );
|
|
}
|
|
if ( isset( $page_hooks[ $parent ] ) ) {
|
|
$file = $page_hooks[ $parent ];
|
|
}
|
|
}
|
|
|
|
if ( empty( $format ) ) {
|
|
$delim = ( strpos( $file, '?' ) === false ) ? '?' : '&';
|
|
$format = '%1$s' . $delim . 'page=%2$s';
|
|
}
|
|
$uri = sprintf( $format, $file, $this->get_id() );
|
|
|
|
return $uri;
|
|
}
|
|
|
|
/* Handlers */
|
|
|
|
/**
|
|
* Default View handler
|
|
* Used as callback when none set
|
|
*/
|
|
public function handle() {}
|
|
|
|
/* Validation */
|
|
|
|
/**
|
|
* Check if instance is valid based on required properties/data types
|
|
* @return bool TRUE if valid, FALSE if not valid
|
|
*/
|
|
public function is_valid() {
|
|
$invalid = false;
|
|
foreach ( $this->required as $prop => $type ) {
|
|
// Baseline validation.
|
|
if (
|
|
empty( $this->{$prop} )
|
|
|| empty( $type )
|
|
|| ! is_string( $type )
|
|
) {
|
|
return $invalid;
|
|
}
|
|
|
|
// Validate data type.
|
|
$f = 'is_' . $type;
|
|
if ( ! function_exists( $f ) || ! $f( $this->{$prop} ) ) {
|
|
return $invalid;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
protected function is_child() {
|
|
return $this->parent_required;
|
|
}
|
|
|
|
protected function is_parent_custom() {
|
|
return ( $this->is_child() && $this->parent_custom ) ? true : false;
|
|
}
|
|
|
|
public function is_parent_wp() {
|
|
return ( $this->is_child() && ! $this->parent_custom ) ? true : false;
|
|
}
|
|
|
|
}
|