ACC SHELL
<?php
/**
* Content Handler Collection
* @package Simple Lightbox
* @subpackage Content Handler
* @author Archetyped
*/
class SLB_Content_Handlers extends SLB_Collection_Controller {
/* Configuration */
protected $item_type = 'SLB_Content_Handler';
public $hook_prefix = 'content_handlers';
protected $key_prop = 'get_id';
protected $key_call = true;
/* Properties */
protected $request_matches = array();
/**
* Cache properties (key, group)
* @var object
*/
protected $cache_props = null;
/* Initialization */
protected function _hooks() {
parent::_hooks();
$this->util->add_action('init', $this->m('init_defaults'), 5);
$this->util->add_action('footer', $this->m('client_output'), 1, 0, false);
$this->util->add_filter('footer_script', $this->m('client_output_script'), $this->util->priority('client_footer_output'), 1, false);
}
/* Collection Management */
/**
* Add content type handler
* Accepts properties to create new handler OR previously-initialized handler instance
* @uses clear_cache()
* @see parent::add()
* @param string $id Handler ID
* @param array $props Handler properties
* @return object Current instance
*/
public function add($id, $props = array(), $priority = 10) {
$this->clear_cache();
if ( is_string($id) ) {
// Initialize new handler
$handler = new $this->item_type($id, $props);
} else {
// Remap parameters
$handler = func_get_arg(0);
if ( func_num_args() == 2 ) {
$priority = func_get_arg(1);
}
}
if ( !is_int($priority) ) {
$priority = 10;
}
// Add to collection
return parent::add($handler, array('priority' => $priority));
}
/**
* Remove item
* @uses clear_cache()
* @see parent::remove()
* @return object Current instance
*/
public function remove($item) {
$this->clear_cache();
return parent::remove($item);
}
/**
* Clear collection
* @uses clear_cache()
* @see parent::clear()
* @return object Current instance
*/
public function clear() {
$this->clear_cache();
return parent::clear();
}
/**
* Retrieves handlers sorted by priority
* @see parent::get()
* @uses get_cache()
* @param mixed $args Unused
* @return array Handlers
*/
public function get($args = null) {
$items = $this->get_cache();
if ( empty($items) ) {
// Retrieve items
$items = parent::get( array( 'orderby' => array('meta' => 'priority') ) );
$this->update_cache($items);
}
return $items;
}
/**
* Get matching handler for URI
* @param string $uri URI to find match for
* @return object Handler package (FALSE if no match found)
* Package members
* > handler (Content_Handler) Matching handler instance (Default: NULL)
* > props (array) Properties returned from matching handler (May be empty depending on handler)
*/
public function match($uri) {
$ret = (object) array('handler' => null, 'props' => array());
foreach ( $this->get() as $handler ) {
$props = $handler->match($uri, $this);
if ( !!$props ) {
$ret->handler = $handler;
// Add handler props
if ( is_array($props) ) {
$ret->props = $props;
}
// Save match
$hid = $handler->get_id();
if ( !isset($this->request_matches[$hid]) ) {
$this->request_matches[$hid] = $handler;
}
break;
}
}
return $ret;
}
/* Cache */
/**
* Retrieve cached items
* @uses get_cache_props()
* @uses wp_cache_get()
* @return array Cached items (Default: empty array)
*/
protected function get_cache() {
$cprops= $this->get_cache_props();
$items = wp_cache_get($cprops->key, $cprops->group);
return ( is_array($items) ) ? $items : array();
}
/**
* Update cached items
* Cache is cleared if no items specified
* @uses get_cache_props()
* @uses wp_cache_get()
* @param array $data Item data to cache
*/
protected function update_cache($data = null) {
$props = $this->get_cache_props();
wp_cache_set($props->key, $data, $props->group);
}
/**
* Clear cache
* @uses update_cache()
*/
protected function clear_cache() {
$this->update_cache();
}
/**
* Retrieve cache properites (key, group)
* @return object Cache properties
*/
protected function get_cache_props() {
if ( !is_object($this->cache_props) ) {
$this->cache_props = (object) array (
'key' => $this->hook_prefix . '_items',
'group' => $this->get_prefix(),
);
}
return $this->cache_props;
}
/* Handlers */
/**
* Initialize default handlers
* @param SLB_Content_Handlers $handlers Handlers controller
*/
public function init_defaults($handlers) {
$src_base = $this->util->get_file_url('content-handlers', true);
$js_path = 'js/';
$js_path .= ( SLB_DEV ) ? 'dev' : 'prod';
$defaults = array (
'image' => array (
'match' => $this->m('match_image'),
'scripts' => array (
array ( 'base', "$src_base/image/$js_path/handler.image.js" ),
),
)
);
foreach ( $defaults as $id => $props ) {
$handlers->add($id, $props);
}
}
/**
* Matches image URIs
* @param string $uri URI to match
* @return bool|array TRUE if URI is image (array is used if extra data needs to be sent)
*/
public function match_image($uri, $handlers) {
// Basic matching
$match = ( $this->util->has_file_extension($uri, array('jpg', 'jpeg', 'jpe', 'jfif', 'jif', 'gif', 'png')) ) ? true : false;
// Filter result
$extra = new stdClass();
$match = $this->util->apply_filters('image_match', $match, $uri, $extra);
// Handle extra data passed from filters
// Currently only `uri` supported
if ( $match && isset($extra->uri) && is_string($extra->uri) ) {
$match = array('uri' => $extra->uri);
}
return $match;
}
/* Output */
/**
* Build client output
* Load handler files in client
*/
public function client_output() {
// Get handlers for current request
foreach ( $this->request_matches as $handler ) {
$handler->enqueue_scripts();
}
}
/**
* Client output script
* @param array $commands Client script commands
* @return array Modified script commands
*/
public function client_output_script($commands) {
$out = array('/* CHDL */');
$code = array();
foreach ( $this->request_matches as $handler ) {
// Attributes
$attrs = $handler->get_attributes();
// Styles
$styles = $handler->get_styles(array('uri_format'=>'full'));
if ( !empty($styles) ) {
$attrs['styles'] = array_values($styles);
}
if ( empty($attrs) ) {
continue;
}
// Setup client parameters
$params = array(
sprintf("'%s'", $handler->get_id()),
json_encode($attrs),
);
// Extend handler in client
$code[] = $this->util->call_client_method('View.extend_content_handler', $params, false);
}
if ( !empty($code) ) {
$out[] = implode('', $code);
$commands[] = implode(PHP_EOL, $out);
}
return $commands;
}
}
ACC SHELL 2018