PluginProbe ʕ •ᴥ•ʔ
Robin Image Optimizer – Unlimited Image Optimization, WebP & AVIF / trunk
Robin Image Optimizer – Unlimited Image Optimization, WebP & AVIF vtrunk
2.0.5 trunk 1.3.7 1.4.0 1.4.1 1.4.2 1.4.6 1.5.0 1.5.3 1.5.6 1.5.8 1.6.5 1.6.6 1.6.9 1.7.0 1.7.4 1.8.1 1.8.2 1.9.0 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4
robin-image-optimizer / libs / factory / core / includes / class-factory-plugin-base.php
robin-image-optimizer / libs / factory / core / includes Last commit date
activation 5 months ago assets-managment 5 months ago components 5 months ago entities 5 months ago premium 5 months ago updates 5 months ago class-check-compatibility.php 6 months ago class-factory-migrations.php 5 months ago class-factory-notices.php 5 months ago class-factory-options.php 4 months ago class-factory-plugin-abstract.php 5 months ago class-factory-plugin-base.php 5 months ago class-factory-requests.php 5 months ago class-factory-requirements.php 5 months ago functions.php 5 months ago index.php 6 months ago
class-factory-plugin-base.php
588 lines
1 <?php
2 // Exit if accessed directly
3 if ( ! defined( 'ABSPATH' ) ) {
4 exit;
5 }
6
7 /**
8 * Базовый класс для создания нового плагина. Полную реализацию класса смотрите в Wbcr_Factory600_Plugin
9 *
10 * @since 1.0.0
11 * @package factory-core
12 */
13 class Wbcr_Factory600_Base {
14
15 use WBCR\Factory_600\Options;
16
17 /**
18 * Обязательное свойство. Префикс, используется для создания пространство имен.
19 * Чаще всего используется на именования опций в базе данны�
20 . Также может быть
21 * использован для именования полей html форм, создания уникальны�
22 имен, �
23 уков.
24 * Пример: wrio_
25 *
26 * Для префикса всегда используете нижнее подчеркивание справа!
27 *
28 * @var string
29 */
30 protected $prefix;
31
32 /**
33 * Обязательное свойство. Заголовок плагина. Используете в интерфейсе плагина,
34 * может быть использован в уведомления�
35 для администратора, чтобы пользователь
36 * мог понять, с каким плагином он ведет коммуникацию. Пример: Robin image optimizer
37 *
38 * @var string
39 */
40 protected $plugin_title;
41
42 /**
43 * Обязательное свойство. Имя плагина. Используется аналогично префиксу, но с небольшим
44 * отличием. Имя плагина имеет человеку понятную строку, которую можно использовать в
45 * именовании �
46 уков, созданию условной логики. Допустимые символы [A-z0-9_].
47 * Пример: wbcr_clearfy
48 *
49 * @var string
50 */
51 protected $plugin_name;
52
53 protected $plugin_slug;
54
55 /**
56 * Обязательное свойство. Версия плагина в формате 0.0.0. Допустимые символы [0-9.]
57 *
58 * @var string
59 */
60 protected $plugin_version;
61
62 /**
63 * Обязательное свойство. Текстовый домен плагина, используется для подключения файлов
64 * переводов. Рекомендуется использовать slug плагина, идентичный slug в репозитории
65 * Wordpress.org
66 *
67 * @since 4.1.1
68 * @var string
69 */
70 protected $plugin_text_domain;
71
72 /**
73 * Обязательное свойство. Информация для поддержки клиента. Для начала работы плагина,
74 * достаточно только указать адрес лендинга в атрибут url. На лендинге должны быть
75 * созданы страницы features, pricing, support, docs. Если страницы (features, pricing,
76 * support, docs) не могут иметь такие же адреса, вы можете наложить карту адресов в
77 * атрибуте pages_map. К примеру: я создал страницу "Pro Features" и она имеет адрес
78 * {site}/premium-features, для pages_map в атрибуте features, я указал, что адрес
79 * страницы со списком функций имеет слаг premium-features. Теперь плагин будет понимать,
80 * что адрес страницы со списком функций будет таким:
81 *
82 * Это свойство заполняется для того, чтобы в процессе разработки вы могли использовать
83 * экземпляр класса \WBCR\Factory_600\Entities\Support, для получения информации о сайте плагина.
84 * Тем самым вы избавляете себя от жесткого прописывания ссылок на лендинг плагина и
85 * можете изменить все ссылки в одном месте.
86 *
87 * @var array
88 */
89 protected $support_details;
90
91 /**
92 * Включение/отключение обновлений для бесплатного плагина. Если вашего плагина нет в репозитори
93 * Wordpress.org, вы можете включить собственный режим обновлений, например через GitHub или
94 * собственный репозиторий. Если установлено true, плагин будет проверять наличие обновлений
95 * для этого плагина.
96 *
97 * @var bool
98 */
99 protected $has_updates = false;
100
101 /**
102 * Настройка обновлений для бесплатного плагина. Если вы �
103 отите настроить обновления для
104 * бесплатного плагина через собственный репозиторий (например: github), вам нужно указать имя
105 * репозитория и slug плагина. Slug может быть идентичен имени репозитория в github. Для Wordpress.org
106 * эти настройки не обязательны, так как в WordPress ядре есть встроенные функции для обновлений
107 * плагинов и тем.
108 *
109 * @var array
110 */
111 protected $updates_settings = [];
112
113 /**
114 * Включение/отключение премиум версии для плагина. Если вы создаете бесплатный плагин и �
115 отите
116 * реализовать для него премиум версию, вам нужно начать с этого свойства. Если свойство установлено,
117 * как true, при инициализации плагина будут подключены функции лицензирования, проверки обновлений
118 * для премиум версии.
119 *
120 * @var bool
121 */
122 protected $has_premium = false;
123
124 /**
125 * Настройки лицензирования
126 *
127 * Лицензирование плагина может быть реализовано для любого провайдера,
128 * к примеру: freemius, codecanyon, templatemonster, вам нужно указать только настройки для
129 * взаимодействия с выбранным вами провайдером. Каждая реализация провайдера лицензий может иметь
130 * индивидуальный настройки, в этом примере приведены настройки для freemius провайдера
131 * WBCR\Factory_600\Premium\Provider > WBCR\Factory_Freemius_Rio_600\Premium\Provider
132 *
133 * На текущий момент существует только реализация для freemius провайдера.
134 *
135 * Для премиум плагина вы должны также указать настройки обновлений. Атрибут has_updates
136 * включает/отключает обновления для премиум плагина, в атрибуте updates_settings вы указываете
137 * дополнительные настройки обновлений.
138 *
139 * @var array
140 */
141 protected $license_settings = [];
142
143 /**
144 * Переключатель внутренней рекламы в плагине
145 *
146 * Если установить true, то плагин будет показывать рекламу компании в интерфейсе WordPress.
147 * Рекламный модуль может отображать рекламу внутри инрефейса плагина, на странице dashboard
148 * и создавать сквозные уведомления на все�
149 страница�
150 админ панели WordPress.
151 *
152 * @since 4.1.9
153 * @var bool
154 */
155 protected $render_adverts = false;
156
157 /**
158 * Настройки внутренней рекламы компании
159 *
160 * @since 4.1.9
161 * @var array
162 */
163 protected $adverts_settings = [];
164
165 /**
166 * Обязательное свойство. Подключаемые модули фреймворка.
167 *
168 * Модули фреймворка позволяют расширять его функциональность.
169 *
170 * @var array {
171 * Array with information about the loadable module
172 * {type} string $module [0] Relative path to the module directory
173 * {type} string $module [1] Module name with prefix 000
174 * {type} string $module [2] Scope:
175 * admin - Module will be loaded only in the admin panel,
176 * public - Module will be loaded only on the frontend
177 * all - Module will be loaded everywhere
178 * }
179 */
180 protected $load_factory_modules = [
181 [ 'libs/factory/bootstrap', 'factory_bootstrap_500', 'admin' ],
182 [ 'libs/factory/forms', 'factory_forms_600', 'admin' ],
183 [ 'libs/factory/pages', 'factory_pages_600', 'admin' ],
184 ];
185
186 /**
187 * Не обязательное свойство. Список подключаемы�
188 компонентов плагина.
189 *
190 * Компоненты плагина, это независимые плагины, которые расширяют возможности текущего плагина.
191 * Вы должны указать файл для автозагрузки компонента и префикс плагина, чтобы фреймворк
192 * мог обращаться к классам и константам компонентов.
193 *
194 * @since 4.2.0 Добавлен
195 * @var array Пример данны�
196
197 * array(
198 * 'component_ID' => array(
199 * 'autoload' => 'relative_path/autoload_filename.php',
200 * 'plugin_prefix' => 'WPRFX_'
201 * ),
202 * // Реальный пример
203 * 'cyrlitera' => array(
204 * 'autoload' => 'components/cyrlitera/clearfy.php',
205 * 'plugin_prefix' => 'WCTR_'
206 * ),
207 * )
208 */
209 protected $load_plugin_components = [];
210
211
212 /**
213 * Экземпляр класса \WBCR\Factory_600\Entities\Support используется для получения информации
214 * о сайте плагина. Чаще всего используется для получения ссылки на страницу с тарифами или
215 * ссылки на форму обратной связи. Встроен ме�
216 анизм отслеживания по utm меткам.
217 *
218 * @var \WBCR\Factory_600\Entities\Support
219 */
220 protected $support;
221
222 /**
223 * Экземпляр класса \WBCR\Factory_600\Entities\Paths используется для получения информации о
224 * путя�
225 плагина. Часто используется для получения путей или ссылок на место �
226 ранения плагина
227 * или его в�
228 одного файла.
229 *
230 * @var \WBCR\Factory_600\Entities\Paths
231 */
232 protected $paths;
233
234 /**
235 * Абсолютный путь к в�
236 одному файлу плагина: C://server/site.dev/wp-content/plugins/plugin_name/plugin_name.php
237 *
238 * @var string
239 */
240 private $plugin_file;
241
242 /**
243 * Свойство �
244 ранит сырые настройки плагина, а также дополнительные настройки, которые не описаны
245 * в интерфейсе класса.
246 *
247 * @var array
248 */
249 private $plugin_data;
250
251 /**
252 * Конструктор:
253 * - Заполняет свойства класса из сыры�
254 данны�
255 плагина
256 * - Выполняет проверку на обязательные настройки
257 * - Инициализирует сущности support и paths
258 *
259 * @param string $plugin_file
260 * @param array $data
261 *
262 * @throws Exception
263 * @since 4.0.8 - добавлена дополнительная логика
264 *
265 * @since 4.1.1 - добавил две сущности support, paths. Удалил свойства, plugin_build
266 * plugin_assembly, main_file, plugin_root, relative_path, plugin_url
267 */
268 public function __construct( $plugin_file, $data ) {
269 $this->plugin_file = $plugin_file;
270 $this->plugin_data = $data;
271
272 foreach ( (array) $data as $option_name => $option_value ) {
273 if ( property_exists( $this, $option_name ) ) {
274 $this->$option_name = $option_value;
275 }
276 }
277
278 if ( empty( $this->prefix ) || empty( $this->plugin_name ) || empty( $this->plugin_title ) || empty( $this->plugin_version ) || empty( $this->plugin_text_domain ) ) {
279 throw new Exception( 'One of the required attributes has not been passed (prefix, plugin_title, plugin_name, plugin_version, plugin_text_domain).' );
280 }
281
282 $this->support = new \WBCR\Factory_600\Entities\Support( $this->support_details );
283 $this->paths = new \WBCR\Factory_600\Entities\Paths( $plugin_file );
284
285 // used only in the module 'updates'
286 $this->plugin_slug = ! empty( $this->plugin_name ) ? $this->plugin_name : basename( $plugin_file );
287 }
288
289 /**
290 * При обновлении фреймворка, некоторые свойства класса были удалены. Однако плагины на старом
291 * фреймворке по прежнему используют удаленные свойства. С помощью этого магического метода мы
292 * добавляем совместимость со старыми плагинами, но при этом выводим предупреждение, что нужно
293 * обновить некоторые свойства.
294 *
295 * @param string $name Имя свойства класса.
296 *
297 * @return mixed
298 */
299 public function __get( $name ) {
300
301 $deprecated_props = [
302 'plugin_build',
303 'plugin_assembly',
304 'main_file',
305 'plugin_root',
306 'relative_path',
307 'plugin_url',
308 ];
309
310 if ( in_array( $name, $deprecated_props ) ) {
311 $deprecated_message = 'In version 4.1.1 of the Factory framework, the class properties ';
312 $deprecated_message .= '(' . implode( ',', $deprecated_props ) . ')';
313 $deprecated_message .= 'have been removed. To get plugin paths, use the new paths property.' . PHP_EOL;
314
315 $backtrace = debug_backtrace();
316 if ( ! empty( $backtrace ) && isset( $backtrace[1] ) ) {
317 $deprecated_message .= 'BACKTRACE:(';
318 $deprecated_message .= 'File: ' . $backtrace[1]['file'];
319 $deprecated_message .= 'Function: ' . $backtrace[1]['function'];
320 $deprecated_message .= 'Line: ' . $backtrace[1]['line'];
321 $deprecated_message .= ')';
322 }
323
324 _deprecated_argument( __METHOD__, '4.1.1', $deprecated_message );
325
326 switch ( $name ) {
327 case 'plugin_build':
328 return null;
329 break;
330 case 'plugin_assembly':
331 return null;
332 break;
333 case 'main_file':
334 return $this->get_paths()->main_file;
335 break;
336 case 'plugin_root':
337 return $this->get_paths()->absolute;
338 break;
339 case 'relative_path':
340 return $this->get_paths()->basename;
341 break;
342 case 'plugin_url':
343 return $this->get_paths()->url;
344 break;
345 }
346 }
347
348 return null;
349 }
350
351 /**
352 * При обновлении фреймворка, некоторые методы класса были удалены. Однако плагины на старом фреймворке
353 * по прежнему используют удаленные методы. С помощью этого магического метода мы добавляем совместимость
354 * со старыми плагинами, но при этом выводим предупреждение, что нужно обновить некоторые методы.
355 *
356 * @param string $name Имя метода класса.
357 * @param array $arguments Массив аргументов метода класса.
358 *
359 * @return stdClass|null
360 * @throws Exception
361 */
362 public function __call( $name, $arguments ) {
363
364 $deprecated_methods = [
365 'getPluginBuild',
366 'getPluginAssembly',
367 'getPluginPathInfo',
368 ];
369
370 if ( in_array( $name, $deprecated_methods ) ) {
371 $deprecated_message = 'In version 4.1.1 of the Factory framework, methods (' . implode( ',', $deprecated_methods ) . ') have been removed.';
372
373 $backtrace = debug_backtrace();
374 if ( ! empty( $backtrace ) && isset( $backtrace[1] ) ) {
375 $deprecated_message .= 'BACKTRACE:(';
376 $deprecated_message .= 'File: ' . $backtrace[1]['file'];
377 $deprecated_message .= 'Function: ' . $backtrace[1]['function'];
378 $deprecated_message .= 'Line: ' . $backtrace[1]['line'];
379 $deprecated_message .= ')';
380 }
381
382 _deprecated_argument( __METHOD__, '4.1.1', $deprecated_message );
383
384 if ( 'getPluginPathInfo' == $name ) {
385 $object = new stdClass();
386
387 $object->main_file = $this->get_paths()->main_file;
388 $object->plugin_root = $this->get_paths()->absolute;
389 $object->relative_path = $this->get_paths()->basename;
390 $object->plugin_url = $this->get_paths()->url;
391
392 return $object;
393 }
394 }
395
396 throw new Exception( "Method {$name} does not exist" );
397 }
398
399 /**
400 * Проверяет, включен ли премиум для этого плагина или нет.
401 *
402 * @return bool Возвращает true, если премиум пакет включен для этого плагина.
403 * См. Wbcr_Factory600_Base::has_premium
404 */
405 public function has_premium() {
406 return $this->has_premium;
407 }
408
409 /**
410 * Позволяет получить заголовок плагина.
411 *
412 * @return string Возвращает заголовок плагина. См. Wbcr_Factory600_Base::plugin_title
413 */
414 public function getPluginTitle() {
415 return apply_filters( 'wbcr/factory/plugin_title', $this->plugin_title, $this->getPluginName() );
416 }
417
418 /**
419 * Позволяет получить префикс плагина.
420 *
421 * @return string Возвращает префикс плагина.См. Wbcr_Factory600_Base::prefix
422 */
423 public function getPrefix() {
424 return $this->prefix;
425 }
426
427 /**
428 * Позволяет получить имя плагина.
429 *
430 * @return string Возвращает имя плагина. См. Wbcr_Factory600_Base::plugin_name
431 */
432 public function getPluginName() {
433 return $this->plugin_name;
434 }
435
436 /**
437 * Позволяет получить версию плагина.
438 *
439 * @return string Возвращает версию плагина. См. Wbcr_Factory600_Base::plugin_version
440 */
441 public function getPluginVersion() {
442 return $this->plugin_version;
443 }
444
445 /**
446 * Позволяет получить список подключаемы�
447 к плагином компонентов
448 *
449 * @return array
450 * @since 4.2.0
451 */
452 public function get_load_plugin_components() {
453 return $this->load_plugin_components;
454 }
455
456 /**
457 * Предоставляет доступ к сырым данным плагина. Может быть полезен, если вы �
458 отите получить
459 * какие-то данные не описанные в интерфейсе этого плагина.
460 *
461 * @param string $attr_name Имя атрибута, который нужно получить. Идентично ключу в массиве
462 * Wbcr_Factory600_Base::plugin_data
463 *
464 * @return null
465 */
466 public function getPluginInfoAttr( $attr_name ) {
467 if ( isset( $this->plugin_data[ $attr_name ] ) ) {
468 return $this->plugin_data[ $attr_name ];
469 }
470
471 return null;
472 }
473
474 /**
475 * Предоставляет доступ к экземпляру класса \WBCR\Factory_600\Entities\Support.
476 *
477 * @return \WBCR\Factory_600\Entities\Support
478 */
479 public function get_support() {
480 return $this->support;
481 }
482
483 /**
484 * Предоставляет доступ к экземпляру класса \WBCR\Factory_600\Entities\Paths.
485 *
486 * @return \WBCR\Factory_600\Entities\Paths
487 */
488 public function get_paths() {
489 return $this->paths;
490 }
491
492 /**
493 * Позволяет получить сырые данные плагина в виде объекта StdClass.
494 *
495 * @return object Возвращает объект с сырыми данными плагина. См. Wbcr_Factory600_Base::plugin_data
496 */
497 public function getPluginInfo() {
498 return (object) $this->plugin_data;
499 }
500
501 /**
502 * Проверяет права пользователя
503 *
504 * @return bool
505 * @since 4.2.0 Добавлен
506 */
507 public function current_user_can( $capability = 'manage_options' ) {
508 // Просмотр страниц: read_pages
509 // Просмотр уведомлений: read_notices
510 // Редактирование: edit_forms
511
512 if ( 'manage_options' == $capability && is_multisite() && $this->isNetworkActive() ) {
513 $capability = 'manage_network';
514 }
515
516 return current_user_can( $capability );
517 }
518
519 /**
520 * Проверят, на�
521 одится ли пользователь в панели усправления сетью сайтов
522 *
523 * @return bool
524 * @since 4.0.8 Добавлен
525 */
526 public function isNetworkAdmin() {
527 return is_multisite() && is_network_admin();
528 }
529
530 /**
531 * Проверяет активирован ли плагин для сети. Если проект работает в режиме мультисайтов..
532 *
533 * @return bool Если true, плагин активирован для сети или в текущий момент активируется для сети.
534 * @since 4.0.8 Добавлен
535 */
536 public function isNetworkActive() {
537 // Makes sure the plugin is defined before trying to use it
538 if ( ! function_exists( 'is_plugin_active_for_network' ) ) {
539 require_once ABSPATH . '/wp-admin/includes/plugin.php';
540 }
541
542 $activate = is_plugin_active_for_network( $this->get_paths()->basename );
543
544 if ( ! $activate && $this->isNetworkAdmin() && isset( $_GET['action'] ) && $_GET['action'] == 'activate' ) {
545 return isset( $_GET['networkwide'] ) && 1 == (int) $_GET['networkwide'];
546 }
547
548 return $activate;
549 }
550
551 /**
552 * Позволяет получить все активные сайты сети. Если проект работает в режиме мультисайтов.
553 *
554 * @return array|int
555 * @since 4.0.8
556 */
557 public function getActiveSites( $args = [
558 'archived' => 0,
559 'mature' => 0,
560 'spam' => 0,
561 'deleted' => 0,
562 ]) {
563 global $wp_version;
564
565 if ( version_compare( $wp_version, '4.6', '>=' ) ) {
566 return get_sites( $args );
567 } else {
568 $converted_array = [];
569
570 $sites = wp_get_sites( $args );
571
572 if ( empty( $sites ) ) {
573 return $converted_array;
574 }
575
576 foreach ( (array) $sites as $key => $site ) {
577 $obj = new stdClass();
578 foreach ( $site as $attr => $value ) {
579 $obj->$attr = $value;
580 }
581 $converted_array[ $key ] = $obj;
582 }
583
584 return $converted_array;
585 }
586 }
587 }
588