<?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