File Editor
Directories:
.. (Back)
classes
config
elements
extend
integration
settings
shortcodes
tco
utility
views
Files:
boot.php
plugin.php
registry.php
Create New File
Create
Edit File: plugin.php
<?php /** * Plugin boilerplate. * This bootstraps the plugin and activates the required components. */ abstract class Cornerstone_Plugin_Base { // Optionally override in a child class to adjust behavior protected $init_priority = 10; protected $admin_init_priority = 10; protected $includes_folder = 'includes'; protected $config_folder = 'includes/config'; protected $i18n_folder = 'includes/i18n'; protected $templates_folder = 'templates'; protected $views_folder = 'includes/views'; protected $theme_template_folder = ''; // defaults to slug // These should never be overriden by the child class protected $registry; protected $components = array(); protected $config_store = array(); protected $i18n_strings = array(); protected $name = 'Cornerstone'; protected $slug = 'cornerstone'; protected $path; protected $url; protected $i18n_path; /** * Assign plugin variables */ public function __construct( $path, $i18n_path, $url ) { $this->path = $path; $this->i18n_path = $i18n_path; $this->url = $url; } /** * Run after plugin instantiation */ public function superPreinit() { $this->preinitBefore(); $plugin_setup = apply_filters( '_cs_plugin_setup', $this->path('includes/setup.php' ) ); if ( file_exists ( $plugin_setup ) ) { require_once( $plugin_setup ); } // Load WP-CLI commands if ( defined( 'WP_CLI' ) && WP_CLI ) { $this->loadFiles( 'wp-cli' ); $this->loadComponents( 'wp-cli' ); } $this->components = array(); $this->registry = include $this->path( $this->includes_folder . '/registry.php' ); // Load preinit files and components $this->loadFiles( 'preinit' ); $this->loadComponents( 'preinit' ); do_action( 'cornerstone_integrations' ); // Defer actions add_action( 'init', array( $this, 'init' ), $this->init_priority ); add_action( 'after_setup_theme', array( $this, 'after_setup_theme' ) ); add_action( 'plugins_loaded', array( $this, 'plugins_loaded' ) ); add_action( 'admin_init', array( $this, 'adminInit' ), $this->admin_init_priority ); $this->preinitAfter(); $this->maybe_deactivate_x_shortcodes(); } public function maybe_deactivate_x_shortcodes() { if (defined( 'X_SHORTCODES_VERSION' )) { include_once( ABSPATH . '/wp-admin/includes/plugin.php' ); deactivate_plugins( array( 'x-shortcodes/x-shortcodes.php' ) ); remove_action( 'init', 'x_shortcodes_init' ); Cornerstone_Admin_Notice::updated( csi18n('admin.x-shortcodes-notice'), true ); } } /** * Perform boilerplate init actions * @return none */ public function init() { $this->initBefore(); // Load init files and components $this->loadFiles( 'init' ); $this->loadComponents( 'init' ); $this->versionMigration(); $this->initAfter(); // Load user/admin classes if ( ! is_user_logged_in() ) { return; } $this->loggedinBefore(); // Load logged-in files and components $this->loadFiles( 'loggedin' ); $this->loadComponents( 'loggedin' ); $this->loggedinAfter(); } /** * Perform boilerplate init actions * @return none */ public function after_setup_theme() { // Load after_setup_theme files and components $this->loadFiles( 'after_setup_theme' ); $this->loadComponents( 'after_setup_theme' ); } public function adminInit() { $this->adminBefore(); // Load logged-in files and components $this->loadFiles( 'admin' ); $this->loadComponents( 'admin' ); $this->adminAfter(); } public function plugins_loaded() { do_action( 'cornerstone_integrations' ); } /** * Require a set of registered files * @param string $group A group of files found in registry.php * @return bool whether or not the operation suceeded */ public function loadFiles( $group ) { if ( ! isset( $this->registry['files'][ $group ] ) ) { return false; } $includes = $this->registry['files'][ $group ]; if ( ! is_array( $includes ) ) { return false; } try { foreach ( $includes as $filename ) { require_once $this->path( "$this->includes_folder/$filename.php" ); } } catch ( Exception $e ) { trigger_error( 'Exception: ' . $e->getMessage() ); return false; } return true; } /** * Instantiate a set of component classes * @param string $group A group of componenets found in registry.php * @return bool whether or not the operation suceeded */ public function loadComponents( $group ) { if ( ! isset( $this->registry['components'][ $group ] ) ) { return false; } $components = $this->registry['components'][ $group ]; if ( ! is_array( $components ) ) { return; } foreach ( $components as $component ) { $this->component( $component ); } } public function get_registry() { $args = func_get_args(); $registry = null; $args = array_reverse($args); $level = $this->registry; while(count($args)) { $key = array_pop( $args ); if ( isset( $level[$key] ) ) { $level = $level[$key]; } else { return null; } } return $level; } public function loadComponent( $name ) { try { if ( ! isset( $this->components[ $name ] ) ) { $class = $this->name . '_' . $name; $exists = false; try { $exists = class_exists( $class ); } catch ( Exception $e ) { trigger_error( 'Exception: ' . $e->getMessage() . "\n" ); } if ( ! $exists ) { return false; } $name = $this->componentConditions( $name ); if ( false === $name ) { return false; } $instance = new $class( $this ); $this->components[ $name ] = $instance; $instance->beforeDependencies(); if ( is_array( $instance->dependencies ) ) { foreach ( $instance->dependencies as $component ) { $this->component( $component ); } } $instance->setup(); } return $this->components[ $name ]; } catch ( Exception $e ) { trigger_error( 'Exception: ' . $e->getMessage() . "\n" ); } return false; } public function componentConditions( $name ) { $name = explode( ':', $name ); if ( count( $name ) === 1 ) { return $name[0]; } if ( $name[1] == 'theme-support' ) { if ( isset( $name[2] ) && current_theme_supports( $name[2] ) ) { return $name[0]; } } return false; } /** * Returns a component instance via its name * @return object Component instance */ public function component( $handle ) { return $this->loadComponent( $handle ); } /** * Gets the path to the Cornerstone plugin directory. * Should be used in combination with the instance wrapper funciton. * For example: $path = CS()->path(); * This will include a trailing slash, so do not include one when using $to * @param string $to Path to desired location relative to the plugin path. * @return string filterable equivilent of plugin_dir_path( __FILE__ ) */ public function path( $to = '' ) { return apply_filters( $this->slug . '_path', $this->path ) . $to; } /** * Gets the url to the plugin directory. * Should be used in combination with the instance wrapper funciton. * This will include a trailing slash, so do not include one when using $to * @param string $to URL to desired location relative to the plugin URL. * @return string filterable equivilent of plugin_dir_url( __FILE__ ) */ public function url( $to = '' ) { return apply_filters( $this->slug . '_url', $this->url ) . $to; } /** * Returns the plugin name * @return string */ public function name() { return $this->name; } /** * Returns the plugin slug * @return string */ public function slug() { return $this->slug; } /** * Simple version migration system * Hook into `myplugin_updated` and test against the supplied * version number to conditionally run migration logic * @return none */ public function versionMigration() { $prior = get_option( $this->slug . '_version', 0 ); if ( version_compare( $prior, CS_VERSION, '>=' ) ) { return; } do_action( $this->slug .'_updated', $prior ); update_option( $this->slug . '_version', CS_VERSION, true ); } public function get_template_part( $slug, $name = null, $load = true ) { do_action( 'get_template_part_' . $slug, $slug, $name ); $templates = array(); if ( isset( $name ) ) { $templates[] = $slug . '-' . $name . '.php'; } $templates[] = $slug . '.php'; $templates = apply_filters( $this->slug . '_get_template_part', $templates, $slug, $name ); return $this->locate_template( $templates, $load, false ); } /** * Retrieve the name of the highest priority template file that exists. * * Searches in the STYLESHEETPATH before TEMPLATEPATH so that themes which * inherit from a parent theme can just overload one file. If the template is * not found in either of those, it looks in the theme-compat folder last. * * @param string|array $template_names Template file(s) to search for, in order. * @param bool $load If true the template file will be loaded if it is found. * @param bool $require_once Whether to require_once or require. Default true. * Has no effect if $load is false. * @return string The template filename if one is located. */ public function locate_template( $template_names, $load = false, $require_once = true ) { $filename = false; foreach ( (array) $template_names as $template_name ) { if ( empty( $template_name ) ) { continue; } $template_name = untrailingslashit( $template_name ); $theme_template_folder = trailingslashit( ( '' !== $this->theme_template_folder ) ? $this->theme_template_folder : $this->slug ); // Check child theme first $child = get_stylesheet_directory() . '/' . $theme_template_folder . $template_name; if ( file_exists( $child ) ) { $filename = $child; break; } $parent = get_template_directory() . '/' . $theme_template_folder . $template_name; if ( file_exists( $parent ) ) { $filename = $parent; break; } $plugin = $this->path( "$this->templates_folder/$template_name" ); if ( file_exists( $plugin ) ) { $filename = $plugin; break; } } if ( $load && ! empty( $filename ) ) { load_template( $filename, $require_once ); } return $filename; } /** * Find a template so we can include it ourselves. * Doesn't run through `load_template` so some globals may need to be declared. * This can be used to load markup used in the dashboard. */ public function template( $slug, $name = null, $echo = true ) { ob_start(); $template = $this->get_template_part( $slug, $name, false ); if ( $template ) { include( $template ); } $contents = ob_get_clean(); if ( $echo ) { echo $contents; } return $contents; } /** * Include a view file, optionally outputting its contents. */ public function view( $name, $echo = true, $data = array(), $extract = false ) { ob_start(); $view = $this->locate_view( $name ); if ( $extract ) { extract( $data ); } if ( $view ) { include( $view ); } $contents = ob_get_clean(); if ( $echo ) { echo $contents; } return $contents; } public function locate_view( $name ) { $file = $this->path( trailingslashit( $this->views_folder ) . $name . '.php' ); if ( ! file_exists( $file ) ) { return false; } return $file; } /** * * @param * @param string path to config file * @return array */ /** * Retrieve a particular configuration set and apply filters. * @param string $name string path to config file * @param string $namespace namespace to prepend to key for caching * @param string $path alternate path * @return array requested configuration values */ public function config_group( $name = '', $namespace = '', $path = '', $abs_path = false ) { $key = ( $namespace ) ? "{$namespace}.{$name}" : $name; $path = ( $path ) ? $path : $this->config_folder; if ( ! isset( $this->config_store[ $key ] ) ) { $config_path = trailingslashit( $path ) . $name . '.php'; if ( ! $abs_path ) { $config_path = $this->path( $config_path ); } $value = include( $config_path ); $data = is_array( $value ) ? $value : array(); /** * Filter example: $name == 'folder/defaults-file' * 'plugin_config_folder_defaults-file' * 'plugin_config_folder_defaults-file' */ $filter_name = sanitize_key( str_replace( '.', '_', str_replace( '/', '_', $key ) ) ); $this->config_store[ $key ] = apply_filters( "{$this->slug}_config_{$filter_name}", $data ); } return $this->config_store[ $key ]; } public function config( $group_name, $item ) { $group = $this->config_group( $group_name ); return ( isset( $group[$item] ) ) ? $group[$item] : null; } /** * Get a named set of localized strings from the i18n directory * @param string $group Name of the strings file to load * @param boolean $namespace Should we prepend a namespace to the keys? * @return array Localized strings */ public function i18n_group( $group, $namespace = true, $filter = '' ) { $strings = $this->config_group( $group, 'i18n', $this->i18n_path, true ); if ( $filter ) { $filtered = array(); foreach ($strings as $key => $value) { if ( 0 === strpos($key,"$filter.") ) { $k = substr($key, strlen($filter) + 1); $filtered[$k] = $value; } } $strings = $filtered; } if ( ! $namespace ) { return $strings; } $namespaced = array(); $namespace = $filter ? $filter : $group; foreach ( $strings as $key => $value ) { $namespaced["$namespace.$key"] = $value; } return $namespaced; } public function i18n( $key ) { if ( ! isset( $this->i18n_strings[ $key ] ) ) { $group = 'common'; $group_index = strpos($key, '.'); if ( -1 !== $group_index ) { $group = substr( $key, 0, $group_index ); } $strings = $this->i18n_group( $group ); foreach ($strings as $string => $value) { $this->i18n_strings[ $string ] = $value; } } return isset( $this->i18n_strings[ $key ] ) ? $this->i18n_strings[ $key ] : ''; } /** * Plugin entry point. * @param string $file This should be __FILE__ from the main plugin file * @return bool true if the instance was generated for the first time */ public static function run( $path, $i18n_path, $url ) { if ( ! defined( 'ABSPATH' ) ) { die(); } $class = new ReflectionClass( 'Cornerstone_Plugin' ); if ( ! is_null( $class->getStaticPropertyValue( 'instance', null ) ) ) { return false; } $instance = $class->newInstance( $path, $i18n_path, $url ); // Setup as a singleton for global access if ( $class->hasProperty( 'instance' ) ) { $class->setStaticPropertyValue( 'instance', $instance ); } else { // If the child doesn't have an instance property, we'll create a global variable. $GLOBALS[ $slug . '_plugin' ] = $instance; } $instance->superPreinit(); return true; } /** * Methods to optionally override in child class */ protected function preinitBefore() {} protected function preinitAfter() {} protected function initBefore() {} protected function initAfter() {} protected function loggedinBefore() {} protected function loggedinAfter() {} protected function adminBefore() {} protected function adminAfter() {} } /** * Offers simple dependency injection * Automatically creates a reference to the main plugin * Having your components extend this class allows you to do things like: * * $this->plugin->url( 'path/to/file' ) */ abstract class Cornerstone_Plugin_Component { protected $plugin; public $dependencies = false; protected $path = ''; protected $url = ''; public function __construct( $plugin ) { $this->plugin = $plugin; } public function setup() { } public function beforeDependencies() { } /** * Shortcut to plugin path method including component local path additions. * @param $to (optional) Append to the current path * @return string */ public function path( $to = '' ) { return trailingslashit( $this->plugin->path( $this->path ) ) . $to; } /** * Shortcut to plugin url method including component local path additions. * @param $to (optional) Append to the current url * @return string */ public function url( $to = '' ) { return trailingslashit( $this->plugin->url( $this->url ) ) . $to; } /** * Returns a component instance via its name * @return object Component instance */ public function component( $handle ) { return $this->plugin->component($handle); } /** * Passthrough get_template_part * This runs through WordPress `load_template` when $load is true */ public function get_template_part( $slug, $name = null, $load = true ) { return $this->plugin->get_template_part( $slug, $name, $load ); } /** * Find a template so we can include it ourselves. * Doesn't run through `load_template` so some globals may need to be declared. * This can be used to load markup used in the dashboard. */ public function template( $slug, $name = null, $echo = true ) { ob_start(); $template = $this->plugin->get_template_part( $slug, $name, false ); if ( $template ) { include( $template ); } $contents = ob_get_clean(); if ( $echo ) { echo $contents; } return $contents; } /** * Get the path to a view so it can be passed to "include", preserving scope. */ public function locate_view( $name ) { return $this->plugin->locate_view( $name ); } /** * Include a view file, optionally outputting its contents. */ public function view( $name, $echo = true, $data = array(), $extract = false ) { ob_start(); $view = $this->locate_view( $name ); if ( $extract ) { extract( $data ); } if ( $view ) { include( $view ); } $contents = ob_get_clean(); if ( $echo ) { echo $contents; } return $contents; } public function i18n_group( $group, $namespace = true, $filter = '' ) { return $this->plugin->i18n_group( $group, $namespace, $filter ); } public function config_group( $group, $namespace = true, $path = '' ) { return $this->plugin->config_group( $group, $namespace, $path ); } public function config_item( $group, $key = null ) { return $this->plugin->config( $group, $key ); } } class Cornerstone_Plugin extends Cornerstone_Plugin_Base { public static $instance; protected $init_priority = -1000; /** * Common Component Accessor * @return object reference to Cornerstone_Common instance */ public function common() { return $this->component( 'Common' ); } /** * Shortcut to getting javascript asset URLs. * @param string asset name. For example: "admin/builder" * @return string URL to asset */ public function js( $asset ) { return $this->versioned_url( "assets/dist/js/$asset", 'js'); } /** * Shortcut to getting css asset URLs. * @param string asset name. For example: "admin/builder" * @return string URL to asset */ public function css( $asset ) { return $this->versioned_url( "assets/dist/css/$asset", 'css' ); } public function versioned_url( $asset, $ext ) { // Return matching asset rev file if it exists if ( defined('CS_ASSET_REV') && CS_ASSET_REV ) { $rev = CS_ASSET_REV; $path = "$asset.$rev.$ext"; $filename = $this->path( $path ); if (file_exists($filename)) { return array( 'asset_rev' => true, 'url' => $this->url($path), 'version' => defined('CS_APP_BUILD_TOOLS') && CS_APP_BUILD_TOOLS ? time() : null ); } } // Return a unversioned file if it exists $basepath = $this->path($asset); $unversioned = "$basepath.$ext"; if (file_exists($unversioned)) { return array( 'unversioned' => true, 'url' => $this->url("$asset.$ext"), 'version' => null ); } // Try to detect a versioned file that wasn't declared $files = glob("$basepath.*.$ext", GLOB_NOSORT); if (count($files) > 0) { $urlpath = dirname($asset); $filename = basename($files[0]); return array( 'versioned' => true, 'url' => $this->url("$urlpath/$filename"), 'version' => null ); } // If we can't find anything, return a fallback to the exact requested URL even though it will 404 return array( 'not_found' => true, 'url' => $this->url("$asset.$ext"), 'version' => null ); } /** * Get array of Cornerstone settings with defaults applied * @return array */ public function settings() { return wp_parse_args( get_option( 'cornerstone_settings', array() ), $this->config_group( 'common/default-settings' ) ); } /** * Return plugin instance. * @return object Singleton instance */ public static function instance() { return ( isset( self::$instance ) ) ? self::$instance : false; } /** * Run immediately after object instantiation, before anything else is loaded. * @return void */ public function preinitBefore() { // Register class autoloader $classes = glob( self::$instance->path( 'includes/classes' ) . '/*' ); $classic_classes = glob( self::$instance->path( 'includes/classes/classic' ) . '/*' ); $this->autoload_directories = array_merge( $classes, $classic_classes ); spl_autoload_register( array( __CLASS__, 'autoloader' ) ); add_action( 'cornerstone_updated', array( $this, 'update' ) ); } public function update( $prior ) { /** * Run if coming from a version prior to Before 1.0.7 * if ( version_compare( $prior, '1.0.7', '<' ) ) { * } */ // if ( ! is_null( $prior ) ) { // // } CS()->component('Cleanup')->clean_generated_styles(); CS()->component('Caching')->clear_all_caches(); } /** * Cornerstone class autoloader. * @param string $class_name * @return void */ public static function autoloader( $class_name ) { if ( false === strpos( $class_name, self::$instance->name ) ) { return; } $class = str_replace( self::$instance->name . '_', '', $class_name ); $file = 'class-' . str_replace( '_', '-', strtolower( $class ) ) . '.php'; foreach ( self::$instance->autoload_directories as $directory ) { $path = $directory . '/' . $file; if ( ! file_exists( $path ) ) { continue; } require_once( $path ); } } } /** * Access Cornerstone without a global variable * @return object main Cornerstone instance. */ function CS($component = '') { if ($component) { return Cornerstone_Plugin::instance()->component( $component ); } return Cornerstone_Plugin::instance(); }
Save Changes
Rename File
Rename