PluginProbe ʕ •ᴥ•ʔ
ShortPixel Image Optimizer – Optimize Images, Convert WebP & AVIF / 4.17.0
ShortPixel Image Optimizer – Optimize Images, Convert WebP & AVIF v4.17.0
6.5.1 trunk 1.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.6 1.2.0 1.3.1 1.3.5 1.4.0 1.4.1 1.5.0 1.5.3 1.6.0 1.6.1 1.6.10 1.6.2 1.6.3 1.6.4 1.6.6 1.6.7 1.6.8 1.6.9 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1.0 2.1.1 2.1.10 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 3.0.0 3.0.2 3.0.3 3.0.5 3.0.6 3.0.7 3.0.8 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 3.2.0 3.2.1 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4 3.3.5 3.3.6 3.3.7 3.3.8 4.0.0 4.0.1 4.0.2 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4 4.1.5 4.1.7 4.10.0 4.10.1 4.10.2 4.10.3 4.10.4 4.10.5 4.11.0 4.11.1 4.11.2 4.11.3 4.12.0 4.12.1 4.12.2 4.12.3 4.12.4 4.12.5 4.12.6 4.12.7 4.12.8 4.13.0 4.13.1 4.14.0 4.14.1 4.14.2 4.14.3 4.14.4 4.14.5 4.14.6 4.15.0 4.15.1 4.15.2 4.15.3 4.15.4 4.16.0 4.16.1 4.16.2 4.16.3 4.16.4 4.17.0 4.17.1 4.17.2 4.17.3 4.17.4 4.18.0 4.18.1 4.19.0 4.19.1 4.19.2 4.19.3 4.2.0 4.2.1 4.2.2 4.2.4 4.2.5 4.2.6 4.2.7 4.2.8 4.2.9 4.20.0 4.20.1 4.20.2 4.21.0 4.21.1 4.21.2 4.22.0 4.22.1 4.22.10 4.22.2 4.22.3 4.22.4 4.22.5 4.22.6 4.22.7 4.22.8 4.22.9 4.3.0 4.3.1 4.4.0 4.4.1 4.4.2 4.5.0 4.5.1 4.5.2 4.5.3 4.5.5 4.6.0 4.7.0 4.7.1 4.7.2 4.8.0 4.8.1 4.8.2 4.8.4 4.8.5 4.8.6 4.8.7 4.8.8 4.8.9 4.9.0 4.9.1 5.0.0 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 5.0.8 5.0.9 5.1.0 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.2.0 5.2.1 5.2.2 5.2.3 5.3.0 5.4.0 5.4.1 5.4.2 5.4.3 5.5.0 5.5.1 5.5.2 5.5.3 5.5.4 5.5.5 5.6.0 5.6.1 5.6.2 5.6.3 5.6.4 6.0.0 6.0.1 6.0.2 6.0.3 6.0.4 6.0.5 6.1.0 6.1.1 6.1.2 6.1.3 6.1.4 6.2.0 6.2.1 6.2.2 6.3.0 6.3.1 6.3.2 6.3.3 6.3.4 6.3.5 6.4.0 6.4.1 6.4.2 6.4.3 6.4.4 6.5.0
shortpixel-image-optimiser / shortpixel-plugin.php
shortpixel-image-optimiser Last commit date
build 6 years ago class 6 years ago res 6 years ago changelog.txt 6 years ago readme.txt 6 years ago shortpixel-plugin.php 6 years ago shortpixel_api.php 6 years ago wp-shortpixel-req.php 6 years ago wp-shortpixel.php 6 years ago
shortpixel-plugin.php
471 lines
1 <?php
2 namespace ShortPixel;
3 use ShortPixel\ShortpixelLogger\ShortPixelLogger as Log;
4 use ShortPixel\Notices\NoticeController as Notices;
5
6
7 /** Plugin class
8 * This class is meant for: WP Hooks, init of runtime and Controller Routing.
9
10 */
11 class ShortPixelPlugin
12 {
13 private static $instance;
14 protected static $modelsLoaded = array(); // don't require twice, limit amount of require looksups..
15
16 private $paths = array('class', 'class/controller', 'class/external', 'class/controller/views'); // classes that are autoloaded
17
18 protected $is_noheaders = false;
19
20 protected $plugin_path;
21 protected $plugin_url;
22
23 protected $shortPixel; // shortpixel megaclass
24 protected $settings; // settings object.
25
26 protected $admin_pages = array(); // admin page hooks.
27
28 public function __construct()
29 {
30 $this->plugin_path = plugin_dir_path(SHORTPIXEL_PLUGIN_FILE);
31 $this->plugin_url = plugin_dir_url(SHORTPIXEL_PLUGIN_FILE);
32
33 $this->initRuntime(); // require controllers, and other needed classes
34 $this->initHooks();
35 add_action('plugins_loaded', array($this, 'init'), 5); // early as possible init.
36 }
37
38 /*
39 * Init the plugin after plugins_loaded hook. All of WP is there, all plugins.
40 * This can't be loaded on construct time, because of model Loaders etc, with would result in loop.
41 *
42 */
43 public function init()
44 {
45 if(isset($_REQUEST['noheader'])) {
46 $this->is_noheaders = true;
47 }
48
49 // @todo Transitionary init for the time being, since plugin init functionality is still split between.
50 global $shortPixelPluginInstance;
51 $shortPixelPluginInstance = new \wpShortPixel();
52 $this->shortPixel = $shortPixelPluginInstance;
53
54 $front = new frontController();
55 $admin = adminController::getInstance();
56 $adminNotices = adminNoticesController::getInstance(); // Hook in the admin notices.
57 $notices = Notices::getInstance(); // This hooks the ajax listener
58
59 if ($this->settings()->autoMediaLibrary)
60 {
61 // compat filter to shortcircuit this in cases. (see external - visualcomposer)
62 if (apply_filters('shortpixel/init/automedialibrary', true))
63 {
64 // $autoPng2Jpg = get_option('wp-short-pixel-png2jpg');
65 //$autoMediaLibrary = get_option('wp-short-pixel-auto-media-library');
66
67 if($this->settings()->autoMediaLibrary && $this->settings()->png2jpg) {
68 add_action( 'wp_handle_upload', array($admin,'handlePng2JpgHook'));
69 // @todo Document what plugin does mpp
70 add_action( 'mpp_handle_upload', array($admin,'handlePng2JpgHook'));
71 }
72 add_action('wp_handle_replace', array($admin,'handleReplaceHook'));
73
74 if($this->settings()->autoMediaLibrary) {
75
76 add_filter( 'wp_generate_attachment_metadata', array($admin,'handleImageUploadHook'), 10, 2 );
77 // @todo Document what plugin does mpp
78 add_filter( 'mpp_generate_metadata', array($admin,'handleImageUploadHook'), 10, 2 );
79 }
80 }
81 }
82 elseif($this->settings()->frontBootstrap && $this->env()->is_front)
83 {
84 // if automedialibrary is off, but we do want to auto-optimize on the front, still load the hook.
85 add_filter( 'wp_generate_attachment_metadata', array($admin,'handleImageUploadHook'), 10, 2 );
86 }
87 }
88
89 /** Function to get plugin settings
90 *
91 * @return SettingsModel The settings model object.
92 */
93 public function settings()
94 {
95 if (is_null($this->settings))
96 $this->settings = new \WPShortPixelSettings();
97
98 return $this->settings;
99 }
100
101 /** Function to get all enviromental variables
102 *
103 * @return EnvironmentModel
104 */
105 public function env()
106 {
107 $this->loadModel('environment');
108 return EnvironmentModel::getInstance();
109 }
110
111 public function fileSystem()
112 {
113 return new \ShortPixel\FileSystemController();
114 }
115
116 /** Create instance. This should not be needed to call anywhere else than main plugin file
117 * This should not be called *after* plugins_loaded action
118 **/
119 public static function getInstance()
120 {
121 if (is_null(self::$instance))
122 {
123 self::$instance = new ShortPixelPlugin();
124 }
125 return self::$instance;
126
127 }
128
129 /** Init Runtime. Loads all classes. */
130 protected function initRuntime()
131 {
132 $plugin_path = plugin_dir_path(SHORTPIXEL_PLUGIN_FILE);
133 foreach($this->paths as $short_path)
134 {
135 $directory_path = realpath($plugin_path . $short_path);
136
137 if ($directory_path !== false)
138 {
139 $it = new \DirectoryIterator($directory_path);
140 foreach($it as $file)
141 {
142 $file_path = $file->getRealPath();
143 if ($file->isFile() && pathinfo($file_path, PATHINFO_EXTENSION) == 'php')
144 {
145 require_once($file_path);
146 }
147 }
148 }
149 }
150
151 // Loads all subclassed controllers. This is used for slug-based discovery of which controller to run
152 $controllerClass = \ShortPixelTools::namespaceit('ShortPixelController');
153 $controllerClass::init();
154 }
155
156 /** Hooks for all WordPress related hooks
157 */
158 public function initHooks()
159 {
160 add_action('admin_menu', array($this,'admin_pages'));
161 add_action('admin_enqueue_scripts', array($this, 'admin_scripts')); // admin scripts
162 add_action('admin_enqueue_scripts', array($this, 'load_admin_scripts'), 90); // loader via route.
163 // defer notices a little to allow other hooks ( notable adminnotices )
164 add_action('admin_notices', array($this, 'admin_notices'), 50); // notices occured before page load
165 add_action('admin_footer', array($this, 'admin_notices')); // called in views.
166
167 }
168
169 /** Hook in our admin pages */
170 public function admin_pages()
171 {
172 $admin_pages = array();
173 // settings page
174 $admin_pages[] = add_options_page( __('ShortPixel Settings','shortpixel-image-optimiser'), 'ShortPixel', 'manage_options', 'wp-shortpixel-settings', array($this, 'route'));
175
176 if($this->shortPixel->getSpMetaDao()->hasFoldersTable() && count($this->shortPixel->getSpMetaDao()->getFolders())) {
177 /*translators: title and menu name for the Other media page*/
178 $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' ) );
179 }
180 /*translators: title and menu name for the Bulk Processing page*/
181 $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->shortPixel, 'bulkProcess' ) );
182
183 $this->admin_pages = $admin_pages;
184 }
185
186 /** PluginRunTime. Items that should be initialized *only* when doing our pages and territory. */
187 protected function initPluginRunTime()
188 {
189
190 }
191
192 /** All scripts should be registed, not enqueued here (unless global wp-admin is needed )
193 *
194 * Not all those registered must be enqueued however.
195 */
196 public function admin_scripts()
197 {
198 // FileTree in Settings
199 wp_register_style('sp-file-tree', plugins_url('/res/css/sp-file-tree.min.css',SHORTPIXEL_PLUGIN_FILE),array(), SHORTPIXEL_IMAGE_OPTIMISER_VERSION );
200 wp_register_script('sp-file-tree', plugins_url('/res/js/sp-file-tree.min.js',SHORTPIXEL_PLUGIN_FILE) );
201
202 wp_register_style('shortpixel-admin', plugins_url('/res/css/shortpixel-admin.css', SHORTPIXEL_PLUGIN_FILE),array(), SHORTPIXEL_IMAGE_OPTIMISER_VERSION );
203
204 wp_register_style('shortpixel', plugins_url('/res/css/short-pixel.min.css',SHORTPIXEL_PLUGIN_FILE), array(), SHORTPIXEL_IMAGE_OPTIMISER_VERSION);
205
206 //modal - used in settings for selecting folder
207 wp_register_style('shortpixel-modal', plugins_url('/res/css/short-pixel-modal.min.css',SHORTPIXEL_PLUGIN_FILE), array(), SHORTPIXEL_IMAGE_OPTIMISER_VERSION);
208
209 // notices. additional styles for SPIO.
210 wp_register_style('shortpixel-notices', plugins_url('/res/css/shortpixel-notices.css',SHORTPIXEL_PLUGIN_FILE), array(), SHORTPIXEL_IMAGE_OPTIMISER_VERSION);
211
212 // other media screen
213 wp_register_style('shortpixel-othermedia', plugins_url('/res/css/shortpixel-othermedia.css',SHORTPIXEL_PLUGIN_FILE), array(), SHORTPIXEL_IMAGE_OPTIMISER_VERSION);
214
215
216 wp_register_script('shortpixel-debug', plugins_url('/res/js/debug.js',SHORTPIXEL_PLUGIN_FILE), array('jquery', 'jquery-ui-draggable'), SHORTPIXEL_IMAGE_OPTIMISER_VERSION);
217
218 }
219
220 public function admin_notices()
221 {
222 $noticeControl = Notices::getInstance();
223 $noticeControl->loadIcons(array(
224 'normal' => '<img class="short-pixel-notice-icon" src="' . plugins_url('res/img/slider.png', SHORTPIXEL_PLUGIN_FILE) . '">',
225 'success' => '<img class="short-pixel-notice-icon" src="' . plugins_url('res/img/robo-cool.png', SHORTPIXEL_PLUGIN_FILE) . '">',
226 'warning' => '<img class="short-pixel-notice-icon" src="' . plugins_url('res/img/robo-scared.png', SHORTPIXEL_PLUGIN_FILE) . '">',
227 'error' => '<img class="short-pixel-notice-icon" src="' . plugins_url('res/img/robo-scared.png', SHORTPIXEL_PLUGIN_FILE) . '">',
228 ));
229
230 if ($noticeControl->countNotices() > 0)
231 {
232 $notices = $noticeControl->getNoticesForDisplay();
233
234 if (count($notices) > 0)
235 {
236 wp_enqueue_style('shortpixel-notices');
237
238 foreach($notices as $notice)
239 {
240 echo $notice->getForDisplay();
241
242 if ($notice->getID() == adminNoticesController::MSG_QUOTA_REACHED || $notice->getID() == adminNoticesController::MSG_UPGRADE_MONTH
243 || $notice->getID() == adminNoticesController::MSG_UPGRADE_BULK)
244 {
245 wp_enqueue_script('jquery.knob.min.js');
246 wp_enqueue_script('jquery.tooltip.min.js');
247 wp_enqueue_script('shortpixel');
248 $this->load_style('shortpixel-modal');
249 }
250 }
251 }
252 }
253 $noticeControl->update(); // puts views, and updates
254 }
255
256 /** Load Style via Route, on demand */
257 public function load_style($name)
258 {
259 if ($this->is_noheaders) // fail silently, if this is a no-headers request.
260 return;
261
262 if (wp_style_is($name, 'registered'))
263 {
264 wp_enqueue_style($name);
265 }
266 else {
267 Log::addWarn("Style $name was asked for, but not registered");
268 }
269 }
270
271 /** Load Style via Route, on demand */
272 public function load_script($name)
273 {
274 if ($this->is_noheaders) // fail silently, if this is a no-headers request.
275 return;
276
277 if (wp_script_is($name, 'registered'))
278 {
279 wp_enqueue_script($name);
280 }
281 else {
282 Log::addWarn("Script $name was asked for, but not registered");
283 }
284 }
285
286 /** This is separated from route to load in head, preventing unstyled content all the time */
287 public function load_admin_scripts()
288 {
289 global $plugin_page;
290
291 switch($plugin_page)
292 {
293 case 'wp-shortpixel-settings': // settings
294 $this->load_style('shortpixel-admin');
295 $this->load_style('shortpixel');
296 $this->load_style('shortpixel-modal');
297 $this->load_style('sp-file-tree');
298 $this->load_script('sp-file-tree');
299
300 break;
301 case 'wp-short-pixel-custom': // other media
302 $this->load_style('shortpixel-othermedia');
303 break;
304 }
305 }
306
307 /** Route, based on the page slug
308 *
309 * Principially all page controller should be routed from here.
310 */
311 public function route()
312 {
313 global $plugin_page;
314 $this->initPluginRunTime();
315
316 $default_action = 'load'; // generic action on controller.
317 $action = isset($_REQUEST['sp-action']) ? sanitize_text_field($_REQUEST['sp-action']) : $default_action;
318 $controller = false;
319
320 if ($this->env()->is_debug)
321 {
322 $this->load_script('shortpixel-debug');
323 }
324
325 switch($plugin_page)
326 {
327 case 'wp-shortpixel-settings': // settings
328 /* $this->load_style('shortpixel-admin');
329 $this->load_style('shortpixel');
330 $this->load_style('shortpixel-modal');
331 $this->load_style('sp-file-tree');
332 $this->load_script('sp-file-tree'); */
333 $controller = \shortPixelTools::namespaceit("SettingsController");
334 $url = menu_page_url($plugin_page, false);
335 break;
336 case 'wp-short-pixel-custom': // other media
337 /* $this->load_style('shortpixel-othermedia'); */
338 $controller = \shortPixelTools::namespaceit('OtherMediaViewController');
339 $url = menu_page_url($plugin_page, false);
340 break;
341 }
342
343 if ($controller !== false)
344 {
345 $c = new $controller();
346 $c->setShortPixel($this->shortPixel);
347 $c->setControllerURL($url);
348 if (method_exists($c, $action))
349 $c->$action();
350 else {
351 Log::addWarn("Attempted Action $action on $controller does not exist!");
352 $c->$default_action();
353 }
354
355 }
356 }
357
358 /** Loads the Model Data Structure upon request
359 *
360 * @param string $name Name of the model
361 */
362 public function loadModel($name){
363 $path = \ShortPixelTools::getPluginPath() . 'class/model/' . $name . '_model.php';
364
365 if (! in_array($name, self::$modelsLoaded))
366 {
367 self::$modelsLoaded[] = $name;
368 if(file_exists($path)){
369 require_once($path);
370 }
371 else {
372 Log::addError("Model $name could not be found");
373 }
374 }
375 }
376
377 // Get the plugin URL, based on real URL.
378 public function plugin_url($urlpath = '')
379 {
380 $url = trailingslashit($this->plugin_url);
381 if (strlen($urlpath) > 0)
382 $url .= $urlpath;
383 return $url;
384 }
385
386 // Get the plugin path.
387 public function plugin_path($path = '')
388 {
389 $plugin_path = trailingslashit($this->plugin_path);
390 if (strlen($path) > 0)
391 $plugin_path .= $path;
392
393 return $plugin_path;
394 }
395
396 // Get the ShortPixel Object.
397 public function getShortPixel()
398 {
399 return $this->shortPixel;
400 }
401
402 /** Returns defined admin page hooks. Internal use - check states via environmentmodel
403 * @returns Array
404 */
405 public function get_admin_pages()
406 {
407 return $this->admin_pages;
408 }
409
410 public static function activatePlugin()
411 {
412 self::deactivatePlugin();
413 if(SHORTPIXEL_RESET_ON_ACTIVATE === true && WP_DEBUG === true) { //force reset plugin counters, only on specific occasions and on test environments
414 \WPShortPixelSettings::debugResetOptions();
415 $settings = new \WPShortPixelSettings();
416 $spMetaDao = new \ShortPixelCustomMetaDao(new \WpShortPixelDb(), $settings->excludePatterns);
417 $spMetaDao->dropTables();
418 }
419
420 $env = wpSPIO()->env();
421
422 if(\WPShortPixelSettings::getOpt('deliverWebp') == 3 && ! $env->is_nginx) {
423 \WpShortPixel::alterHtaccess(); //add the htaccess lines
424 }
425
426 adminNoticesController::resetCompatNotice();
427 adminNoticesController::resetAPINotices();
428 adminNoticesController::resetQuotaNotices();
429 adminNoticesController::resetIntegrationNotices();
430
431 \WPShortPixelSettings::onActivate();
432
433 }
434
435 public static function deactivatePlugin()
436 {
437 \ShortPixelQueue::resetBulk();
438 (! defined('SHORTPIXEL_NOFLOCK')) ? \ShortPixelQueue::resetPrio() : \ShortPixelQueueDB::resetPrio();
439 \WPShortPixelSettings::onDeactivate();
440
441 //$settingsControl = new \ShortPixel\SettingsController();
442 $env = wpSPIO()->env();
443
444 if (! $env->is_nginx)
445 \WpShortPixel::alterHtaccess(true);
446
447 // save remove.
448 $fs = new FileSystemController();
449 $log = $fs->getFile(SHORTPIXEL_BACKUP_FOLDER . "/shortpixel_log");
450 if ($log->exists())
451 $log->delete();
452 // @unlink(SHORTPIXEL_BACKUP_FOLDER . "/shortpixel_log");
453 }
454
455 public static function uninstallPlugin()
456 {
457 $settings = new \WPShortPixelSettings();
458 $env = \wpSPIO()->env();
459
460 if($settings->removeSettingsOnDeletePlugin == 1) {
461 \WPShortPixelSettings::debugResetOptions();
462 if (! $env->is_nginx)
463 insert_with_markers( get_home_path() . '.htaccess', 'ShortPixelWebp', '');
464
465 $spMetaDao = new \ShortPixelCustomMetaDao(new \WpShortPixelDb());
466 $spMetaDao->dropTables();
467 }
468 }
469
470 } // class plugin
471