<?php namespace ShortPixel; use ShortPixel\ShortpixelLogger\ShortPixelLogger as Log; use ShortPixel\Notices\NoticeController as Notices; //use ShortPixel\Controller; /** Plugin class * This class is meant for: WP Hooks, init of runtime and Controller Routing. */ class ShortPixelPlugin { private static $instance; protected static $modelsLoaded = array(); // don't require twice, limit amount of require looksups.. private $paths = array('class', 'class/controller', 'class/external', 'class/controller/views'); // classes that are autoloaded protected $is_noheaders = false; protected $plugin_path; protected $plugin_url; protected $shortPixel; // shortpixel megaclass protected $settings; // settings object. protected $admin_pages = array(); // admin page hooks. public function __construct() { $this->plugin_path = plugin_dir_path(SHORTPIXEL_PLUGIN_FILE); $this->plugin_url = plugin_dir_url(SHORTPIXEL_PLUGIN_FILE); //$this->initHooks(); add_action('plugins_loaded', array($this, 'lowInit'), 5); // early as possible init. } /** LowInit after all Plugins are loaded. Core WP function can still be missing. This should mostly add hooks */ public function lowInit() { if(isset($_REQUEST['noheader'])) { $this->is_noheaders = true; } /* Filter to prevent SPIO from starting. This can be used by third-parties to prevent init when needed for a particular situation. * Hook into plugins_loaded with priority lower than 5 */ $init = apply_filters('shortpixel/plugin/init', true); if (! $init) { return; } // @todo Transitionary init for the time being, since plugin init functionality is still split between. global $shortPixelPluginInstance; $shortPixelPluginInstance = new \wpShortPixel(); $this->shortPixel = $shortPixelPluginInstance; $front = new Controller\FrontController(); $admin = Controller\AdminController::getInstance(); $adminNotices = Controller\AdminNoticesController::getInstance(); // Hook in the admin notices. $this->initHooks(); add_action('admin_init', array($this, 'init')); } /** Mainline Admin Init. Tasks that can be loaded later should go here */ public function init() { $this->shortPixel->loadHooks(); $notices = Notices::getInstance(); // This hooks the ajax listener } /** Function to get plugin settings * * @return SettingsModel The settings model object. */ public function settings() { if (is_null($this->settings)) $this->settings = new \WPShortPixelSettings(); return $this->settings; } /** Function to get all enviromental variables * * @return EnvironmentModel */ public function env() { return Model\EnvironmentModel::getInstance(); } public function fileSystem() { return new Controller\FileSystemController(); } /** Create instance. This should not be needed to call anywhere else than main plugin file * This should not be called *after* plugins_loaded action **/ public static function getInstance() { if (is_null(self::$instance)) { self::$instance = new ShortPixelPlugin(); } return self::$instance; } /** Hooks for all WordPress related hooks * For now hooks in the lowInit, asap. */ public function initHooks() { add_action('admin_menu', array($this,'admin_pages')); add_action('admin_enqueue_scripts', array($this, 'admin_scripts')); // admin scripts add_action('admin_enqueue_scripts', array($this, 'load_admin_scripts'), 90); // loader via route. // defer notices a little to allow other hooks ( notable adminnotices ) add_action( 'shortpixel-thumbnails-before-regenerate', array( $this->shortPixel, 'thumbnailsBeforeRegenerateHook' ), 10, 1); add_action( 'shortpixel-thumbnails-regenerated', array( $this->shortPixel, 'thumbnailsRegeneratedHook' ), 10, 4); $admin = Controller\AdminController::getInstance(); if ($this->settings()->autoMediaLibrary) { // compat filter to shortcircuit this in cases. (see external - visualcomposer) if (apply_filters('shortpixel/init/automedialibrary', true)) { if($this->settings()->autoMediaLibrary && $this->settings()->png2jpg) { add_action( 'wp_handle_upload', array($admin,'handlePng2JpgHook')); // @todo Document what plugin does mpp add_action( 'mpp_handle_upload', array($admin,'handlePng2JpgHook')); } add_action('wp_handle_replace', array($admin,'handleReplaceHook')); if($this->settings()->autoMediaLibrary) { add_filter( 'wp_generate_attachment_metadata', array($admin,'handleImageUploadHook'), 10, 2 ); // @todo Document what plugin does mpp add_filter( 'mpp_generate_metadata', array($admin,'handleImageUploadHook'), 10, 2 ); } } if($this->settings()->frontBootstrap && $this->env()->is_front) { // We want this only to work when the automedialibrary setting is on. add_filter( 'wp_generate_attachment_metadata', array($admin,'handleImageUploadHook'), 10, 2 ); } } // *** AJAX HOOKS @todo These must be moved from wp-short-pixel in future */ add_action('wp_ajax_shortpixel_helpscoutOptin', array(\wpSPIO()->settings(), 'ajax_helpscoutOptin')); } /** Hook in our admin pages */ public function admin_pages() { $admin_pages = array(); // settings page $admin_pages[] = add_options_page( __('ShortPixel Settings','shortpixel-image-optimiser'), 'ShortPixel', 'manage_options', 'wp-shortpixel-settings', array($this, 'route')); if($this->shortPixel->getSpMetaDao()->hasFoldersTable() && count($this->shortPixel->getSpMetaDao()->getFolders())) { /*translators: title and menu name for the Other media page*/ $admin_pages[] = add_media_page( __('Other Media Optimized by ShortPixel','shortpixel-image-optimiser'), __('Other Media','shortpixel-image-optimiser'), 'edit_others_posts', 'wp-short-pixel-custom', array( $this, 'route' ) ); } /*translators: title and menu name for the Bulk Processing page*/ $admin_pages[] = add_media_page( __('ShortPixel Bulk Process','shortpixel-image-optimiser'), __('Bulk ShortPixel','shortpixel-image-optimiser'), 'edit_others_posts', 'wp-short-pixel-bulk', array( $this, 'route' ) ); $this->admin_pages = $admin_pages; } /** PluginRunTime. Items that should be initialized *only* when doing our pages and territory. */ protected function initPluginRunTime() { } /** All scripts should be registed, not enqueued here (unless global wp-admin is needed ) * * Not all those registered must be enqueued however. */ public function admin_scripts($hook_suffix) { // FileTree in Settings wp_register_style('sp-file-tree', plugins_url('/res/css/sp-file-tree.min.css',SHORTPIXEL_PLUGIN_FILE),array(), SHORTPIXEL_IMAGE_OPTIMISER_VERSION ); wp_register_script('sp-file-tree', plugins_url('/res/js/sp-file-tree.min.js',SHORTPIXEL_PLUGIN_FILE) ); wp_register_style('shortpixel-admin', plugins_url('/res/css/shortpixel-admin.css', SHORTPIXEL_PLUGIN_FILE),array(), SHORTPIXEL_IMAGE_OPTIMISER_VERSION ); wp_register_style('shortpixel', plugins_url('/res/css/short-pixel.min.css',SHORTPIXEL_PLUGIN_FILE), array(), SHORTPIXEL_IMAGE_OPTIMISER_VERSION); //modal - used in settings for selecting folder wp_register_style('shortpixel-modal', plugins_url('/res/css/short-pixel-modal.min.css',SHORTPIXEL_PLUGIN_FILE), array(), SHORTPIXEL_IMAGE_OPTIMISER_VERSION); // notices. additional styles for SPIO. wp_register_style('shortpixel-notices', plugins_url('/res/css/shortpixel-notices.css',SHORTPIXEL_PLUGIN_FILE), array(), SHORTPIXEL_IMAGE_OPTIMISER_VERSION); // other media screen wp_register_style('shortpixel-othermedia', plugins_url('/res/css/shortpixel-othermedia.css',SHORTPIXEL_PLUGIN_FILE), array(), SHORTPIXEL_IMAGE_OPTIMISER_VERSION); wp_register_script('shortpixel-debug', plugins_url('/res/js/debug.js',SHORTPIXEL_PLUGIN_FILE), array('jquery', 'jquery-ui-draggable'), SHORTPIXEL_IMAGE_OPTIMISER_VERSION); } /** Load Style via Route, on demand */ public function load_style($name) { if ($this->is_noheaders) // fail silently, if this is a no-headers request. return; if (wp_style_is($name, 'registered')) { wp_enqueue_style($name); } else { Log::addWarn("Style $name was asked for, but not registered"); } } /** Load Style via Route, on demand */ public function load_script($name) { if ($this->is_noheaders) // fail silently, if this is a no-headers request. return; if (wp_script_is($name, 'registered')) { wp_enqueue_script($name); } else { Log::addWarn("Script $name was asked for, but not registered"); } } /** This is separated from route to load in head, preventing unstyled content all the time */ public function load_admin_scripts($hook_suffix) { global $plugin_page; switch($plugin_page) { case 'wp-shortpixel-settings': // settings $this->load_style('shortpixel-admin'); $this->load_style('shortpixel'); $this->load_style('shortpixel-modal'); $this->load_style('sp-file-tree'); $this->load_script('sp-file-tree'); break; case 'wp-short-pixel-custom': // other media $this->load_style('shortpixel-othermedia'); break; } } /** Route, based on the page slug * * Principially all page controller should be routed from here. */ public function route() { global $plugin_page; $this->initPluginRunTime(); $default_action = 'load'; // generic action on controller. $action = isset($_REQUEST['sp-action']) ? sanitize_text_field($_REQUEST['sp-action']) : $default_action; $template_part = isset($_GET['part']) ? sanitize_text_field($_GET['part']) : false; $controller = false; if ($this->env()->is_debug) { $this->load_script('shortpixel-debug'); } $url = menu_page_url($plugin_page, false); switch($plugin_page) { case 'wp-shortpixel-settings': // settings $controller = 'ShortPixel\Controller\SettingsController'; break; case 'wp-short-pixel-custom': // other media /* $this->load_style('shortpixel-othermedia'); */ $controller = 'ShortPixel\Controller\View\OtherMediaViewController'; break; case 'wp-short-pixel-bulk': if ($template_part) { switch($template_part) { case 'bulk-restore-all': $controller = '\ShortPixel\Controller\View\BulkRestoreAll'; break; } } else $controller = '\ShortPixel\Controller\View\BulkViewController'; break; } if ($controller !== false) { $c = new $controller(); $c->setShortPixel($this->shortPixel); $c->setControllerURL($url); if (method_exists($c, $action)) $c->$action(); else { Log::addWarn("Attempted Action $action on $controller does not exist!"); $c->$default_action(); } } } // Get the plugin URL, based on real URL. public function plugin_url($urlpath = '') { $url = trailingslashit($this->plugin_url); if (strlen($urlpath) > 0) $url .= $urlpath; return $url; } // Get the plugin path. public function plugin_path($path = '') { $plugin_path = trailingslashit($this->plugin_path); if (strlen($path) > 0) $plugin_path .= $path; return $plugin_path; } // Get the ShortPixel Object. public function getShortPixel() { return $this->shortPixel; } /** Returns defined admin page hooks. Internal use - check states via environmentmodel * @returns Array */ public function get_admin_pages() { return $this->admin_pages; } public static function activatePlugin() { self::deactivatePlugin(); if(SHORTPIXEL_RESET_ON_ACTIVATE === true && WP_DEBUG === true) { //force reset plugin counters, only on specific occasions and on test environments \WPShortPixelSettings::debugResetOptions(); $settings = new \WPShortPixelSettings(); $spMetaDao = new \ShortPixelCustomMetaDao(new \WpShortPixelDb(), $settings->excludePatterns); $spMetaDao->dropTables(); } $env = wpSPIO()->env(); if(\WPShortPixelSettings::getOpt('deliverWebp') == 3 && ! $env->is_nginx) { \WpShortPixel::alterHtaccess(true, true); //add the htaccess lines } \WpShortPixelDb::checkCustomTables(); Controller\AdminNoticesController::resetAllNotices(); /* Controller\AdminNoticesController::resetCompatNotice(); Controller\AdminNoticesController::resetAPINotices(); Controller\AdminNoticesController::resetQuotaNotices(); Controller\AdminNoticesController::resetIntegrationNotices(); */ \WPShortPixelSettings::onActivate(); } public static function deactivatePlugin() { \ShortPixelQueue::resetBulk(); (! defined('SHORTPIXEL_NOFLOCK')) ? \ShortPixelQueue::resetPrio() : \ShortPixelQueueDB::resetPrio(); \WPShortPixelSettings::onDeactivate(); $env = wpSPIO()->env(); if (! $env->is_nginx) { \WpShortPixel::alterHtaccess(false, false); } // save remove. $fs = new Controller\FileSystemController(); $log = $fs->getFile(SHORTPIXEL_BACKUP_FOLDER . "/shortpixel_log"); if ($log->exists()) $log->delete(); } public static function uninstallPlugin() { $settings = new \WPShortPixelSettings(); $env = \wpSPIO()->env(); if($settings->removeSettingsOnDeletePlugin == 1) { \WPShortPixelSettings::debugResetOptions(); if (! $env->is_nginx) insert_with_markers( get_home_path() . '.htaccess', 'ShortPixelWebp', ''); $spMetaDao = new \ShortPixelCustomMetaDao(new \WpShortPixelDb()); $spMetaDao->dropTables(); } } } // class plugin