ACC SHELL
<?php
/**
* Utility methods
*
* @package Simple Lightbox
* @subpackage Utilities
* @author Archetyped
*
*/
class SLB_Utilities {
/* Properties */
/**
* Instance parent
* @var object
*/
private $_parent = null;
/**
* Plugin Base
* @var string
*/
private $_plugin = array(
'base' => null,
'file' => null,
'name' => null,
'data' => null,
'uri' => null,
'headers' => array (
'Name' => 'Plugin Name',
'PluginURI' => 'Plugin URI',
'SupportURI' => 'Support URI',
'Version' => 'Version',
'Description' => 'Description',
'Author' => 'Author',
'AuthorURI' => 'Author URI',
)
);
/**
* Plugin base path
* @var string
*/
private $_path_base = null;
/**
* Standard hook priorities
* @var array
*/
private $_priorities = array (
'high' => 1,
'low' => 99,
'safe' => 15,
'client_footer_output' => 25,
);
/* Constructors */
function __construct($obj) {
if ( is_object($obj) ) {
$this->_parent = $obj;
}
}
/**
* Returns callback array to instance method
* @param object $obj Instance object
* @param string $method Name of method
* @return array Callback array
*/
function m($obj, $method = '') {
if ( is_string($obj) ) {
$method = $obj;
$obj = null;
}
if ( !is_object($obj) && isset($this) ) {
$obj = $this;
}
$cb = array($obj, $method);
return $cb;
}
/* Helper Functions */
/*-** Prefix **-*/
/**
* Get valid separator
* @param string $sep (optional) Separator supplied
* @return string Separator
*/
function get_sep($sep = false) {
if ( is_null($sep) )
$sep = '';
return ( is_string($sep) ) ? $sep : '_';
}
/**
* Retrieve class prefix (with separator if set)
* @param bool|string $sep Separator to append to class prefix (Default: no separator)
* @return string Class prefix
*/
function get_prefix($sep = null) {
$sep = $this->get_sep($sep);
$prefix = ( !empty($this->_parent->prefix) ) ? $this->_parent->prefix . $sep : '';
return $prefix;
}
/**
* Check if a string is prefixed
* @param string|array $text Text to check for prefix
* @param string $sep (optional) Separator used
*/
function has_prefix($text, $sep = null) {
if ( empty($text) )
return false;
if ( !is_array($text) )
$text = array($text);
$text = array_values($text);
$text = $text[0];
return ( !empty($text) && stripos($text, $this->get_prefix($sep)) === 0 );
}
/**
* Prepend plugin prefix to some text
* @param string|array $text Text to add to prefix
* @param string $sep (optional) Text used to separate prefix and text
* @param bool $once (optional) Whether to add prefix to text that already contains a prefix or not
* @return string Text with prefix prepended
*/
function add_prefix($text, $sep = '_', $once = true) {
// Normalize data type (array)
if ( empty($text) )
$text = array('');
if ( !is_array($text) )
$text = array($text);
// Add prefix (if necessary)
if ( !$once || ( $once && !$this->has_prefix($text, $sep) ) )
array_unshift($text, $this->get_prefix());
return implode($sep, $text);
}
/**
* Prepend uppercased plugin prefix to some text
* @param string|array $text Text to add to prefix
* @param string $sep (optional) Text used to separate prefix and text
* @param bool $once (optional) Whether to add prefix to text that already contains a prefix or not
* @return string Text with prefix prepended
*/
function add_prefix_uc($text, $sep = '_', $once = true) {
$args = func_get_args();
$var = call_user_func_array($this->m($this, 'add_prefix'), $args);
$pre = $this->get_prefix();
return str_replace($pre . $sep, strtoupper($pre) . $sep, $var);
}
/**
* Add prefix to variable reference
* Updates actual variable rather than return value
* @uses add_prefix() to add prefix to variable
* @param string $var Variable to add prefix to
* @param string $sep (optional) Separator text
* @param bool $once (optional) Add prefix only once
* @return void
*/
function add_prefix_ref(&$var, $sep = null, $once = true) {
$args = func_get_args();
$var = call_user_func_array($this->m($this, 'add_prefix'), $args);
}
/**
* Remove prefix from specified string
* @param string $text String to remove prefix from
* @param string $sep (optional) Separator used with prefix
*/
function remove_prefix($text, $sep = '_') {
if ( $this->has_prefix($text,$sep) )
$text = substr($text, strlen($this->get_prefix($sep)));
return $text;
}
/**
* Returns Database prefix for plugin-related DB Tables
* @return string Database prefix
*/
function get_db_prefix() {
global $wpdb;
return $wpdb->prefix . $this->get_prefix('_');
}
/*-** Priority **-*/
/**
* Retrieve standard priority
* @var string $id Priority ID to retrieve
* @return int Priority
*/
public function priority($id = null) {
$pri = 10;
if ( !is_null($id) && array_key_exists($id, $this->_priorities) ) {
$pri = $this->_priorities[$id];
}
return $pri;
}
/* Wrapped Values */
/**
* Create wrapper object
* Properties
* > start
* > end
* @param string|array $start Start text (Can also be array defining start & end values)
* @param string $end (optional) End text
* If $end not defined, then $start is used
* @return obj Wrapper
*/
function get_wrapper($start = null, $end = null) {
// Validate existing wrapper
if ( is_object($start) && isset($start->start) && isset($start->end) )
return $start;
// Initialize wrapper
$w = array (
'start' => '[',
'end' => ']',
);
if ( !empty($start) ) {
if ( is_string($start) ) {
$w['start'] = $start;
} elseif ( is_array($start) ) {
$start = array_values($start);
if ( is_string($start) ) {
$w['start'] = $start[0];
}
if ( isset($start[1]) && is_string($start[1]) ) {
$w['end'] = $start[1];
}
}
}
if ( is_string($end) ) {
$w['end'] = $end;
}
return (object) $w;
}
/**
* Check if text is wrapped by specified character(s)
* @uses this->get_wrapper() to Validate wrapper text
* @param string $text Text to check
* @param string|array $start (optional) Start text (Array defines both start/end text)
* @param string $end (optional) End text
*/
function has_wrapper($text, $start = null, $end = null) {
if ( !is_string($text) || empty($text) )
return false;
// Validate wrapper
$w = $this->get_wrapper($start, $end);
// Check for wrapper
return ( substr($text, 0, strlen($w->start)) == $w->start && substr($text, -1, strlen($w->end)) == $w->end ) ? true : false;
}
/**
* Remove wrapper from specified text
* @uses this->has_wrapper() to check if text is wrapped
* @uses this->get_wrapper() to retrieve wrapper object
* @param string $text Text to check
* @param string|array $start (optional) Start text (Array defines both start/end text)
* @param string $end (optional) End text
* @return string Unwrapped text
*/
function remove_wrapper($text, $start = null, $end = null) {
if ( $this->has_wrapper($text, $start, $end) ) {
$w = $this->get_wrapper($start, $end);
$text = substr($text, strlen($w->start), strlen($text) - strlen($w->start) - strlen($w->end) );
}
return $text;
}
/**
* Add wrapper to specified text
* @uses Utilities::get_wrapper() to retrieve wrapper object
* @param string $text Text to wrap
* @param string|array $start (optional) Start text (Array defines both start/end text)
* @param string $end (optional) End text
* @param bool $once (optional) Whether to wrap text only once (Default: TRUE)
* @return string Wrapped text
*/
function add_wrapper($text, $start = null, $end = null, $once = true) {
$w = $this->get_wrapper($start, $end);
if ( !$once || !$this->has_wrapper($text, $w) )
$text = $w->start . $text . $w->end;
return $text;
}
/*-** Client **-*/
/**
* Parses client files array
* > Adds ID property (prefixed file key)
* > Parses and validates internal dependencies
* > Converts properties array to object
* Properties
* > file (string|array): File name (string) or callback (array) to retrieve file name
* > deps (array) [optional]: Dependencies
* > Values wrapped in square brackets (`[` & `]`) are internal files
* > callback (string|array) [optional]: Global callback to determine whether file should be loaded
* > Values wrapped in square brackets (`[` & `]`) are internal methods (of parent object)
* > context (array) [optional]: Context(s) in which to load the file
* Acceptable values
* > string: Context name
* > array: Context name + callback (both must return TRUE to load file)
* > Callback follows same pattern as `callback` member
* @param array $files Files array
* @return object Client files
*/
function parse_client_files($files, $type = 'scripts') {
if ( is_array($files) && !empty($files) ) {
// Defaults
$defaults = array(
'file' => null,
'deps' => array(),
'callback' => null,
'context' => array(),
'enqueue' => true,
'enqueued' => false
);
switch ( $type ) {
case 'styles':
$defaults['media'] = 'all';
break;
default:
$defaults['in_footer'] = false;
}
// Iterate through files
/**
* $h (string) handle
* $p (array) properties
*/
foreach ( $files as $h => $p ) {
unset($file, $cb, $ctxs, $ctx);
// Set ID
$p['id'] = $this->add_prefix($h);
// Type Validation
/**
* $m (string) property name
* $d (mixed) default value
*/
foreach ( $defaults as $m => $d ) {
// Check if value requires validation
if ( !is_array($d) || !isset($p[$m]) || is_array($p[$m]) )
continue;
// Wrap value in array or destroy it
if ( is_scalar($p[$m]) )
$p[$m] = array($p[$m]);
else
unset($p[$m]);
}
// Normalize file properties
$p = array_merge($defaults, $p);
/* File name */
// Validate file
$file =& $p['file'];
// Determine if filename or callback
if ( !$this->is_file($file) )
$file = ( is_callable($file) ) ? $file : null;
// Remove invalid file and move on to next
if ( empty($file) ) {
unset($files[$h]);
continue;
}
/* Dependencies */
// Format internal dependencies
foreach ( $p['deps'] as $idx => $dep ) {
if ( $this->has_wrapper($dep) ) {
$dep = $this->remove_wrapper($dep);
$p['deps'][$idx] = $this->add_prefix($dep);
}
}
/* Context */
// Validate callback
$cb =& $p['callback'];
if ( !is_null($cb) && !is_callable($cb) ) {
// Remove files with invalid callbacks (will never be loaded)
unset($files[$h]);
continue;
}
// Validate contexts
$ctxs =& $p['context'];
$ctxs = array_unique($ctxs);
$has_contexts = ( count($ctxs) > 0 ) ? true : false;
foreach ( $ctxs as $idx => $ctx ) {
// Convert to array
$ctx = array_values( array_slice( (array) $ctx, 0, 2 ) );
switch ( count($ctx) ) {
case 1 :
// Simple context
$ctx = $ctx[0];
break;
case 2 :
// Context + Callback
if ( is_callable($ctx[1]) ) {
break;
}
// Continue to default case if callback is invalid
default :
// Context is invalid
$ctx = false;
break;
}
// Remove invalid contexts
if ( empty($ctx) ) {
unset($ctxs[$idx]);
} else {
$ctxs[$idx] = $ctx;
}
}
// Remove file if all specified contexts invalid (no context is OK)
if ( $has_contexts && empty($ctxs) ) {
unset($files[$h]);
continue;
}
$ctxs = array_values($ctxs);
/* Finalize Properties */
// Convert properties to object
$files[$h] = (object) $p;
}
}
// Cast to object before returning
$files = (object) $files;
return $files;
}
/**
* Build JS client object
* @param string (optional) $path Additional object path
* @return string Client object
*/
function get_client_object($path = null) {
$obj = strtoupper($this->get_prefix());
if ( !empty($path) && is_string($path) ) {
if ( 0 !== strpos($path, '[') )
$obj .= '.';
$obj .= $path;
}
return $obj;
}
/**
* Build jQuery JS expression to add data to specified client object
* @param string|obj $obj Name of client object (Set to root object if not a valid name)
* @param mixed $data Data to add to client object
* @param bool (optional) $out Whether or not to output code (Default: false)
* @return string JS expression to extend client object
*/
function extend_client_object($obj, $data = null, $out = false) {
// Validate parameters
$args = func_get_args();
switch ( count($args) ) {
case 2:
if ( !is_scalar($args[0]) ) {
if ( is_bool($args[1]) )
$out = $args[1];
} else {
break;
}
case 1:
$data = $args[0];
$obj = null;
break;
}
// Default client object
if ( !is_string($obj) || empty($obj) )
$obj = null;
// Default data
if ( is_array($data) ) {
$data = (object)$data;
}
// Build expression
if ( empty($data) || ( empty($obj) && is_scalar($data) ) ) {
$ret = '';
} else {
$c_obj = $this->get_client_object($obj);
$ret = $this->validate_client_object($obj, sprintf('{$.extend(%1$s, %2$s);}', $c_obj, json_encode($data)) );
if ( $out )
echo $this->build_script_element($ret, 'context', true, true);
}
return $ret;
}
/**
* Validate client object $obj before running command $cmd
*
* @param string $obj Full object name
* @param string $cmd (optional) Command to wrap in validation
* @return string Command wrapped in validation block
* If no command is specified the validation conditions are returned
*/
public function validate_client_object($obj, $cmd = null) {
// Get base object
$base = $this->get_client_object();
// Build condition
$sep = '.';
$obj = trim($obj, $sep);
// Strip base object
if ( 0 === strpos($obj, $base . $sep) ) {
$obj = substr($obj, strlen($base . $sep));
}
$fmt = '!!window.%1$s';
if ( !empty($obj) ) {
$fmt .= ' && %1$s.has_child(\'%2$s\')';
}
$condition = sprintf($fmt, $base, $obj);
// Wrap command in validation
if ( !empty($cmd) && is_string($cmd) ) {
$condition = sprintf('if ( %1$s ) { %2$s }', $condition, $cmd);
}
return $condition;
}
/**
* Build client method call
* @uses get_client_object() to generate the body of the method call
* @param string $method Method name
* @param array|string $params (optional) Parameters to pass to method
* @param bool $encode (optional) JSON-encode parameters? (Default: TRUE)
* @param bool $validate (optional) Validate method before calling it?
* @return string Method call
*/
function call_client_method($method, $params = null, $encode = true, $validate = true) {
$ret = '';
if ( !is_string($method) || empty($method) ) {
return $ret;
}
$encode = !!$encode;
$validate = !!$validate;
// Build parameters
if ( !is_null($params) ) {
if ( $encode ) {
$params = json_encode($params);
} elseif ( is_array($params) ) {
$params = implode(',', $params);
}
}
if ( !is_string($params) ) {
$params = '';
}
$ret = sprintf('%s(%s);', $this->get_client_object($method), $params);
if ( $validate ) {
$ret = $this->validate_client_object($method, $ret);
}
return $ret;
}
/*-** WP **-*/
/**
* Checks if $post is a valid Post object
* If $post is not valid, assigns global post object to $post (if available)
* @return bool TRUE if $post is valid object by end of function processing
* @param object $post Post object to evaluate
*/
function check_post(&$post) {
if (empty($post)) {
if (isset($GLOBALS['post'])) {
$post = $GLOBALS['post'];
$GLOBALS['post'] =& $post;
}
else
return false;
}
if (is_array($post))
$post = (object) $post;
elseif (is_numeric($post))
$post = get_post($post);
if (!is_object($post))
return false;
return true;
}
/**
* Retrieve parent object
* @return obj|bool Parent object (FALSE if no valid parent set)
*/
function get_parent() {
if ( is_object($this->_parent) ) {
return $this->_parent;
} else {
return false;
}
}
/**
* Retrieve parent property value
* @uses self::get_parent()
* @param string $prop Property name
* @param mixed $default Default value
* @return mixed Parent property value
*/
function get_parent_property($prop, $default = '') {
$p = $this->get_parent();
return ( !!$p && property_exists($p, $prop) ) ? $p->{$prop} : $default;
}
/* Hooks */
/**
* Retrieve formatted name for internal hooks
* Prefixes with parent prefix and hook prefix
* @uses self::get_parent_property() to retrieve hook prefix
* @uses self::add_prefix()
* @param string $tag Base tag
* @param bool|string $hook_prefix (optional) Secondary prefix to use for hook (Default: Use predefined hook name, FALSE: no secondary hook)
* @return string Formatted hook
*/
function get_hook($tag, $hook_prefix = true) {
// Hook prefix
$hook = '';
if ( is_bool($hook_prefix) && $hook_prefix ) {
$hook = $this->get_parent_property('hook_prefix', '');
} elseif ( is_string($hook_prefix) ) {
$hook = $hook_prefix;
}
if ( !empty($hook) )
$hook .= '_';
// Prefix
return $this->add_prefix($hook . $tag);
}
/**
* Run internal action
* Namespaces $tag
* @uses self::get_hook()
* @see do_action()
* @param string|array $tag Action hook. If array, get hook prefix
*/
function do_action($tag, $arg = '') {
// Handle hook prefix
$hook_prefix = true;
if ( is_array($tag) ) {
$hook_prefix = $tag[1];
$tag = $tag[0];
}
$args = func_get_args();
$args[0] = $this->get_hook($tag, $hook_prefix);
return call_user_func_array('do_action', $args);
}
/**
* Run internal action passing arguments in array
* @uses do_action_ref_array()
* @param bool|string $hook_prefix (optional) Secondary prefix to use for hook (Default: Use predefined hook name, FALSE: no secondary hook)
*/
function do_action_ref_array($tag, $args, $hook_prefix = true) {
return do_action_ref_array($this->get_hook($tag, $hook_prefix), $args);
}
/**
* Run internal filter
* Namespaces $tag
* @uses self::get_hook()
* @see apply_filters()
* @param string|array $tag Action hook. If array, get hook prefix
*/
function apply_filters($tag, $value) {
// Handle hook prefix
$hook_prefix = true;
if ( is_array($tag) ) {
$hook_prefix = $tag[1];
$tag = $tag[0];
}
$args = func_get_args();
$args[0] = $this->get_hook($tag, $hook_prefix);
return call_user_func_array('apply_filters', $args);
}
/**
* Run internal filter passing arguments in array
* @uses apply_filters_ref_array()
* @param bool|string $hook_prefix (optional) Secondary prefix to use for hook (Default: Use predefined hook name, FALSE: no secondary hook)
*/
function apply_filters_ref_array($tag, $args, $hook_prefix = true) {
return apply_filters_ref_array($this->get_hook($tag, $hook_prefix), $args);
}
/**
* Add internal action
* Namespaces $tag
* @uses self::get_hook()
* @see add_action()
* @param bool|string $hook_prefix (optional) Secondary prefix to use for hook (Default: Use predefined hook name, FALSE: no secondary hook)
*/
function add_action($tag, $function_to_add, $priority = 10, $accepted_args = 1, $hook_prefix = true) {
return add_action($this->get_hook($tag, $hook_prefix), $function_to_add, $priority, $accepted_args);
}
/**
* Add internal filter
* Namespaces $tag
* @uses self::get_hook()
* @see add_filter()
* @param bool|string $hook_prefix (optional) Secondary prefix to use for hook (Default: Use predefined hook name, FALSE: no secondary hook)
*/
function add_filter($tag, $function_to_add, $priority = 10, $accepted_args = 1, $hook_prefix = true) {
return add_filter($this->get_hook($tag, $hook_prefix), $function_to_add, $priority, $accepted_args);
}
/**
* Remove internal action
* Namespaces $tag
* @uses self::get_hook()
* @uses remove_action()
* @param bool|string $hook_prefix (optional) Secondary prefix to use for hook (Default: Use predefined hook name, FALSE: no secondary hook)
*/
function remove_action($tag, $function_to_remove, $priority = 10, $accepted_args = 1, $hook_prefix = true) {
return remove_action($this->get_hook($tag, $hook_prefix), $function_to_remove, $priority, $accepted_args);
}
/**
* Remove internal filter
* Namespaces $tag
* @uses self::get_hook()
* @uses remove_filter()
* @param bool|string $hook_prefix (optional) Secondary prefix to use for hook (Default: Use predefined hook name, FALSE: no secondary hook)
*/
function remove_filter($tag, $function_to_remove, $priority = 10, $accepted_args = 1, $hook_prefix = true) {
return remove_filter($this->get_hook($tag, $hook_prefix), $function_to_remove, $priority, $accepted_args);
}
/* Shortcode */
/**
* Process specific shortcode(s) in content
* Default: Process all existing shortcodes
* @uses $shortcode_tags - array tag => callback
* @uses do_shortcode()
*
* @param string $content Content to process for shortcodes
* @param string|array $shortcode Single tag or array of tags to process
* > Associative array sets temporary callbacks for shortcodes (`tag => callback`)
*/
public function do_shortcode($content, $shortcode = null) {
global $shortcode_tags;
// Process custom shortcodes
if ( !is_null($shortcode) ) {
// Cast to array
$shortcode = (array) $shortcode;
// Backup and reset shortcode handlers
$tags_temp = $shortcode_tags;
$shortcode_tags = array();
// Register specified tags
foreach ( $shortcode as $key => $val ) {
if ( is_string($key) && is_callable($val) ) {
// Tag w/custom callback
$shortcode_tags[$key] = $val;
} elseif ( is_int($key) && is_string($val) && isset($tags_temp[$val]) ) {
// Tag with default callback
$shortcode_tags[$val] = $tags_temp[$val];
}
}
}
// Process shortcodes in content
$content = do_shortcode($content);
// Restore default shortcode handlers
if ( isset($tags_temp) ) {
$shortcode_tags = $tags_temp;
unset($tags_temp);
}
return $content;
}
/**
* Build shortcode tag
* @param string $tag Shortcode base
* @param array (optional) $attr Shortcode attributes
* @param string (optional) $content Shortcode content
* @return string Shortcode tag
*/
public function make_shortcode($tag, $attr = null, $content = null) {
return $this->build_element(array (
'tag' => $tag,
'attributes' => $attr,
'content' => $content,
));
}
/* Meta */
/**
* Retrieves post metadata for internal methods
* Metadata set internally is wrapped in an array so it is unwrapped before returned the retrieved value
* @see get_post_meta()
* @param int $post_id Post ID
* @param string $key Name of metadata to retrieve
* @param boolean $single Whether or not to retrieve single value or not
* @return mixed Retrieved post metadata
*/
function post_meta_get($post_id, $key, $single = false) {
$meta_value = get_post_meta($post_id, $this->post_meta_get_key($key), $single);
if (is_array($meta_value) && count($meta_value) == 1)
$meta_value = $meta_value[0];
return $meta_value;
}
/**
* Wraps metadata in array for storage in database
* @param mixed $meta_value Value to be set as metadata
* @return array Wrapped metadata value
*/
function post_meta_prepare_value($meta_value) {
return array($meta_value);
}
/**
* Adds Metadata for a post to database
* For internal methods
* @see add_post_meta
* @param $post_id
* @param $meta_key
* @param $meta_value
* @param $unique
* @return boolean Result of operation
*/
function post_meta_add($post_id, $meta_key, $meta_value, $unique = false) {
$meta_value = $this->post_meta_value_prepare($meta_value);
return add_post_meta($post_id, $meta_key, $meta_value, $unique);
}
/**
* Updates post metadata for internal data/methods
* @see update_post_meta()
* @param $post_id
* @param $meta_key
* @param $meta_value
* @param $prev_value
* @return boolean Result of operation
*/
function post_meta_update($post_id, $meta_key, $meta_value, $prev_value = '') {
$meta_value = $this->post_meta_prepare_value($meta_value);
return update_post_meta($post_id, $meta_key, $meta_value, $prev_value);
}
/**
* Builds postmeta key for custom data set by plugin
* @param string $key Base key name
* @return string Formatted postmeta key
*/
function post_meta_get_key($key) {
$sep = '_';
if ( strpos($key, $sep . $this->prefix) !== 0 ) {
$key_base = func_get_args();
if ( !empty($key_base) ) {
$key = array_merge((array)$this->prefix, $key_base);
return $sep . implode($sep, $key);
}
}
return $key;
}
/**
* Creates a meta key for storing post meta data
* Prefixes standard prefixed text with underscore to hide meta data on post edit forms
* @param string $text Text to use as base of meta key
* @return string Formatted meta key
*/
function make_meta_key($text = '') {
return '_' . $this->add_prefix($text);
}
/* Class */
/**
* Retrieve name of internal class
* @param string $class Base name of class
* @return string Full name of internal class
*/
function get_class($class) {
return $this->add_prefix_uc($class);
}
/* Context */
/**
* Retrieve context for current request
* @return array Context
*/
function get_context() {
// Context
static $ctx = null;
if ( !is_array($ctx) ) {
// Standard
$ctx = array($this->build_context());
// Action
$action = $this->get_action();
if ( !empty($action) ) {
$ctx[] = $this->build_context('action', $action);
}
// Post type
$post_type = $this->get_post_type();
if ( !empty($action) ) {
$ctx[] = $this->build_context('post-type', $post_type);
}
// Admin page
if ( is_admin() ) {
global $pagenow;
$pg = $this->strip_file_extension($pagenow);
$ctx[] = $this->build_context('page', $pg);
// Query String
if ( isset($_SERVER['QUERY_STRING']) ) {
parse_str($_SERVER['QUERY_STRING'], $qv);
if ( isset($qv['page']) ) {
$ctx[] = $this->build_context('page', $qv['page']);
if ( stripos($qv['page'], $this->get_prefix()) === 0 ) {
$ctx[] = $this->build_context('page', $this->get_prefix());
}
}
}
// Action
if ( !empty($action) ) {
$ctx[] = $this->build_context('page', $pg, 'action', $action);
$ctx[] = $this->build_context('post-type', $post_type, 'action', $action);
}
}
// User
$u = wp_get_current_user();
$ctx[] = $this->build_context('user', ( $u->ID ) ? 'registered' : 'guest', false);
}
return $ctx;
}
/**
* Builds context from multiple components
* Usage:
* > $prefix can be omitted and context strings can be added as needed
* > Multiple context strings may be passed to be joined together
*
* @param string (optional) $context Variable number of components to add to context
* @param bool (optional) $prefix Whether or not to prefix context with request type (public or admin) [Default: TRUE]
* @return string Context
*/
function build_context($context = null, $prefix = true) {
$args = func_get_args();
// Get prefix option
if ( !empty($args) ) {
$prefix = ( is_bool($args[count($args) - 1]) ) ? array_pop($args) : true;
}
// Validate
$context = array_filter($args, 'is_string');
$sep = '_';
// Context Prefix
if ( $prefix )
array_unshift($context, ( is_admin() ) ? 'admin' : 'public' );
return implode($sep, $context);
}
/**
* Check if context exists in current request
* @param string $context Context to check for
* @return bool TRUE if context exists FALSE otherwise
*/
function is_context($context) {
$ret = false;
if ( is_scalar($context) )
$context = array($context);
if ( is_array($context) && !empty($context) ) {
$ictx = array_intersect($this->get_context(), $context);
if ( !empty($ictx) )
$ret = true;
}
return $ret;
}
/**
* Output current context to client-side
* @uses `wp_head` action hook
* @uses `admin_head` action hook
* @return void
*/
function set_client_context() {
$ctx = new stdClass();
$ctx->context = $this->get_context();
$this->extend_client_object($ctx, true);
}
/* Path */
/**
* Joins and normalizes the slashes in the paths passed to method
* All forward/back slashes are converted to forward slashes
* Multiple path segments can be passed as additional argments
* @param string $path Path to normalize
* @param bool|array $trailing_slash (optional) Whether or not normalized path should have a trailing slash or not (Default: FALSE)
* If array is passed, first index is trailing, second is leading slash
* If multiple path segments are passed, $trailing_slash will be the LAST parameter (default value used if omitted)
*/
function normalize_path($path, $trailing_slash = false) {
$sl_f = '/';
$sl_b = '\\';
$parts = func_get_args();
// Slash defaults (trailing, leading);
$slashes = array(false, true);
if ( func_num_args() > 1 ) {
// Get last argument
$arg_last = $parts[count($parts) - 1];
if ( is_bool($arg_last) ) {
$arg_last = array($arg_last);
}
if ( is_array($arg_last) && count($arg_last) > 0 && is_bool($arg_last[0]) ) {
// Remove slash paramter from args array
array_pop($parts);
// Normalize slashes options
if ( isset($arg_last[0]) )
$slashes[0] = $arg_last[0];
if ( isset($arg_last[1]) )
$slashes[1] = $arg_last[1];
}
}
// Extract to slash options local variables
list($trailing_slash, $leading_slash) = $slashes;
// Clean path segments
foreach ( $parts as $key => $part ) {
// Trim slashes/spaces
$parts[$key] = trim($part, " " . $sl_f . $sl_b);
// Verify path segment still contains value
if ( empty($parts[$key]) ) {
unset($parts[$key]);
continue;
}
}
// Join path parts together
$parts = implode($sl_b, $parts);
$parts = str_replace($sl_b, $sl_f, $parts);
// Add trailing slash (if necessary)
if ( $trailing_slash )
$parts .= $sl_f;
// Add leading slash (if necessary)
$regex = '#^.+:[\\/]#';
if ( $leading_slash && !preg_match($regex, $parts) ) {
$parts = $sl_f . $parts;
}
return $parts;
}
/**
* Returns URL of file (assumes that it is in plugin directory)
* @param string $file name of file get URL
* @param string|bool $relative Path that URI should be relative to (Default: full path)
* @return string File URL
*/
function get_file_url($file, $relative = null) {
if ( is_string($file) && '' != trim($file) ) {
$file = str_replace(' ', '%20', $this->normalize_path($this->get_url_base(false, $relative), $file));
}
return $file;
}
/**
* Returns path to plugin file
* @param string $file file name
* @return string File path
*/
function get_file_path($file, $relative = null) {
// Build path
if ( is_string($file) && '' != trim($file) ) {
$file = $this->normalize_path($this->get_path_base($relative), $file);
}
return $file;
}
function get_plugin_file_path($file, $trailing_slash = false) {
if ( is_string($file) && '' != trim($file) )
$file = $this->normalize_path($this->get_plugin_base(), $file, $trailing_slash);
return $file;
}
/**
* Checks if value is valid file name
* @param string $filename File name to check
* @return bool TRUE if valid file name, FALSE otherwise
*/
function is_file($filename) {
$ext = $this->get_file_extension($filename);
return ( empty($ext) ) ? false : true;
}
/**
* Check if string is valid URI
* @param string $uri String to check
* @return bool TRUE if string is valid URI
*/
function is_uri($uri) {
return ( preg_match('|^(https?:)?//|', $uri) ) ? true : false;
}
/**
* Retrieves file extension
* @param string $file file name/path
* @param bool (optional) $lowercase Whether lowercase extension should be returned (Default: TRUE)
* @return string File's extension
*/
function get_file_extension($file, $lowercase = true) {
$ret = '';
$sep = '.';
// Validate
if ( !is_string($file) )
return $ret;
// Strip query string (if necessary)
if ( ( $qpos = strpos($file, '?') ) && $qpos !== false ) {
$file = substr($file, 0, $qpos);
}
if ( ( $rpos = strrpos($file, $sep) ) > 0 )
$ret = substr($file, $rpos + 1);
if ( !!$lowercase )
$ret = strtolower($ret);
return $ret;
}
/**
* Checks if file has specified extension
* @uses get_file_extension()
* @param string $file File name/path
* @param string|array $extension File ending(s) to check $file for
* @param bool (optional) Whether check should be case senstive or not (Default: FALSE)
* @return bool TRUE if file has extension
*/
function has_file_extension($file, $extension, $case_sensitive = false) {
if ( !is_array($extension) )
$extension = array(strval($extension));
if ( !$case_sensitive ) {
// Normalize extensions
$extension = array_map('strtolower', $extension);
}
return ( in_array($this->get_file_extension($file, !$case_sensitive), $extension) ) ? true : false;
}
/**
* Removes file extension from file name
* The extension is the text following the last period ('.') in the file name
* @uses get_file_extension()
* @param string $file File name
* @return string File name without extension
*/
function strip_file_extension($file) {
$ext = $this->get_file_extension($file);
if ( !empty($ext) ) {
$file = substr($file, 0, (strlen($ext) + 1) * -1);
}
return $file;
}
/**
* Retrieve base URL for plugin-specific files
* @uses get_plugin_base()
* @uses normalize_path()
* @return string Base URL
*/
function get_url_base($trailing_slash = false, $relative = null) {
$ret = $this->_plugin['uri'];
if ( empty($ret) ) {
$ret = $this->normalize_path(plugins_url(), $this->get_plugin_base());
}
// Trailing slash
if ( !!$trailing_slash ) {
$ret .= '/';
}
// Relative
if ( !empty($relative) ) {
// Default
if ( is_bool($relative) ) {
$relative = site_url();
}
// Custom
if ( is_string($relative) ) {
$ret = $this->get_relative_path($ret, $relative);
}
}
return $ret;
}
/**
* Retrieve plugin's base path
* @uses WP_PLUGIN_DIR
* @uses get_plugin_base()
* @uses normalize_path()
* @return string Base path
*/
function get_path_base($relative = null) {
$ret = $this->_path_base;
if ( empty($ret) ) {
// Get base directory of parent object
if ( $this->get_parent() ) {
$r = new ReflectionClass(get_class($this->get_parent()));
$base = $r->getFileName();
unset($r);
} else {
$base = __FILE__;
}
// Extract base path
$base = $this->normalize_path($base);
if ( 0 === strpos($base, $this->normalize_path(WP_PLUGIN_DIR)) ) {
$end = strpos($base, '/', strlen(WP_PLUGIN_DIR) + 1);
$base = substr($base, 0, $end);
}
$ret = $this->_path_base = $base;
}
// Make relative path
if ( !empty($relative) ) {
// Default
if ( is_bool($relative) ) {
$relative = ABSPATH;
}
// Custom
if ( is_string($relative) ) {
$ret = $this->get_relative_path($ret, $relative);
}
}
return $ret;
}
/**
* Retrieve relative path for absolute paths
* @param string $path Path to modify
* @param string $relative (optional) Base path to make $path relative to (Default: Site's base path)
* @return string Relative path
*/
function get_relative_path($path, $relative = true) {
// Default base path
if ( !is_string($relative) ) {
$relative = ABSPATH;
}
if ( !empty($relative) && !empty($path) ) {
$relative = $this->normalize_path($relative);
$path = $this->normalize_path($path);
// Strip base path
if ( strpos($path, $relative) === 0 ) {
$path = substr($path, strlen($relative));
}
}
return $path;
}
/**
* Retrieve plugin's base directory
* @uses WP_PLUGIN_DIR
* @uses Utilities::get_path_base() to retrieve plugin base path
* @uses Utilities::_plugin_base to save plugin base
* @return string Base directory
*/
function get_plugin_base() {
$ret = $this->_plugin['base'];
if ( empty($ret) ) {
$ret = $this->_plugin['base'] = basename($this->get_path_base());
}
return $ret;
}
/**
* Retrieve plugin's base file path
* @uses get_path_base()
* @uses get_file_path()
* @return string Base file path
*/
function get_plugin_base_file() {
$ret = $this->_plugin['file'];
if ( empty($ret) ) {
$dir = @opendir($this->get_path_base());
if ( $dir ) {
while ( ($ftemp = readdir($dir)) !== false ) {
// Only process PHP files
$ftemp = $this->get_file_path($ftemp);
if ( !$this->has_file_extension($ftemp, 'php') || !is_readable($ftemp) )
continue;
// Check for data
$data = get_file_data($ftemp, $this->_plugin['headers']);
if ( !empty($data['Name']) ) {
// Set base file
$file = $ftemp;
// Save plugin data
$this->set_plugin_info($data);
break;
}
}
}
@closedir($dir);
}
// Return
return $file;
}
/**
* Retrieve plugin's internal name
* Internal name is used by WP core
* @uses get_plugin_base_file()
* @uses plugin_basename()
* @return string Internal plugin name
*/
function get_plugin_base_name() {
$ret = $this->_plugin['name'];
if ( empty($ret) ) {
$ret = $this->_plugin['name'] = plugin_basename( $this->get_plugin_base_file() );
}
return $ret;
}
private function set_plugin_info($data) {
if ( is_array($data) ) {
$this->_plugin['data'] = $data;
}
}
/**
* Retrieve plugin info
* Parses info comment in main plugin file
* @uses get_plugin_base_file() to retrieve plugin info
* @return array|string Plugin info (specific value if field set)
*/
function get_plugin_info($field = null) {
$ret = $this->_plugin['data'];
// Get plugin data
if ( empty($ret) ) {
$this->get_plugin_base_file();
$ret = $this->_plugin['data'];
}
// Return specified field
if ( !empty($field) ) {
$ret = ( is_array($ret) && isset($ret[$field]) ) ? $ret[$field] : '';
}
return $ret;
}
/**
* Retrieve plugin version
* @uses get_plugin_info()
* @param bool $strip_desc Strip any additional version text
* @return string Plugin version
*/
function get_plugin_version($strip_desc = true) {
// Retrieve version
$ret = $this->get_plugin_info('Version');
// Format
if ( !empty($ret) && $strip_desc ) {
$ret = explode(' ', $ret, 2);
$ret = $ret[0];
}
// Return
return $ret;
}
/**
* Retrieve current post type based on URL query variables
* @return string|null Current post type
*/
public function get_post_type() {
if ( isset($_GET['post_type']) && !empty($_GET['post_type']) ) {
return $_GET['post_type'];
}
$pt = null;
if ( isset($_GET['post']) && is_numeric($_GET['post']) ) {
$pt = get_post_type($_GET['post']);
}
return $pt;
}
/**
* Retrieve current action based on URL query variables
* @param mixed $default (optional) Default action if no action exists
* @return string Current action
*/
function get_action($default = null) {
$action = '';
// Check if action is set in URL
if ( isset($_GET['action']) )
$action = $_GET['action'];
// Otherwise, Determine action based on plugin plugin admin page suffix
elseif ( isset($_GET['page']) && ($pos = strrpos($_GET['page'], '-')) && $pos !== false && ( $pos != count($_GET['page']) - 1 ) )
$action = trim(substr($_GET['page'], $pos + 1), '-_');
// Determine action for core admin pages
if ( ( !isset($_GET['page']) || empty($action) ) && isset($_SERVER['SCRIPT_NAME']) ) {
$actions = array(
'add' => array('page-new', 'post-new'),
'edit-item' => array('page', 'post'),
'edit' => array('edit', 'edit-pages')
);
$page = basename($_SERVER['SCRIPT_NAME'], '.php');
foreach ( $actions as $act => $pages ) {
if ( in_array($page, $pages) ) {
$action = $act;
break;
}
}
}
if ( empty($action) )
$action = $default;
return $action;
}
/*-** General **-*/
/**
* Checks if a property exists in a class or object
* Compatibility method for PHP 4
* @param mixed $class Class or object to check
* @param string $property Name of property to look for in $class
*/
function property_exists($class, $property) {
if ( !is_object($class) && !is_array($class) )
return false;
if ( function_exists('property_exists') && is_object($class) ) {
return property_exists($class, $property);
} else {
return array_key_exists($property, $class);
}
}
/**
* Retrieve specified property from object or array
* @param object|array $obj Object or array to get property from
* @param string $property Property name to retrieve
* @return mixed Property value
*/
function &get_property(&$obj, $property) {
$property = trim($property);
// Object
if ( is_object($obj) )
return $obj->{$property};
// Array
if ( is_array($obj) )
return $obj[$property];
// Class
if ( is_string($obj) && class_exists($obj) ) {
$cvars = get_class_vars($obj);
if ( isset($cvars[$property]) )
return $cvars[$property];
}
}
/**
* Remap array members based on a
* mapping of source/destination keys
* @param array $properties Associative array of properties
* @param array $map Source/Destination mapping
* > Key: Source member
* > Val: Destination member
* @param bool $overwrite If TRUE, source value will be set in destination regardless of whether member already exists or not
* @return array Remapped properties
*/
function array_remap($arr, $map = array(), $overwrite = false) {
if ( !empty($map) && is_array($map) ) {
// Iterate through mappings
foreach ( $map as $from => $to ) {
if ( !array_key_exists($from, $arr) )
continue;
$move = $overwrite;
// Only remap if parent property doesn't already exist in array
if ( !array_key_exists($to, $arr) )
$move = true;
if ( $move ) {
// Move member value to new key
$arr[$to] = $arr[$from];
// Remove source member
unset($arr[$from]);
}
}
}
// Return remapped properties
return $arr;
}
function array_filter_keys($arr, $keys) {
if ( is_array($arr) && !empty($arr) && is_array($keys) && !empty($keys) ) {
foreach ( $keys as $rem ) {
if ( array_key_exists($rem, $arr) )
unset($arr[$rem]);
}
}
return $arr;
}
/**
* Insert an item into an array at the specified position
* @param mixed $item Item to insert into array
* @param int $pos Index position to insert item into array
* @return array Modified array
*/
function array_insert($array, $item, $pos = null) {
array_splice($array, $pos, 0, $item);
return $array;
}
/**
* Merges 1 or more arrays together
* Methodology
* - Set first parameter as base array
* - All other parameters will be merged into base array
* - Iterate through other parameters (arrays)
* - Skip all non-array parameters
* - Iterate though key/value pairs of current array
* - Merge item in base array with current item based on key name
* - If the current item's value AND the corresponding item in the base array are BOTH arrays, recursively merge the the arrays
* - If the current item's value OR the corresponding item in the base array is NOT an array, current item overwrites base item
* @param array Variable number of arrays
* @param array $arr1 Default array
* @return array Merged array
*/
function array_merge_recursive_distinct($arr1) {
// Get all arrays passed to function
$args = func_get_args();
if ( empty($args) )
return false;
// Return empty array if first parameter is not an array
if ( !is_array($args[0]) )
return array();
// Set first array as base array
$merged = $args[0];
// Iterate through arrays to merge
$arg_length = count($args);
for ( $x = 1; $x < $arg_length; $x++ ) {
// Skip if argument is not an array (only merge arrays)
if ( !is_array($args[$x]) )
continue;
// Iterate through argument items
foreach ( $args[$x] as $key => $val ) {
// Generate key for numeric indexes
if ( is_int($key) ) {
// Add new item to merged array
$merged[] = null;
// Get key of new item
$key = array_pop(array_keys($merged));
}
if ( !isset($merged[$key]) || !is_array($merged[$key]) || !is_array($val) ) {
$merged[$key] = $val;
} elseif ( is_array($merged[$key]) && is_array($val) ) {
$merged[$key] = $this->array_merge_recursive_distinct($merged[$key], $val);
}
}
}
return $merged;
}
/**
* Replaces string value in one array with the value of the matching element in a another array
*
* @param string $search Text to search for in array
* @param array $arr_replace Array to use for replacing values
* @param array $arr_subject Array to search for specified value
* @return array Searched array with replacements made
*/
function array_replace_recursive($search, $arr_replace, $arr_subject) {
foreach ($arr_subject as $key => $val) {
// Skip element if key does not exist in the replacement array
if (!isset($arr_replace[$key]))
continue;
// If element values for both arrays are strings, replace text
if (is_string($val) && strpos($val, $search) !== false && is_string($arr_replace[$key]))
$arr_subject[$key] = str_replace($search, $arr_replace[$key], $val);
// If value in both arrays are arrays, recursively replace text
if (is_array($val) && is_array($arr_replace[$key]))
$arr_subject[$key] = $this->array_replace_recursive($search, $arr_replace[$key], $val);
}
return $arr_subject;
}
/**
* Checks if item at specified path in array is set
* @param array $arr Array to check for item
* @param array $path Array of segments that form path to array (each array item is a deeper dimension in the array)
* @return boolean TRUE if item is set in array, FALSE otherwise
*/
function array_item_isset(&$arr, &$path) {
$f_path = $this->get_array_path($path);
return eval('return isset($arr' . $f_path . ');');
}
/**
* Build formatted string based on array values
* Array values in formatted string will be ordered by index order
* @param array $attribute Values to build string with
* @param string $format (optional) Format name (Default: Multidimensional array representation > ['value1']['value2']['value3'], etc.)
* @return string Formatted string based on array values
*/
function get_array_path($attribute = '', $format = null) {
// Formatted value
$fmtd = '';
if (!empty($attribute)) {
// Make sure attribute is array
if (!is_array($attribute)) {
$attribute = array($attribute);
}
// Format attribute
$format = strtolower($format);
switch ($format) {
case 'id':
$fmtd = array_shift($attribute) . '[' . implode('][', $attribute) . ']';
break;
case 'metadata':
case 'attribute':
// Join segments
$delim = '_';
$fmtd = implode($delim, $attribute);
// Replace white space and repeating delimiters
$fmtd = str_replace(' ', $delim, $fmtd);
while (strpos($fmtd, $delim.$delim) !== false)
$fmtd = str_replace($delim.$delim, $delim, $fmtd);
// Prefix formatted value with delimeter for metadata keys
if ('metadata' == $format)
$fmtd = $delim . $fmtd;
break;
case 'path':
case 'post':
default:
$fmtd = '["' . implode('"]["', $attribute) . '"]';
}
}
return $fmtd;
}
/**
* Builds array of path elements based on arguments
* Each item in path array represents a deeper level in structure path is for (object, array, filesystem, etc.)
* @param array|string Value to add to the path
* @return array 1-dimensional array of path elements
*/
function build_path() {
$path = array();
$args = func_get_args();
// Iterate through parameters and build path
foreach ( $args as $arg ) {
if ( empty($arg) )
continue;
if (is_array($arg)) {
// Recurse through array items to pull out any more arrays
foreach ($arg as $key => $val) {
$path = array_merge($path, $this->build_path($val));
}
// $path = array_merge($path, array_values($arg));
} elseif ( is_scalar($arg) ) {
$path[] = $arg;
}
}
return $path;
}
/**
* Build generic element
* @param array $args
* @return string Element output
*/
public function build_element($args = array()) {
$ret = '';
$args_default = array(
'tag' => '',
'wrap' => false,
'content' => '',
'attributes' => array(),
'format' => array(),
);
$format_default = array(
'open' => '[%s]',
'close' => '[/%s]',
);
$args = wp_parse_args($args, $args_default);
$args['format'] = wp_parse_args($args['format'], $format_default);
// Validate
if ( !is_string($args['tag']) || empty($args['tag']) ) {
return $ret;
}
$args = (object) $args;
$args->attributes = $this->build_attribute_string($args->attributes);
if ( strlen($args->attributes) > 0 ) {
$args->attributes = ' ' . $args->attributes;
}
// Build output
$args->format = (object) $args->format;
$ret = sprintf( $args->format->open, $args->tag . $args->attributes);
// Wrap content if necessary
if ( $args->wrap || ( is_string($args->content) && !empty($args->content) ) ) {
$ret .= $args->content . sprintf( $args->format->close, $args->tag);
}
return $ret;
}
/**
* Parse string of attributes into array
* For XML/XHTML tag attributes
* @param string $txt Attribute text (Can be full tag or just attributes)
* @return array Attributes as associative array
*/
function parse_attribute_string($txt, $defaults = array()) {
$txt = trim($txt, ' >');
$matches = $attr = array();
// Strip tag
if ( $txt[0] == '<' && ($s = strpos($txt, ' ')) && $s !== false ) {
$txt = trim(substr($txt, $s + 1));
}
// Parse attributes
$rgx = "/\b(\w+.*?)=([\"'])(.*?)\\2(?:\s|$)/i";
preg_match_all($rgx, $txt, $matches);
if ( count($matches) > 3 ) {
foreach ( $matches[1] as $sub_idx => $val ) {
if ( isset($matches[3][$sub_idx]) )
$attr[trim($val)] = trim($matches[3][$sub_idx]);
}
}
// Destroy parsing vars
unset($txt, $matches);
return array_merge($defaults, $attr);
}
/**
* Builds attribute string for HTML element
* @param array $attr Attributes
* @return string Formatted attribute string
*/
function build_attribute_string($attr) {
$ret = '';
if ( is_object($attr) ) {
$attr = (array) $attr;
}
if ( is_array($attr) && !empty($attr) ) {
array_map('esc_attr', $attr);
$attr_str = array();
foreach ( $attr as $key => $val ) {
$attr_str[] = $key . '="' . $val . '"';
}
$ret = implode(' ', $attr_str);
}
return $ret;
}
/* HTML */
/**
* Generate HTML element based on values
* @param $args Element arguments
* @return string Generated HTML element
*/
public function build_html_element($args) {
$args_default = array(
'tag' => 'span',
'content' => '',
'attributes' => array()
);
$args = wp_parse_args($args, $args_default);
$args['format'] = array(
'open' => '<%s>',
'close' => '</%s>',
);
// Build element
return $this->build_element($args);
}
/**
* Build HTML link element
* @uses build_html_element() to build link output
* @param string $uri Link URI
* @param string $content Link content
* @param $array (optional) $attributes Additional link attributes
* @return string HTML link element
*/
function build_html_link($uri, $content, $attributes = array()) {
$attributes = array_merge(array('href' => $uri, 'title' => $content), $attributes);
return $this->build_html_element(array('tag' => 'a', 'wrap' => true, 'content' => $content, 'attributes' => $attributes));
}
/**
* Generate external stylesheet element
* @param $url Stylesheet URL
* @return string Stylesheet element
*/
function build_stylesheet_element($url) {
$attributes = array('href' => $url, 'type' => 'text/css', 'rel' => 'stylesheet');
return $this->build_html_element(array('tag' => 'link', 'wrap' => false, 'attributes' => $attributes));
}
/**
* Build client-side script element
*
* @param string $content Script content
* @param string $id (optional) Element ID
* @param bool $wrap_jquery (optional) Wrap commands in jQuery? (Default: Yes)
* @param bool $wait_doc_ready (optional) Wait until document is fully loaded before executing commands? (Default: No)
*/
function build_script_element($content = '', $id = '', $wrap_jquery = true, $wait_doc_ready = false) {
// Stop processing invalid content
if ( is_array($content) && !empty($content) ) {
$content = implode(PHP_EOL, $content);
}
if ( empty($content) || !is_string($content) ) {
return '';
}
$attributes = array('type' => 'text/javascript');
$start = array('/* <![CDATA[ */');
$end = array('/* ]]> */');
if ( $wrap_jquery ) {
$start[] = 'if ( !!window.jQuery ) {(function($){';
$end[] = '})(jQuery);}';
// Add event handler (if necessary)
if ( $wait_doc_ready ) {
$start[] = '$(document).ready(function(){';
$end[] = '})';
}
}
// Reverse order of end values
$end = array_reverse($end);
$content = implode('', array_merge($start, array($content), $end));
if ( is_string($id) && !empty($id) ) {
$attributes['id'] = $this->add_prefix($id);
}
return $this->build_html_element(array('tag' => 'script', 'content' => $content, 'wrap' => true, 'attributes' => $attributes)) . PHP_EOL;
}
}
ACC SHELL 2018