Clearfy – WordPress optimization plugin and disable ultimate tweaker - Version 1.3.1

Version Description

Download this release

Release Info

Developer webcraftic
Plugin Icon 128x128 Clearfy – WordPress optimization plugin and disable ultimate tweaker
Version 1.3.1
Comparing to
See all releases

Code changes from version 1.2.1 to 1.3.1

Files changed (220) hide show
  1. admin/activation.php +50 -4
  2. admin/ajax/configurate.php +2 -0
  3. admin/ajax/import-settings.php +14 -2
  4. admin/ajax/install-addons.php +113 -0
  5. admin/ajax/update-package.php +48 -0
  6. admin/assets/css/components.css +37 -1
  7. admin/assets/css/components.less +38 -3
  8. admin/assets/css/general.css +88 -0
  9. admin/assets/css/install-addons.css +31 -0
  10. admin/assets/css/install-addons.less +38 -0
  11. admin/assets/css/license-manager.css +659 -0
  12. admin/assets/img/bind-key.png +0 -0
  13. admin/assets/img/create-account-bg.png +0 -0
  14. admin/assets/img/finish.png +0 -0
  15. admin/assets/img/free-license-chip.png +0 -0
  16. admin/assets/img/green-license-chip.png +0 -0
  17. admin/assets/img/hlp-icon-128x128.png +0 -0
  18. admin/assets/img/how-to-find-key.png +0 -0
  19. admin/assets/img/key-bound-icon.png +0 -0
  20. admin/assets/img/loader.gif +0 -0
  21. admin/assets/img/paid-license-chip.png +0 -0
  22. admin/assets/img/robin-image-optimizer-fake-board.png +0 -0
  23. admin/assets/img/trial-license-chip.png +0 -0
  24. admin/assets/img/warning.png +0 -0
  25. admin/assets/js/general.js +16 -0
  26. admin/assets/js/install-addons.js +224 -0
  27. admin/assets/js/license-manager.js +31 -0
  28. admin/assets/js/update-package.js +67 -0
  29. admin/boot.php +181 -105
  30. admin/includes/classes/class.delete-plugins-button.php +62 -0
  31. admin/includes/classes/class.install-plugins-button.php +394 -0
  32. admin/includes/classes/class.pages.php +9 -2
  33. admin/includes/classes/class.upgrader-skin.php +15 -0
  34. admin/includes/classes/class.upgrader.php +50 -0
  35. admin/includes/options.php +34 -75
  36. admin/pages/advanced.php +18 -2
  37. admin/pages/components.php +199 -64
  38. admin/pages/defence-privacy-code.php +0 -90
  39. admin/pages/defence.php +82 -6
  40. admin/pages/license.php +429 -0
  41. admin/pages/performance-google.php +2 -106
  42. admin/pages/performance-html-minify.php +0 -154
  43. admin/pages/performance.php +3 -34
  44. admin/pages/quick-start.php +10 -7
  45. admin/pages/seo-double-pages.php +2 -2
  46. admin/pages/seo.php +12 -4
  47. admin/pages/widgets.php +1 -1
  48. assets/css/admin-bar.css +23 -0
  49. assets/css/admin-bar.less +25 -0
  50. assets/img/webcraftic-plugin-icon.png +0 -0
  51. cache/local-ga.js +0 -59
  52. clearfy.php +10 -5
  53. components/assets-manager/admin/assets/css/general.css +3 -3
  54. components/assets-manager/admin/boot.php +12 -3
  55. components/assets-manager/admin/pages/assets-manager.php +22 -4
  56. components/assets-manager/admin/pages/more-features.php +1 -1
  57. components/assets-manager/gonzales.php +4 -4
  58. components/assets-manager/includes/class.configurate-assets.php +22 -6
  59. components/assets-manager/includes/class.plugin.php +8 -8
  60. components/assets-manager/readme.txt +7 -1
  61. components/assets-manager/updates/010100.php +26 -0
  62. components/comments-plus/admin/assets/css/general.css +3 -3
  63. components/comments-plus/admin/boot.php +22 -13
  64. components/comments-plus/admin/pages/comments.php +23 -6
  65. components/comments-plus/admin/pages/delete-comments.php +50 -12
  66. components/comments-plus/admin/pages/more-features.php +1 -1
  67. components/comments-plus/comments-plus.php +3 -3
  68. components/comments-plus/includes/class.plugin.php +8 -8
  69. components/comments-plus/includes/classes/class.configurate-comments.php +4 -3
  70. components/comments-plus/readme.txt +15 -3
  71. components/cyrlitera/admin/activation.php +2 -2
  72. components/cyrlitera/admin/boot.php +56 -32
  73. components/cyrlitera/admin/options.php +13 -3
  74. components/cyrlitera/admin/pages/cyrlitera.php +22 -4
  75. components/cyrlitera/admin/pages/more-features.php +1 -1
  76. components/cyrlitera/cyrlitera.php +3 -3
  77. components/cyrlitera/includes/class.plugin.php +9 -8
  78. components/cyrlitera/includes/classes/class.configurate-cyrlitera.php +3 -3
  79. components/cyrlitera/languages/cyrlitera-ru_RU.mo +0 -0
  80. components/cyrlitera/languages/cyrlitera-ru_RU.po +24 -16
  81. components/cyrlitera/readme.txt +9 -1
  82. components/cyrlitera/updates/010004.php +1 -1
  83. components/disable-admin-notices/admin/ajax/hide-notice.php +1 -1
  84. components/disable-admin-notices/admin/ajax/restore-notice.php +1 -1
  85. components/disable-admin-notices/admin/assets/js/notifications-panel.js +1 -0
  86. components/disable-admin-notices/admin/boot.php +18 -12
  87. components/disable-admin-notices/admin/options.php +2 -2
  88. components/disable-admin-notices/admin/pages/more-features.php +1 -1
  89. components/disable-admin-notices/admin/pages/notices.php +24 -6
  90. components/disable-admin-notices/disable-admin-notices.php +3 -3
  91. components/disable-admin-notices/includes/class.plugin.php +9 -9
  92. components/disable-admin-notices/includes/classes/class.configurate-notices.php +36 -4
  93. components/disable-admin-notices/readme.txt +3 -1
  94. components/ga-cache/admin/activation.php +57 -0
  95. components/{hide-login-page/admin → ga-cache/admin/ajax}/index.php +0 -0
  96. components/{hide-login-page/admin/pages → ga-cache/admin/assets/css}/index.php +0 -0
  97. components/ga-cache/admin/assets/css/notifications-panel.css +65 -0
  98. components/ga-cache/admin/assets/css/notifications-panel.less +77 -0
  99. components/{hide-login-page/includes/classes → ga-cache/admin/assets}/index.php +0 -0
  100. components/{hide-login-page/includes → ga-cache/admin/assets/js}/index.php +0 -0
  101. components/ga-cache/admin/assets/js/notifications-panel.js +44 -0
  102. components/ga-cache/admin/boot.php +214 -0
  103. components/ga-cache/admin/options.php +148 -0
  104. components/ga-cache/admin/pages/ga_cache.php +92 -0
  105. components/{hide-login-page → ga-cache/admin/pages}/index.php +0 -0
  106. components/{hide-login-page → ga-cache}/admin/pages/more-features.php +1 -1
  107. components/ga-cache/cache/local-ga.js +58 -0
  108. components/ga-cache/includes/class.plugin.php +135 -0
  109. components/ga-cache/includes/classes/class.configurate-ga.php +129 -0
  110. components/{hide-login-page/languages → ga-cache/includes/classes}/index.php +0 -0
  111. components/{hide-login-page/libs → ga-cache/includes}/index.php +0 -0
  112. {includes → components/ga-cache/includes}/update-local-ga.php +1 -1
  113. components/ga-cache/languages/index.php +0 -0
  114. components/ga-cache/languages/simple-google-analytics-ru_RU.mo +0 -0
  115. components/ga-cache/languages/simple-google-analytics-ru_RU.po +198 -0
  116. components/ga-cache/readme.txt +137 -0
  117. components/ga-cache/simple_google_analytics.php +73 -0
  118. components/{hide-login-page → ga-cache}/uninstall.php +1 -1
  119. components/hide-login-page/admin/boot.php +0 -136
  120. components/hide-login-page/admin/options.php +0 -255
  121. components/hide-login-page/admin/pages/hide-login.php +0 -73
  122. components/hide-login-page/hide-login-page.php +0 -59
  123. components/hide-login-page/includes/class.plugin.php +0 -127
  124. components/hide-login-page/includes/classes/class.configurate-hide-login-page.php +0 -247
  125. components/hide-login-page/languages/hide_login_page-ru_RU.mo +0 -0
  126. components/hide-login-page/languages/hide_login_page-ru_RU.po +0 -191
  127. components/hide-login-page/readme.txt +0 -34
  128. components/html-minify/admin/boot.php +82 -0
  129. components/html-minify/admin/index.php +0 -0
  130. components/html-minify/admin/pages/index.php +0 -0
  131. components/html-minify/admin/pages/settings.php +127 -0
  132. components/html-minify/html-minify.php +103 -0
  133. components/html-minify/includes/class.plugin.php +174 -0
  134. components/html-minify/includes/classes/class.mac-base.php +260 -0
  135. components/html-minify/includes/classes/class.mac-html.php +126 -0
  136. components/html-minify/includes/classes/class.mac-main.php +270 -0
  137. components/html-minify/includes/classes/ext/php/minify-html.php +270 -0
  138. components/html-minify/includes/classes/index.php +0 -0
  139. components/html-minify/includes/index.php +0 -0
  140. components/html-minify/index.php +0 -0
  141. components/html-minify/languages/html-minify-ru_RU.mo +0 -0
  142. components/html-minify/languages/html-minify-ru_RU.po +417 -0
  143. components/html-minify/languages/index.php +0 -0
  144. components/html-minify/readme.txt +15 -0
  145. components/html-minify/uninstall.php +12 -0
  146. components/minify-and-combine/admin/boot.php +146 -0
  147. components/minify-and-combine/admin/index.php +0 -0
  148. components/minify-and-combine/admin/pages/index.php +0 -0
  149. components/minify-and-combine/admin/pages/settings.php +376 -0
  150. components/minify-and-combine/assets/css/index.php +0 -0
  151. components/minify-and-combine/assets/index.php +0 -0
  152. components/minify-and-combine/assets/js/index.php +0 -0
  153. components/minify-and-combine/includes/boot.php +77 -0
  154. components/minify-and-combine/includes/class.plugin.php +183 -0
  155. components/minify-and-combine/includes/classes/class.mac-base.php +666 -0
  156. components/minify-and-combine/includes/classes/class.mac-cache-checker.php +112 -0
  157. components/minify-and-combine/includes/classes/class.mac-cache.php +769 -0
  158. components/minify-and-combine/includes/classes/class.mac-css-min.php +63 -0
  159. components/minify-and-combine/includes/classes/class.mac-helper.php +340 -0
  160. components/minify-and-combine/includes/classes/class.mac-main.php +450 -0
  161. components/minify-and-combine/includes/classes/class.mac-scripts.php +635 -0
  162. components/minify-and-combine/includes/classes/class.mac-styles.php +1127 -0
  163. components/minify-and-combine/includes/classes/ext/php/jsmin.php +472 -0
  164. components/minify-and-combine/includes/classes/ext/php/yui-php-cssmin-bundled/Colors.php +159 -0
  165. components/minify-and-combine/includes/classes/ext/php/yui-php-cssmin-bundled/Minifier.php +864 -0
  166. components/minify-and-combine/includes/classes/ext/php/yui-php-cssmin-bundled/Utils.php +159 -0
  167. components/minify-and-combine/includes/classes/ext/php/yui-php-cssmin-bundled/index.html +1 -0
  168. components/minify-and-combine/includes/classes/index.php +0 -0
  169. components/minify-and-combine/includes/index.php +0 -0
  170. components/minify-and-combine/index.php +0 -0
  171. components/minify-and-combine/languages/index.php +0 -0
  172. components/minify-and-combine/languages/minify-and-combine-ru_RU.mo +0 -0
  173. components/minify-and-combine/languages/minify-and-combine-ru_RU.po +573 -0
  174. components/minify-and-combine/minify-and-combine.php +104 -0
  175. components/minify-and-combine/readme.txt +155 -0
  176. components/minify-and-combine/uninstall.php +47 -0
  177. components/updates-manager/admin/boot.php +54 -29
  178. components/updates-manager/admin/pages/advanced.php +22 -4
  179. components/updates-manager/admin/pages/more-features.php +1 -1
  180. components/updates-manager/admin/pages/plugins.php +10 -5
  181. components/updates-manager/admin/pages/updates.php +22 -4
  182. components/updates-manager/includes/class.plugin.php +9 -8
  183. components/updates-manager/includes/classes/class.configurate-updates.php +5 -1
  184. components/updates-manager/languages/webcraftic-updates-manager-ru_RU.mo +0 -0
  185. components/updates-manager/languages/webcraftic-updates-manager-ru_RU.po +21 -21
  186. components/updates-manager/readme.txt +25 -4
  187. components/updates-manager/webcraftic-updates-manager.php +3 -3
  188. includes/boot.php +74 -0
  189. includes/class.plugin.php +140 -25
  190. includes/classes/class.configurate-advanced.php +8 -1
  191. includes/classes/class.configurate-google-performance.php +5 -113
  192. includes/classes/class.configurate-performance.php +5 -2
  193. includes/classes/class.configurate-privacy.php +11 -1
  194. includes/classes/class.configurate-security.php +1 -1
  195. includes/classes/class.configurate-seo.php +12 -4
  196. includes/classes/class.licensing.php +632 -0
  197. includes/classes/class.package.php +279 -0
  198. includes/freemius/class.storage.php +93 -0
  199. includes/freemius/entities/class.wcl-fs-entity.php +164 -0
  200. includes/freemius/entities/class.wcl-fs-plugin-license.php +296 -0
  201. includes/freemius/entities/class.wcl-fs-scope-entity.php +29 -0
  202. includes/freemius/entities/class.wcl-fs-site.php +240 -0
  203. includes/freemius/entities/class.wcl-fs-user.php +71 -0
  204. includes/freemius/sdk/Exceptions/ArgumentNotExistException.php +2 -0
  205. includes/freemius/sdk/Exceptions/EmptyArgumentException.php +2 -0
  206. includes/freemius/sdk/Exceptions/Exception.php +84 -0
  207. includes/freemius/sdk/Exceptions/InvalidArgumentException.php +2 -0
  208. includes/freemius/sdk/Exceptions/OAuthException.php +9 -0
  209. includes/freemius/sdk/Exceptions/index.php +0 -0
  210. includes/freemius/sdk/FreemiusBase.php +204 -0
  211. includes/freemius/sdk/FreemiusWordPress.php +704 -0
  212. includes/freemius/sdk/LICENSE.txt +340 -0
  213. includes/freemius/sdk/index.php +0 -0
  214. includes/helpers.php +84 -172
  215. languages/clearfy-ru_RU.mo +0 -0
  216. languages/clearfy-ru_RU.po +918 -504
  217. libs/factory/bootstrap/assets/css-min/bootstrap.accordion.min.css +1 -1
  218. libs/factory/bootstrap/assets/css-min/bootstrap.blue.min.css +1 -1
  219. libs/factory/bootstrap/assets/css-min/bootstrap.coffee.min.css +1 -1
  220. libs/factory/bootstrap/assets/css-min/bootstrap.core.min.css +0 -1
admin/activation.php CHANGED
@@ -4,7 +4,7 @@
4
  * Activator for the clearfy
5
  * @author Webcraftic <wordpress.webraftic@gmail.com>
6
  * @copyright (c) 09.09.2017, Webcraftic
7
- * @see Factory400_Activator
8
  * @version 1.0
9
  */
10
 
@@ -13,7 +13,7 @@
13
  exit;
14
  }
15
 
16
- class WCL_Activation extends Wbcr_Factory400_Activator {
17
 
18
  /**
19
  * Runs activation actions.
@@ -22,7 +22,35 @@
22
  */
23
  public function activate()
24
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  // Deactivate yoast component features if it is not activated
 
 
26
  if( !defined('WPSEO_VERSION') ) {
27
  WCL_Plugin::app()->deactivateComponent('yoast_seo');
28
  }
@@ -31,9 +59,10 @@
31
  if( !in_array(get_locale(), array('ru_RU', 'bel', 'kk', 'uk', 'bg', 'bg_BG', 'ka_GE')) ) {
32
  WCL_Plugin::app()->deactivateComponent('cyrlitera');
33
  }
34
-
35
  // Caching google analytics on a schedule
36
- //----------------------------------------
 
37
  $ga_cache = WCL_Plugin::app()->getOption('ga_cache');
38
 
39
  if( $ga_cache ) {
@@ -47,6 +76,9 @@
47
  }
48
  }
49
  }
 
 
 
50
  }
51
 
52
  /**
@@ -59,5 +91,19 @@
59
  if( wp_next_scheduled('wbcr_clearfy_update_local_ga') ) {
60
  wp_clear_scheduled_hook('wbcr_clearfy_update_local_ga');
61
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  }
63
  }
4
  * Activator for the clearfy
5
  * @author Webcraftic <wordpress.webraftic@gmail.com>
6
  * @copyright (c) 09.09.2017, Webcraftic
7
+ * @see Factory406_Activator
8
  * @version 1.0
9
  */
10
 
13
  exit;
14
  }
15
 
16
+ class WCL_Activation extends Wbcr_Factory406_Activator {
17
 
18
  /**
19
  * Runs activation actions.
22
  */
23
  public function activate()
24
  {
25
+ // Deactivate components for code minification, if alternative plugins are installed
26
+ // -------------
27
+
28
+ require_once ABSPATH . '/wp-admin/includes/plugin.php';
29
+ $minify_js_plugins = array(
30
+ 'autoptimize/autoptimize.php',
31
+ 'fast-velocity-minify/fvm.php',
32
+ 'js-css-script-optimizer/js-css-script-optimizer.php',
33
+ 'merge-minify-refresh/merge-minify-refresh.php',
34
+ 'wp-super-minify/wp-super-minify.php'
35
+ );
36
+
37
+ $is_activate_minify_js = true;
38
+ foreach($minify_js_plugins as $m_plugin) {
39
+
40
+ if(is_plugin_active($m_plugin) ) {
41
+ $is_activate_minify_js = false;
42
+ }
43
+ }
44
+
45
+ if( !$is_activate_minify_js ) {
46
+ WCL_Plugin::app()->deactivateComponent('minify_and_combine');
47
+ WCL_Plugin::app()->deactivateComponent('html_minify');
48
+ }
49
+
50
+ // -------------
51
  // Deactivate yoast component features if it is not activated
52
+ // -------------
53
+
54
  if( !defined('WPSEO_VERSION') ) {
55
  WCL_Plugin::app()->deactivateComponent('yoast_seo');
56
  }
59
  if( !in_array(get_locale(), array('ru_RU', 'bel', 'kk', 'uk', 'bg', 'bg_BG', 'ka_GE')) ) {
60
  WCL_Plugin::app()->deactivateComponent('cyrlitera');
61
  }
62
+ // -------------
63
  // Caching google analytics on a schedule
64
+ // -------------
65
+
66
  $ga_cache = WCL_Plugin::app()->getOption('ga_cache');
67
 
68
  if( $ga_cache ) {
76
  }
77
  }
78
  }
79
+ // -------------
80
+ $package_plugin = WCL_Package::instance();
81
+ $package_plugin->active();
82
  }
83
 
84
  /**
91
  if( wp_next_scheduled('wbcr_clearfy_update_local_ga') ) {
92
  wp_clear_scheduled_hook('wbcr_clearfy_update_local_ga');
93
  }
94
+
95
+ $dependent = 'clearfy_package/clearfy-package.php';
96
+
97
+ if( is_plugin_active($dependent) ){
98
+ add_action('update_option_active_plugins', array($this, 'deactivateDependent'));
99
+ }
100
+ }
101
+
102
+ /**
103
+ * Deactivate clearfy package
104
+ */
105
+ public function deactivateDependent() {
106
+ $package_plugin = WCL_Package::instance();
107
+ $package_plugin->deactive();
108
  }
109
  }
admin/ajax/configurate.php CHANGED
@@ -78,6 +78,8 @@
78
  $GLOBALS['wp_fastest_cache']->deleteCache();
79
  }
80
 
 
 
81
  echo json_encode(array('status' => 'success', 'export_options' => WCL_Helper::getExportOptions()));
82
  exit;
83
  }
78
  $GLOBALS['wp_fastest_cache']->deleteCache();
79
  }
80
 
81
+ do_action('wbcr_clearfy_configurated_quick_mode', $mode_name);
82
+
83
  echo json_encode(array('status' => 'success', 'export_options' => WCL_Helper::getExportOptions()));
84
  exit;
85
  }
admin/ajax/import-settings.php CHANGED
@@ -65,6 +65,11 @@
65
  }
66
  }
67
  }
 
 
 
 
 
68
 
69
  array_push($values, $option_name, $option_value);
70
  $place_holders[] = "('%s', '%s')";/* In my case, i know they will always be integers */
@@ -78,11 +83,18 @@
78
 
79
  // Сбрасываем кеш опций
80
  WCL_Plugin::app()->flushOptionsCache();
 
81
 
82
  // Импортируем опции
83
  $wpdb->query($wpdb->prepare("$query ", $values));
84
-
85
- echo json_encode(array('status' => 'success'));
 
 
 
 
 
 
86
  exit;
87
  }
88
 
65
  }
66
  }
67
  }
68
+
69
+ if( WCL_Plugin::app()->getPrefix() . 'freemius_activated_addons' == $option_name ) {
70
+ $option_value = serialize( $option_value );
71
+ }
72
+
73
 
74
  array_push($values, $option_name, $option_value);
75
  $place_holders[] = "('%s', '%s')";/* In my case, i know they will always be integers */
83
 
84
  // Сбрасываем кеш опций
85
  WCL_Plugin::app()->flushOptionsCache();
86
+ wp_cache_flush(); // сброс объектного кеша WP
87
 
88
  // Импортируем опции
89
  $wpdb->query($wpdb->prepare("$query ", $values));
90
+ $send_data = array( 'status' => 'success' );
91
+
92
+ $package_plugin = WCL_Package::instance();
93
+ $send_data['updateNotice'] = $package_plugin->getUpdateNotice();
94
+
95
+ do_action('wbcr_clearfy_imported_settings');
96
+
97
+ wp_send_json( $send_data );
98
  exit;
99
  }
100
 
admin/ajax/install-addons.php ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Ajax plugin configuration
4
+ * @author Webcraftic <wordpress.webraftic@gmail.com>
5
+ * @copyright (c) 2017 Webraftic Ltd
6
+ * @version 1.0
7
+ */
8
+
9
+ // Exit if accessed directly
10
+ if( !defined('ABSPATH') ) {
11
+ exit;
12
+ }
13
+
14
+ /**
15
+ * This action allows you to process Ajax requests to activate external components Clearfy
16
+ */
17
+ function wbcr_clearfy_update_component()
18
+ {
19
+ check_ajax_referer('updates');
20
+
21
+ $slug = WCL_Plugin::app()->request->post('plugin', null, true);
22
+ $action = WCL_Plugin::app()->request->post('plugin_action', null, true);
23
+ $storage = WCL_Plugin::app()->request->post('storage', null, true);
24
+
25
+ if( !current_user_can('activate_plugins') ) {
26
+ wp_send_json_error(array('errorMessage' => __('You don\'t have enough capability to edit this information.', 'clearfy')), 403);
27
+ }
28
+
29
+ if( empty($slug) || empty($action) ) {
30
+ wp_send_json_error(array('errorMessage' => __('Required attributes are not passed or empty.', 'clearfy')));
31
+ }
32
+ $success = false;
33
+ $send_data = array();
34
+
35
+ if( $storage == 'freemius' ) {
36
+ $licensing = WCL_Licensing::instance();
37
+ $result = false;
38
+
39
+ switch( $action ) {
40
+ /*case 'install':
41
+ $result = $licensing->installAddon($slug);
42
+ break;
43
+ case 'delete':
44
+ $result = $licensing->deleteAddon($slug);
45
+ break;*/
46
+ case 'deactivate':
47
+ $result = $licensing->deactivateAddon($slug);
48
+ break;
49
+ case 'activate':
50
+ $result = $licensing->activateAddon($slug);
51
+ break;
52
+ default:
53
+ wp_send_json_error(array('errorMessage' => __('You are trying to perform an invalid action.', 'clearfy')));
54
+ break;
55
+ }
56
+
57
+ if( is_wp_error($result) ) {
58
+ wp_send_json_error(array('errorMessage' => $result->get_error_message()));
59
+ } else {
60
+ $success = true;
61
+ $package_plugin = WCL_Package::instance();
62
+ $send_data['updateNotice'] = $package_plugin->getUpdateNotice();
63
+ }
64
+ } else if( $storage == 'internal' ) {
65
+
66
+ if( $action == 'activate' ) {
67
+ if( WCL_Plugin::app()->activateComponent($slug) ) {
68
+ $success = true;
69
+
70
+ }
71
+ } else if( $action == 'deactivate' ) {
72
+
73
+ if( WCL_Plugin::app()->deactivateComponent($slug) ) {
74
+ $success = true;
75
+ }
76
+ } else {
77
+ wp_send_json_error(array('errorMessage' => __('You are trying to perform an invalid action.', 'clearfy')));
78
+ }
79
+ } else if( $storage == 'wordpress' ) {
80
+ if( !empty($slug) ) {
81
+ if( $action == 'activate' ) {
82
+ $result = activate_plugin($slug);
83
+ if( is_wp_error($result) ) {
84
+ wp_send_json_error(array('errorMessage' => $result->get_error_message()));
85
+ }
86
+ } elseif( $action == 'deactivate' ) {
87
+ deactivate_plugins($slug);
88
+ }
89
+
90
+ $success = true;
91
+ }
92
+ }
93
+
94
+ if( $action == 'install' || $action == 'deactivate' ) {
95
+ try {
96
+ // Delete button
97
+ $delete_button = WCL_Plugin::app()->getDeleteComponentsButton($storage, $slug);
98
+ $send_data['delete_button'] = $delete_button->getButton();
99
+ } catch( Exception $e ) {
100
+ wp_send_json_error(array('errorMessage' => $e->getMessage()));
101
+ }
102
+ }
103
+
104
+ if($success) {
105
+ do_action('wbcr_clearfy_update_component', $slug, $action, $storage);
106
+
107
+ wp_send_json_success($send_data);
108
+ }
109
+
110
+ wp_send_json_error(array('errorMessage' => __('An unknown error occurred during the activation of the component.', 'clearfy')));
111
+ }
112
+
113
+ add_action('wp_ajax_wbcr-clearfy-update-component', 'wbcr_clearfy_update_component');
admin/ajax/update-package.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Ajax plugin configuration
4
+ * @author Webcraftic <wordpress.webraftic@gmail.com>
5
+ * @copyright (c) 2017 Webraftic Ltd
6
+ * @version 1.0
7
+ */
8
+
9
+ // Exit if accessed directly
10
+ if( !defined('ABSPATH') ) {
11
+ exit;
12
+ }
13
+
14
+ /**
15
+ * This action allows you to process Ajax requests to activate external components Clearfy
16
+ */
17
+ function wbcr_clearfy_update_package() {
18
+
19
+ check_ajax_referer( 'package' );
20
+
21
+ $licensing = WCL_Licensing::instance();
22
+ $licensing->getAddons( true ); // обновляем список аддонов
23
+ $package_plugin = WCL_Package::instance();
24
+ if ( ! $licensing->isLicenseValid() and $licensing->isActivePaidAddons() ) {
25
+ wp_send_json_error(array('msg' => __( 'To use premium components, you need activate a license!', 'clearfy' ) . '<a href="admin.php?page=license-wbcr_clearfy" class="btn btn-gold">' . __( 'Activate license', 'clearfy' ) . '</a>'));
26
+ }
27
+ $result = $package_plugin->update();
28
+
29
+ if ( is_wp_error( $result ) ) {
30
+ wp_send_json_error( array(
31
+ 'msg' => __($result->get_error_message(), 'clearfy'),
32
+ 'code' => __($result->get_error_code(), 'clearfy'),
33
+ ) );
34
+ }
35
+ $success = true;
36
+ $data = array();
37
+ $data['msg'] = __( 'Configuration updated.', 'clearfy' );
38
+ $data['result'] = $result;
39
+ if($success) {
40
+ do_action('wbcr_clearfy_package_updated', $package_plugin->getSlugs());
41
+
42
+ wp_send_json_success( $data );
43
+ }
44
+
45
+ wp_send_json_error(array('errorMessage' => __('An unknown error occurred during the activation of the component.', 'clearfy')));
46
+ }
47
+
48
+ add_action('wp_ajax_wbcr-clearfy-update-package', 'wbcr_clearfy_update_package');
admin/assets/css/components.css CHANGED
@@ -6,6 +6,9 @@
6
  #WBCR .wbcr-clearfy-components {
7
  padding: 20px;
8
  }
 
 
 
9
  #WBCR .wbcr-clearfy-components .plugin-card .plugin-card-top {
10
  min-height: 163px;
11
  }
@@ -20,14 +23,44 @@
20
  #WBCR .wbcr-clearfy-components .plugin-card .install-now {
21
  float: right;
22
  }
 
 
 
 
 
 
 
 
 
 
23
  #WBCR .wbcr-clearfy-components .plugin-card a.open-plugin-details-modal {
24
  color: #5c5d5f;
25
  text-decoration: none;
26
  font-weight: 600;
27
  font-size: 15px;
28
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  #WBCR .wbcr-clearfy-components .plugin-card.plugin-status-deactive {
30
- background-color: #f9f2f1;
31
  }
32
  #WBCR .wbcr-clearfy-components .plugin-card.plugin-status-deactive a.open-plugin-details-modal {
33
  color: #ababab;
@@ -41,3 +74,6 @@
41
  #WBCR .wbcr-clearfy-components .plugin-card.plugin-status-deactive .desc {
42
  color: #afafaf;
43
  }
 
 
 
6
  #WBCR .wbcr-clearfy-components {
7
  padding: 20px;
8
  }
9
+ #WBCR .wbcr-clearfy-components .plugin-card {
10
+ position: relative;
11
+ }
12
  #WBCR .wbcr-clearfy-components .plugin-card .plugin-card-top {
13
  min-height: 163px;
14
  }
23
  #WBCR .wbcr-clearfy-components .plugin-card .install-now {
24
  float: right;
25
  }
26
+ #WBCR .wbcr-clearfy-components .plugin-card .delete-now {
27
+ float: right;
28
+ margin-left: 5px;
29
+ }
30
+ #WBCR .wbcr-clearfy-components .plugin-card .delete-now .dashicons,
31
+ #WBCR .wbcr-clearfy-components .plugin-card .delete-now .dashicons-before:before {
32
+ font-size: 16px !important;
33
+ line-height: 1.5 !important;
34
+ color: #62696f;
35
+ }
36
  #WBCR .wbcr-clearfy-components .plugin-card a.open-plugin-details-modal {
37
  color: #5c5d5f;
38
  text-decoration: none;
39
  font-weight: 600;
40
  font-size: 15px;
41
  }
42
+ #WBCR .wbcr-clearfy-components .plugin-card .premium-ribbon {
43
+ position: absolute;
44
+ top: 10px;
45
+ right: 0;
46
+ height: 30px;
47
+ width: 120px;
48
+ border-radius: 3px 0 0 3px;
49
+ background-color: #f7dea9;
50
+ color: #67532f;
51
+ text-align: center;
52
+ font-size: 12px;
53
+ font-weight: 600;
54
+ line-height: 2.4;
55
+ text-transform: uppercase;
56
+ z-index: 1;
57
+ }
58
+ #WBCR .wbcr-clearfy-components .plugin-card.premium {
59
+ border-color: #e8d7b2;
60
+ background-color: #fff9eb;
61
+ }
62
  #WBCR .wbcr-clearfy-components .plugin-card.plugin-status-deactive {
63
+ background-color: #f1f1f1;
64
  }
65
  #WBCR .wbcr-clearfy-components .plugin-card.plugin-status-deactive a.open-plugin-details-modal {
66
  color: #ababab;
74
  #WBCR .wbcr-clearfy-components .plugin-card.plugin-status-deactive .desc {
75
  color: #afafaf;
76
  }
77
+ #WBCR .wbcr-clearfy-components .plugin-card.plugin-status-deactive.premium {
78
+ background-color: #f9f2f1;
79
+ }
admin/assets/css/components.less CHANGED
@@ -8,6 +8,7 @@
8
  .wbcr-clearfy-components {
9
  padding: 20px;
10
  .plugin-card {
 
11
 
12
  .plugin-card-top {
13
  min-height: 163px;
@@ -25,6 +26,16 @@
25
  float: right;
26
  }
27
 
 
 
 
 
 
 
 
 
 
 
28
  a.open-plugin-details-modal {
29
  color: #5c5d5f;
30
  text-decoration: none;
@@ -32,8 +43,32 @@
32
  font-size: 15px;
33
  }
34
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  &.plugin-status-deactive {
36
- background-color: #f9f2f1;
 
37
 
38
  a.open-plugin-details-modal {
39
  color: #ababab;
@@ -49,8 +84,8 @@
49
  color: #afafaf;
50
  }
51
 
52
- .button-success {
53
-
54
  }
55
  }
56
  }
8
  .wbcr-clearfy-components {
9
  padding: 20px;
10
  .plugin-card {
11
+ position: relative;
12
 
13
  .plugin-card-top {
14
  min-height: 163px;
26
  float: right;
27
  }
28
 
29
+ .delete-now {
30
+ float: right;
31
+ margin-left: 5px;
32
+ .dashicons, .dashicons-before:before {
33
+ font-size: 16px !important;
34
+ line-height: 1.5 !important;
35
+ color: #62696f;
36
+ }
37
+ }
38
+
39
  a.open-plugin-details-modal {
40
  color: #5c5d5f;
41
  text-decoration: none;
43
  font-size: 15px;
44
  }
45
 
46
+ // Premium
47
+ .premium-ribbon {
48
+ position: absolute;
49
+ top: 10px;
50
+ right: 0;
51
+ height: 30px;
52
+ width: 120px;
53
+ border-radius: 3px 0 0 3px;
54
+ background-color: #f7dea9;
55
+ color: #67532f;
56
+ text-align: center;
57
+ font-size: 12px;
58
+ font-weight: 600;
59
+ line-height: 2.4;
60
+ text-transform: uppercase;
61
+ z-index: 1;
62
+ }
63
+
64
+ &.premium {
65
+ border-color: #e8d7b2;
66
+ background-color: #fff9eb;
67
+ }
68
+
69
  &.plugin-status-deactive {
70
+ background-color: #f1f1f1;
71
+ //background-color: #f9f2f1;
72
 
73
  a.open-plugin-details-modal {
74
  color: #ababab;
84
  color: #afafaf;
85
  }
86
 
87
+ &.premium {
88
+ background-color: #f9f2f1;
89
  }
90
  }
91
  }
admin/assets/css/general.css CHANGED
@@ -3,6 +3,14 @@
3
  * @author Alex Kovalev <alex.kovalevv@gmail.com>
4
  * @copyright Alex Kovalev 23.08.2017
5
  */
 
 
 
 
 
 
 
 
6
  #WBCR .wbcr-content-section,
7
  #WBCR .wbcr-right-sidebar-section {
8
  display: inline-block;
@@ -15,6 +23,35 @@
15
  width: 49%;
16
  padding-top: 20px;
17
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  #WBCR .wbcr-clearfy-group-header {
19
  background: #efefef;
20
  padding: 20px 0 10px 20px;
@@ -41,6 +78,57 @@
41
  #WBCR #wbcr-clearfy-quick-mode-board h4 {
42
  margin-top: 30px;
43
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
  #WBCR .wbcr-clearfy-switch-success-message,
45
  #WBCR .wbcr-clearfy-switch-error-message {
46
  display: none;
3
  * @author Alex Kovalev <alex.kovalevv@gmail.com>
4
  * @copyright Alex Kovalev 23.08.2017
5
  */
6
+ #WBCR {
7
+ /**
8
+ * Widgets
9
+ */
10
+ /**
11
+ * Navigation bar
12
+ */
13
+ }
14
  #WBCR .wbcr-content-section,
15
  #WBCR .wbcr-right-sidebar-section {
16
  display: inline-block;
23
  width: 49%;
24
  padding-top: 20px;
25
  }
26
+ #WBCR #wbcr-clr-go-to-premium-widget .wbcr-clr-purchase-premium {
27
+ position: relative;
28
+ text-decoration: none;
29
+ font-weight: bold;
30
+ background: #fffaea;
31
+ padding: 0;
32
+ border-radius: 4px;
33
+ outline: none;
34
+ margin-top: 15px;
35
+ box-shadow: 0 0 8px #fddf67;
36
+ }
37
+ #WBCR #wbcr-clr-go-to-premium-widget .wbcr-clr-purchase-premium .fa {
38
+ position: relative;
39
+ margin-right: 3px;
40
+ margin-left: 3px;
41
+ }
42
+ #WBCR .wbcr-factory-left-navigation-bar #components-wbcr_clearfy-tab {
43
+ border-left: 5px solid #7edbff;
44
+ }
45
+ #WBCR .wbcr-factory-left-navigation-bar #license-wbcr_clearfy-tab {
46
+ border-left: 5px solid #ffd762;
47
+ }
48
+ #WBCR .wbcr-factory-left-navigation-bar .wbcr-factory-active-tab #license-wbcr_clearfy-tab {
49
+ font-weight: lighter;
50
+ color: #222;
51
+ }
52
+ #WBCR .wbcr-factory-left-navigation-bar .wbcr-factory-active-tab #license-wbcr_clearfy-tab .dashicons-admin-network {
53
+ color: #222;
54
+ }
55
  #WBCR .wbcr-clearfy-group-header {
56
  background: #efefef;
57
  padding: 20px 0 10px 20px;
78
  #WBCR #wbcr-clearfy-quick-mode-board h4 {
79
  margin-top: 30px;
80
  }
81
+ #WBCR .wbcr-clearfy-fake-image-optimizer-board .wbcr-clearfy-fake-widget {
82
+ position: relative;
83
+ width: 659px;
84
+ height: 250px;
85
+ }
86
+ #WBCR .wbcr-clearfy-fake-image-optimizer-board .wbcr-clearfy-fake-widget .wbcr-clr-proccess-button {
87
+ opacity: 0;
88
+ position: absolute;
89
+ top: 50%;
90
+ left: 50%;
91
+ margin: -25px 0 0 -100px;
92
+ width: 200px;
93
+ height: 50px;
94
+ font-size: 16px;
95
+ font-weight: bold;
96
+ text-align: center;
97
+ line-height: 3;
98
+ background: #fdd599 !important;
99
+ color: #a57b3c !important;
100
+ text-decoration: none !important;
101
+ text-shadow: none !important;
102
+ box-shadow: none !important;
103
+ border: 1px solid #e0c08f !important;
104
+ border-radius: 3px;
105
+ outline: none;
106
+ -webkit-transition: opacity 1000ms;
107
+ -moz-transition: opacity 1000ms;
108
+ -o-transition: opacity 1000ms;
109
+ transition: opacity 1000ms;
110
+ }
111
+ #WBCR .wbcr-clearfy-fake-image-optimizer-board .wbcr-clearfy-fake-widget:hover .wbcr-clr-proccess-button {
112
+ display: block;
113
+ opacity: 1;
114
+ }
115
+ #WBCR .wbcr-clearfy-fake-image-optimizer-board .wbcr-clearfy-fake-widget:hover .wbcr-clearfy-widget-overlay img {
116
+ /* display: block;
117
+ position: absolute;
118
+ top: 0;
119
+ left: 0;
120
+ bottom: 0;
121
+ right: 0;
122
+ content: '';*/
123
+ opacity: 0.2;
124
+ }
125
+ #WBCR .wbcr-clearfy-fake-image-optimizer-board .wbcr-clearfy-fake-widget .wbcr-clearfy-widget-overlay img {
126
+ width: 100%;
127
+ -webkit-transition: opacity 500ms;
128
+ -moz-transition: opacity 500ms;
129
+ -o-transition: opacity 500ms;
130
+ transition: opacity 500ms;
131
+ }
132
  #WBCR .wbcr-clearfy-switch-success-message,
133
  #WBCR .wbcr-clearfy-switch-error-message {
134
  display: none;
admin/assets/css/install-addons.css ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Install addons global styles
3
+ * @author Webcraftic <wordpress.webraftic@gmail.com>
4
+ * @copyright Webcraftic 11.07.2018
5
+ */
6
+ .wbcr-clr-new-component {
7
+ background: #f7f7f7;
8
+ border: 1px solid #eaeaea;
9
+ padding: 5px 20px;
10
+ margin-bottom: 10px;
11
+ }
12
+ .wbcr-clr-new-component h4 {
13
+ margin: 5px 0;
14
+ display: inline-block;
15
+ }
16
+ .wbcr-clr-new-component .wbcr-clr-proccess-button {
17
+ display: inline-block;
18
+ margin: 5px 0;
19
+ }
20
+ .wbcr-clr-new-component.wbcr-clr-premium {
21
+ background: #fff6db;
22
+ border: 1px solid #e4dea9;
23
+ }
24
+ .wbcr-clr-new-component.wbcr-clr-premium h4 {
25
+ color: #88690c;
26
+ }
27
+ .wbcr-clr-proccess-button.button-link,
28
+ .wbcr-clr-proccess-button.button-link:focus {
29
+ outline: none !important;
30
+ box-shadow: none !important;
31
+ }
admin/assets/css/install-addons.less ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Install addons global styles
3
+ * @author Webcraftic <wordpress.webraftic@gmail.com>
4
+ * @copyright Webcraftic 11.07.2018
5
+ */
6
+
7
+ .wbcr-clr-new-component {
8
+ background: #f7f7f7;
9
+ border: 1px solid #eaeaea;
10
+ padding: 5px 20px;
11
+ margin-bottom: 10px;
12
+
13
+ h4 {
14
+ margin: 5px 0;
15
+ display: inline-block;
16
+ }
17
+
18
+ .wbcr-clr-proccess-button {
19
+ display: inline-block;
20
+ margin: 5px 0;
21
+ }
22
+
23
+ &.wbcr-clr-premium {
24
+ background: #fff6db;
25
+ border: 1px solid #e4dea9;
26
+
27
+ h4 {
28
+ color: #88690c;
29
+ }
30
+ }
31
+ }
32
+
33
+ .wbcr-clr-proccess-button {
34
+ &.button-link, &.button-link:focus {
35
+ outline: none !important;
36
+ box-shadow: none !important;
37
+ }
38
+ }
admin/assets/css/license-manager.css ADDED
@@ -0,0 +1,659 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ .not-visible-in-manager {
3
+ display: none;
4
+ }
5
+
6
+ /**
7
+ * Global License Message
8
+ */
9
+ .global-license-message {
10
+ width: 600px;
11
+ margin: auto;
12
+ /*margin-top: 100px;*/
13
+ font-size: 14px;
14
+ line-height: 170%;
15
+ }
16
+
17
+ .global-license-message h2, .global-license-message h3 {
18
+ padding: 0px;
19
+ margin: 5px 0;
20
+ }
21
+
22
+ .onp-page-wrap {
23
+ max-width: 720px;
24
+ margin: auto;
25
+ margin-top: 40px;
26
+ font-size: 14px;
27
+ line-height: 170%;
28
+ }
29
+
30
+ .onp-container {
31
+ border: 0px;
32
+ padding: 0px;
33
+ border-radius: 5px;
34
+ background: rgb(255, 255, 255) !important;
35
+ box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);
36
+ -moz-box-sizing: border-box;
37
+ box-sizing: border-box;
38
+ }
39
+
40
+ #license-manager .onp-container {
41
+ background: -moz-linear-gradient(top, rgba(255, 255, 255, 1) 63%, rgba(246, 246, 246, 1) 100%); /* FF3.6+ */
42
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(63%, rgba(255, 255, 255, 1)), color-stop(100%, rgba(246, 246, 246, 1))); /* Chrome,Safari4+ */
43
+ background: -webkit-linear-gradient(top, rgba(255, 255, 255, 1) 63%, rgba(246, 246, 246, 1) 100%); /* Chrome10+,Safari5.1+ */
44
+ background: -o-linear-gradient(top, rgba(255, 255, 255, 1) 63%, rgba(246, 246, 246, 1) 100%); /* Opera 11.10+ */
45
+ background: -ms-linear-gradient(top, rgba(255, 255, 255, 1) 63%, rgba(246, 246, 246, 1) 100%); /* IE10+ */
46
+ background: linear-gradient(to bottom, rgba(255, 255, 255, 1) 63%, rgba(246, 246, 246, 1) 100%); /* W3C */
47
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#f6f6f6', GradientType=0); /* IE6-9 */
48
+ }
49
+
50
+ .onp-container h2 {
51
+ margin: 0px;
52
+ padding: 0px;
53
+ }
54
+
55
+ .onp-container p {
56
+ margin: 0 0 2px 0;
57
+ padding: 0px;
58
+ line-height: 170%;
59
+ }
60
+
61
+ .btn-uppercase {
62
+ font-size: 12px;
63
+ letter-spacing: 1px;
64
+ text-transform: uppercase;
65
+ text-decoration: none;
66
+ }
67
+
68
+ .btn-uppercase *[class^=icon] {
69
+ position: relative;
70
+ top: -1px;
71
+ left: -1px;
72
+ }
73
+
74
+ .onp-page-wrap .license-message {
75
+ margin-bottom: 20px;
76
+ overflow: hidden;
77
+ }
78
+
79
+ .onp-page-wrap .license-message .alert {
80
+ margin: 0px;
81
+ }
82
+
83
+ .onp-page-wrap .license-message strong {
84
+ display: block;
85
+ margin-bottom: 0px;
86
+ }
87
+
88
+ .onp-page-wrap .license-message p {
89
+ margin: 1px 0 1px 0;
90
+ padding: 0px;
91
+ }
92
+
93
+ .onp-page-wrap .license-message a {
94
+ font-weight: bold;
95
+ }
96
+
97
+ .license-message .alert-warning-icon {
98
+ padding-left: 60px;
99
+ background-image: url("../img/warning.png");
100
+ background-position: 15px 11px;
101
+ background-repeat: no-repeat;
102
+ }
103
+
104
+ #onp-hide-license-manager {
105
+ position: absolute;
106
+ top: 2px;
107
+ right: 15px;
108
+ font-size: 12px;
109
+ color: #777;
110
+ font-weight: bold;
111
+ }
112
+
113
+ #onp-hide-license-manager:hover {
114
+ text-decoration: none;
115
+ }
116
+
117
+ #onp-hide-license-manager,
118
+ #onp-hide-license-manager:focus,
119
+ #onp-hide-license-manager:hover {
120
+ outline: none;
121
+ border: 0px;
122
+ box-shadow: none;
123
+ }
124
+
125
+ #onp-hide-license-manager .fa {
126
+ margin-right: 5px;
127
+ }
128
+
129
+ #license-manager .license-details-wrap {
130
+ border: 1px solid #e9e9e9;
131
+ padding: 0px;
132
+ border-radius: 5px;
133
+
134
+ background: rgb(255, 255, 255); /* Old browsers */
135
+ background: -moz-linear-gradient(top, rgba(255, 255, 255, 1) 63%, rgba(246, 246, 246, 1) 100%); /* FF3.6+ */
136
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(63%, rgba(255, 255, 255, 1)), color-stop(100%, rgba(246, 246, 246, 1))); /* Chrome,Safari4+ */
137
+ background: -webkit-linear-gradient(top, rgba(255, 255, 255, 1) 63%, rgba(246, 246, 246, 1) 100%); /* Chrome10+,Safari5.1+ */
138
+ background: -o-linear-gradient(top, rgba(255, 255, 255, 1) 63%, rgba(246, 246, 246, 1) 100%); /* Opera 11.10+ */
139
+ background: -ms-linear-gradient(top, rgba(255, 255, 255, 1) 63%, rgba(246, 246, 246, 1) 100%); /* IE10+ */
140
+ background: linear-gradient(to bottom, rgba(255, 255, 255, 1) 63%, rgba(246, 246, 246, 1) 100%); /* W3C */
141
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#f6f6f6', GradientType=0); /* IE6-9 */
142
+
143
+ box-shadow: 0px 2px 1px #c9c9c9;
144
+ }
145
+
146
+ #license-manager .activate-trial-hint {
147
+ background-color: #f8f8f8;
148
+ padding: 10px 20px;
149
+ position: relative;
150
+ -moz-box-sizing: content-box;
151
+ box-sizing: content-box;
152
+ }
153
+
154
+ #license-manager .activate-error-hint {
155
+ background-color: #fb7976;
156
+ color: #f5f5f5;
157
+ text-shadow: none;
158
+ padding: 2px 9px;
159
+ width: 100%;
160
+ position: relative;
161
+ margin-left: -9px;
162
+ -moz-box-sizing: content-box;
163
+ box-sizing: content-box;
164
+ }
165
+
166
+ #license-manager .license-details {
167
+ padding: 20px;
168
+ padding-bottom: 0px;
169
+ -webkit-border-top-left-radius: 5px;
170
+ -webkit-border-top-right-radius: 5px;
171
+ -moz-border-radius-topleft: 5px;
172
+ -moz-border-radius-topright: 5px;
173
+ border-top-left-radius: 5px;
174
+ border-top-right-radius: 5px;
175
+
176
+ position: relative;
177
+ z-index: 10;
178
+ }
179
+
180
+ #license-manager .license-key-identity {
181
+ font-style: italic;
182
+ position: relative;
183
+ top: -6px;
184
+ }
185
+
186
+ #license-manager .license-key-identity code {
187
+ display: inline-block;
188
+ padding:2px 5px;
189
+ font-size: 16px;
190
+ }
191
+
192
+ #license-manager .license-key-description {
193
+ font-size: 12px;
194
+ }
195
+
196
+ #license-manager .license-delete-button {
197
+ float: right;
198
+ text-decoration: none;
199
+ position: relative;
200
+ top: -7px;
201
+ left: 10px;
202
+ }
203
+
204
+ #license-manager .license-synchronization-button {
205
+ float: right;
206
+ text-decoration: none;
207
+ position: relative;
208
+ top: -7px;
209
+ left: 5px;
210
+ }
211
+
212
+ #license-manager .license-details-block {
213
+ padding: 28px 35px 15px 35px;
214
+ margin-left: -35px;
215
+ width: 100%;
216
+ position: relative;
217
+ margin-top: 20px;
218
+
219
+ background: #fff;
220
+ border: 0px;
221
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
222
+ color: #333;
223
+
224
+ border-radius: 5px;
225
+
226
+ -webkit-box-sizing: content-box;
227
+ -moz-box-sizing: content-box;
228
+ box-sizing: content-box;
229
+ }
230
+
231
+ #license-manager .license-details-block p + p {
232
+ margin-top: 10px;
233
+ }
234
+
235
+ #license-manager .license-details-block a {
236
+ font-weight: bold;
237
+ }
238
+
239
+ #license-manager .license-details-block.trial-details-block {
240
+ background: #ffdede;
241
+
242
+ border: 0;
243
+ box-shadow: 0 0 7px #cf4944;
244
+ color: #a04342;
245
+ text-shadow: 1px 1px 2px #fff2f2;
246
+ }
247
+
248
+ #license-manager .license-details-block.trial-details-block a {
249
+ color: #a04342;
250
+ }
251
+
252
+ #license-manager .license-details-block.paid-details-block {
253
+ border: 0;
254
+ box-shadow: 0 0 7px #b8823b;
255
+ color: #8a6d3b;
256
+ background: #fcf8e3;
257
+ }
258
+
259
+ #license-manager .license-details-block.paid-details-block a {
260
+ color: #7a4c00;
261
+ }
262
+
263
+ #license-manager .license-details-block.gift-details-block {
264
+ background: #DFF0D8;
265
+ border: 1px solid #D6E9C6;
266
+ box-shadow: 0px 0px 5px #D6E9C6;
267
+ color: #468847;
268
+ }
269
+
270
+ #license-manager .license-details-block.gift-details-block a {
271
+ color: #468847;
272
+ }
273
+
274
+ #license-manager .license-params {
275
+ margin-top: 15px;
276
+ position: relative;
277
+ left: -2px;
278
+ }
279
+
280
+ #license-manager .license-value {
281
+ display: block;
282
+ font-size: 16px;
283
+ font-weight: bold;
284
+ }
285
+
286
+ #license-manager .license-value small {
287
+ font-weight: normal;
288
+ }
289
+
290
+ #license-manager .license-value-name {
291
+ display: block;
292
+ font-size: 12px;
293
+ }
294
+
295
+ #license-manager .license-param {
296
+ white-space: nowrap;
297
+ line-height: 130%;
298
+ padding: 10px 0 10px 35px;
299
+ vertical-align: top;
300
+ }
301
+
302
+ #license-manager .license-param-domain {
303
+ padding-left: 65px;
304
+ background: url('../img/free-license-chip.png') -3px 0px no-repeat;
305
+ }
306
+
307
+ #license-manager .trial-details-block .license-param-domain {
308
+ background: url('../img/trial-license-chip.png') -3px 0px no-repeat;
309
+ }
310
+
311
+ #license-manager .paid-details-block .license-param-domain {
312
+ background: url('../img/paid-license-chip.png') -3px 0px no-repeat;
313
+ }
314
+
315
+ #license-manager .license-details-block h3 {
316
+ margin: 0px;
317
+ padding: 0px;
318
+ font-size: 22px;
319
+ margin-bottom: 10px;
320
+ }
321
+
322
+ #license-manager .license-details-block a {
323
+ color: #a04342;
324
+ }
325
+
326
+ #license-manager .license-input {
327
+
328
+ padding: 20px;
329
+ -webkit-border-bottom-right-radius: 5px;
330
+ -webkit-border-bottom-left-radius: 5px;
331
+ -moz-border-radius-bottomright: 5px;
332
+ -moz-border-radius-bottomleft: 5px;
333
+ border-bottom-right-radius: 5px;
334
+ border-bottom-left-radius: 5px;
335
+ }
336
+
337
+ #license-manager .license-input .btn {
338
+ text-decoration: none;
339
+ }
340
+
341
+ #license-manager .license-key-wrap {
342
+ padding-right: 110px;
343
+ }
344
+
345
+ #license-key {
346
+ width: 100%;
347
+ position: relative;
348
+ font-size: 18px;
349
+ line-height: 20px;
350
+ position: relative;
351
+ top: -1px;
352
+ height: 36px;
353
+ color: #000;
354
+ }
355
+
356
+ #license-submit {
357
+ float: right;
358
+ padding: 7px 14px 6px 14px;
359
+ }
360
+
361
+ #plugin-update-block {
362
+ padding-top: 10px;
363
+ font-size: 10px;
364
+ color: #666;
365
+ max-width: 700px;
366
+ margin: auto;
367
+ }
368
+
369
+ #plugin-update-block a {
370
+ color: #000;
371
+ }
372
+
373
+ .purchase-premium {
374
+ float: right;
375
+ position: relative;
376
+ top: -11px;
377
+ left: 8px;
378
+ text-decoration: none;
379
+ font-weight: bold;
380
+ background: #fffaea;
381
+ padding: 0px;
382
+ border-radius: 4px;
383
+ outline: none;
384
+ margin-top: 4px;
385
+ box-shadow: 0 0 8px #fddf67;
386
+ }
387
+
388
+ .purchase-premium .fa {
389
+ position: relative;
390
+ margin-right: 3px;
391
+ margin-left: 3px;
392
+ }
393
+
394
+ /*
395
+ * Manual Trial Activation
396
+ */
397
+ #trial-manual .onp-container {
398
+ padding: 20px;
399
+ overflow: hidden;
400
+ }
401
+
402
+ #trial-manual ul {
403
+ margin: 0px;
404
+ padding: 0px;
405
+ margin-top: 10px;
406
+ }
407
+
408
+ #trial-manual ul li {
409
+ margin-bottom: 10px;
410
+ }
411
+
412
+ #trial-manual .license-reponse-code {
413
+ width: 100%;
414
+ height: 150px;
415
+ margin-top: 5px;
416
+ }
417
+
418
+ /*
419
+ * Manual Key Activation
420
+ */
421
+ #activate-key-manual .onp-container {
422
+ padding: 20px;
423
+ overflow: hidden;
424
+ }
425
+
426
+ #activate-key-manual ul {
427
+ margin: 0px;
428
+ padding: 0px;
429
+ margin-top: 10px;
430
+ }
431
+
432
+ #activate-key-manual ul li {
433
+ margin-bottom: 10px;
434
+ }
435
+
436
+ #activate-key-manual .license-reponse-code {
437
+ width: 100%;
438
+ height: 150px;
439
+ margin-top: 5px;
440
+ }
441
+
442
+ /**
443
+ * FAQ
444
+ */
445
+
446
+ #faq-block {
447
+ border-top: 1px solid #d7d7d7;
448
+
449
+ margin-top: 20px;
450
+ width: 100%;
451
+
452
+ padding: 10px 20px;
453
+ position: relative;
454
+ }
455
+
456
+ #faq-block .faq-header {
457
+ border-bottom: 1px dotted #333;
458
+ display: inline-block;
459
+ cursor: pointer;
460
+ font-weight: bold;
461
+ line-height: 16px;
462
+ font-size: 13px;
463
+ color: #333;
464
+ }
465
+
466
+ #faq-block .faq-header:hover {
467
+ border-bottom: 0px;
468
+ }
469
+
470
+ #faq-block .faq-header:focus, #faq-block .faq-header:active {
471
+ outline: 0;
472
+ }
473
+
474
+ #faq-block li > div {
475
+ display: none;
476
+ }
477
+
478
+ #faq-block p {
479
+ margin: 6px 0 10px 0;
480
+ font-size: 13px;
481
+ line-height: 170%;
482
+ }
483
+
484
+ #open-faq {
485
+ color: #000 !important;
486
+ text-decoration: none;
487
+ border-bottom: 1px dotted #000;
488
+ margin-left: 4px;
489
+ }
490
+
491
+ #open-faq:hover {
492
+ border-bottom: 0px;
493
+ }
494
+
495
+ .gray-link, .gray-link a {
496
+ color: #666666 !important;
497
+ }
498
+
499
+ /**
500
+ * A form to create a customer account
501
+ */
502
+
503
+ .onp-single-block .onp-header {
504
+ text-align: center;
505
+ padding: 10px;
506
+ }
507
+
508
+ .onp-single-block .onp-header h4 {
509
+ font-size: 26px;
510
+ line-height: 130%;
511
+ }
512
+
513
+ .onp-single-block .onp-container {
514
+ padding: 50px 60px;
515
+ border: 1px solid #bbb;
516
+ position: relative;
517
+ }
518
+
519
+ .onp-single-block .onp-container .onp-container-header {
520
+ margin-bottom: 20px;
521
+ }
522
+
523
+ .onp-single-block .onp-container .onp-container-header h4 {
524
+ color: #000;
525
+ margin: 0px;
526
+ font-size: 20px;
527
+ }
528
+
529
+ .onp-single-block .onp-container .onp-container-header .onp-key-info {
530
+ color: #666;
531
+ }
532
+
533
+ .onp-single-block .onp-container .onp-container-header .onp-key-info .fa {
534
+ color: #777;
535
+ }
536
+
537
+ .onp-single-block .onp-container .onp-container-header .onp-icon {
538
+ position: absolute;
539
+ top: 30px;
540
+ right: 30px;
541
+ }
542
+
543
+ .onp-single-block .onp-container p,
544
+ .onp-single-block .onp-container li {
545
+ color: #333;
546
+ font-size: 14px;
547
+ }
548
+
549
+ .onp-single-block .onp-container p + p {
550
+ margin-top: 15px;
551
+ }
552
+
553
+ .onp-single-block .onp-container .onp-form {
554
+ text-align: left;
555
+ padding: 10px 0 0 0;
556
+ }
557
+
558
+ .onp-single-block #email {
559
+ font-size: 26px;
560
+ line-height: 26px;
561
+ height: 50px;
562
+ }
563
+
564
+ .onp-single-block .checkbox {
565
+ padding-left: 25px;
566
+ color: #999;
567
+ font-style: italic;
568
+ }
569
+
570
+ .onp-single-block .checkbox input {
571
+ margin-left: -25px;
572
+ }
573
+
574
+ .onp-single-block .onp-actions {
575
+ padding-top: 20px;
576
+ }
577
+
578
+ .onp-single-block .onp-actions .btn-primary {
579
+ margin-right: 15px;
580
+ }
581
+
582
+ .onp-single-block .onp-actions a.onp-cancel {
583
+ text-decoration: none;
584
+ color: #111;
585
+ }
586
+
587
+ .onp-single-block .onp-actions a.onp-cancel:hover {
588
+ text-decoration: none;
589
+ border-bottom: 1px solid #111;
590
+ background-color: #f9f9f9;
591
+ }
592
+
593
+ .onp-single-block .onp-benefits {
594
+ padding-left: 25px;
595
+ margin-top: 15px;
596
+ list-style: initial;
597
+ }
598
+
599
+ .onp-single-block .onp-login-details {
600
+
601
+ }
602
+
603
+ .onp-single-block .onp-text-seporator {
604
+ border-top: 1px solid #eee;
605
+ margin: 30px 0;
606
+ }
607
+
608
+ #create-account .onp-container {
609
+ background: #fff url("../img/create-account-bg.png") no-repeat 370px 230px !important;
610
+ }
611
+
612
+ #account-created .onp-step {
613
+ overflow: hidden;
614
+ }
615
+
616
+ #account-created .onp-steps {
617
+ padding: 25px 0 20px 10px;
618
+ }
619
+
620
+ #account-created .onp-step + .onp-step {
621
+ margin-top: 20px;
622
+ }
623
+
624
+ #account-created .onp-step .onp-num {
625
+ font-size: 25px;
626
+ line-height: 40px;
627
+ background-color: #f5f5f5;
628
+ width: 40px;
629
+ height: 40px;
630
+ display: inline-block;
631
+ border-radius: 7px;
632
+ text-align: center;
633
+ -moz-box-sizing: border-box;
634
+ box-sizing: border-box;
635
+ margin-right: 10px;
636
+ vertical-align: middle;
637
+ font-weight: bolder;
638
+ font-family: Arial, sans-serif;
639
+ }
640
+
641
+ #account-created .onp-step .onp-desc {
642
+ width: 490px;
643
+ display: inline-block;
644
+ vertical-align: middle;
645
+ line-height: 150%;
646
+ }
647
+
648
+ #finish .onp-container {
649
+ background: #fff url("../img/finish.png") no-repeat 0 -90px !important;
650
+ padding-left: 260px;
651
+ min-height: 250px;
652
+
653
+ border-bottom: 3px solid #ccc;
654
+ }
655
+
656
+ .wcl-loader {
657
+ float: right;
658
+ width: 32px;
659
+ }
admin/assets/img/bind-key.png ADDED
Binary file
admin/assets/img/create-account-bg.png ADDED
Binary file
admin/assets/img/finish.png ADDED
Binary file
admin/assets/img/free-license-chip.png ADDED
Binary file
admin/assets/img/green-license-chip.png ADDED
Binary file
admin/assets/img/hlp-icon-128x128.png ADDED
Binary file
admin/assets/img/how-to-find-key.png ADDED
Binary file
admin/assets/img/key-bound-icon.png ADDED
Binary file
admin/assets/img/loader.gif ADDED
Binary file
admin/assets/img/paid-license-chip.png ADDED
Binary file
admin/assets/img/robin-image-optimizer-fake-board.png ADDED
Binary file
admin/assets/img/trial-license-chip.png ADDED
Binary file
admin/assets/img/warning.png ADDED
Binary file
admin/assets/js/general.js CHANGED
@@ -154,6 +154,22 @@
154
  }, function(data) {
155
  //console.log(data);
156
  $this.prop('disabled', false);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
157
  });
158
 
159
  return false;
154
  }, function(data) {
155
  //console.log(data);
156
  $this.prop('disabled', false);
157
+ if ( data.updateNotice ) {
158
+ if ( ! $('.wbcr-clr-update-package').length ) {
159
+ $('.wbcr-factory-content').prepend(
160
+ '<div class="alert alert-warning wbcr-factory-warning-notice">\
161
+ <p>\
162
+ <span class="dashicons dashicons-warning"></span>\
163
+ '+data.updateNotice+'\
164
+ </p>\
165
+ </div>\
166
+ ');
167
+ }
168
+ } else {
169
+ if ( $('.wbcr-clr-update-package').length ) {
170
+ $('.wbcr-clr-update-package').closest( '.wbcr-factory-warning-notice' ).remove();
171
+ }
172
+ }
173
  });
174
 
175
  return false;
admin/assets/js/install-addons.js ADDED
@@ -0,0 +1,224 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * This code provides tools for downloading, installing external add-ons for the Clearfy plugin
3
+ *
4
+ * @author Webcraftic <wordpress.webraftic@gmail.com>
5
+ * @copyright (c) 10.09.2017, Webcraftic
6
+ * @version 1.0
7
+ */
8
+
9
+
10
+ (function($) {
11
+ 'use strict';
12
+
13
+ var externalAddon = {
14
+ init: function() {
15
+ this.events();
16
+ },
17
+ events: function() {
18
+ var self = this;
19
+
20
+ /**
21
+ * This event is intended for installation, removal, activation, deactivation of external add-ons
22
+ */
23
+
24
+ $(document).on('click', '.wbcr-clr-update-component-button', function() {
25
+ var $this = $(this),
26
+ button_i18n = $(this).data('i18n'),
27
+ plugin_slug = $(this).data('slug'),
28
+ plugin_action = $(this).data('plugin-action'),
29
+ plugin = $(this).data('plugin'),
30
+ storage = $(this).data('storage'),
31
+ wpnonce = $(this).data('wpnonce');
32
+
33
+ var action = 'install-plugin';
34
+
35
+ if( storage == 'freemius' || ((storage == 'wordpress' || storage == 'internal') && (plugin_action == 'activate' || plugin_action == 'deactivate')) ) {
36
+ action = 'wbcr-clearfy-update-component';
37
+ } else if( storage == 'wordpress' && plugin_action == 'delete' ) {
38
+ action = 'delete-plugin';
39
+ }
40
+
41
+ var data = {
42
+ action: action,
43
+ slug: plugin_slug,
44
+ storage: storage,
45
+ plugin: plugin,
46
+ plugin_action: plugin_action,
47
+ _wpnonce: wpnonce
48
+ };
49
+
50
+ if( plugin_action == 'install' ) {
51
+ $this.addClass('updating-message');
52
+ }
53
+ $this.addClass('disabled').text(button_i18n.loading);
54
+
55
+ self.sendRequest(data, function(response) {
56
+ if( response.success ) {
57
+ $this.removeClass('disabled').removeClass('updating-message');
58
+ if( storage == 'freemius' ) {
59
+ if( response.data.updateNotice ) {
60
+ if( !$('.wbcr-clr-update-package').length ) {
61
+ $('.wbcr-factory-content').prepend(
62
+ '<div class="alert alert-warning wbcr-factory-warning-notice">\
63
+ <p>\
64
+ <span class="dashicons dashicons-warning"></span>\
65
+ ' + response.data.updateNotice + '\
66
+ </p>\
67
+ </div>\
68
+ ');
69
+ }
70
+ } else {
71
+ if( $('.wbcr-clr-update-package').length ) {
72
+ $('.wbcr-clr-update-package').closest('.wbcr-factory-warning-notice').remove();
73
+ }
74
+ }
75
+ }
76
+
77
+ if( plugin_action == 'install' ) {
78
+
79
+ plugin_action = 'activate';
80
+ $this.data('plugin-action', 'activate');
81
+ $this.attr('data-plugin-action', 'activate');
82
+
83
+ if( $this.hasClass('button') ) {
84
+ $this.removeClass('button-default').addClass('button-primary');
85
+ }
86
+
87
+ } else if( plugin_action == 'activate' ) {
88
+
89
+ plugin_action = 'deactivate';
90
+ $this.data('plugin-action', 'deactivate');
91
+ $this.attr('data-plugin-action', 'deactivate');
92
+
93
+ if( $this.hasClass('button') ) {
94
+ $this.removeClass('button-primary').addClass('button-default');
95
+ }
96
+
97
+ // If the button is installed inside the notification,
98
+ // then delete the button container after activating the component
99
+
100
+ if( $this.closest('.wbcr-clr-new-component').length ) {
101
+ $this.closest('.wbcr-clr-new-component').remove();
102
+ }
103
+
104
+ // If the button is installed inside the notification (inside),
105
+ // then delete the button container after activating the component
106
+
107
+ if( $this.closest('.alert').length ) {
108
+ $this.closest('.alert').remove();
109
+ }
110
+
111
+ // If the button is installed inside the notification (inside),
112
+ // then delete the button container after activating the component
113
+
114
+ if( $this.closest('.wbcr-clearfy-fake-image-optimizer-board').length ) {
115
+ $this.remove();
116
+ window.location.reload();
117
+ }
118
+
119
+ // If the button is installed on the components page,
120
+ // the active and inactive components are highlighted
121
+
122
+ if( $this.closest('.plugin-card').length ) {
123
+ $this.closest('.plugin-card').removeClass('plugin-status-deactive');
124
+ $this.closest('.plugin-card').find('.delete-now').remove();
125
+ }
126
+
127
+ } else if( plugin_action == 'deactivate' ) {
128
+
129
+ plugin_action = 'activate';
130
+ $this.data('plugin-action', 'activate');
131
+ $this.attr('data-plugin-action', 'activate');
132
+
133
+ if( $this.hasClass('button') ) {
134
+ $this.removeClass('button-default').addClass('button-primary');
135
+ }
136
+
137
+ // If the button is installed on the components page,
138
+ // the active and inactive components are highlighted
139
+
140
+ if( $this.closest('.plugin-card').length ) {
141
+ $this.closest('.plugin-card').addClass('plugin-status-deactive');
142
+
143
+ if( response.data['delete_button'] && response.data['delete_button'] != '' ) {
144
+ $this.before($(response.data['delete_button']).addClass('delete-now'));
145
+ }
146
+ }
147
+
148
+ // If the button is installed on the components page,
149
+ // the active and inactive components are highlighted
150
+ if( $this.closest('.wbcr-hide-after-action').length ) {
151
+ $this.closest('.wbcr-hide-after-action').remove();
152
+ }
153
+
154
+ } else if( plugin_action == 'delete' ) {
155
+
156
+ plugin_action = 'install';
157
+ $this.closest('.plugin-card').find('.install-now').data('plugin-action', 'install');
158
+ $this.closest('.plugin-card').find('.install-now').attr('data-plugin-action', 'install');
159
+ $this.closest('.plugin-card').find('.install-now').removeClass('button-primary').addClass('button-default');
160
+ $this.closest('.plugin-card').find('.install-now').text(button_i18n.install);
161
+
162
+ // If the button is installed on the components page,
163
+ // the active and inactive components are highlighted
164
+
165
+ if( $this.closest('.plugin-card').length ) {
166
+ $this.closest('.plugin-card').addClass('plugin-status-deactive');
167
+ $this.remove();
168
+ }
169
+ }
170
+ } else {
171
+ if( plugin_action == 'install' ) {
172
+ $this.removeClass('updating-message');
173
+ }
174
+ }
175
+
176
+ $this.text(button_i18n[plugin_action]);
177
+ });
178
+
179
+ return false;
180
+ });
181
+
182
+ $(document).on('click', '.wbcr-clr-plugin-update-link', function() {
183
+ var $this = $(this),
184
+ loading = $(this).data('loading'),
185
+ success_msg = $(this).data('ok'),
186
+ wpnonce = $(this).data('wpnonce'),
187
+ container = $this.closest('p');
188
+
189
+ var data = {
190
+ action: 'wbcr-clearfy-update-package',
191
+ _wpnonce: wpnonce
192
+ };
193
+
194
+ container.text(loading);
195
+
196
+ self.sendRequest(data, function(response) {
197
+ if( response.success ) {
198
+ container.closest('div').removeClass('notice-warning').addClass('notice-success');
199
+ container.text(success_msg);
200
+ } else {
201
+ container.text(response.data.msg);
202
+ }
203
+ });
204
+
205
+ return false;
206
+ });
207
+ },
208
+ sendRequest: function(data, callback) {
209
+ $.ajax(ajaxurl, {
210
+ type: 'post',
211
+ dataType: 'json',
212
+ data: data,
213
+ success: function(data, textStatus, jqXHR) {
214
+ callback && callback(data);
215
+ }
216
+ });
217
+ }
218
+ };
219
+
220
+ $(document).ready(function() {
221
+ externalAddon.init();
222
+ });
223
+
224
+ })(jQuery);
admin/assets/js/license-manager.js ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * General
3
+ * @author Webcraftic <wordpress.webraftic@gmail.com>
4
+ * @copyright (c) 10.09.2017, Webcraftic
5
+ * @version 1.0
6
+ */
7
+
8
+
9
+ jQuery(function($) {
10
+
11
+ $(document).on( 'click', '.wcl-control-btn', function() {
12
+ $('.wcl-control-btn').hide();
13
+ var wrapper = $('#wcl-license-wrapper');
14
+ var loader = wrapper.data('loader');
15
+ $(this).after('<img class="wcl-loader" src="'+loader+'">');
16
+ var data = {
17
+ action: 'wbcr_clr_licensing',
18
+ _wpnonce: $('#_wpnonce').val(),
19
+ license_action: $(this).data( 'action' ),
20
+ licensekey: '',
21
+ };
22
+ if ( $(this).data( 'action' ) == 'activate' ) {
23
+ data.licensekey = $('#license-key').val();
24
+ }
25
+ $.post( ajaxurl, data, function( response ) {
26
+ wrapper.html( response );
27
+ });
28
+ return false;
29
+ });
30
+
31
+ });
admin/assets/js/update-package.js ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * This code provides tools for downloading, installing external add-ons for the Clearfy plugin
3
+ *
4
+ * @author Webcraftic <wordpress.webraftic@gmail.com>
5
+ * @copyright (c) 10.09.2017, Webcraftic
6
+ * @version 1.0
7
+ */
8
+
9
+
10
+ (function($) {
11
+ 'use strict';
12
+
13
+ var clearfyPackage = {
14
+ init: function() {
15
+ this.events();
16
+ },
17
+ events: function() {
18
+ var self = this;
19
+
20
+ /**
21
+ * This event is intended for installation, removal, activation, deactivation of external add-ons
22
+ */
23
+
24
+ $(document).on('click', '.wbcr-clr-update-package', function() {
25
+ var $this = $(this),
26
+ loading = $(this).data( 'loading' ),
27
+ wpnonce = $(this).data('wpnonce');
28
+
29
+ var data = {
30
+ action: 'wbcr-clearfy-update-package',
31
+ _wpnonce: wpnonce
32
+ };
33
+
34
+ $this.addClass('disabled').text(loading);
35
+
36
+ self.sendRequest(data, function(response) {
37
+ var alert_block = $this.closest('div.alert');
38
+ if( response.success ) {
39
+ alert_block.removeClass('alert-warning').addClass('alert-success');
40
+ alert_block.find('p').html( '<span class="dashicons dashicons-plus"></span> ' + response.data.msg );
41
+ setTimeout( function() { alert_block.hide() }, 3000 );
42
+ } else {
43
+ alert_block.removeClass('alert-warning').addClass('alert-danger');
44
+ alert_block.find('p').html( '<span class="dashicons dashicons-warning"></span> ' + response.data.msg );
45
+ }
46
+ });
47
+
48
+ return false;
49
+ });
50
+ },
51
+ sendRequest: function(data, callback) {
52
+ $.ajax(ajaxurl, {
53
+ type: 'post',
54
+ dataType: 'json',
55
+ data: data,
56
+ success: function(data, textStatus, jqXHR) {
57
+ callback && callback(data);
58
+ }
59
+ });
60
+ }
61
+ };
62
+
63
+ $(document).ready(function() {
64
+ clearfyPackage.init();
65
+ });
66
+
67
+ })(jQuery);
admin/boot.php CHANGED
@@ -12,129 +12,205 @@
12
  }
13
 
14
  /**
15
- * Ошибки совместимости с похожими плагинами
 
 
16
  */
17
- function wbcr_clearfy_admin_conflict_notices_error()
18
  {
19
- $notices = array();
 
 
 
 
 
 
20
 
21
- $default_notice = WCL_Plugin::app()
22
- ->getPluginTitle() . ': ' . __('We found that you have the plugin %s installed. The functions of this plugin already exist in %s. Please deactivate plugin %s to avoid conflicts between plugins functions.', 'clearfy');
23
- $default_notice .= ' ' . __('If you do not want to deactivate the plugin %s for some reason, we strongly recommend do not use the same plugins functions at the same time!', 'clearfy');
 
 
 
 
 
 
 
 
 
 
 
24
 
25
  if( is_plugin_active('wp-disable/wpperformance.php') ) {
26
- $notices[] = sprintf($default_notice, 'WP Disable', WCL_Plugin::app()
27
- ->getPluginTitle(), 'WP Disable', 'WP Disable');
 
 
 
 
 
 
 
 
 
 
28
  }
29
 
30
- if( empty($notices) ) {
31
- return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  }
33
 
34
- ?>
35
- <div id="wbcr-clearfy-conflict-error" class="notice notice-error is-dismissible">
36
- <?php foreach((array)$notices as $notice): ?>
37
- <p>
38
- <?= $notice ?>
39
- </p>
40
- <?php endforeach; ?>
41
- </div>
42
- <?php
 
 
 
 
43
  }
44
 
45
- add_action('admin_notices', 'wbcr_clearfy_admin_conflict_notices_error');
46
 
47
  /**
48
- * Welcome guid
49
- * @param string $hook_suffix
50
  */
51
- function wbcr_enqueue_pointer_script_style($hook_suffix)
52
  {
53
- $enqueue_pointer_script_style = false;
54
- $dismissed_pointers = explode(',', get_user_meta(get_current_user_id(), 'dismissed_wp_pointers', true));
55
-
56
- if( !in_array('wbcr_clearfy_defence_pointer_1_2_0', $dismissed_pointers) || !in_array('wbcr_clearfy_settings_pointer_1_2_0', $dismissed_pointers) || !in_array('wbcr_clearfy_components_pointer_1_2_0', $dismissed_pointers) ) {
57
- $enqueue_pointer_script_style = true;
58
- add_action('admin_print_footer_scripts', 'wbcr_pointer_print_scripts');
59
- }
60
-
61
- if( $enqueue_pointer_script_style ) {
62
- wp_enqueue_style('wp-pointer');
63
- wp_enqueue_script('wp-pointer');
 
 
 
 
 
 
 
64
  }
65
  }
66
 
67
- // todo: remove in 1.2.0
68
- function wbcr_pointer_print_scripts()
 
 
 
 
 
 
 
 
69
  {
70
- $dismissed_pointers = explode(',', get_user_meta(get_current_user_id(), 'dismissed_wp_pointers', true));
71
-
72
- $pointer_setting_content = "<h3>" . sprintf(__('Welcome to Clearfy (%s)', 'clearfy'), '1.2.0') . "</h3>";
73
- $pointer_setting_content .= "<p>" . __('There are new optimization and protection features in the plugin. We recommend you to look at them maybe they will be useful!', 'clearfy') . "</p>";
74
-
75
- $pointer_performance_content = "<h3>" . __('The section "Code cleaning" was renamed', 'clearfy') . "</h3>";
76
- $pointer_performance_content .= "<p>" . __('Asynchronous Google fonts loading, Google Analytics optimization, disabling Google Fonts and Maps, disabling of gravatars, Font Awesome icons was added.', 'clearfy') . "</p>";
77
-
78
- $pointer_defence_content = "<h3>" . __('Login page protection added', 'clearfy') . "</h3>";
79
- $pointer_defence_content .= "<p>" . __('With the new Clearfy version, you can use the hide login page function. Nobody will know the address of your login page, which means there will be no password bruteforce and the attempts of your website hack will decrease.', 'clearfy') . "</p>";
80
-
81
- ?>
82
-
83
- <script type="text/javascript">
84
- //<![CDATA[
85
- jQuery(document).ready(function($) {
86
- <?php if(!in_array('wbcr_clearfy_settings_pointer_1_2_0', $dismissed_pointers)): ?>
87
- $('#menu-settings').pointer({
88
- content: '<?php echo $pointer_setting_content; ?>',
89
- position: {
90
- edge: 'left', // arrow direction
91
- align: 'center' // vertical alignment
92
- },
93
- pointerWidth: 350,
94
- close: function() {
95
- $.post(ajaxurl, {
96
- pointer: 'wbcr_clearfy_settings_pointer_1_2_0', // pointer ID
97
- action: 'dismiss-wp-pointer'
98
- });
99
- }
100
- }).pointer('open');
101
- <?php endif; ?>
102
- <?php if(!in_array('wbcr_clearfy_performance_pointer_1_2_0', $dismissed_pointers) && in_array('wbcr_clearfy_settings_pointer_1_2_0', $dismissed_pointers)): ?>
103
- $('#performance-clearfy-tab').pointer({
104
- content: '<?php echo $pointer_performance_content; ?>',
105
- position: {
106
- edge: 'left', // arrow direction
107
- align: 'center' // vertical alignment
108
- },
109
- pointerWidth: 350,
110
- close: function() {
111
- $.post(ajaxurl, {
112
- pointer: 'wbcr_clearfy_performance_pointer_1_2_0', // pointer ID
113
- action: 'dismiss-wp-pointer'
114
- });
115
- }
116
- }).pointer('open');
117
- <?php endif; ?>
118
- <?php if(!in_array('wbcr_clearfy_defence_pointer_1_2_0', $dismissed_pointers) && in_array('wbcr_clearfy_performance_pointer_1_2_0', $dismissed_pointers)): ?>
119
- $('#defence-clearfy-tab').pointer({
120
- content: '<?php echo $pointer_defence_content; ?>',
121
- position: {
122
- edge: 'left', // arrow direction
123
- align: 'center' // vertical alignment
124
- },
125
- pointerWidth: 350,
126
- close: function() {
127
- $.post(ajaxurl, {
128
- pointer: 'wbcr_clearfy_defence_pointer_1_2_0', // pointer ID
129
- action: 'dismiss-wp-pointer'
130
- });
131
- }
132
- }).pointer('open');
133
- <?php endif; ?>
134
- });
135
- //]]>
136
- </script>
137
- <?php
138
  }
139
 
140
- add_action('admin_enqueue_scripts', 'wbcr_enqueue_pointer_script_style');
 
12
  }
13
 
14
  /**
15
+ * We assets scripts in the admin panel on each page.
16
+ *
17
+ * @param $hook
18
  */
19
+ function wbcr_clearfy_enqueue_global_scripts($hook)
20
  {
21
+ wp_enqueue_style('wbcr-clearfy-install-addons', WCL_PLUGIN_URL . '/admin/assets/css/install-addons.css', array(), WCL_Plugin::app()
22
+ ->getPluginVersion());
23
+ wp_enqueue_script('wbcr-clearfy-install-addons', WCL_PLUGIN_URL . '/admin/assets/js/install-addons.js', array('jquery'), WCL_Plugin::app()
24
+ ->getPluginVersion());
25
+ }
26
+
27
+ add_action('admin_enqueue_scripts', 'wbcr_clearfy_enqueue_global_scripts');
28
 
29
+ /**
30
+ * This proposal to download new components from the team Webcraftic,
31
+ * all components are installed without reloading the page, if the components are already installed,
32
+ * then this notice will be hidden.
33
+ *
34
+ * @param $notices
35
+ * @return mixed|void
36
+ */
37
+ function wbcr_clearfy_admin_notices($notices, $plugin_name)
38
+ {
39
+
40
+ if( $plugin_name != WCL_Plugin::app()->getPluginName() ) {
41
+ return $notices;
42
+ }
43
 
44
  if( is_plugin_active('wp-disable/wpperformance.php') ) {
45
+ $default_notice = WCL_Plugin::app()
46
+ ->getPluginTitle() . ': ' . __('We found that you have the plugin %s installed. The functions of this plugin already exist in %s. Please deactivate plugin %s to avoid conflicts between plugins functions.', 'clearfy');
47
+ $default_notice .= ' ' . __('If you do not want to deactivate the plugin %s for some reason, we strongly recommend do not use the same plugins functions at the same time!', 'clearfy');
48
+
49
+ $notices[] = array(
50
+ 'id' => 'clearfy_plugin_conflicts_notice',
51
+ 'type' => 'warning',
52
+ 'dismissible' => true,
53
+ 'dismiss_expires' => 0,
54
+ 'text' => '<p>' . sprintf($default_notice, 'WP Disable', WCL_Plugin::app()
55
+ ->getPluginTitle(), 'WP Disable', 'WP Disable') . '</p>'
56
+ );
57
  }
58
 
59
+ $new_external_componetns = array(
60
+ array(
61
+ 'name' => 'cyr3lat',
62
+ 'base_path' => 'robin-image-optimizer/robin-image-optimizer.php',
63
+ 'type' => 'wordpress',
64
+ 'title' => __('Robin image optimizer – saves your money on image optimization!', 'clearfy'),
65
+ 'description' => '<br><span><b>' . __('Our new component!', 'clearfy') . '</b> ' . __('We’ve created a fully free solution for image optimization, which is as good as the paid products. The plugin optimizes your images automatically, reducing their weight with no quality loss.', 'clearfy') . '</span><br>'
66
+ ),
67
+ array(
68
+ 'name' => 'hide_login_page',
69
+ 'base_path' => 'hide-login-page/hide-login-page.php',
70
+ 'type' => 'wordpress',
71
+ 'title' => __('Hide login page (Reloaded) – hides your login page!', 'clearfy'),
72
+ 'description' => '<br><span> <b style="color:red;">' . __('Attention! If you’ve ever used features associated with hiding login page, then, please, re-activate this component.', 'clearfy') . '</b><br> ' . __('This simple module changes the login page URL to a custom link quickly and safely. The plugin requires installation.', 'clearfy') . '</span><br>'
73
+ ),
74
+ array(
75
+ 'name' => 'webcraftic-hide-my-wp',
76
+ 'type' => 'freemius',
77
+ 'title' => __('Hide my wp (Premium) – hides your WordPress from hackers and bots!', 'clearfy'),
78
+ 'description' => '<br><span><b>' . __('Our new component! ', 'clearfy') . '</b>' . __('This premium component helps in hiding your WordPress from hackers and bots. Basically, it disables identification of your CMS by changing directories and files names, removing meta data and replacing HTML content which can provide all information about the platform you use.
79
+ Most websites can be hacked easily, as hackers and bots know all security flaws in plugins, themes and the WordPress core. You can secure the website from the attack by hiding the information the hackers will need.
80
+ ', 'clearfy') . '</span><br>'
81
+ ),
82
+ /*array(
83
+ 'name' => 'minify_and_combine',
84
+ 'type' => 'internal',
85
+ 'title' => __('Minify and Combine (JS, CSS) – optimizes your scripts and styles!', 'clearfy'),
86
+ 'description' => '<br><span><b>' . __('Our new component! ', 'clearfy') . '</b> ' . __('This component combines all your scripts and styles in one file, compresses & caches it. ', 'clearfy') . '
87
+ </span><br>'
88
+ ),
89
+ array(
90
+ 'name' => 'html_minify',
91
+ 'type' => 'internal',
92
+ 'title' => __('Html minify (Reloaded) – reduces the amount of code on your pages!', 'clearfy'),
93
+ 'description' => '<br><span><b>' . __('Our new component! ', 'clearfy') . '</b> ' . __('We’ve completely redesigned HTML compression of the pages and added these features to another component. It’s more stable and reliable solution for HTML code optimization of your pages.', 'clearfy') . '</span><br>'
94
+ ),*/
95
+ );
96
+
97
+ $need_show_new_components_notice = false;
98
+
99
+ $new_component_notice_text = '<div>';
100
+ $new_component_notice_text .= '<h3>' . __('Welcome to Clearfy!', 'clearfy') . '</h3>';
101
+ $new_component_notice_text .= '<p>' . __('We apologize for the delay in updates!', 'clearfy') . ' ';
102
+ $new_component_notice_text .= __('Our team has spent a lot of time designing new, useful, and the most important – free! – features of the Clearfy plugin! ', 'clearfy') . ' ';
103
+ $new_component_notice_text .= __('Now it is time to try it.', 'clearfy') . '</p>';
104
+
105
+ foreach($new_external_componetns as $new_component) {
106
+ $slug = $new_component['name'];
107
+
108
+ if( $new_component['type'] == 'wordpress' ) {
109
+ $slug = $new_component['base_path'];
110
+ }
111
+ $install_button = WCL_Plugin::app()->getInstallComponentsButton($new_component['type'], $slug);
112
+
113
+ if( $install_button->isPluginActivate() ) {
114
+ continue;
115
+ }
116
+
117
+ $premium_class = $new_component['name'] == 'webcraftic-hide-my-wp'
118
+ ? ' wbcr-clr-premium'
119
+ : '';
120
+
121
+ $new_component_notice_text .= '<div class="wbcr-clr-new-component' . $premium_class . '">';
122
+ $new_component_notice_text .= '<h4>' . $new_component['title'] . '</h4>';
123
+ $new_component_notice_text .= $new_component['description'];
124
+ $new_component_notice_text .= $install_button->getButton();
125
+ $new_component_notice_text .= '</div>';
126
+
127
+ $need_show_new_components_notice = true;
128
  }
129
 
130
+ $new_component_notice_text .= '</div>';
131
+
132
+ if( $need_show_new_components_notice ) {
133
+ $notices[] = array(
134
+ 'id' => 'clearfy_plugin_install_new_components_notice',
135
+ 'type' => 'warning',
136
+ 'dismissible' => true,
137
+ 'dismiss_expires' => 0,
138
+ 'text' => $new_component_notice_text
139
+ );
140
+ }
141
+
142
+ return apply_filters('wbcr_clearfy_admin_notices', $notices);
143
  }
144
 
145
+ add_filter('wbcr_factory_notices_405_list', 'wbcr_clearfy_admin_notices', 10, 2);
146
 
147
  /**
148
+ * Fake stubs for the Clearfy plugin board
 
149
  */
150
+ function wbcr_clearfy_fake_boards()
151
  {
152
+ if( !defined('WIO_PLUGIN_ACTIVE') ) {
153
+ require_once WCL_PLUGIN_DIR . '/admin/includes/classes/class.install-plugins-button.php';
154
+ $install_button = new WCL_InstallPluginsButton('wordpress', 'robin-image-optimizer/robin-image-optimizer.php');
155
+
156
+ ?>
157
+ <div class="col-sm-12">
158
+ <div class="wbcr-clearfy-fake-image-optimizer-board wbcr-clearfy-board">
159
+ <h4 class="wio-text-left"><?php _e('Images optimization', 'image-optimizer'); ?></h4>
160
+
161
+ <div class="wbcr-clearfy-fake-widget">
162
+ <div class="wbcr-clearfy-widget-overlay">
163
+ <img src="<?= WCL_PLUGIN_URL ?>/admin/assets/img/robin-image-optimizer-fake-board.png" alt=""/>
164
+ </div>
165
+ <?php $install_button->renderButton(); ?>
166
+ </div>
167
+ </div>
168
+ </div>
169
+ <?php
170
  }
171
  }
172
 
173
+ add_action('wbcr_clearfy_quick_boards', 'wbcr_clearfy_fake_boards');
174
+
175
+ /**
176
+ * Widget with the offer to buy Clearfy Business
177
+ *
178
+ * @param array $widgets
179
+ * @param string $position
180
+ * @param Wbcr_Factory406_Plugin $plugin
181
+ */
182
+ function wbcr_clearfy_donate_widget($widgets, $position, $plugin)
183
  {
184
+ if( $plugin->getPluginName() == WCL_Plugin::app()->getPluginName() ) {
185
+ $buy_premium_url = WCL_Plugin::app()->getAuthorSitePageUrl('pricing', 'license_page');
186
+
187
+ ob_start();
188
+ ?>
189
+ <div id="wbcr-clr-go-to-premium-widget" class="wbcr-factory-sidebar-widget">
190
+ <p>
191
+ <strong><?php _e('Activation Clearfy Business', 'clearfy'); ?></strong>
192
+ </p>
193
+
194
+ <div class="wbcr-clr-go-to-premium-widget-body">
195
+ <p><?php _e('<b>Clearfy Business</b> is a paid package of components for the popular free WordPress plugin named Clearfy. You get access to all paid components at one price.', 'clearfy') ?></p>
196
+
197
+ <p><?php _e('Paid license guarantees that you can download and update existing and future paid components of the plugin.', 'clearfy') ?></p>
198
+ <a href="<?= $buy_premium_url ?>" class="wbcr-clr-purchase-premium" target="_blank" rel="noopener">
199
+ <span class="btn btn-gold btn-inner-wrap">
200
+ <i class="fa fa-star"></i> <?php printf(__('Upgrade to Clearfy Business for $%s', 'clearfy'), 19) ?>
201
+ <i class="fa fa-star"></i>
202
+ </span>
203
+ </a>
204
+ </div>
205
+ </div>
206
+ <?php
207
+
208
+ $widgets['donate_widget'] = ob_get_contents();
209
+ ob_end_clean();
210
+ }
211
+
212
+ return $widgets;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
213
  }
214
 
215
+ add_filter('wbcr_factory_pages_407_imppage_get_widgets', 'wbcr_clearfy_donate_widget', 10, 3);
216
+
admin/includes/classes/class.delete-plugins-button.php ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * This file groups the settings for quick setup
5
+ * @author Webcraftic <wordpress.webraftic@gmail.com>
6
+ * @copyright (c) 16.09.2017, Webcraftic
7
+ * @version 1.0
8
+ */
9
+
10
+ // Exit if accessed directly
11
+ if( !defined('ABSPATH') ) {
12
+ exit;
13
+ }
14
+
15
+ require_once WCL_PLUGIN_DIR . '/admin/includes/classes/class.install-plugins-button.php';
16
+
17
+ class WCL_DeletePluginsButton extends WCL_InstallPluginsButton {
18
+
19
+ /**
20
+ * @throws Exception
21
+ */
22
+ protected function buildWordpress()
23
+ {
24
+ parent::buildWordpress();
25
+
26
+ $this->action = 'delete';
27
+ $this->addData('plugin-action', $this->action);
28
+ $this->removeClass('button-primary');
29
+ }
30
+
31
+ protected function buildInternal()
32
+ {
33
+ // nothing
34
+ }
35
+
36
+ /**
37
+ * @throws Exception
38
+ */
39
+ protected function buildFreemius()
40
+ {
41
+ parent::buildFreemius();
42
+ $this->action = 'delete';
43
+ $this->addData('plugin-action', $this->action);
44
+ $this->removeClass('button-primary');
45
+ }
46
+
47
+ /**
48
+ * @param bool $echo
49
+ * @return string|void
50
+ */
51
+ public function getButton()
52
+ {
53
+ $button = '<a href="#" class="' . implode(' ', $this->getClasses()) . '" ' . implode(' ', $this->getData()) . '><span class="dashicons dashicons-trash"></span></a>';
54
+
55
+ if( $this->type == 'freemius' || $this->type == 'internal' || !$this->isPluginInstall() || $this->isPluginActivate() ) {
56
+ $button = '';
57
+ }
58
+
59
+ return $button;
60
+ }
61
+ }
62
+
admin/includes/classes/class.install-plugins-button.php ADDED
@@ -0,0 +1,394 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * This file groups the settings for quick setup
5
+ * @author Webcraftic <wordpress.webraftic@gmail.com>
6
+ * @copyright (c) 16.09.2017, Webcraftic
7
+ * @version 1.0
8
+ */
9
+
10
+ // Exit if accessed directly
11
+ if( !defined('ABSPATH') ) {
12
+ exit;
13
+ }
14
+
15
+ class WCL_InstallPluginsButton {
16
+
17
+ protected $type;
18
+ protected $plugin_slug;
19
+ protected $classes = array(
20
+ 'button',
21
+ 'wbcr-clr-proccess-button',
22
+ 'wbcr-clr-update-component-button'
23
+ );
24
+ protected $data = array();
25
+ protected $base_path;
26
+
27
+ protected $action;
28
+
29
+ protected $url;
30
+
31
+ /**
32
+ * @param string $group_name
33
+ * @throws Exception
34
+ */
35
+ public function __construct($type, $plugin_slug)
36
+ {
37
+ if( empty($type) || !is_string($plugin_slug) ) {
38
+ throw new Exception('Empty type or plugin_slug attribute.');
39
+ }
40
+ $this->type = $type;
41
+ $this->plugin_slug = $plugin_slug;
42
+
43
+ // todo нужно строго делать проверку на базовый путь, так как можно запутаться при работе
44
+ // todo если пользователь передал просто slug и тип хранения wordpress, то выводим ошибку, что нужно ввести базовый путь
45
+ if( $this->type == 'wordpress' ) {
46
+ if( strpos(rtrim(trim($this->plugin_slug)), '/') !== false ) {
47
+ $this->base_path = $this->plugin_slug;
48
+ $base_path_parts = explode('/', $this->base_path);
49
+ if( sizeof($base_path_parts) === 2 ) {
50
+ $this->plugin_slug = $base_path_parts[0];
51
+ }
52
+ } else {
53
+ $this->base_path = $this->getPluginBasePathBySlug($this->plugin_slug);
54
+ }
55
+
56
+ $this->buildWordpress();
57
+ } else if( $this->type == 'internal' ) {
58
+ $this->buildInternal();
59
+ } else if( $this->type == 'freemius' ) {
60
+ $this->buildFreemius();
61
+ } else {
62
+ throw new Exception('Invalid button type.');
63
+ }
64
+
65
+ // Set default data
66
+ $this->addData('storage', $this->type);
67
+ $this->addData('i18n', WCL_Helper::getEscapeJson($this->getI18n()));
68
+ $this->addData('wpnonce', wp_create_nonce('updates'));
69
+ }
70
+
71
+ /**
72
+ * @return bool
73
+ */
74
+ public function isPluginActivate()
75
+ {
76
+ if( $this->type == 'wordpress' && $this->isPluginInstall() ) {
77
+ return is_plugin_active($this->base_path);
78
+ } elseif( $this->type == 'internal' ) {
79
+ $preinsatall_components = WCL_Plugin::app()->getOption('deactive_preinstall_components', array());
80
+
81
+ return !in_array($this->plugin_slug, $preinsatall_components);
82
+ } elseif( $this->type == 'freemius' ) {
83
+ $freemius_activated_addons = WCL_Plugin::app()->getOption( 'freemius_activated_addons', array() );
84
+ return in_array( $this->plugin_slug, $freemius_activated_addons );
85
+ }
86
+
87
+ return false;
88
+ }
89
+
90
+ /**
91
+ * @return bool
92
+ */
93
+ public function isPluginInstall()
94
+ {
95
+ if( $this->type == 'wordpress' ) {
96
+ if( empty($this->base_path) ) {
97
+ return false;
98
+ }
99
+
100
+ // Check if the function get_plugins() is registered. It is necessary for the front-end
101
+ // usually get_plugins() only works in the admin panel.
102
+ if( !function_exists('get_plugins') ) {
103
+ require_once ABSPATH . 'wp-admin/includes/plugin.php';
104
+ }
105
+
106
+ $plugins = get_plugins();
107
+
108
+ if( isset($plugins[$this->base_path]) ) {
109
+ return true;
110
+ }
111
+ } else if( $this->type == 'internal' ) {
112
+ return true;
113
+ } else if( $this->type == 'freemius' ) {
114
+ $freemius_activated_addons = WCL_Plugin::app()->getOption( 'freemius_activated_addons', array() );
115
+ return in_array( $this->plugin_slug, $freemius_activated_addons );
116
+ }
117
+
118
+ return false;
119
+ }
120
+
121
+ /**
122
+ * @param $class
123
+ * @throws Exception
124
+ */
125
+ public function addClass($class)
126
+ {
127
+ if( !is_string($class) ) {
128
+ throw new Exception('Attribute class must be a string.');
129
+ }
130
+ $this->classes[] = $class;
131
+ }
132
+
133
+ /**
134
+ * @param $class
135
+ * @return bool
136
+ * @throws Exception
137
+ */
138
+ public function removeClass($class)
139
+ {
140
+ if( !is_string($class) ) {
141
+ throw new Exception('Attribute class must be a string.');
142
+ }
143
+ $key = array_search($class, $this->classes);
144
+ if( isset($this->classes[$key]) ) {
145
+ unset($this->classes[$key]);
146
+
147
+ return true;
148
+ }
149
+
150
+ return false;
151
+ }
152
+
153
+ /**
154
+ * @param $name
155
+ * @param $value
156
+ * @throws Exception
157
+ */
158
+ public function addData($name, $value)
159
+ {
160
+ if( !is_string($name) || !is_string($value) ) {
161
+ throw new Exception('Attributes name and value must be a string.');
162
+ }
163
+
164
+ $this->data[$name] = $value;
165
+ }
166
+
167
+ /**
168
+ * @param $name
169
+ * @return bool
170
+ * @throws Exception
171
+ */
172
+ public function removeData($name)
173
+ {
174
+ if( !is_string($name) ) {
175
+ throw new Exception('Attribute name must be a string.');
176
+ }
177
+
178
+ if( isset($this->data[$name]) ) {
179
+ unset($this->data[$name]);
180
+
181
+ return true;
182
+ }
183
+
184
+ return false;
185
+ }
186
+
187
+ /**
188
+ * @return string
189
+ */
190
+ public function getButton()
191
+ {
192
+ $i18n = $this->getI18n();
193
+
194
+ if( $this->type == 'freemius' ) {
195
+ if ( $this->action == 'read' and isset( $this->url ) ) {
196
+ $button = '<a target="_blank" href="' .esc_attr( $this->url ) . '" class="button button-default install-now">' . $i18n[$this->action] . '</a>';
197
+ return $button;
198
+ }
199
+ }
200
+
201
+ $button = '<a href="#" class="' . implode(' ', $this->getClasses()) . '" ' . implode(' ', $this->getData()) . '>' . $i18n[$this->action] . '</a>';
202
+
203
+ return $button;
204
+ }
205
+
206
+ /**
207
+ * @return string
208
+ * @throws Exception
209
+ */
210
+ public function getLink()
211
+ {
212
+ $this->removeClass('button');
213
+ $this->removeClass('button-default');
214
+ $this->removeClass('button-primary');
215
+
216
+ //$this->addClass('link');
217
+ $this->addClass('button-link');
218
+
219
+ return $this->getButton();
220
+ }
221
+
222
+ /**
223
+ * Print install button
224
+ */
225
+ public function renderButton()
226
+ {
227
+ echo $this->getButton();
228
+ }
229
+
230
+ /**
231
+ * Print install link
232
+ */
233
+ public function renderLink()
234
+ {
235
+ echo $this->getButton();
236
+ }
237
+
238
+ /**
239
+ * @return array
240
+ */
241
+ protected function getData()
242
+ {
243
+ $data_to_print = array();
244
+
245
+ foreach((array)$this->data as $key => $value) {
246
+ $data_to_print[$key] = 'data-' . esc_attr($key) . '="' . esc_attr($value) . '"';
247
+ }
248
+
249
+ return $data_to_print;
250
+ }
251
+
252
+ /**
253
+ * @return array
254
+ */
255
+ protected function getClasses()
256
+ {
257
+ return array_map('esc_attr', $this->classes);
258
+ }
259
+
260
+ protected function buildWordpress()
261
+ {
262
+ if( $this->type != 'wordpress' || empty($this->base_path) ) {
263
+ return;
264
+ }
265
+
266
+ $this->action = 'install';
267
+
268
+ if( $this->isPluginInstall() ) {
269
+ $this->action = 'deactivate';
270
+ if( !$this->isPluginActivate() ) {
271
+ $this->action = 'activate';
272
+ }
273
+ }
274
+
275
+ $this->addData('plugin-action', $this->action);
276
+ $this->addData('slug', $this->plugin_slug);
277
+ $this->addData('plugin', $this->base_path);
278
+
279
+ if( $this->action == 'activate' ) {
280
+ $this->addClass('button-primary');
281
+ } else {
282
+ $this->addClass('button-default');
283
+ }
284
+ }
285
+
286
+ protected function buildInternal()
287
+ {
288
+ if( $this->type != 'internal' ) {
289
+ return;
290
+ }
291
+
292
+ $this->action = 'activate';
293
+
294
+ if( $this->isPluginActivate() ) {
295
+ $this->action = 'deactivate';
296
+ }
297
+
298
+ $this->addData('plugin-action', $this->action);
299
+ $this->addData('plugin', $this->plugin_slug);
300
+
301
+ if( $this->action == 'activate' ) {
302
+ $this->addClass('button-primary');
303
+ } else {
304
+ $this->addClass('button-default');
305
+ }
306
+ }
307
+
308
+ protected function buildFreemius()
309
+ {
310
+ if( $this->type != 'freemius' ) {
311
+ return;
312
+ }
313
+
314
+ $this->action = 'activate';
315
+
316
+ require_once WCL_PLUGIN_DIR . '/includes/classes/class.licensing.php';
317
+
318
+ $licensing = WCL_Licensing::instance();
319
+
320
+ $component = $licensing->getAddonData( $this->plugin_slug );
321
+
322
+ if ( $component['is_free'] ) {
323
+ // если аддон бесплатный
324
+ if ( $component['is_actived'] ) {
325
+ $this->action = 'deactivate';
326
+ }
327
+ } else {
328
+ // если аддон НЕ бесплатный
329
+ if ( $licensing->isLicenseValid() ) {
330
+ // если лицензия валидна, то аддон можно установить
331
+ if ( $component['is_actived'] ) {
332
+ $this->action = 'deactivate';
333
+ }
334
+ } else {
335
+ if ( $component['is_actived'] ) {
336
+ // если лицензия не валидна, но аддон уже был активирован
337
+ $this->action = 'deactivate';
338
+ } else {
339
+ // если лицензия не валидна, то показываем ссылку на страницу аддона
340
+ $this->action = 'read';
341
+ $this->url = $component['url'];
342
+ }
343
+ }
344
+ }
345
+
346
+ $this->addData('plugin-action', $this->action);
347
+ $this->addData('plugin', $this->plugin_slug);
348
+
349
+ if( $this->action == 'activate' ) {
350
+ $this->addClass('button-primary');
351
+ } else {
352
+ $this->addClass('button-default');
353
+ }
354
+ }
355
+
356
+ protected function getI18n()
357
+ {
358
+ return array(
359
+ 'activate' => __('Activate', 'clearfy'),
360
+ 'install' => __('Install', 'clearfy'),
361
+ 'deactivate' => __('Deactivate', 'clearfy'),
362
+ 'delete' => __('Delete', 'clearfy'),
363
+ 'loading' => __('Please wait...', 'clearfy'),
364
+ 'read' => __('Read more', 'clearfy')
365
+ );
366
+ }
367
+
368
+
369
+ /**
370
+ * Allows you to get the base path to the plugin in the directory wp-content/plugins/
371
+ *
372
+ * @param $slug - slug for example "clearfy", "hide-login-page"
373
+ * @return int|null|string - "clearfy/clearfy.php"
374
+ */
375
+ protected function getPluginBasePathBySlug($slug)
376
+ {
377
+ // Check if the function get_plugins() is registered. It is necessary for the front-end
378
+ // usually get_plugins() only works in the admin panel.
379
+ if( !function_exists('get_plugins') ) {
380
+ require_once ABSPATH . 'wp-admin/includes/plugin.php';
381
+ }
382
+
383
+ $plugins = get_plugins();
384
+
385
+ foreach($plugins as $base_path => $plugin) {
386
+ if( strpos($base_path, rtrim(trim($slug))) !== false ) {
387
+ return $base_path;
388
+ }
389
+ }
390
+
391
+ return null;
392
+ }
393
+ }
394
+
admin/includes/classes/class.pages.php CHANGED
@@ -10,7 +10,7 @@
10
  exit;
11
  }
12
 
13
- class WCL_Page extends Wbcr_FactoryPages401_ImpressiveThemplate {
14
 
15
  /**
16
  * @param WCL_Plugin $plugin
@@ -23,7 +23,7 @@
23
  /**
24
  * Requests assets (js and css) for the page.
25
  *
26
- * @see Wbcr_FactoryPages401_AdminPage
27
  *
28
  * @since 1.0.0
29
  * @return void
@@ -33,6 +33,13 @@
33
  parent::assets($scripts, $styles);
34
 
35
  $this->styles->add(WCL_PLUGIN_URL . '/admin/assets/css/general.css');
 
 
 
 
 
 
 
36
  }
37
 
38
  /**
10
  exit;
11
  }
12
 
13
+ class WCL_Page extends Wbcr_FactoryPages407_ImpressiveThemplate {
14
 
15
  /**
16
  * @param WCL_Plugin $plugin
23
  /**
24
  * Requests assets (js and css) for the page.
25
  *
26
+ * @see Wbcr_FactoryPages407_AdminPage
27
  *
28
  * @since 1.0.0
29
  * @return void
33
  parent::assets($scripts, $styles);
34
 
35
  $this->styles->add(WCL_PLUGIN_URL . '/admin/assets/css/general.css');
36
+
37
+ /**
38
+ * Allows you to enqueue scripts to the internal pages of the plugin.
39
+ * $this->getResultId() - page id + plugin name = quick_start-wbcr_clearfy
40
+ * @since 1.3.0
41
+ */
42
+ do_action('wbcr_clearfy_page_enqueue_scripts', $this->getResultId(), $scripts, $styles);
43
  }
44
 
45
  /**
admin/includes/classes/class.upgrader-skin.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class WCL_Upgrader_Skin extends WP_Upgrader_Skin {
3
+ public function feedback($string) {
4
+ // @note: Keep it empty.
5
+ }
6
+
7
+ public function header() {
8
+
9
+ }
10
+
11
+ public function footer() {
12
+
13
+ }
14
+
15
+ }
admin/includes/classes/class.upgrader.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WCL_Plugin_Upgrader extends Plugin_Upgrader {
4
+
5
+ /**
6
+ * Download a package.
7
+ *
8
+ * @since 2.8.0
9
+ *
10
+ * @param string $package The URI of the package. If this is the full path to an
11
+ * existing local file, it will be returned untouched.
12
+ * @return string|WP_Error The full path to the downloaded package file, or a WP_Error object.
13
+ */
14
+ public function download_package( $package ) {
15
+
16
+ /**
17
+ * Filters whether to return the package.
18
+ *
19
+ * @since 3.7.0
20
+ *
21
+ * @param bool $reply Whether to bail without returning the package.
22
+ * Default false.
23
+ * @param string $package The package file name.
24
+ * @param WP_Upgrader $this The WP_Upgrader instance.
25
+ */
26
+ $reply = apply_filters( 'upgrader_pre_download', false, $package, $this );
27
+ if ( false !== $reply )
28
+ return $reply;
29
+
30
+ if ( ! preg_match('!^(http|https|ftp)://!i', $package) && file_exists($package) ) //Local file or remote?
31
+ return $package; //must be a local file..
32
+
33
+ if ( empty($package) )
34
+ return new WP_Error('no_package', $this->strings['no_package']);
35
+
36
+
37
+ $download_file = download_url( $package );
38
+ $mime_type = mime_content_type( $download_file );
39
+
40
+ if ( 'text/plain' == $mime_type ) {
41
+ $this->result = new WP_Error( 'builder_error', __( file_get_contents( $download_file ), 'clearfy' ) );
42
+ return $this->result;
43
+ }
44
+
45
+ if ( is_wp_error($download_file) )
46
+ return new WP_Error('download_failed', $this->strings['download_failed'], $download_file->get_error_message());
47
+
48
+ return $download_file;
49
+ }
50
+ }
admin/includes/options.php CHANGED
@@ -33,46 +33,6 @@
33
  'title' => __('Exclude pages from Disable Google Maps filter', 'clearfy'),
34
  'tags' => array()
35
  ),
36
- array(
37
- 'name' => 'ga_cache',
38
- 'title' => __('Google analytic cache', 'clearfy'),
39
- 'tags' => array()
40
- ),
41
- array(
42
- 'name' => 'ga_tracking_id',
43
- 'title' => __('Google analytic Code', 'clearfy'),
44
- 'tags' => array()
45
- ),
46
- array(
47
- 'name' => 'ga_adjusted_bounce_rate',
48
- 'title' => __('Use adjusted bounce rate?', 'clearfy'),
49
- 'tags' => array()
50
- ),
51
- array(
52
- 'name' => 'ga_enqueue_order',
53
- 'title' => __('Change enqueue order?', 'clearfy'),
54
- 'tags' => array()
55
- ),
56
- array(
57
- 'name' => 'ga_caos_disable_display_features',
58
- 'title' => __('Disable all display features functionality?', 'clearfy'),
59
- 'tags' => array()
60
- ),
61
- array(
62
- 'name' => 'ga_anonymize_ip',
63
- 'title' => __('Use Anonymize IP? (Required by law for some countries)', 'clearfy'),
64
- 'tags' => array()
65
- ),
66
- array(
67
- 'name' => 'ga_track_admin',
68
- 'title' => __('Track logged in Administrators?', 'clearfy'),
69
- 'tags' => array()
70
- ),
71
- array(
72
- 'name' => 'ga_caos_remove_wp_cron',
73
- 'title' => __('Remove script from wp-cron?', 'clearfy'),
74
- 'tags' => array()
75
- ),
76
  /** ------------------------ End google services ----------------------------- */
77
  array(
78
  'name' => 'disable_google_maps',
@@ -93,7 +53,7 @@
93
  array(
94
  'name' => 'disable_dashicons',
95
  'title' => __('Disable Dashicons', 'clearfy'),
96
- 'tags' => array()
97
  ),
98
  array(
99
  'name' => 'disable_gravatars',
@@ -108,65 +68,65 @@
108
  array(
109
  'name' => 'disable_emoji',
110
  'title' => __('Disable Emojis', 'clearfy'),
111
- 'tags' => array('recommended', 'clear_code')
112
  ),
113
  /*array(
114
  'name' => 'remove_dns_prefetch',
115
  'title' => __('Remove dns-prefetch', 'clearfy'),
116
- 'tags' => array('recommended', 'clear_code')
117
  ),*/
118
 
119
  array(
120
  'name' => 'remove_rsd_link',
121
  'title' => __('Remove RSD Link', 'clearfy'),
122
- 'tags' => array('recommended', 'clear_code')
123
  ),
124
  array(
125
  'name' => 'remove_wlw_link',
126
  'title' => __('Remove wlwmanifest Link', 'clearfy'),
127
- 'tags' => array('recommended', 'clear_code')
128
  ),
129
  array(
130
  'name' => 'remove_shortlink_link',
131
  'title' => __('Remove Shortlink', 'clearfy'),
132
- 'tags' => array('recommended', 'clear_code')
133
  ),
134
  array(
135
  'name' => 'remove_adjacent_posts_link',
136
  'title' => __('Remove links to previous, next post', 'clearfy'),
137
- 'tags' => array('recommended', 'clear_code')
138
  ),
139
  array(
140
  'name' => 'remove_recent_comments_style',
141
  'title' => __('Remove .recentcomments styles', 'clearfy'),
142
- 'tags' => array('recommended', 'clear_code')
143
  ),
144
  /** ------------------------ End Performance page ----------------------------- */
145
  array(
146
  'name' => 'content_image_auto_alt',
147
  'title' => __('Automatically set the alt attribute', 'clearfy'),
148
- 'tags' => array('recommended', 'seo_optimize')
149
  ),
150
  array(
151
  'name' => 'set_last_modified_headers',
152
  'title' => __('Automatically insert the Last Modified header', 'clearfy'),
153
- 'tags' => array('recommended', 'seo_optimize')
154
  ),
155
  array(
156
  'name' => 'if_modified_since_headers',
157
  'title' => __('Return an If-Modified-Since responce', 'clearfy'),
158
- 'tags' => array('recommended', 'seo_optimize')
159
  ),
160
  array(
161
  'name' => 'remove_last_item_breadcrumb_yoast',
162
  'title' => __('Remove duplicate names in breadcrumbs WP SEO by Yoast', 'clearfy'),
163
- 'tags' => array('recommended', 'seo_optimize')
164
  ),
165
  array(
166
  'name' => 'yoast_remove_image_from_xml_sitemap',
167
  'title' => sprintf(__('Remove the tag %s from XML site map', 'clearfy'), 'image:image'),
168
  'tags' => get_locale() == 'ru_RU'
169
- ? array('recommended', 'clear_code')
170
  : array()
171
  ),
172
  array(
@@ -182,17 +142,17 @@
182
  array(
183
  'name' => 'yoast_remove_head_comment',
184
  'title' => sprintf(__('Remove comment from %s section', 'clearfy'), 'head'),
185
- 'tags' => array('recommended', 'clear_code')
186
  ),
187
  array(
188
  'name' => 'redirect_archives_date',
189
  'title' => __('Remove archives date', 'clearfy'),
190
- 'tags' => array('recommended', 'seo_optimize')
191
  ),
192
  array(
193
  'name' => 'redirect_archives_author',
194
  'title' => __('Remove author archives ', 'clearfy'),
195
- 'tags' => array('recommended', 'seo_optimize')
196
  ),
197
  array(
198
  'name' => 'redirect_archives_tag',
@@ -202,42 +162,42 @@
202
  array(
203
  'name' => 'attachment_pages_redirect',
204
  'title' => __('Remove attachment pages', 'clearfy'),
205
- 'tags' => array('recommended', 'seo_optimize')
206
  ),
207
  array(
208
  'name' => 'remove_single_pagination_duplicate',
209
  'title' => __('Remove post pagination', 'clearfy'),
210
- 'tags' => array('recommended', 'seo_optimize')
211
  ),
212
  array(
213
  'name' => 'remove_replytocom',
214
  'title' => __('Remove ?replytocom', 'clearfy'),
215
- 'tags' => array('recommended', 'seo_optimize')
216
  ),
217
  array(
218
  'name' => 'remove_meta_generator',
219
  'title' => __('Remove meta generator', 'clearfy'),
220
- 'tags' => array('recommended', 'clear_code', 'defence')
221
  ),
222
  array(
223
  'name' => 'protect_author_get',
224
  'title' => __('Hide author login', 'clearfy'),
225
- 'tags' => array('recommended', 'defence')
226
  ),
227
  array(
228
  'name' => 'change_login_errors',
229
- 'title' => __('Hide errors when logging into the site', 'clearfy'),
230
- 'tags' => array('recommended', 'defence')
231
  ),
232
  array(
233
  'name' => 'remove_style_version',
234
- 'title' => __('Remove Version from Stylesheet', 'clearfy'),
235
- 'tags' => array('recommended', 'clear_code', 'defence')
236
  ),
237
  array(
238
  'name' => 'remove_js_version',
239
  'title' => __('Remove Version from Script', 'clearfy'),
240
- 'tags' => array('recommended', 'clear_code', 'defence')
241
  ),
242
  array(
243
  'name' => 'remove_unneeded_widget_page',
@@ -340,21 +300,15 @@
340
  'title' => __('Removes links to wordpress.org site from the admin bar', 'clearfy'),
341
  'tags' => array()
342
  ),
343
- array('name' => 'html_minify', 'title' => __('HTML minify', 'clearfy'), 'tags' => array()),
344
- array(
345
- 'name' => 'redirect_from_http_to_https',
346
- 'title' => __('Redirect Http to Https', 'clearfy'),
347
- 'tags' => array()
348
- ),
349
  array(
350
  'name' => 'remove_style_version',
351
  'title' => __('Remove Version from Stylesheet', 'clearfy'),
352
- 'tags' => array()
353
  ),
354
  array(
355
  'name' => 'remove_js_version',
356
  'title' => __('Remove Version from Script', 'clearfy'),
357
- 'tags' => array()
358
  ),
359
  array(
360
  'name' => 'remove_version_exclude',
@@ -426,4 +380,9 @@
426
  'title' => __('Remove html comments', 'clearfy'),
427
  'tags' => array()
428
  ),
429
- ));
 
 
 
 
 
33
  'title' => __('Exclude pages from Disable Google Maps filter', 'clearfy'),
34
  'tags' => array()
35
  ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  /** ------------------------ End google services ----------------------------- */
37
  array(
38
  'name' => 'disable_google_maps',
53
  array(
54
  'name' => 'disable_dashicons',
55
  'title' => __('Disable Dashicons', 'clearfy'),
56
+ 'tags' => array('hide_my_wp')
57
  ),
58
  array(
59
  'name' => 'disable_gravatars',
68
  array(
69
  'name' => 'disable_emoji',
70
  'title' => __('Disable Emojis', 'clearfy'),
71
+ 'tags' => array('clear_code','hide_my_wp')
72
  ),
73
  /*array(
74
  'name' => 'remove_dns_prefetch',
75
  'title' => __('Remove dns-prefetch', 'clearfy'),
76
+ 'tags' => array('clear_code')
77
  ),*/
78
 
79
  array(
80
  'name' => 'remove_rsd_link',
81
  'title' => __('Remove RSD Link', 'clearfy'),
82
+ 'tags' => array('clear_code','hide_my_wp')
83
  ),
84
  array(
85
  'name' => 'remove_wlw_link',
86
  'title' => __('Remove wlwmanifest Link', 'clearfy'),
87
+ 'tags' => array('clear_code','hide_my_wp')
88
  ),
89
  array(
90
  'name' => 'remove_shortlink_link',
91
  'title' => __('Remove Shortlink', 'clearfy'),
92
+ 'tags' => array('clear_code','hide_my_wp')
93
  ),
94
  array(
95
  'name' => 'remove_adjacent_posts_link',
96
  'title' => __('Remove links to previous, next post', 'clearfy'),
97
+ 'tags' => array('clear_code','hide_my_wp')
98
  ),
99
  array(
100
  'name' => 'remove_recent_comments_style',
101
  'title' => __('Remove .recentcomments styles', 'clearfy'),
102
+ 'tags' => array('clear_code','hide_my_wp')
103
  ),
104
  /** ------------------------ End Performance page ----------------------------- */
105
  array(
106
  'name' => 'content_image_auto_alt',
107
  'title' => __('Automatically set the alt attribute', 'clearfy'),
108
+ 'tags' => array('seo_optimize')
109
  ),
110
  array(
111
  'name' => 'set_last_modified_headers',
112
  'title' => __('Automatically insert the Last Modified header', 'clearfy'),
113
+ 'tags' => array('seo_optimize')
114
  ),
115
  array(
116
  'name' => 'if_modified_since_headers',
117
  'title' => __('Return an If-Modified-Since responce', 'clearfy'),
118
+ 'tags' => array('seo_optimize')
119
  ),
120
  array(
121
  'name' => 'remove_last_item_breadcrumb_yoast',
122
  'title' => __('Remove duplicate names in breadcrumbs WP SEO by Yoast', 'clearfy'),
123
+ 'tags' => array('seo_optimize')
124
  ),
125
  array(
126
  'name' => 'yoast_remove_image_from_xml_sitemap',
127
  'title' => sprintf(__('Remove the tag %s from XML site map', 'clearfy'), 'image:image'),
128
  'tags' => get_locale() == 'ru_RU'
129
+ ? array('clear_code')
130
  : array()
131
  ),
132
  array(
142
  array(
143
  'name' => 'yoast_remove_head_comment',
144
  'title' => sprintf(__('Remove comment from %s section', 'clearfy'), 'head'),
145
+ 'tags' => array('clear_code')
146
  ),
147
  array(
148
  'name' => 'redirect_archives_date',
149
  'title' => __('Remove archives date', 'clearfy'),
150
+ 'tags' => array('seo_optimize')
151
  ),
152
  array(
153
  'name' => 'redirect_archives_author',
154
  'title' => __('Remove author archives ', 'clearfy'),
155
+ 'tags' => array('seo_optimize')
156
  ),
157
  array(
158
  'name' => 'redirect_archives_tag',
162
  array(
163
  'name' => 'attachment_pages_redirect',
164
  'title' => __('Remove attachment pages', 'clearfy'),
165
+ 'tags' => array('seo_optimize')
166
  ),
167
  array(
168
  'name' => 'remove_single_pagination_duplicate',
169
  'title' => __('Remove post pagination', 'clearfy'),
170
+ 'tags' => array('recommended')
171
  ),
172
  array(
173
  'name' => 'remove_replytocom',
174
  'title' => __('Remove ?replytocom', 'clearfy'),
175
+ 'tags' => array('seo_optimize')
176
  ),
177
  array(
178
  'name' => 'remove_meta_generator',
179
  'title' => __('Remove meta generator', 'clearfy'),
180
+ 'tags' => array('clear_code', 'defence','hide_my_wp')
181
  ),
182
  array(
183
  'name' => 'protect_author_get',
184
  'title' => __('Hide author login', 'clearfy'),
185
+ 'tags' => array('defence','hide_my_wp')
186
  ),
187
  array(
188
  'name' => 'change_login_errors',
189
+ 'title' => __('Hide errors when logging into the site', 'clearfy','hide_my_wp'),
190
+ 'tags' => array('defence','hide_my_wp')
191
  ),
192
  array(
193
  'name' => 'remove_style_version',
194
+ 'title' => __('Remove Version from Stylesheet', 'clearfy','hide_my_wp'),
195
+ 'tags' => array('clear_code', 'defence','hide_my_wp')
196
  ),
197
  array(
198
  'name' => 'remove_js_version',
199
  'title' => __('Remove Version from Script', 'clearfy'),
200
+ 'tags' => array('clear_code', 'defence','hide_my_wp')
201
  ),
202
  array(
203
  'name' => 'remove_unneeded_widget_page',
300
  'title' => __('Removes links to wordpress.org site from the admin bar', 'clearfy'),
301
  'tags' => array()
302
  ),
 
 
 
 
 
 
303
  array(
304
  'name' => 'remove_style_version',
305
  'title' => __('Remove Version from Stylesheet', 'clearfy'),
306
+ 'tags' => array('hide_my_wp')
307
  ),
308
  array(
309
  'name' => 'remove_js_version',
310
  'title' => __('Remove Version from Script', 'clearfy'),
311
+ 'tags' => array('hide_my_wp')
312
  ),
313
  array(
314
  'name' => 'remove_version_exclude',
380
  'title' => __('Remove html comments', 'clearfy'),
381
  'tags' => array()
382
  ),
383
+ array(
384
+ 'name' => 'deactive_preinstall_components',
385
+ 'title' => __('Deactivate preinstall components', 'clearfy'),
386
+ 'tags' => array()
387
+ ),
388
+ ));
admin/pages/advanced.php CHANGED
@@ -17,7 +17,7 @@
17
  * The id of the page in the admin menu.
18
  *
19
  * Mainly used to navigate between pages.
20
- * @see FactoryPages401_AdminPage
21
  *
22
  * @since 1.0.0
23
  * @var string
@@ -61,7 +61,7 @@
61
  {
62
  parent::warningNotice();
63
 
64
- if( $this->isPostRevisionConstant() ) {
65
  $this->printWarningNotice(__('Warning! In the wp-config.php file, a constant WP_POST_REVISIONS is found, it determines the number of revisions. Delete it so you can change this value through the admin panel.', 'clearfy'));
66
  }
67
  }
@@ -77,6 +77,22 @@
77
 
78
  $options = array();
79
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
  $options[] = array(
81
  'type' => 'html',
82
  'html' => '<div class="wbcr-clearfy-group-header">' . '<strong>' . __('Heartbeat', 'clearfy') . '</strong>' . '<p>' . __('The WordPress Heartbeat API uses /wp-admin/admin-ajax.php to run AJAX calls from the web-browser. While this is great and all it can also cause high CPU usage and crazy amounts of PHP calls. For example, if you leave your dashboard open it will keep sending POST requests to this file on a regular interval, every 15 seconds. Here is an example below of it happening.', 'clearfy') . '</p>' . '</div>'
17
  * The id of the page in the admin menu.
18
  *
19
  * Mainly used to navigate between pages.
20
+ * @see FactoryPages407_AdminPage
21
  *
22
  * @since 1.0.0
23
  * @var string
61
  {
62
  parent::warningNotice();
63
 
64
+ if( !$this->plugin->getOption('revisions_disable') && $this->isPostRevisionConstant() ) {
65
  $this->printWarningNotice(__('Warning! In the wp-config.php file, a constant WP_POST_REVISIONS is found, it determines the number of revisions. Delete it so you can change this value through the admin panel.', 'clearfy'));
66
  }
67
  }
77
 
78
  $options = array();
79
 
80
+ $options[] = array(
81
+ 'type' => 'html',
82
+ 'html' => '<div class="wbcr-clearfy-group-header">' . '<strong>' . __('Clearfy options', 'clearfy') . '</strong>' . '<p>' . __('This group of settings allows you to configure the work of the Clearfy plugin.', 'clearfy') . '</p>' . '</div>'
83
+ );
84
+
85
+ $options[] = array(
86
+ 'type' => 'checkbox',
87
+ 'way' => 'buttons',
88
+ 'name' => 'disable_clearfy_extra_menu',
89
+ 'title' => __('Disable Clearfy extra menu', 'clearfy'),
90
+ 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
91
+ 'hint' => __('This setting allows you to disable the additional menu of the Clearfy plugin, in the admin bar. This menu is required to work with the Minify and Combine and Assets Manager components.', 'clearfy'),
92
+ 'default' => false
93
+ );
94
+
95
+
96
  $options[] = array(
97
  'type' => 'html',
98
  'html' => '<div class="wbcr-clearfy-group-header">' . '<strong>' . __('Heartbeat', 'clearfy') . '</strong>' . '<p>' . __('The WordPress Heartbeat API uses /wp-admin/admin-ajax.php to run AJAX calls from the web-browser. While this is great and all it can also cause high CPU usage and crazy amounts of PHP calls. For example, if you leave your dashboard open it will keep sending POST requests to this file on a regular interval, every 15 seconds. Here is an example below of it happening.', 'clearfy') . '</p>' . '</div>'
admin/pages/components.php CHANGED
@@ -19,7 +19,7 @@
19
  * The id of the page in the admin menu.
20
  *
21
  * Mainly used to navigate between pages.
22
- * @see FactoryPages401_AdminPage
23
  *
24
  * @since 1.0.0
25
  * @var string
@@ -47,7 +47,7 @@
47
  /**
48
  * Requests assets (js and css) for the page.
49
  *
50
- * @see FactoryPages401_AdminPage
51
  *
52
  * @since 1.0.0
53
  * @return void
@@ -57,87 +57,226 @@
57
  parent::assets($scripts, $styles);
58
 
59
  $this->styles->add(WCL_PLUGIN_URL . '/admin/assets/css/components.css');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  }
61
 
62
  public function showPageContent()
63
  {
64
- $preinsatall_components = $this->plugin->getOption('deactive_preinstall_components', array());
65
 
66
  $default_image = 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzNjAiIGhlaWdodD0iMzYwIiB2aWV3Ym94PSIwIDAgMzYwIDM2MCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0icmdiKDcwLCA4MSwgOTMpIiAvPjxwb2x5bGluZSBwb2ludHM9IjE5LjgsMCw0MC4yLDAsNjAsMTkuOCw2MCw0MC4yLDQwLjIsNjAsMTkuOCw2MCwwLDQwLjIsMCwxOS44LDE5LjgsMCIgZmlsbD0iIzIyMiIgZmlsbC1vcGFjaXR5PSIwLjE1IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLCAwKSIgLz48cG9seWxpbmUgcG9pbnRzPSIxOS44LDAsNDAuMiwwLDYwLDE5LjgsNjAsNDAuMiw0MC4yLDYwLDE5LjgsNjAsMCw0MC4yLDAsMTkuOCwxOS44LDAiIGZpbGw9IiNkZGQiIGZpbGwtb3BhY2l0eT0iMC4wNTQ2NjY2NjY2NjY2NjciIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9IjAuMDIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDYwLCAwKSIgLz48cG9seWxpbmUgcG9pbnRzPSIxOS44LDAsNDAuMiwwLDYwLDE5LjgsNjAsNDAuMiw0MC4yLDYwLDE5LjgsNjAsMCw0MC4yLDAsMTkuOCwxOS44LDAiIGZpbGw9IiMyMjIiIGZpbGwtb3BhY2l0eT0iMC4wNDYiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9IjAuMDIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEyMCwgMCkiIC8+PHBvbHlsaW5lIHBvaW50cz0iMTkuOCwwLDQwLjIsMCw2MCwxOS44LDYwLDQwLjIsNDAuMiw2MCwxOS44LDYwLDAsNDAuMiwwLDE5LjgsMTkuOCwwIiBmaWxsPSIjZGRkIiBmaWxsLW9wYWNpdHk9IjAuMDIiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9IjAuMDIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE4MCwgMCkiIC8+PHBvbHlsaW5lIHBvaW50cz0iMTkuOCwwLDQwLjIsMCw2MCwxOS44LDYwLDQwLjIsNDAuMiw2MCwxOS44LDYwLDAsNDAuMiwwLDE5LjgsMTkuOCwwIiBmaWxsPSIjZGRkIiBmaWxsLW9wYWNpdHk9IjAuMDU0NjY2NjY2NjY2NjY3IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyNDAsIDApIiAvPjxwb2x5bGluZSBwb2ludHM9IjE5LjgsMCw0MC4yLDAsNjAsMTkuOCw2MCw0MC4yLDQwLjIsNjAsMTkuOCw2MCwwLDQwLjIsMCwxOS44LDE5LjgsMCIgZmlsbD0iIzIyMiIgZmlsbC1vcGFjaXR5PSIwLjAyODY2NjY2NjY2NjY2NyIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utb3BhY2l0eT0iMC4wMiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzAwLCAwKSIgLz48cG9seWxpbmUgcG9pbnRzPSIxOS44LDAsNDAuMiwwLDYwLDE5LjgsNjAsNDAuMiw0MC4yLDYwLDE5LjgsNjAsMCw0MC4yLDAsMTkuOCwxOS44LDAiIGZpbGw9IiNkZGQiIGZpbGwtb3BhY2l0eT0iMC4xMDY2NjY2NjY2NjY2NyIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utb3BhY2l0eT0iMC4wMiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwgNjApIiAvPjxwb2x5bGluZSBwb2ludHM9IjE5LjgsMCw0MC4yLDAsNjAsMTkuOCw2MCw0MC4yLDQwLjIsNjAsMTkuOCw2MCwwLDQwLjIsMCwxOS44LDE5LjgsMCIgZmlsbD0iIzIyMiIgZmlsbC1vcGFjaXR5PSIwLjA5OCIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utb3BhY2l0eT0iMC4wMiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNjAsIDYwKSIgLz48cG9seWxpbmUgcG9pbnRzPSIxOS44LDAsNDAuMiwwLDYwLDE5LjgsNjAsNDAuMiw0MC4yLDYwLDE5LjgsNjAsMCw0MC4yLDAsMTkuOCwxOS44LDAiIGZpbGw9IiMyMjIiIGZpbGwtb3BhY2l0eT0iMC4xMTUzMzMzMzMzMzMzMyIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utb3BhY2l0eT0iMC4wMiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTIwLCA2MCkiIC8+PHBvbHlsaW5lIHBvaW50cz0iMTkuOCwwLDQwLjIsMCw2MCwxOS44LDYwLDQwLjIsNDAuMiw2MCwxOS44LDYwLDAsNDAuMiwwLDE5LjgsMTkuOCwwIiBmaWxsPSIjMjIyIiBmaWxsLW9wYWNpdHk9IjAuMDYzMzMzMzMzMzMzMzMzIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxODAsIDYwKSIgLz48cG9seWxpbmUgcG9pbnRzPSIxOS44LDAsNDAuMiwwLDYwLDE5LjgsNjAsNDAuMiw0MC4yLDYwLDE5LjgsNjAsMCw0MC4yLDAsMTkuOCwxOS44LDAiIGZpbGw9IiNkZGQiIGZpbGwtb3BhY2l0eT0iMC4wMzczMzMzMzMzMzMzMzMiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9IjAuMDIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDI0MCwgNjApIiAvPjxwb2x5bGluZSBwb2ludHM9IjE5LjgsMCw0MC4yLDAsNjAsMTkuOCw2MCw0MC4yLDQwLjIsNjAsMTkuOCw2MCwwLDQwLjIsMCwxOS44LDE5LjgsMCIgZmlsbD0iI2RkZCIgZmlsbC1vcGFjaXR5PSIwLjE0MTMzMzMzMzMzMzMzIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzMDAsIDYwKSIgLz48cG9seWxpbmUgcG9pbnRzPSIxOS44LDAsNDAuMiwwLDYwLDE5LjgsNjAsNDAuMiw0MC4yLDYwLDE5LjgsNjAsMCw0MC4yLDAsMTkuOCwxOS44LDAiIGZpbGw9IiNkZGQiIGZpbGwtb3BhY2l0eT0iMC4wMzczMzMzMzMzMzMzMzMiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9IjAuMDIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsIDEyMCkiIC8+PHBvbHlsaW5lIHBvaW50cz0iMTkuOCwwLDQwLjIsMCw2MCwxOS44LDYwLDQwLjIsNDAuMiw2MCwxOS44LDYwLDAsNDAuMiwwLDE5LjgsMTkuOCwwIiBmaWxsPSIjZGRkIiBmaWxsLW9wYWNpdHk9IjAuMDg5MzMzMzMzMzMzMzMzIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg2MCwgMTIwKSIgLz48cG9seWxpbmUgcG9pbnRzPSIxOS44LDAsNDAuMiwwLDYwLDE5LjgsNjAsNDAuMiw0MC4yLDYwLDE5LjgsNjAsMCw0MC4yLDAsMTkuOCwxOS44LDAiIGZpbGw9IiNkZGQiIGZpbGwtb3BhY2l0eT0iMC4wODkzMzMzMzMzMzMzMzMiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9IjAuMDIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEyMCwgMTIwKSIgLz48cG9seWxpbmUgcG9pbnRzPSIxOS44LDAsNDAuMiwwLDYwLDE5LjgsNjAsNDAuMiw0MC4yLDYwLDE5LjgsNjAsMCw0MC4yLDAsMTkuOCwxOS44LDAiIGZpbGw9IiMyMjIiIGZpbGwtb3BhY2l0eT0iMC4wODA2NjY2NjY2NjY2NjciIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9IjAuMDIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE4MCwgMTIwKSIgLz48cG9seWxpbmUgcG9pbnRzPSIxOS44LDAsNDAuMiwwLDYwLDE5LjgsNjAsNDAuMiw0MC4yLDYwLDE5LjgsNjAsMCw0MC4yLDAsMTkuOCwxOS44LDAiIGZpbGw9IiMyMjIiIGZpbGwtb3BhY2l0eT0iMC4xMzI2NjY2NjY2NjY2NyIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utb3BhY2l0eT0iMC4wMiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjQwLCAxMjApIiAvPjxwb2x5bGluZSBwb2ludHM9IjE5LjgsMCw0MC4yLDAsNjAsMTkuOCw2MCw0MC4yLDQwLjIsNjAsMTkuOCw2MCwwLDQwLjIsMCwxOS44LDE5LjgsMCIgZmlsbD0iIzIyMiIgZmlsbC1vcGFjaXR5PSIwLjE1IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzMDAsIDEyMCkiIC8+PHBvbHlsaW5lIHBvaW50cz0iMTkuOCwwLDQwLjIsMCw2MCwxOS44LDYwLDQwLjIsNDAuMiw2MCwxOS44LDYwLDAsNDAuMiwwLDE5LjgsMTkuOCwwIiBmaWxsPSIjMjIyIiBmaWxsLW9wYWNpdHk9IjAuMDk4IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLCAxODApIiAvPjxwb2x5bGluZSBwb2ludHM9IjE5LjgsMCw0MC4yLDAsNjAsMTkuOCw2MCw0MC4yLDQwLjIsNjAsMTkuOCw2MCwwLDQwLjIsMCwxOS44LDE5LjgsMCIgZmlsbD0iIzIyMiIgZmlsbC1vcGFjaXR5PSIwLjA2MzMzMzMzMzMzMzMzMyIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utb3BhY2l0eT0iMC4wMiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNjAsIDE4MCkiIC8+PHBvbHlsaW5lIHBvaW50cz0iMTkuOCwwLDQwLjIsMCw2MCwxOS44LDYwLDQwLjIsNDAuMiw2MCwxOS44LDYwLDAsNDAuMiwwLDE5LjgsMTkuOCwwIiBmaWxsPSIjZGRkIiBmaWxsLW9wYWNpdHk9IjAuMDIiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9IjAuMDIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEyMCwgMTgwKSIgLz48cG9seWxpbmUgcG9pbnRzPSIxOS44LDAsNDAuMiwwLDYwLDE5LjgsNjAsNDAuMiw0MC4yLDYwLDE5LjgsNjAsMCw0MC4yLDAsMTkuOCwxOS44LDAiIGZpbGw9IiNkZGQiIGZpbGwtb3BhY2l0eT0iMC4wMzczMzMzMzMzMzMzMzMiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9IjAuMDIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE4MCwgMTgwKSIgLz48cG9seWxpbmUgcG9pbnRzPSIxOS44LDAsNDAuMiwwLDYwLDE5LjgsNjAsNDAuMiw0MC4yLDYwLDE5LjgsNjAsMCw0MC4yLDAsMTkuOCwxOS44LDAiIGZpbGw9IiMyMjIiIGZpbGwtb3BhY2l0eT0iMC4xMTUzMzMzMzMzMzMzMyIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utb3BhY2l0eT0iMC4wMiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjQwLCAxODApIiAvPjxwb2x5bGluZSBwb2ludHM9IjE5LjgsMCw0MC4yLDAsNjAsMTkuOCw2MCw0MC4yLDQwLjIsNjAsMTkuOCw2MCwwLDQwLjIsMCwxOS44LDE5LjgsMCIgZmlsbD0iIzIyMiIgZmlsbC1vcGFjaXR5PSIwLjA2MzMzMzMzMzMzMzMzMyIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utb3BhY2l0eT0iMC4wMiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzAwLCAxODApIiAvPjxwb2x5bGluZSBwb2ludHM9IjE5LjgsMCw0MC4yLDAsNjAsMTkuOCw2MCw0MC4yLDQwLjIsNjAsMTkuOCw2MCwwLDQwLjIsMCwxOS44LDE5LjgsMCIgZmlsbD0iI2RkZCIgZmlsbC1vcGFjaXR5PSIwLjA1NDY2NjY2NjY2NjY2NyIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utb3BhY2l0eT0iMC4wMiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwgMjQwKSIgLz48cG9seWxpbmUgcG9pbnRzPSIxOS44LDAsNDAuMiwwLDYwLDE5LjgsNjAsNDAuMiw0MC4yLDYwLDE5LjgsNjAsMCw0MC4yLDAsMTkuOCwxOS44LDAiIGZpbGw9IiNkZGQiIGZpbGwtb3BhY2l0eT0iMC4xMDY2NjY2NjY2NjY2NyIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utb3BhY2l0eT0iMC4wMiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNjAsIDI0MCkiIC8+PHBvbHlsaW5lIHBvaW50cz0iMTkuOCwwLDQwLjIsMCw2MCwxOS44LDYwLDQwLjIsNDAuMiw2MCwxOS44LDYwLDAsNDAuMiwwLDE5LjgsMTkuOCwwIiBmaWxsPSIjZGRkIiBmaWxsLW9wYWNpdHk9IjAuMDcyIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMjAsIDI0MCkiIC8+PHBvbHlsaW5lIHBvaW50cz0iMTkuOCwwLDQwLjIsMCw2MCwxOS44LDYwLDQwLjIsNDAuMiw2MCwxOS44LDYwLDAsNDAuMiwwLDE5LjgsMTkuOCwwIiBmaWxsPSIjMjIyIiBmaWxsLW9wYWNpdHk9IjAuMTE1MzMzMzMzMzMzMzMiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9IjAuMDIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE4MCwgMjQwKSIgLz48cG9seWxpbmUgcG9pbnRzPSIxOS44LDAsNDAuMiwwLDYwLDE5LjgsNjAsNDAuMiw0MC4yLDYwLDE5LjgsNjAsMCw0MC4yLDAsMTkuOCwxOS44LDAiIGZpbGw9IiMyMjIiIGZpbGwtb3BhY2l0eT0iMC4xMzI2NjY2NjY2NjY2NyIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utb3BhY2l0eT0iMC4wMiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjQwLCAyNDApIiAvPjxwb2x5bGluZSBwb2ludHM9IjE5LjgsMCw0MC4yLDAsNjAsMTkuOCw2MCw0MC4yLDQwLjIsNjAsMTkuOCw2MCwwLDQwLjIsMCwxOS44LDE5LjgsMCIgZmlsbD0iIzIyMiIgZmlsbC1vcGFjaXR5PSIwLjA4MDY2NjY2NjY2NjY2NyIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utb3BhY2l0eT0iMC4wMiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzAwLCAyNDApIiAvPjxwb2x5bGluZSBwb2ludHM9IjE5LjgsMCw0MC4yLDAsNjAsMTkuOCw2MCw0MC4yLDQwLjIsNjAsMTkuOCw2MCwwLDQwLjIsMCwxOS44LDE5LjgsMCIgZmlsbD0iIzIyMiIgZmlsbC1vcGFjaXR5PSIwLjEzMjY2NjY2NjY2NjY3IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLCAzMDApIiAvPjxwb2x5bGluZSBwb2ludHM9IjE5LjgsMCw0MC4yLDAsNjAsMTkuOCw2MCw0MC4yLDQwLjIsNjAsMTkuOCw2MCwwLDQwLjIsMCwxOS44LDE5LjgsMCIgZmlsbD0iI2RkZCIgZmlsbC1vcGFjaXR5PSIwLjAzNzMzMzMzMzMzMzMzMyIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utb3BhY2l0eT0iMC4wMiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNjAsIDMwMCkiIC8+PHBvbHlsaW5lIHBvaW50cz0iMTkuOCwwLDQwLjIsMCw2MCwxOS44LDYwLDQwLjIsNDAuMiw2MCwxOS44LDYwLDAsNDAuMiwwLDE5LjgsMTkuOCwwIiBmaWxsPSIjZGRkIiBmaWxsLW9wYWNpdHk9IjAuMTI0IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMjAsIDMwMCkiIC8+PHBvbHlsaW5lIHBvaW50cz0iMTkuOCwwLDQwLjIsMCw2MCwxOS44LDYwLDQwLjIsNDAuMiw2MCwxOS44LDYwLDAsNDAuMiwwLDE5LjgsMTkuOCwwIiBmaWxsPSIjMjIyIiBmaWxsLW9wYWNpdHk9IjAuMDI4NjY2NjY2NjY2NjY3IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxODAsIDMwMCkiIC8+PHBvbHlsaW5lIHBvaW50cz0iMTkuOCwwLDQwLjIsMCw2MCwxOS44LDYwLDQwLjIsNDAuMiw2MCwxOS44LDYwLDAsNDAuMiwwLDE5LjgsMTkuOCwwIiBmaWxsPSIjZGRkIiBmaWxsLW9wYWNpdHk9IjAuMDcyIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyNDAsIDMwMCkiIC8+PHBvbHlsaW5lIHBvaW50cz0iMTkuOCwwLDQwLjIsMCw2MCwxOS44LDYwLDQwLjIsNDAuMiw2MCwxOS44LDYwLDAsNDAuMiwwLDE5LjgsMTkuOCwwIiBmaWxsPSIjMjIyIiBmaWxsLW9wYWNpdHk9IjAuMDI4NjY2NjY2NjY2NjY3IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzMDAsIDMwMCkiIC8+PC9zdmc+';
67
 
68
  $response = array(
69
  array(
70
- 'id' => 'hide_login_page',
 
 
 
 
 
 
 
 
 
71
  'title' => __('Hide login page', 'clearfy'),
 
 
 
 
 
 
 
 
 
72
  'url' => '#',
 
73
  'icon' => $default_image,
74
- 'description' => __('Hide Login Page is a very light plugin that lets you easily and safely change the url of the login form page to anything you want.', 'clearfy')
75
  ),
76
  array(
77
- 'id' => 'updates_manager',
78
- 'title' => __('Updates manager', 'clearfy'),
79
  'url' => '#',
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
  'icon' => WCL_PLUGIN_URL . '/admin/assets/img/upm-icon-128x128.png',
81
  'description' => __('Disable updates enable auto updates for themes, plugins and WordPress.', 'clearfy')
82
  ),
83
  array(
84
- 'id' => 'comments_tools',
85
  'title' => __('Comments tools', 'clearfy'),
86
  'url' => '#',
 
87
  'icon' => WCL_PLUGIN_URL . '/admin/assets/img/dic-icon-128x128.png',
88
  'description' => __('Bulk disable and remove comments, disable “Website” field, hides external links, disable XML-RPC.', 'clearfy')
89
  ),
90
  array(
91
- 'id' => 'widget_tools',
92
  'title' => __('Widgets tools', 'clearfy'),
93
  'url' => '#',
 
94
  'icon' => $default_image,
95
  'description' => __('Disable unused widgets such as tag cloud, links, calendar etc.', 'clearfy')
96
  ),
97
  array(
98
- 'id' => 'asset_manager',
99
  'title' => __('Asset manager', 'clearfy'),
100
  'url' => '#',
 
101
  'icon' => WCL_PLUGIN_URL . '/admin/assets/img/asm-icon-128x128.png',
102
  'description' => __('Selectively disable unused scripts and styles on the pages of your website.', 'clearfy')
103
  ),
104
  array(
105
- 'id' => 'disable_notices',
106
  'title' => __('Disable admin notices', 'clearfy'),
107
  'url' => '#',
 
108
  'icon' => WCL_PLUGIN_URL . '/admin/assets/img/dan-icon-128x128.png',
109
  'description' => __('Disables admin notices bulk or individually. Collects notices into the admin bar.', 'clearfy')
110
  ),
111
  array(
112
- 'id' => 'adminbar_manager',
113
  'title' => __('Admin bar manager', 'clearfy'),
114
  'url' => '#',
 
115
  'icon' => $default_image,
116
  'description' => __('Disables admin bar. Allows to change and remove admin bar elements.', 'clearfy')
117
  ),
118
  array(
119
- 'id' => 'post_tools',
120
  'title' => __('Posts tools', 'clearfy'),
121
  'url' => '#',
 
122
  'icon' => $default_image,
123
  'description' => __('Disable revisions, disable posts autosave, disable smart quotes and disable auto paragraphs.', 'clearfy')
124
  ),
125
  array(
126
- 'id' => 'yoast_seo',
127
  'title' => __('Yoast SEO optimization', 'clearfy'),
128
  'url' => '#',
 
129
  'icon' => $default_image,
130
  'description' => __('Set of optimization functions for the popular Yoast SEO plugin.', 'clearfy')
131
  )
132
  );
133
 
134
  $response[] = array(
135
- 'id' => 'cyrlitera',
136
  'title' => __('Transliteration of Cyrillic alphabet', 'clearfy'),
137
- 'url' => '#',
 
138
  'icon' => WCL_PLUGIN_URL . '/admin/assets/img/ctr-icon-128x128.png',
139
  'description' => __('Converts Cyrillic permalinks of post, pages, taxonomies and media files to the Latin alphabet. Supports Russian, Ukrainian, Georgian, Bulgarian languages.', 'clearfy')
140
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
141
  ?>
142
  <div class="wbcr-factory-page-group-header"><?php _e('<strong>Plugin Components</strong>.', 'clearfy') ?>
143
  <p>
@@ -146,37 +285,66 @@
146
  </div>
147
 
148
  <div class="wbcr-clearfy-components">
149
- <?php foreach($response as $addon): ?>
150
  <?php
151
- $status_class = '';
152
- $plugin_activate = true;
153
 
154
- if( in_array($addon['id'], $preinsatall_components) ) {
155
- $status_class = ' plugin-status-deactive';
156
- $plugin_activate = false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
157
  }
 
 
 
 
 
 
 
158
  ?>
159
 
160
  <div class="plugin-card<?= $status_class ?>">
 
 
 
161
  <div class="plugin-card-top">
162
  <div class="name column-name">
163
  <h3>
164
- <a href="<?= $addon['url'] ?>" class="thickbox open-plugin-details-modal">
165
- <?= $addon['title'] ?>
166
- <img src="<?= $addon['icon'] ?>" class="plugin-icon" alt="">
167
  </a>
168
  </h3>
169
  </div>
170
  <div class="desc column-description">
171
- <p><?= $addon['description']; ?></p>
 
 
172
  </div>
173
  </div>
174
  <div class="plugin-card-bottom">
175
- <?php if( !$plugin_activate ): ?>
176
- <a class="install-now button button-success" href="<?= wp_nonce_url($this->getActionUrl('activate', array('id' => $addon['id'])), 'activate_' . $this->getResultId() . '_' . $addon['id']) ?>"><?php _e('Activate', 'clearfy') ?></a>
177
- <?php else: ?>
178
- <a class="install-now button" href="<?= wp_nonce_url($this->getActionUrl('deactivate', array('id' => $addon['id'])), 'deactivate_' . $this->getResultId() . '_' . $addon['id']) ?>"><?php _e('Deactivate', 'clearfy') ?></a>
179
- <?php endif; ?>
180
  </div>
181
  </div>
182
  <?php endforeach; ?>
@@ -185,39 +353,6 @@
185
  <?php
186
  }
187
 
188
- public function deactivateAction()
189
- {
190
- $plugin_id = $this->request->get('id', null, true);
191
- check_admin_referer('deactivate_' . $this->getResultId() . '_' . $plugin_id);
192
-
193
- $preinsatall_components = $this->plugin->getOption('deactive_preinstall_components', array());
194
-
195
- if( !in_array($plugin_id, $preinsatall_components) ) {
196
- $preinsatall_components[] = $plugin_id;
197
- }
198
-
199
- $this->plugin->updateOption('deactive_preinstall_components', $preinsatall_components);
200
- $this->redirectToAction('index');
201
- }
202
-
203
- public function activateAction()
204
- {
205
- $plugin_id = $this->request->get('id', null, true);
206
- check_admin_referer('activate_' . $this->getResultId() . '_' . $plugin_id);
207
-
208
- $preinsatall_components = $this->plugin->getOption('deactive_preinstall_components', array());
209
-
210
- if( in_array($plugin_id, $preinsatall_components) ) {
211
- foreach($preinsatall_components as $key => $component) {
212
- if( $component == $plugin_id ) {
213
- unset($preinsatall_components[$key]);
214
- }
215
- }
216
- }
217
-
218
- $this->plugin->updateOption('deactive_preinstall_components', $preinsatall_components);
219
- $this->redirectToAction('index');
220
- }
221
  }
222
 
223
 
19
  * The id of the page in the admin menu.
20
  *
21
  * Mainly used to navigate between pages.
22
+ * @see FactoryPages407_AdminPage
23
  *
24
  * @since 1.0.0
25
  * @var string
47
  /**
48
  * Requests assets (js and css) for the page.
49
  *
50
+ * @see FactoryPages407_AdminPage
51
  *
52
  * @since 1.0.0
53
  * @return void
57
  parent::assets($scripts, $styles);
58
 
59
  $this->styles->add(WCL_PLUGIN_URL . '/admin/assets/css/components.css');
60
+ $this->scripts->add(WCL_PLUGIN_URL . '/admin/assets/js/update-package.js');
61
+ }
62
+
63
+ public function warningNotice() {
64
+ $package_plugin = WCL_Package::instance();
65
+ $package_update_notice = $package_plugin->getUpdateNotice();
66
+
67
+
68
+ if ( $package_update_notice ) {
69
+ $this->printWarningNotice( $package_update_notice );
70
+ }
71
+ }
72
+
73
+ public function order( $components ) {
74
+
75
+ $deactivate_components = WCL_Plugin::app()->getOption( 'deactive_preinstall_components', array() ); // это для всех остальных аддонов
76
+ $ordered_components = array(
77
+ 'premium_active' => array(),
78
+ 'premium_deactive' => array(),
79
+ 'free_active' => array(),
80
+ 'free_deactive' => array(),
81
+ );
82
+ $order_key = 'free_deactive';
83
+ foreach ( $components as $component ) {
84
+ if ( in_array( $component['type'], array( 'wordpress', 'internal' ) ) ) {
85
+ if ( in_array( $component['name'], $deactivate_components ) ) {
86
+ // бесплатный компонент деактивирован
87
+ $order_key = 'free_deactive';
88
+ } else {
89
+ // бесплатный компонент активирован
90
+ $order_key = 'free_active';
91
+ }
92
+ } elseif ( $component['type'] == 'freemius' ) {
93
+ if ( $component['is_free'] ) {
94
+ // фримиус бесплатный
95
+ if ( $component['actived'] ) {
96
+ $order_key = 'free_active';
97
+ } else {
98
+ $order_key = 'free_deactive';
99
+ }
100
+ } else {
101
+ // фримиус премиум
102
+ if ( $component['actived'] ) {
103
+ $order_key = 'premium_active';
104
+ } else {
105
+ $order_key = 'premium_deactive';
106
+ }
107
+ }
108
+ }
109
+ $ordered_components[$order_key][] = $component;
110
+ }
111
+
112
+ return array_merge(
113
+ $ordered_components['premium_active'],
114
+ $ordered_components['premium_deactive'],
115
+ $ordered_components['free_active'],
116
+ $ordered_components['free_deactive']
117
+ );
118
  }
119
 
120
  public function showPageContent()
121
  {
122
+ $freemius_activated_addons = WCL_Plugin::app()->getOption( 'freemius_activated_addons', array() ); // это только для фримиус
123
 
124
  $default_image = 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzNjAiIGhlaWdodD0iMzYwIiB2aWV3Ym94PSIwIDAgMzYwIDM2MCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0icmdiKDcwLCA4MSwgOTMpIiAvPjxwb2x5bGluZSBwb2ludHM9IjE5LjgsMCw0MC4yLDAsNjAsMTkuOCw2MCw0MC4yLDQwLjIsNjAsMTkuOCw2MCwwLDQwLjIsMCwxOS44LDE5LjgsMCIgZmlsbD0iIzIyMiIgZmlsbC1vcGFjaXR5PSIwLjE1IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLCAwKSIgLz48cG9seWxpbmUgcG9pbnRzPSIxOS44LDAsNDAuMiwwLDYwLDE5LjgsNjAsNDAuMiw0MC4yLDYwLDE5LjgsNjAsMCw0MC4yLDAsMTkuOCwxOS44LDAiIGZpbGw9IiNkZGQiIGZpbGwtb3BhY2l0eT0iMC4wNTQ2NjY2NjY2NjY2NjciIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9IjAuMDIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDYwLCAwKSIgLz48cG9seWxpbmUgcG9pbnRzPSIxOS44LDAsNDAuMiwwLDYwLDE5LjgsNjAsNDAuMiw0MC4yLDYwLDE5LjgsNjAsMCw0MC4yLDAsMTkuOCwxOS44LDAiIGZpbGw9IiMyMjIiIGZpbGwtb3BhY2l0eT0iMC4wNDYiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9IjAuMDIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEyMCwgMCkiIC8+PHBvbHlsaW5lIHBvaW50cz0iMTkuOCwwLDQwLjIsMCw2MCwxOS44LDYwLDQwLjIsNDAuMiw2MCwxOS44LDYwLDAsNDAuMiwwLDE5LjgsMTkuOCwwIiBmaWxsPSIjZGRkIiBmaWxsLW9wYWNpdHk9IjAuMDIiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9IjAuMDIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE4MCwgMCkiIC8+PHBvbHlsaW5lIHBvaW50cz0iMTkuOCwwLDQwLjIsMCw2MCwxOS44LDYwLDQwLjIsNDAuMiw2MCwxOS44LDYwLDAsNDAuMiwwLDE5LjgsMTkuOCwwIiBmaWxsPSIjZGRkIiBmaWxsLW9wYWNpdHk9IjAuMDU0NjY2NjY2NjY2NjY3IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyNDAsIDApIiAvPjxwb2x5bGluZSBwb2ludHM9IjE5LjgsMCw0MC4yLDAsNjAsMTkuOCw2MCw0MC4yLDQwLjIsNjAsMTkuOCw2MCwwLDQwLjIsMCwxOS44LDE5LjgsMCIgZmlsbD0iIzIyMiIgZmlsbC1vcGFjaXR5PSIwLjAyODY2NjY2NjY2NjY2NyIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utb3BhY2l0eT0iMC4wMiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzAwLCAwKSIgLz48cG9seWxpbmUgcG9pbnRzPSIxOS44LDAsNDAuMiwwLDYwLDE5LjgsNjAsNDAuMiw0MC4yLDYwLDE5LjgsNjAsMCw0MC4yLDAsMTkuOCwxOS44LDAiIGZpbGw9IiNkZGQiIGZpbGwtb3BhY2l0eT0iMC4xMDY2NjY2NjY2NjY2NyIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utb3BhY2l0eT0iMC4wMiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwgNjApIiAvPjxwb2x5bGluZSBwb2ludHM9IjE5LjgsMCw0MC4yLDAsNjAsMTkuOCw2MCw0MC4yLDQwLjIsNjAsMTkuOCw2MCwwLDQwLjIsMCwxOS44LDE5LjgsMCIgZmlsbD0iIzIyMiIgZmlsbC1vcGFjaXR5PSIwLjA5OCIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utb3BhY2l0eT0iMC4wMiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNjAsIDYwKSIgLz48cG9seWxpbmUgcG9pbnRzPSIxOS44LDAsNDAuMiwwLDYwLDE5LjgsNjAsNDAuMiw0MC4yLDYwLDE5LjgsNjAsMCw0MC4yLDAsMTkuOCwxOS44LDAiIGZpbGw9IiMyMjIiIGZpbGwtb3BhY2l0eT0iMC4xMTUzMzMzMzMzMzMzMyIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utb3BhY2l0eT0iMC4wMiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTIwLCA2MCkiIC8+PHBvbHlsaW5lIHBvaW50cz0iMTkuOCwwLDQwLjIsMCw2MCwxOS44LDYwLDQwLjIsNDAuMiw2MCwxOS44LDYwLDAsNDAuMiwwLDE5LjgsMTkuOCwwIiBmaWxsPSIjMjIyIiBmaWxsLW9wYWNpdHk9IjAuMDYzMzMzMzMzMzMzMzMzIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxODAsIDYwKSIgLz48cG9seWxpbmUgcG9pbnRzPSIxOS44LDAsNDAuMiwwLDYwLDE5LjgsNjAsNDAuMiw0MC4yLDYwLDE5LjgsNjAsMCw0MC4yLDAsMTkuOCwxOS44LDAiIGZpbGw9IiNkZGQiIGZpbGwtb3BhY2l0eT0iMC4wMzczMzMzMzMzMzMzMzMiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9IjAuMDIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDI0MCwgNjApIiAvPjxwb2x5bGluZSBwb2ludHM9IjE5LjgsMCw0MC4yLDAsNjAsMTkuOCw2MCw0MC4yLDQwLjIsNjAsMTkuOCw2MCwwLDQwLjIsMCwxOS44LDE5LjgsMCIgZmlsbD0iI2RkZCIgZmlsbC1vcGFjaXR5PSIwLjE0MTMzMzMzMzMzMzMzIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzMDAsIDYwKSIgLz48cG9seWxpbmUgcG9pbnRzPSIxOS44LDAsNDAuMiwwLDYwLDE5LjgsNjAsNDAuMiw0MC4yLDYwLDE5LjgsNjAsMCw0MC4yLDAsMTkuOCwxOS44LDAiIGZpbGw9IiNkZGQiIGZpbGwtb3BhY2l0eT0iMC4wMzczMzMzMzMzMzMzMzMiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9IjAuMDIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsIDEyMCkiIC8+PHBvbHlsaW5lIHBvaW50cz0iMTkuOCwwLDQwLjIsMCw2MCwxOS44LDYwLDQwLjIsNDAuMiw2MCwxOS44LDYwLDAsNDAuMiwwLDE5LjgsMTkuOCwwIiBmaWxsPSIjZGRkIiBmaWxsLW9wYWNpdHk9IjAuMDg5MzMzMzMzMzMzMzMzIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg2MCwgMTIwKSIgLz48cG9seWxpbmUgcG9pbnRzPSIxOS44LDAsNDAuMiwwLDYwLDE5LjgsNjAsNDAuMiw0MC4yLDYwLDE5LjgsNjAsMCw0MC4yLDAsMTkuOCwxOS44LDAiIGZpbGw9IiNkZGQiIGZpbGwtb3BhY2l0eT0iMC4wODkzMzMzMzMzMzMzMzMiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9IjAuMDIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEyMCwgMTIwKSIgLz48cG9seWxpbmUgcG9pbnRzPSIxOS44LDAsNDAuMiwwLDYwLDE5LjgsNjAsNDAuMiw0MC4yLDYwLDE5LjgsNjAsMCw0MC4yLDAsMTkuOCwxOS44LDAiIGZpbGw9IiMyMjIiIGZpbGwtb3BhY2l0eT0iMC4wODA2NjY2NjY2NjY2NjciIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9IjAuMDIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE4MCwgMTIwKSIgLz48cG9seWxpbmUgcG9pbnRzPSIxOS44LDAsNDAuMiwwLDYwLDE5LjgsNjAsNDAuMiw0MC4yLDYwLDE5LjgsNjAsMCw0MC4yLDAsMTkuOCwxOS44LDAiIGZpbGw9IiMyMjIiIGZpbGwtb3BhY2l0eT0iMC4xMzI2NjY2NjY2NjY2NyIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utb3BhY2l0eT0iMC4wMiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjQwLCAxMjApIiAvPjxwb2x5bGluZSBwb2ludHM9IjE5LjgsMCw0MC4yLDAsNjAsMTkuOCw2MCw0MC4yLDQwLjIsNjAsMTkuOCw2MCwwLDQwLjIsMCwxOS44LDE5LjgsMCIgZmlsbD0iIzIyMiIgZmlsbC1vcGFjaXR5PSIwLjE1IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzMDAsIDEyMCkiIC8+PHBvbHlsaW5lIHBvaW50cz0iMTkuOCwwLDQwLjIsMCw2MCwxOS44LDYwLDQwLjIsNDAuMiw2MCwxOS44LDYwLDAsNDAuMiwwLDE5LjgsMTkuOCwwIiBmaWxsPSIjMjIyIiBmaWxsLW9wYWNpdHk9IjAuMDk4IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLCAxODApIiAvPjxwb2x5bGluZSBwb2ludHM9IjE5LjgsMCw0MC4yLDAsNjAsMTkuOCw2MCw0MC4yLDQwLjIsNjAsMTkuOCw2MCwwLDQwLjIsMCwxOS44LDE5LjgsMCIgZmlsbD0iIzIyMiIgZmlsbC1vcGFjaXR5PSIwLjA2MzMzMzMzMzMzMzMzMyIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utb3BhY2l0eT0iMC4wMiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNjAsIDE4MCkiIC8+PHBvbHlsaW5lIHBvaW50cz0iMTkuOCwwLDQwLjIsMCw2MCwxOS44LDYwLDQwLjIsNDAuMiw2MCwxOS44LDYwLDAsNDAuMiwwLDE5LjgsMTkuOCwwIiBmaWxsPSIjZGRkIiBmaWxsLW9wYWNpdHk9IjAuMDIiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9IjAuMDIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEyMCwgMTgwKSIgLz48cG9seWxpbmUgcG9pbnRzPSIxOS44LDAsNDAuMiwwLDYwLDE5LjgsNjAsNDAuMiw0MC4yLDYwLDE5LjgsNjAsMCw0MC4yLDAsMTkuOCwxOS44LDAiIGZpbGw9IiNkZGQiIGZpbGwtb3BhY2l0eT0iMC4wMzczMzMzMzMzMzMzMzMiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9IjAuMDIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE4MCwgMTgwKSIgLz48cG9seWxpbmUgcG9pbnRzPSIxOS44LDAsNDAuMiwwLDYwLDE5LjgsNjAsNDAuMiw0MC4yLDYwLDE5LjgsNjAsMCw0MC4yLDAsMTkuOCwxOS44LDAiIGZpbGw9IiMyMjIiIGZpbGwtb3BhY2l0eT0iMC4xMTUzMzMzMzMzMzMzMyIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utb3BhY2l0eT0iMC4wMiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjQwLCAxODApIiAvPjxwb2x5bGluZSBwb2ludHM9IjE5LjgsMCw0MC4yLDAsNjAsMTkuOCw2MCw0MC4yLDQwLjIsNjAsMTkuOCw2MCwwLDQwLjIsMCwxOS44LDE5LjgsMCIgZmlsbD0iIzIyMiIgZmlsbC1vcGFjaXR5PSIwLjA2MzMzMzMzMzMzMzMzMyIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utb3BhY2l0eT0iMC4wMiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzAwLCAxODApIiAvPjxwb2x5bGluZSBwb2ludHM9IjE5LjgsMCw0MC4yLDAsNjAsMTkuOCw2MCw0MC4yLDQwLjIsNjAsMTkuOCw2MCwwLDQwLjIsMCwxOS44LDE5LjgsMCIgZmlsbD0iI2RkZCIgZmlsbC1vcGFjaXR5PSIwLjA1NDY2NjY2NjY2NjY2NyIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utb3BhY2l0eT0iMC4wMiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwgMjQwKSIgLz48cG9seWxpbmUgcG9pbnRzPSIxOS44LDAsNDAuMiwwLDYwLDE5LjgsNjAsNDAuMiw0MC4yLDYwLDE5LjgsNjAsMCw0MC4yLDAsMTkuOCwxOS44LDAiIGZpbGw9IiNkZGQiIGZpbGwtb3BhY2l0eT0iMC4xMDY2NjY2NjY2NjY2NyIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utb3BhY2l0eT0iMC4wMiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNjAsIDI0MCkiIC8+PHBvbHlsaW5lIHBvaW50cz0iMTkuOCwwLDQwLjIsMCw2MCwxOS44LDYwLDQwLjIsNDAuMiw2MCwxOS44LDYwLDAsNDAuMiwwLDE5LjgsMTkuOCwwIiBmaWxsPSIjZGRkIiBmaWxsLW9wYWNpdHk9IjAuMDcyIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMjAsIDI0MCkiIC8+PHBvbHlsaW5lIHBvaW50cz0iMTkuOCwwLDQwLjIsMCw2MCwxOS44LDYwLDQwLjIsNDAuMiw2MCwxOS44LDYwLDAsNDAuMiwwLDE5LjgsMTkuOCwwIiBmaWxsPSIjMjIyIiBmaWxsLW9wYWNpdHk9IjAuMTE1MzMzMzMzMzMzMzMiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9IjAuMDIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE4MCwgMjQwKSIgLz48cG9seWxpbmUgcG9pbnRzPSIxOS44LDAsNDAuMiwwLDYwLDE5LjgsNjAsNDAuMiw0MC4yLDYwLDE5LjgsNjAsMCw0MC4yLDAsMTkuOCwxOS44LDAiIGZpbGw9IiMyMjIiIGZpbGwtb3BhY2l0eT0iMC4xMzI2NjY2NjY2NjY2NyIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utb3BhY2l0eT0iMC4wMiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjQwLCAyNDApIiAvPjxwb2x5bGluZSBwb2ludHM9IjE5LjgsMCw0MC4yLDAsNjAsMTkuOCw2MCw0MC4yLDQwLjIsNjAsMTkuOCw2MCwwLDQwLjIsMCwxOS44LDE5LjgsMCIgZmlsbD0iIzIyMiIgZmlsbC1vcGFjaXR5PSIwLjA4MDY2NjY2NjY2NjY2NyIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utb3BhY2l0eT0iMC4wMiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzAwLCAyNDApIiAvPjxwb2x5bGluZSBwb2ludHM9IjE5LjgsMCw0MC4yLDAsNjAsMTkuOCw2MCw0MC4yLDQwLjIsNjAsMTkuOCw2MCwwLDQwLjIsMCwxOS44LDE5LjgsMCIgZmlsbD0iIzIyMiIgZmlsbC1vcGFjaXR5PSIwLjEzMjY2NjY2NjY2NjY3IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLCAzMDApIiAvPjxwb2x5bGluZSBwb2ludHM9IjE5LjgsMCw0MC4yLDAsNjAsMTkuOCw2MCw0MC4yLDQwLjIsNjAsMTkuOCw2MCwwLDQwLjIsMCwxOS44LDE5LjgsMCIgZmlsbD0iI2RkZCIgZmlsbC1vcGFjaXR5PSIwLjAzNzMzMzMzMzMzMzMzMyIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utb3BhY2l0eT0iMC4wMiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNjAsIDMwMCkiIC8+PHBvbHlsaW5lIHBvaW50cz0iMTkuOCwwLDQwLjIsMCw2MCwxOS44LDYwLDQwLjIsNDAuMiw2MCwxOS44LDYwLDAsNDAuMiwwLDE5LjgsMTkuOCwwIiBmaWxsPSIjZGRkIiBmaWxsLW9wYWNpdHk9IjAuMTI0IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMjAsIDMwMCkiIC8+PHBvbHlsaW5lIHBvaW50cz0iMTkuOCwwLDQwLjIsMCw2MCwxOS44LDYwLDQwLjIsNDAuMiw2MCwxOS44LDYwLDAsNDAuMiwwLDE5LjgsMTkuOCwwIiBmaWxsPSIjMjIyIiBmaWxsLW9wYWNpdHk9IjAuMDI4NjY2NjY2NjY2NjY3IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxODAsIDMwMCkiIC8+PHBvbHlsaW5lIHBvaW50cz0iMTkuOCwwLDQwLjIsMCw2MCwxOS44LDYwLDQwLjIsNDAuMiw2MCwxOS44LDYwLDAsNDAuMiwwLDE5LjgsMTkuOCwwIiBmaWxsPSIjZGRkIiBmaWxsLW9wYWNpdHk9IjAuMDcyIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyNDAsIDMwMCkiIC8+PHBvbHlsaW5lIHBvaW50cz0iMTkuOCwwLDQwLjIsMCw2MCwxOS44LDYwLDQwLjIsNDAuMiw2MCwxOS44LDYwLDAsNDAuMiwwLDE5LjgsMTkuOCwwIiBmaWxsPSIjMjIyIiBmaWxsLW9wYWNpdHk9IjAuMDI4NjY2NjY2NjY2NjY3IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzMDAsIDMwMCkiIC8+PC9zdmc+';
125
 
126
  $response = array(
127
  array(
128
+ 'name' => 'robin_image_optimizer',
129
+ 'title' => __('Robin image optimizer', 'clearfy'),
130
+ 'url' => 'https://wordpress.org/plugins/robin-image-optimizer/',
131
+ 'type' => 'wordpress',
132
+ 'base_path' => 'robin-image-optimizer/robin-image-optimizer.php',
133
+ 'icon' => $default_image,
134
+ 'description' => __('Automatic image optimization without any quality loss. No limitations, no paid plans. The best Wordpress image optimization plugin allows optimizing any amount of images for free!', 'clearfy')
135
+ ),
136
+ array(
137
+ 'name' => 'hide_login_page',
138
  'title' => __('Hide login page', 'clearfy'),
139
+ 'url' => 'https://wordpress.org/plugins/hide-login-page/',
140
+ 'type' => 'wordpress',
141
+ 'base_path' => 'hide-login-page/hide-login-page.php',
142
+ 'icon' => WCL_PLUGIN_URL . '/admin/assets/img/hlp-icon-128x128.png',
143
+ 'description' => __('Hide Login Page is a very light plugin that lets you easily and safely change the url of the login form page to anything you want.', 'clearfy')
144
+ ),
145
+ array(
146
+ 'name' => 'html_minify',
147
+ 'title' => __('Html minify', 'clearfy'),
148
  'url' => '#',
149
+ 'type' => 'internal',
150
  'icon' => $default_image,
151
+ 'description' => __('Ever look at the HTML markup of your website and notice how sloppy and amateurish it looks? The Minify HTML options cleans up sloppy looking markup and minifies, which also speeds up download', 'clearfy')
152
  ),
153
  array(
154
+ 'name' => 'minify_and_combine',
155
+ 'title' => __('Minify and combine (JS, CSS)', 'clearfy'),
156
  'url' => '#',
157
+ 'type' => 'internal',
158
+ 'icon' => $default_image,
159
+ 'description' => __('Improve your speed score on GTmetrix, Pingdom Tools and Google PageSpeed Insights by merging and minifying CSS, JavaScript.', 'clearfy')
160
+ ),
161
+ array(
162
+ 'name' => 'ga_cache',
163
+ 'title' => __('Google Analytics Cache', 'clearfy'),
164
+ 'url' => 'https://wordpress.org/plugins/simple-google-analytics/',
165
+ 'type' => 'internal',
166
+ 'icon' => $default_image,
167
+ 'description' => __('To improve Google Page Speed indicators Analytics caching is needed. However, it can also slightly increase your website loading speed, because Analytics js files will load locally.', 'clearfy')
168
+ ),
169
+ array(
170
+ 'name' => 'updates_manager',
171
+ 'title' => __('Updates manager', 'clearfy'),
172
+ 'url' => 'https://wordpress.org/plugins/webcraftic-updates-manager/',
173
+ 'type' => 'internal',
174
  'icon' => WCL_PLUGIN_URL . '/admin/assets/img/upm-icon-128x128.png',
175
  'description' => __('Disable updates enable auto updates for themes, plugins and WordPress.', 'clearfy')
176
  ),
177
  array(
178
+ 'name' => 'comments_tools',
179
  'title' => __('Comments tools', 'clearfy'),
180
  'url' => '#',
181
+ 'type' => 'internal',
182
  'icon' => WCL_PLUGIN_URL . '/admin/assets/img/dic-icon-128x128.png',
183
  'description' => __('Bulk disable and remove comments, disable “Website” field, hides external links, disable XML-RPC.', 'clearfy')
184
  ),
185
  array(
186
+ 'name' => 'widget_tools',
187
  'title' => __('Widgets tools', 'clearfy'),
188
  'url' => '#',
189
+ 'type' => 'internal',
190
  'icon' => $default_image,
191
  'description' => __('Disable unused widgets such as tag cloud, links, calendar etc.', 'clearfy')
192
  ),
193
  array(
194
+ 'name' => 'asset_manager',
195
  'title' => __('Asset manager', 'clearfy'),
196
  'url' => '#',
197
+ 'type' => 'internal',
198
  'icon' => WCL_PLUGIN_URL . '/admin/assets/img/asm-icon-128x128.png',
199
  'description' => __('Selectively disable unused scripts and styles on the pages of your website.', 'clearfy')
200
  ),
201
  array(
202
+ 'name' => 'disable_notices',
203
  'title' => __('Disable admin notices', 'clearfy'),
204
  'url' => '#',
205
+ 'type' => 'internal',
206
  'icon' => WCL_PLUGIN_URL . '/admin/assets/img/dan-icon-128x128.png',
207
  'description' => __('Disables admin notices bulk or individually. Collects notices into the admin bar.', 'clearfy')
208
  ),
209
  array(
210
+ 'name' => 'adminbar_manager',
211
  'title' => __('Admin bar manager', 'clearfy'),
212
  'url' => '#',
213
+ 'type' => 'internal',
214
  'icon' => $default_image,
215
  'description' => __('Disables admin bar. Allows to change and remove admin bar elements.', 'clearfy')
216
  ),
217
  array(
218
+ 'name' => 'post_tools',
219
  'title' => __('Posts tools', 'clearfy'),
220
  'url' => '#',
221
+ 'type' => 'internal',
222
  'icon' => $default_image,
223
  'description' => __('Disable revisions, disable posts autosave, disable smart quotes and disable auto paragraphs.', 'clearfy')
224
  ),
225
  array(
226
+ 'name' => 'yoast_seo',
227
  'title' => __('Yoast SEO optimization', 'clearfy'),
228
  'url' => '#',
229
+ 'type' => 'internal',
230
  'icon' => $default_image,
231
  'description' => __('Set of optimization functions for the popular Yoast SEO plugin.', 'clearfy')
232
  )
233
  );
234
 
235
  $response[] = array(
236
+ 'name' => 'cyrlitera',
237
  'title' => __('Transliteration of Cyrillic alphabet', 'clearfy'),
238
+ 'type' => 'internal',
239
+ 'url' => 'https://wordpress.org/plugins/cyrlitera/',
240
  'icon' => WCL_PLUGIN_URL . '/admin/assets/img/ctr-icon-128x128.png',
241
  'description' => __('Converts Cyrillic permalinks of post, pages, taxonomies and media files to the Latin alphabet. Supports Russian, Ukrainian, Georgian, Bulgarian languages.', 'clearfy')
242
  );
243
+
244
+ $licensing = WCL_Licensing::instance();
245
+ $freemius_addons_data = $licensing->getAddons(); // получаем все аддоны
246
+
247
+ if ( isset( $freemius_addons_data->plugins ) ) {
248
+ foreach( $freemius_addons_data->plugins as $freemius_addon ) {
249
+ $is_free_addon = false;
250
+ if ( $freemius_addon->free_releases_count ) {
251
+ $is_free_addon = true;
252
+ }
253
+ $actual_version = isset( $freemius_addon->info ) ? $freemius_addon->info->selling_point_0 : '';
254
+ if ( ! $actual_version ) {
255
+ $actual_version = $licensing->getAddonCurrentVersion( $freemius_addon->slug );
256
+ }
257
+ $component = array(
258
+ 'name' => $freemius_addon->slug,
259
+ 'slug' => $freemius_addon->slug,
260
+ 'title' => __( $freemius_addon->title, 'clearfy' ),
261
+ 'type' => 'freemius',
262
+ 'installed' => false,
263
+ 'is_free' => $is_free_addon,
264
+ 'actived' => false,
265
+ 'version' => $actual_version,
266
+ 'url' => isset( $freemius_addon->info ) ? $freemius_addon->info->url : '#',
267
+ 'icon' => isset( $freemius_addon->icon ) ? $freemius_addon->icon : WCL_PLUGIN_URL . '/admin/assets/img/ctr-icon-128x128.png',
268
+ 'description' => isset( $freemius_addon->info ) ? __( $freemius_addon->info->short_description, 'clearfy' ) : '',
269
+ );
270
+
271
+ if ( in_array( $component['name'], $freemius_activated_addons ) ) {
272
+ $component['actived'] = true;
273
+ }
274
+
275
+ array_unshift($response, $component);
276
+ }
277
+ }
278
+
279
+ $response = $this->order( $response );
280
  ?>
281
  <div class="wbcr-factory-page-group-header"><?php _e('<strong>Plugin Components</strong>.', 'clearfy') ?>
282
  <p>
285
  </div>
286
 
287
  <div class="wbcr-clearfy-components">
288
+ <?php foreach($response as $component): ?>
289
  <?php
 
 
290
 
291
+ $slug = $component['name'];
292
+
293
+ if($component['type'] == 'wordpress') {
294
+ $slug = $component['base_path'];
295
+ }
296
+
297
+ if( $component['type'] == 'freemius' ) {
298
+ $install_button = WCL_Plugin::app()->getInstallComponentsButton($component['type'], $slug);
299
+
300
+ if( ! $component['actived'] ) {
301
+ $status_class = ' plugin-status-deactive';
302
+ } else {
303
+ $status_class = ' plugin-status-active';
304
+ }
305
+
306
+ if(!$component['is_free']) {
307
+ $status_class .= ' premium';
308
+ }
309
+
310
+ } else {
311
+ $install_button = WCL_Plugin::app()->getInstallComponentsButton($component['type'], $slug);
312
+
313
+ $status_class = '';
314
+ if(!$install_button->isPluginActivate()) {
315
+ $status_class = ' plugin-status-deactive';
316
+ }
317
  }
318
+
319
+ $install_button->addClass( 'install-now' );
320
+
321
+ // Delete button
322
+ $delete_button = WCL_Plugin::app()->getDeleteComponentsButton($component['type'], $slug);
323
+ $delete_button->addClass('delete-now');
324
+
325
  ?>
326
 
327
  <div class="plugin-card<?= $status_class ?>">
328
+ <?php if($component['type'] == 'freemius' && !$component['is_free']): ?>
329
+ <div class="premium-ribbon"><?php _e('Premium', 'clearfy') ?></div>
330
+ <?php endif; ?>
331
  <div class="plugin-card-top">
332
  <div class="name column-name">
333
  <h3>
334
+ <a href="<?= $component['url'] ?>" class="thickbox open-plugin-details-modal">
335
+ <?= $component['title'] ?>
336
+ <img src="<?= $component['icon'] ?>" class="plugin-icon" alt="">
337
  </a>
338
  </h3>
339
  </div>
340
  <div class="desc column-description">
341
+ <p><?= $component['description']; ?></p>
342
+ <?php // для теста выводим текущую версию и актуальную ?>
343
+ <?php if ( isset( $component['version'] ) ) : ?><p>Freemius: <?php echo $component['version']; ?>, current: <?php echo $licensing->getAddonCurrentVersion( $slug ); ?></p><?php endif; ?>
344
  </div>
345
  </div>
346
  <div class="plugin-card-bottom">
347
+ <?php $delete_button->renderButton(); ?> <?php $install_button->renderButton(); ?>
 
 
 
 
348
  </div>
349
  </div>
350
  <?php endforeach; ?>
353
  <?php
354
  }
355
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
356
  }
357
 
358
 
admin/pages/defence-privacy-code.php DELETED
@@ -1,90 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * The page Settings.
5
- *
6
- * @since 1.0.0
7
- */
8
-
9
- // Exit if accessed directly
10
- if( !defined('ABSPATH') ) {
11
- exit;
12
- }
13
-
14
- class WCL_PrivacyContentPage extends WCL_Page {
15
-
16
- /**
17
- * The id of the page in the admin menu.
18
- *
19
- * Mainly used to navigate between pages.
20
- * @see FactoryPages401_AdminPage
21
- *
22
- * @since 1.0.0
23
- * @var string
24
- */
25
- public $id = "privacy";
26
-
27
- public $page_parent_page = 'defence';
28
-
29
- public $page_menu_position = 15;
30
-
31
- public $page_menu_dashicon = 'dashicons-hidden';
32
-
33
- /**
34
- * @param WCL_Plugin $plugin
35
- */
36
- public function __construct(WCL_Plugin $plugin)
37
- {
38
- $this->menu_title = __('Code privacy', 'clearfy');
39
-
40
- parent::__construct($plugin);
41
-
42
- $this->plugin = $plugin;
43
- }
44
-
45
- /**
46
- * Permalinks options.
47
- *
48
- * @since 1.0.0
49
- * @return mixed[]
50
- */
51
- public function getOptions()
52
- {
53
- $options = array();
54
-
55
- $options[] = array(
56
- 'type' => 'html',
57
- 'html' => '<div class="wbcr-factory-page-group-header">' . __('<strong>Hide WordPress plugins versions</strong>.', 'clearfy') . '<p>' . __('WordPress itself and many plugins shows their version at the public areas of your site. An attacker received this information may be aware of the vulnerabilities found in the version of the WordPress core or plugins.', 'clearfy') . '</p></div>'
58
- );
59
-
60
- $options[] = array(
61
- 'type' => 'checkbox',
62
- 'way' => 'buttons',
63
- 'name' => 'remove_html_comments',
64
- 'title' => __('Remove html comments', 'clearfy'),
65
- 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
66
- 'hint' => __('This function will remove all html comments in the source code, except for special and hidden comments. This is necessary to hide the version of installed plugins.', 'clearfy') . '<br><br><b>Clearfy: </b>' . __('Remove html comments in source code.', 'clearfy'),
67
- 'default' => false
68
- );
69
-
70
- $options[] = array(
71
- 'type' => 'checkbox',
72
- 'way' => 'buttons',
73
- 'name' => 'remove_meta_generator',
74
- 'title' => __('Remove meta generator', 'clearfy') . ' <span class="wbcr-clearfy-recomended-text">(' . __('Recommended', 'clearfy') . ')</span>',
75
- 'layout' => array('hint-type' => 'icon'),
76
- 'hint' => __('Allows attacker to learn the version of WP installed on the site. This meta tag has no useful function.', 'clearfy') . '<br><b>Clearfy: </b>' . sprintf(__('Removes the meta tag from the %s section', 'clearfy'), '&lt;head&gt;'),
77
- 'default' => false
78
- );
79
-
80
- $form_options = array();
81
-
82
- $form_options[] = array(
83
- 'type' => 'form-group',
84
- 'items' => $options,
85
- //'cssClass' => 'postbox'
86
- );
87
-
88
- return apply_filters('wbcr_clr_privacy_form_options', $form_options, $this);
89
- }
90
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/pages/defence.php CHANGED
@@ -17,7 +17,7 @@
17
  * The id of the page in the admin menu.
18
  *
19
  * Mainly used to navigate between pages.
20
- * @see FactoryPages401_AdminPage
21
  *
22
  * @since 1.0.0
23
  * @var string
@@ -83,17 +83,93 @@
83
  'default' => false
84
  );
85
 
86
- //todo: убрать этот хук в hide my wp
87
- //$options = apply_filters('wbcr_clr_defence_form_base_options', $options);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
 
89
  $form_options = array();
90
 
91
  $form_options[] = array(
92
  'type' => 'form-group',
93
- 'items' => $options,
94
  //'cssClass' => 'postbox'
95
  );
96
-
97
- return apply_filters('wbcr_clr_defence_form_options', $form_options, $this);
 
 
 
98
  }
99
  }
17
  * The id of the page in the admin menu.
18
  *
19
  * Mainly used to navigate between pages.
20
+ * @see FactoryPages407_AdminPage
21
  *
22
  * @since 1.0.0
23
  * @var string
83
  'default' => false
84
  );
85
 
86
+ $options[] = array(
87
+ 'type' => 'html',
88
+ 'html' => '<div class="wbcr-factory-page-group-header">' . __('<strong>Hide WordPress versions</strong>', 'clearfy') . '<p>' . __('WordPress itself and many plugins shows their version at the public areas of your site. An attacker received this information may be aware of the vulnerabilities found in the version of the WordPress core or plugins.', 'clearfy') . '</p></div>'
89
+ );
90
+
91
+ $options[] = array(
92
+ 'type' => 'checkbox',
93
+ 'way' => 'buttons',
94
+ 'name' => 'remove_html_comments',
95
+ 'title' => __('Remove html comments', 'clearfy'),
96
+ 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
97
+ 'hint' => __('This function will remove all html comments in the source code, except for special and hidden comments. This is necessary to hide the version of installed plugins.', 'clearfy') . '<br><br><b>Clearfy: </b>' . __('Remove html comments in source code.', 'clearfy'),
98
+ 'default' => false
99
+ );
100
+
101
+ $options[] = array(
102
+ 'type' => 'checkbox',
103
+ 'way' => 'buttons',
104
+ 'name' => 'remove_meta_generator',
105
+ 'title' => __('Remove meta generator', 'clearfy') . ' <span class="wbcr-clearfy-recomended-text">(' . __('Recommended', 'clearfy') . ')</span>',
106
+ 'layout' => array('hint-type' => 'icon'),
107
+ 'hint' => __('Allows attacker to learn the version of WP installed on the site. This meta tag has no useful function.', 'clearfy') . '<br><b>Clearfy: </b>' . sprintf(__('Removes the meta tag from the %s section', 'clearfy'), '&lt;head&gt;'),
108
+ 'default' => false
109
+ );
110
+
111
+ $options[] = array(
112
+ 'type' => 'html',
113
+ 'html' => '<div class="wbcr-clearfy-group-header">' . '<strong>' . __('Remove query strings from static resources', 'clearfy') . '</strong>' . '<p>' . __('This funcitons will remove query strings from static resources like CSS & JS files inside the HTML <head> element to improve your speed scores in services like Pingdom, GTmetrix, PageSpeed and YSlow.', 'clearfy') . '</p>' . '</div>'
114
+ );
115
+
116
+ $options[] = array(
117
+ 'type' => 'checkbox',
118
+ 'way' => 'buttons',
119
+ 'name' => 'remove_js_version',
120
+ 'title' => __('Remove Version from Script', 'clearfy') . ' <span class="wbcr-clearfy-recomended-text">(' . __('Recommended', 'clearfy') . ')</span>',
121
+ 'layout' => array('hint-type' => 'icon'),
122
+ 'hint' => __('To make it more difficult for others to hack your website you can remove the WordPress version number from your site, your css and js. Without that number it\'s not possible to see if you run not the current version to exploit bugs from the older versions. <br><br>
123
+ Additionally it can improve the loading speed of your site, because without query strings in the URL the css and js files can be cached.', 'clearfy') . '<br><br><b>Clearfy: </b>' . __('Removes wordpress version number from scripts (not logged in user only).', 'clearfy'),
124
+ 'default' => false
125
+ );
126
+
127
+ $options[] = array(
128
+ 'type' => 'checkbox',
129
+ 'way' => 'buttons',
130
+ 'name' => 'remove_style_version',
131
+ 'title' => __('Remove Version from Stylesheet', 'clearfy') . ' <span class="wbcr-clearfy-recomended-text">(' . __('Recommended', 'clearfy') . ')</span>',
132
+ 'layout' => array('hint-type' => 'icon'),
133
+ 'hint' => __('To make it more difficult for others to hack your website you can remove the WordPress version number from your site, your css and js. Without that number it\'s not possible to see if you run not the current version to exploit bugs from the older versions. <br><br>
134
+ Additionally it can improve the loading speed of your site, because without query strings in the URL the css and js files can be cached.', 'clearfy') . '<br><br><b>Clearfy: </b>' . __('Removes the wordpress version number from stylesheets (not logged in user only).', 'clearfy'),
135
+ 'default' => false
136
+ /*'eventsOn' => array(
137
+ 'show' => '.factory-control-disable_remove_style_version_for_auth_users'
138
+ ),
139
+ 'eventsOff' => array(
140
+ 'hide' => '.factory-control-disable_remove_style_version_for_auth_users'
141
+ )*/
142
+ );
143
+
144
+ $options[] = array(
145
+ 'type' => 'checkbox',
146
+ 'way' => 'buttons',
147
+ 'name' => 'disable_remove_style_version_for_auth_users',
148
+ 'title' => __('Disable remove versions for auth users', 'clearfy') . ' <span class="wbcr-clearfy-recomended-text">(' . __('Recommended', 'clearfy') . ')</span>',
149
+ 'layout' => array('hint-type' => 'icon'),
150
+ 'default' => true
151
+ );
152
+
153
+ $options[] = array(
154
+ 'type' => 'textarea',
155
+ 'name' => 'remove_version_exclude',
156
+ 'height' => '120',
157
+ 'title' => __('Exclude stylesheet/script file names', 'clearfy'),
158
+ 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
159
+ 'hint' => __('Enter Stylesheet/Script file names to exclude from version removal (each exclude file starts with a new line)', 'clearfy') . '<br><br><b>' . __('Example', 'clearfy') . ':</b>' . ' http://testwp.dev/wp-includes/js/jquery/jquery.js',
160
+ );
161
 
162
  $form_options = array();
163
 
164
  $form_options[] = array(
165
  'type' => 'form-group',
166
+ 'items' => apply_filters('wbcr_clearfy_defence_form_options', $options, $this),
167
  //'cssClass' => 'postbox'
168
  );
169
+
170
+ return wbcr_factory_406_apply_filters_deprecated('wbcr_clr_defence_form_options', array(
171
+ $form_options,
172
+ $this
173
+ ), '1.3.1', 'wbcr_clearfy_defence_form_options');
174
  }
175
  }
admin/pages/license.php ADDED
@@ -0,0 +1,429 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The page License page class.
4
+ *
5
+ * @since 1.0.0
6
+ */
7
+
8
+ // Exit if accessed directly
9
+ if( !defined('ABSPATH') ) {
10
+ exit;
11
+ }
12
+
13
+ class WCL_LicensePage extends WCL_Page {
14
+
15
+ /**
16
+ * The id of the page in the admin menu.
17
+ *
18
+ * Mainly used to navigate between pages.
19
+ * @see Wbcr_FactoryPages407_AdminPage
20
+ *
21
+ * @since 1.0.0
22
+ * @var string
23
+ */
24
+ public $id = "license";
25
+
26
+ /**
27
+ * Тип страницы - произвольный контент
28
+ * @var string
29
+ */
30
+ public $type = "page";
31
+
32
+ /**
33
+ * Иконка страницы
34
+ * Полный список иконок смотреть тут:
35
+ * https://developer.wordpress.org/resource/dashicons/#admin-network
36
+ * @var string
37
+ */
38
+ public $page_menu_dashicon = 'dashicons-admin-network';
39
+
40
+ /**
41
+ * Позиция закладки в меню плагина.
42
+ * 0 - в самом конце, 100 - в самом начале
43
+ * @var int
44
+ */
45
+ public $page_menu_position = 0;
46
+
47
+ /**
48
+ * @param WCL_Plugin $plugin
49
+ */
50
+ public function __construct(WCL_Plugin $plugin)
51
+ {
52
+ $this->menu_title = __('License', 'clearfy');
53
+
54
+ parent::__construct($plugin);
55
+
56
+ $this->plugin = $plugin;
57
+ $this->hooks();
58
+ }
59
+
60
+ /**
61
+ * [MAGIC] Magic method that configures assets for a page.
62
+ */
63
+ public function assets($scripts, $styles)
64
+ {
65
+ parent::assets($scripts, $styles);
66
+
67
+ $this->styles->add(WCL_PLUGIN_URL . '/admin/assets/css/license-manager.css');
68
+ $this->scripts->add(WCL_PLUGIN_URL . '/admin/assets/js/license-manager.js');
69
+ }
70
+
71
+ public function hooks()
72
+ {
73
+ add_action('wp_ajax_wbcr_clr_licensing', array($this, 'ajax'));
74
+ add_action('wbcr_clr_license_autosync', array($this, 'autoSync'));
75
+ if( !wp_next_scheduled('wbcr_clr_license_autosync') ) {
76
+ wp_schedule_event(time(), 'twicedaily', 'wbcr_clr_license_autosync');
77
+ }
78
+ add_filter('site_transient_update_plugins', array($this, 'updateFreemiusAddons'));
79
+ add_action('wbcr_factory_pages_407_imppage_print_all_notices', array($this, 'printUpdateNotice'), 10, 2);
80
+ add_action('after_plugin_row_clearfy/clearfy.php', array($this, 'addonsUpdateMessage'), 100, 3);
81
+ }
82
+
83
+ /**
84
+ * @param WCL_Plugin $plugin
85
+ * @param Wbcr_FactoryPages407_ImpressiveThemplate $obj
86
+ * @return bool
87
+ */
88
+ public function printUpdateNotice($plugin, $obj)
89
+ {
90
+ // выводим уведомление везде, кроме страницы компонентов. Там выводится отдельно.
91
+ if( ($this->plugin->getPluginName() != $plugin->getPluginName()) || ($obj->id == 'components') ) {
92
+ return false;
93
+ }
94
+ $package_plugin = WCL_Package::instance();
95
+ $package_update_notice = $package_plugin->getUpdateNotice();
96
+
97
+ if( $package_update_notice ) {
98
+ if( $obj->id != 'quick_start' ) {
99
+ $obj->scripts->add(WCL_PLUGIN_URL . '/admin/assets/js/update-package.js');
100
+ }
101
+ $obj->printWarningNotice($package_update_notice);
102
+ }
103
+ }
104
+
105
+ public function updateFreemiusAddons($transient)
106
+ {
107
+ if( empty($transient->checked) ) {
108
+ return $transient;
109
+ }
110
+
111
+ $package_plugin = WCL_Package::instance();
112
+ if( !$package_plugin->isActive() ) {
113
+ return $transient;
114
+ }
115
+ $need_update_package = $package_plugin->isNeedUpdate();
116
+ $need_update_addons = $package_plugin->isNeedUpdateAddons();
117
+ $info = $package_plugin->info();
118
+ if( $need_update_package and $need_update_addons ) {
119
+ $update_data = new stdClass();
120
+ $update_data->slug = $info['plugin_slug'];
121
+ $update_data->plugin = $info['plugin_basename'];
122
+ $update_data->new_version = '1.1';
123
+ $update_data->package = $package_plugin->downloadUrl();
124
+ //$res->compatibility = new stdClass();
125
+ $transient->response[$update_data->plugin] = $update_data;
126
+ }
127
+
128
+ return $transient;
129
+ }
130
+
131
+ public function addonsUpdateMessage($plugin_file, $plugin_data, $status)
132
+ {
133
+ $package_plugin = WCL_Package::instance();
134
+ $need_update_package = $package_plugin->isNeedUpdate();
135
+
136
+ if ( $need_update_package ) {
137
+ if ( $package_plugin->isNeedUpdateAddons() ) {
138
+ $package_plugin_info = $package_plugin->info();
139
+ $update_link = ' <a href="#" data-wpnonce="' . wp_create_nonce( 'package' ) . '" data-loading="'. __( 'Update in progress...', 'clearfy' ) .'" data-ok="'. __( 'Components have been successfully updated!', 'clearfy' ) .'" class="wbcr-clr-plugin-update-link">' . __( 'update now', 'clearfy' ) . '</a>';
140
+ printf(
141
+ '<tr class="plugin-update-tr active update">
142
+
143
+
144
+ <td colspan="3" class="plugin-update colspanchange">
145
+ <div class="update-message notice inline notice-warning notice-alt" style="background-color:#f5e9f5;border-color: #dab9da;">
146
+ <p>%s</p>
147
+ </div>
148
+ </td>
149
+
150
+ </tr>',
151
+ __( 'Updates are available for one of the components.', 'clearfy' ) . $update_link
152
+ );
153
+ }
154
+ }
155
+ }
156
+
157
+ public function ajax()
158
+ {
159
+ check_admin_referer('license');
160
+ $license_action = isset($_POST['license_action'])
161
+ ? $_POST['license_action']
162
+ : false;
163
+ $actions = array(
164
+ 'activate',
165
+ 'deactivate',
166
+ 'sync',
167
+ 'unsubscribe'
168
+ );
169
+ if( in_array($license_action, $actions) ) {
170
+ $method_name = $license_action . 'AjaxHandler';
171
+ $this->{$method_name}();
172
+ }
173
+ die();
174
+ }
175
+
176
+ public function autoSync()
177
+ {
178
+ $licensing = WCL_Licensing::instance();
179
+ $notice = $licensing->sync();
180
+ }
181
+
182
+ /**
183
+ * Метод печатает html содержимое страницы
184
+ * @return void
185
+ */
186
+ public function showPageContent()
187
+ {
188
+ ?>
189
+ <?php wp_nonce_field('license'); ?>
190
+ <div id="wcl-license-wrapper" data-loader="<?php echo WCL_PLUGIN_URL . '/admin/assets/img/loader.gif'; ?>">
191
+ <?php $this->showLicenseForm(); ?>
192
+ </div>
193
+
194
+ <?php
195
+ }
196
+
197
+ public function showLicenseForm($notice = false)
198
+ {
199
+ $licensing = WCL_Licensing::instance();
200
+ $storage = $licensing->getStorage();
201
+ $license = $storage->get('license');
202
+ // Тип лицензии, цветовое оформление для формы лицензирования
203
+ // free - бесплатная
204
+ // gift - пожизненная лицензия, лицензия на особых условиях
205
+ // trial - красный цвет, применяется для триалов, если лиценизия истекла или заблокирована
206
+ // paid - обычная оплаченная лицензия, в данный момент активна.
207
+ $license_type = 'free';
208
+ // Лицензионный ключ
209
+ $license_key = '';
210
+ // Тарифный план
211
+ $plan = 'free';
212
+ $premium = false;
213
+ $has_key = false;
214
+ // Сколько осталось дней до истечения лицензии
215
+ $remained = 999;
216
+ $subscribe = false;
217
+ if( isset($license->id) ) {
218
+ $subscribe = true;
219
+ $license_type = 'paid';
220
+ $activated = $license->activated;
221
+ $quota = $license->quota;
222
+ // Лицензионный ключ
223
+ $license_key = substr_replace($license->secret_key, '******', 15, 6);
224
+ // Тарифный план
225
+ $plan = $license->plan_title;
226
+ $premium = true;
227
+ $has_key = true;
228
+ // Сколько осталось дней до истечения лицензии
229
+ $remained = $license->remainingDays();
230
+ if( 1 == $license->billing_cycle ) {
231
+ $billing = 'month';
232
+ }
233
+ if( 12 == $license->billing_cycle ) {
234
+ $billing = 'year';
235
+ }
236
+ if( 0 == $license->billing_cycle ) {
237
+ $billing = 'lifetime';
238
+ }
239
+ if( $license->is_lifetime() ) {
240
+ $billing = 'lifetime';
241
+ $license_type = 'gift';
242
+ $quota = 999;
243
+ }
244
+ if( is_null($license->billing_cycle) ) {
245
+ $billing = 'month';
246
+ $subscribe = false;
247
+ }
248
+ }
249
+
250
+ if( $remained < 1 ) {
251
+ $license_type = 'trial';
252
+ }
253
+
254
+
255
+ ?>
256
+ <div class="factory-bootstrap-406 onp-page-wrap <?= $license_type ?>-license-manager-content" id="license-manager">
257
+ <div>
258
+ <h3><?php _e('Activation Clearfy Business', 'clearfy') ?></h3>
259
+
260
+ <p style="font-size: 16px;"><?php _e('<b>Clearfy Business</b> is a paid package of components for the popular free WordPress plugin named Clearfy. You get access to all paid components at one price.', 'clearfy')?></p>
261
+
262
+ <p style="font-size: 16px;"><?php _e('Paid license guarantees that you can download and update existing and future paid components of the plugin.', 'clearfy')?></p>
263
+ </div>
264
+ <br>
265
+ <?php if( is_wp_error($notice) ) : ?>
266
+ <div class="license-message <?= $license_type ?>-license-message">
267
+ <div class="alert <?php echo esc_attr($notice->get_error_code()); ?>">
268
+ <h4 class="alert-heading"><?php _e($notice->get_error_message(), 'clearfy') ?></h4>
269
+ </div>
270
+ </div>
271
+ <?php endif; ?>
272
+
273
+ <div class="onp-container">
274
+ <div class="license-details">
275
+ <a href="<?= $this->plugin->getAuthorSitePageUrl('pricing', 'license_page') ?>" class="purchase-premium" target="_blank" rel="noopener">
276
+ <span class="btn btn-gold btn-inner-wrap">
277
+ <i class="fa fa-star"></i> <?php printf(__('Upgrade to Premium for $%s', 'clearfy'), '19') ?>
278
+ <i class="fa fa-star"></i>
279
+ </span>
280
+ </a>
281
+
282
+ <p><?php printf(__('Your current license for %1$s:', 'clearfy'), $this->plugin->getPluginTitle()) ?></p>
283
+
284
+ <div class="license-details-block <?= $license_type ?>-details-block">
285
+ <?php if( $has_key ) { ?>
286
+ <a data-action="deactivate" href="#" class="btn btn-default btn-small license-delete-button wcl-control-btn"><i class="icon-remove-sign"></i> <?php _e('Delete Key', 'clearfy') ?>
287
+ </a>
288
+ <a data-action="sync" href="#" class="btn btn-default btn-small license-synchronization-button wcl-control-btn"><i class="icon-remove-sign"></i> <?php _e('Synchronization', 'clearfy') ?>
289
+ </a>
290
+ <?php } ?>
291
+
292
+ <h3>
293
+ <?= ucfirst($plan); ?>
294
+ <?php if( $premium and $subscribe ) { ?>
295
+ <span style="font-size: 15px;">(Automatic renewal, every <?php echo esc_attr($billing); ?>
296
+ )</span>
297
+ <?php } ?>
298
+ </h3>
299
+
300
+ <?php if( $has_key ) { ?>
301
+ <div class="license-key-identity"><code><?= esc_attr($license_key) ?></code></div>
302
+ <?php } ?>
303
+
304
+ <div class="license-key-description">
305
+ <p><?php _e('Public License is a GPLv2 compatible license allowing you to change and use this version of the plugin for free. Please keep in mind this license covers only free edition of the plugin. Premium versions are distributed with other type of a license.', 'clearfy') ?>
306
+ </p>
307
+ <?php if( $premium and $subscribe and $license->billing_cycle ) { ?>
308
+ <p class="activate-trial-hint">
309
+ <?php _e('You use a paid subscription for the plugin updates. In case you don’t want to receive paid updates, please, click <a data-action="unsubscribe" class="wcl-control-btn" href="#">cancel subscription</a>', 'clearfy') ?>
310
+ </p>
311
+ <?php } ?>
312
+ <?php if( $remained < 1 ) { ?>
313
+ <p class="activate-error-hint">
314
+ <?php printf(__('Your license has expired, please extend the license to get updates and support.', 'clearfy'), '') ?>
315
+ </p>
316
+ <?php } ?>
317
+ </div>
318
+ <table class="license-params" colspacing="0" colpadding="0">
319
+ <tr>
320
+ <!--<td class="license-param license-param-domain">
321
+ <span class="license-value"><?php echo esc_attr($_SERVER['SERVER_NAME']); ?></span>
322
+ <span class="license-value-name"><?php _e('domain', 'clearfy') ?></span>
323
+ </td>-->
324
+ <td class="license-param license-param-days">
325
+ <span class="license-value"><?= $plan ?></span>
326
+ <span class="license-value-name"><?php _e('plan', 'clearfy') ?></span>
327
+ </td>
328
+ <?php if( $premium ) : ?>
329
+ <td class="license-param license-param-sites">
330
+ <span class="license-value"><?php echo esc_attr($activated); ?> <?php _e('of', 'clearfy') ?> <?php echo esc_attr($quota); ?></span>
331
+ <span class="license-value-name"><?php _e('active sites', 'clearfy') ?></span>
332
+ </td>
333
+ <?php endif; ?>
334
+ <td class="license-param license-param-version">
335
+ <span class="license-value"><?= $this->plugin->getPluginVersion() ?>
336
+ <small><?php _e('version', 'clearfy') ?></small></span>
337
+ <span class="license-value-name"><span><?php _e('up-to-date', 'clearfy') ?></span></span>
338
+ </td>
339
+ <?php if( $premium ) { ?>
340
+ <td class="license-param license-param-days">
341
+ <?php if( $remained < 1 ) { ?>
342
+ <span class="license-value"><?php _e('EXPIRED!', 'clearfy') ?></span>
343
+ <span class="license-value-name"><?php _e('please update the key', 'clearfy') ?></span>
344
+ <?php } else { ?>
345
+ <span class="license-value">
346
+ <?php
347
+ if( $billing == 'lifetime' ) {
348
+ $remained = 'infiniate';
349
+ }
350
+ ?>
351
+ <?= $remained ?>
352
+ <small> <?php _e('day(s)', 'clearfy') ?></small>
353
+ </span>
354
+ <span class="license-value-name"><?php _e('remained', 'clearfy') ?></span>
355
+ <?php } ?>
356
+ </td>
357
+ <?php } ?>
358
+ </tr>
359
+ </table>
360
+ </div>
361
+ </div>
362
+ <div class="license-input">
363
+ <form action="" method="post">
364
+ <?php if ($premium) { ?>
365
+ <p><?php _e('Have a key to activate the premium version? Paste it here:', 'clearfy') ?><p>
366
+ <?php } else { ?>
367
+ <p><?php _e('Have a key to activate the plugin? Paste it here:', 'clearfy') ?>
368
+
369
+ <p>
370
+ <?php } ?>
371
+
372
+ <button data-action="activate" class="btn btn-default wcl-control-btn" type="button" id="license-submit">
373
+ <?php _e('Submit Key', 'clearfy') ?>
374
+ </button>
375
+ <div class="license-key-wrap">
376
+ <input type="text" id="license-key" name="licensekey" value="" class="form-control"/>
377
+ </div>
378
+
379
+ <?php if( $premium ) { ?>
380
+ <p style="margin-top: 10px;">
381
+ <?php printf(__('<a href="%s" target="_blank" rel="noopener">Lean more</a> about the premium version and get the license key to activate it now!', 'clearfy'), $this->plugin->getAuthorSitePageUrl('pricing', 'license_page')) ?>
382
+ </p>
383
+ <?php } else { ?>
384
+ <p style="margin-top: 10px;">
385
+ <?php printf(__('Can’t find your key? Go to <a href="%s" target="_blank" rel="noopener">this page</a> and login using the e-mail address associated with your purchase.', 'clearfy'), $this->plugin->getAuthorSitePageUrl('contact-us', 'license_page')) ?>
386
+ </p>
387
+ <?php } ?>
388
+ </form>
389
+ </div>
390
+ </div>
391
+ </div>
392
+
393
+ <?php
394
+ }
395
+
396
+
397
+ public function activateAjaxHandler()
398
+ {
399
+ $license_key = $_POST['licensekey'];
400
+ if( !$license_key ) {
401
+ $this->showLicenseForm();
402
+ } else {
403
+ $licensing = WCL_Licensing::instance();
404
+ $notice = $licensing->activate($license_key);
405
+ $this->showLicenseForm($notice);
406
+ }
407
+ }
408
+
409
+ public function deactivateAjaxHandler()
410
+ {
411
+ $licensing = WCL_Licensing::instance();
412
+ $notice = $licensing->uninstall();
413
+ $this->showLicenseForm($notice);
414
+ }
415
+
416
+ public function syncAjaxHandler()
417
+ {
418
+ $licensing = WCL_Licensing::instance();
419
+ $notice = $licensing->sync();
420
+ $this->showLicenseForm($notice);
421
+ }
422
+
423
+ public function unsubscribeAjaxHandler()
424
+ {
425
+ $licensing = WCL_Licensing::instance();
426
+ $notice = $licensing->unsubscribe();
427
+ $this->showLicenseForm($notice);
428
+ }
429
+ }
admin/pages/performance-google.php CHANGED
@@ -16,7 +16,7 @@
16
  * The id of the page in the admin menu.
17
  *
18
  * Mainly used to navigate between pages.
19
- * @see FactoryPages401_AdminPage
20
  *
21
  * @since 1.0.0
22
  * @var string
@@ -141,110 +141,6 @@ Reasons for not using Google Maps might be privacy and security, local developme
141
  'hint' => __('Posts or Pages IDs separated by a ,', 'clearfy')
142
  );
143
 
144
- $options[] = array(
145
- 'type' => 'html',
146
- 'html' => '<div class="wbcr-factory-page-group-header">' . __('<strong>Google Analytics cache</strong>.', 'clearfy') . '<p>' . __('To improve Google Page Speed indicators Analytics caching is needed. However, it can also slightly increase your website loading speed, because Analytics js files will load locally. The second case that you might need these settings is the usual Google Analytics connection to your website. You do not need to do this with other plugins or insert the tracking code into your theme.', 'clearfy') . '</p></div>'
147
- );
148
-
149
- $options[] = array(
150
- 'type' => 'checkbox',
151
- 'way' => 'buttons',
152
- 'name' => 'ga_cache',
153
- 'title' => __('Google analytic cache', 'clearfy'),
154
- 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
155
- 'hint' => __('If you enable this option, the plugin will begin to save a local copy of Google Analytics to speed up the loading of your website and improve Google Page Speed.', 'clearfy') . '<br>--<br><span class="hint-warnign-color">' . __('ATTENTION! Before using this option, remove the previously installed Google Analytics code inside your theme or plugins associated with this feature!', 'clearfy') . '</span>',
156
- 'default' => false,
157
- 'eventsOn' => array(
158
- 'show' => '#wbcr-clearfy-performance-ga-block'
159
- ),
160
- 'eventsOff' => array(
161
- 'hide' => '#wbcr-clearfy-performance-ga-block'
162
- )
163
-
164
- );
165
-
166
- $options[] = array(
167
- 'type' => 'div',
168
- 'id' => 'wbcr-clearfy-performance-ga-block',
169
- 'items' => array(
170
- array(
171
- 'type' => 'textbox',
172
- 'way' => 'buttons',
173
- 'name' => 'ga_tracking_id',
174
- 'title' => __('Google analytic Code', 'clearfy'),
175
- 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
176
- 'hint' => __('Set the Google Analytics tracking code.', 'clearfy'),
177
- 'placeholder' => 'UA-XXXXX-Y'
178
- ),
179
- array(
180
- 'type' => 'dropdown',
181
- 'way' => 'buttons',
182
- 'name' => 'ga_script_position',
183
- 'data' => array(
184
- array('header', 'Header'),
185
- array('footer', 'Footer'),
186
- ),
187
- 'title' => __('Save GA in', 'clearfy'),
188
- 'hint' => __('Select location for the Google Analytics code.', 'clearfy'),
189
- 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
190
- 'default' => 'footer'
191
- ),
192
- array(
193
- 'type' => 'integer',
194
- 'name' => 'ga_adjusted_bounce_rate',
195
- 'title' => __('Use adjusted bounce rate?', 'clearfy'),
196
- 'default' => 0,
197
- 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
198
- 'hint' => __('Essentially, you set up an event which is triggered after a user spends a certain amount of time on the landing page, telling Google Analytics not to count these users as bounces. A user may come to your website, find all of the information they need (a phone number, for example) and then leave the site without visiting another page. Without adjusted bounce rate, such a user would be considered a bounce, even though they had a successful experience. By defining a time limit after which you can consider a user to be "engaged," that user would no longer count as a bounce, and you\'d get a more accurate idea of whether they found what they were looking for.', 'clearfy')
199
- ),
200
- array(
201
- 'type' => 'integer',
202
- 'way' => 'buttons',
203
- 'name' => 'ga_enqueue_order',
204
- 'title' => __('Change enqueue order?', 'clearfy'),
205
- 'default' => 0,
206
- 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
207
- 'hint' => __('By default, Google Analytics code is loaded before other scripts and javasscript code, but if you set the value to 100, the GA code will be loaded after all other scripts. By changing the priority, you can set code position on the page.', 'clearfy')
208
- ),
209
- array(
210
- 'type' => 'checkbox',
211
- 'way' => 'buttons',
212
- 'name' => 'ga_caos_disable_display_features',
213
- 'title' => __('Disable all display features functionality?', 'clearfy'),
214
- //'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
215
- 'hint' => sprintf(__('Disable all <a href="%s">display features functionality?</a>', 'clearfy'), 'https://developers.google.com/analytics/devguides/collection/analyticsjs/display-features'),
216
- 'default' => false
217
- ),
218
- array(
219
- 'type' => 'checkbox',
220
- 'way' => 'buttons',
221
- 'name' => 'ga_anonymize_ip',
222
- 'title' => __('Use Anonymize IP? (Required by law for some countries)', 'clearfy'),
223
- //'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
224
- 'hint' => sprintf(__('Use <a href="%s">Anonymize IP?</a> (Required by law for some countries)', 'clearfy'), 'https://developers.google.com/analytics/devguides/collection/analyticsjs/display-features'),
225
- 'default' => false
226
- ),
227
- array(
228
- 'type' => 'checkbox',
229
- 'way' => 'buttons',
230
- 'name' => 'ga_track_admin',
231
- 'title' => __('Track logged in Administrators?', 'clearfy'),
232
- 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
233
- 'hint' => __('Track logged in Administrators?', 'clearfy'),
234
- 'default' => false
235
- ),
236
- array(
237
- 'type' => 'checkbox',
238
- 'way' => 'buttons',
239
- 'name' => 'ga_caos_remove_wp_cron',
240
- 'title' => __('Remove script from wp-cron?', 'clearfy'),
241
- 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
242
- 'hint' => __('Clearfy creates a cron job to daily update Google Analytics cache scripts. After enabling this option, the plugin will not update Google Analytics cache file. Do not use this option if you do not understand why you need it!', 'clearfy'),
243
- 'default' => false
244
- )
245
- )
246
- );
247
-
248
  $form_options = array();
249
 
250
  $form_options[] = array(
@@ -253,6 +149,6 @@ Reasons for not using Google Maps might be privacy and security, local developme
253
  //'cssClass' => 'postbox'
254
  );
255
 
256
- return apply_filters('wbcr_clr_code_clean_form_options', $form_options, $this);
257
  }
258
  }
16
  * The id of the page in the admin menu.
17
  *
18
  * Mainly used to navigate between pages.
19
+ * @see FactoryPages407_AdminPage
20
  *
21
  * @since 1.0.0
22
  * @var string
141
  'hint' => __('Posts or Pages IDs separated by a ,', 'clearfy')
142
  );
143
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
144
  $form_options = array();
145
 
146
  $form_options[] = array(
149
  //'cssClass' => 'postbox'
150
  );
151
 
152
+ return apply_filters('wbcr_clr_google_performance_form_options', $form_options, $this);
153
  }
154
  }
admin/pages/performance-html-minify.php DELETED
@@ -1,154 +0,0 @@
1
- <?php
2
- /**
3
- * The page Settings.
4
- *
5
- * @since 1.0.0
6
- */
7
-
8
- // Exit if accessed directly
9
- if( !defined('ABSPATH') ) {
10
- exit;
11
- }
12
-
13
- class WCL_PerformanceHtmlMinifyPage extends WCL_Page {
14
-
15
- /**
16
- * The id of the page in the admin menu.
17
- *
18
- * Mainly used to navigate between pages.
19
- * @see FactoryPages401_AdminPage
20
- *
21
- * @since 1.0.0
22
- * @var string
23
- */
24
- public $id = "performance_html_minify";
25
-
26
- /**
27
- * @var string
28
- */
29
- public $page_parent_page = 'performance';
30
-
31
- /**
32
- * @var string
33
- */
34
- public $page_menu_dashicon = 'dashicons-performance';
35
-
36
- /**
37
- * @var int
38
- */
39
- public $page_menu_position = 20;
40
-
41
- /**
42
- * @param WCL_Plugin $plugin
43
- */
44
- public function __construct(WCL_Plugin $plugin)
45
- {
46
- $this->menu_title = __('Html Minify', 'clearfy');
47
-
48
- parent::__construct($plugin);
49
-
50
- $this->plugin = $plugin;
51
- }
52
-
53
- /**
54
- * Permalinks options.
55
- *
56
- * @since 1.0.0
57
- * @return mixed[]
58
- */
59
- public function getOptions()
60
- {
61
- $options = array();
62
-
63
- $options[] = array(
64
- 'type' => 'html',
65
- 'html' => '<div class="wbcr-factory-page-group-header">' . __('<strong>Make your website’s markup look professional by using Minify HTML options</strong>.', 'clearfy') . '<p>' . __('Ever look at the HTML markup of your website and notice how sloppy and amateurish it looks? The Minify HTML options cleans up sloppy looking markup and minifies, which also speeds up download time.', 'clearfy') . '</p></div>'
66
- );
67
-
68
- $options[] = array(
69
- 'type' => 'checkbox',
70
- 'way' => 'buttons',
71
- 'name' => 'html_minify',
72
- 'title' => __('HTML minify', 'clearfy'),
73
- 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
74
- 'hint' => __('Reduces the weight of the page by removing line breaks, tabs, spaces, etc.', 'clearfy') . '<br><br><b>Clearfy: </b>' . __('Minify pages.', 'clearfy'),
75
- 'default' => false,
76
- 'eventsOn' => array(
77
- 'show' => '#wbcr-clearfy-performance-html-minify-options'
78
- ),
79
- 'eventsOff' => array(
80
- 'hide' => '#wbcr-clearfy-performance-html-minify-options'
81
- )
82
- );
83
-
84
- $options[] = array(
85
- 'type' => 'separator'
86
- );
87
-
88
- $sub_options[] = array(
89
- 'type' => 'checkbox',
90
- 'way' => 'buttons',
91
- 'name' => 'minify_javascript',
92
- 'title' => __('Minify inline JavaScript', 'clearfy'),
93
- 'default' => true
94
- );
95
-
96
- $sub_options[] = array(
97
- 'type' => 'checkbox',
98
- 'way' => 'buttons',
99
- 'name' => 'minify_html_comments',
100
- 'title' => __('Remove HTML, JavaScript and CSS comments', 'clearfy'),
101
- 'default' => true
102
- );
103
-
104
- $sub_options[] = array(
105
- 'type' => 'checkbox',
106
- 'way' => 'buttons',
107
- 'name' => 'minify_html_xhtml',
108
- 'title' => __('Remove XHTML closing tags from HTML5 void elements', 'clearfy'),
109
- 'default' => false
110
- );
111
-
112
- $sub_options[] = array(
113
- 'type' => 'checkbox',
114
- 'way' => 'buttons',
115
- 'name' => 'minify_html_relative',
116
- 'title' => __('Remove relative domain from internal URLs', 'clearfy'),
117
- 'default' => false
118
- );
119
-
120
- $sub_options[] = array(
121
- 'type' => 'checkbox',
122
- 'way' => 'buttons',
123
- 'name' => 'minify_html_scheme',
124
- 'title' => __('Remove schemes (HTTP: and HTTPS:) from all URLs', 'clearfy'),
125
- 'default' => false
126
- );
127
-
128
- $sub_options[] = array(
129
- 'type' => 'checkbox',
130
- 'way' => 'buttons',
131
- 'name' => 'minify_html_utf8',
132
- 'title' => __('Support multi-byte UTF-8 encoding (if you see odd characters)', 'clearfy'),
133
- 'default' => in_array(get_locale(), array('ru_RU', 'bel', 'kk', 'hy', 'uk', 'bg', 'bg_BG', 'ka_GE'))
134
- ? true
135
- : false
136
- );
137
-
138
- $options[] = array(
139
- 'type' => 'div',
140
- 'id' => 'wbcr-clearfy-performance-html-minify-options',
141
- 'items' => $sub_options
142
- );
143
-
144
- $form_options = array();
145
-
146
- $form_options[] = array(
147
- 'type' => 'form-group',
148
- 'items' => $options,
149
- //'cssClass' => 'postbox'
150
- );
151
-
152
- return apply_filters('wbcr_clr_code_clean_form_options', $form_options, $this);
153
- }
154
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/pages/performance.php CHANGED
@@ -16,7 +16,7 @@
16
  * The id of the page in the admin menu.
17
  *
18
  * Mainly used to navigate between pages.
19
- * @see FactoryPages401_AdminPage
20
  *
21
  * @since 1.0.0
22
  * @var string
@@ -125,7 +125,7 @@
125
  'name' => 'remove_jquery_migrate',
126
  'title' => __('Remove jQuery Migrate', 'clearfy'),
127
  'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'red'),
128
- 'hint' => __('They started adding jQuery migrate in WordPress 3.6. Most up-to-date frontend code and plugins don’t require jquery-migrate.min.js. In most cases, this simply adds unnecessary load to your site. You can see this running if you launch Chrome Devtools console.', 'clearfy') . '<br><br><b>Clearfy: </b>' . __('Removes jQuery Migrate JavaScript file (jquery-migrate.min.js).', 'clearfy') . '<br>--<br><span class="hint-warnign-color">' . __('Warning! If there is a broke on your site, disable this option!', 'clearfy') . '</span>',
129
  'default' => false
130
  );
131
 
@@ -240,37 +240,6 @@ In particular, the profile is used for the XFN microformat (XHTML Friends Networ
240
  ', 'clearfy'),
241
  'default' => false
242
  );
243
-
244
- $options[] = array(
245
- 'type' => 'checkbox',
246
- 'way' => 'buttons',
247
- 'name' => 'remove_style_version',
248
- 'title' => __('Remove Version from Stylesheet', 'clearfy') . ' <span class="wbcr-clearfy-recomended-text">(' . __('Recommended', 'clearfy') . ')</span>',
249
- 'layout' => array('hint-type' => 'icon'),
250
- 'hint' => __('To make it more difficult for others to hack your website you can remove the WordPress version number from your site, your css and js. Without that number it\'s not possible to see if you run not the current version to exploit bugs from the older versions. <br><br>
251
- Additionally it can improve the loading speed of your site, because without query strings in the URL the css and js files can be cached.', 'clearfy') . '<br><br><b>Clearfy: </b>' . __('Removes the wordpress version number from stylesheets (not logged in user only).', 'clearfy'),
252
- 'default' => false
253
- );
254
-
255
- $options[] = array(
256
- 'type' => 'checkbox',
257
- 'way' => 'buttons',
258
- 'name' => 'remove_js_version',
259
- 'title' => __('Remove Version from Script', 'clearfy') . ' <span class="wbcr-clearfy-recomended-text">(' . __('Recommended', 'clearfy') . ')</span>',
260
- 'layout' => array('hint-type' => 'icon'),
261
- 'hint' => __('To make it more difficult for others to hack your website you can remove the WordPress version number from your site, your css and js. Without that number it\'s not possible to see if you run not the current version to exploit bugs from the older versions. <br><br>
262
- Additionally it can improve the loading speed of your site, because without query strings in the URL the css and js files can be cached.', 'clearfy') . '<br><br><b>Clearfy: </b>' . __('Removes wordpress version number from scripts (not logged in user only).', 'clearfy'),
263
- 'default' => false
264
- );
265
-
266
- $options[] = array(
267
- 'type' => 'textarea',
268
- 'name' => 'remove_version_exclude',
269
- 'height' => '120',
270
- 'title' => __('Exclude stylesheet/script file names', 'clearfy'),
271
- 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
272
- 'hint' => __('Enter Stylesheet/Script file names to exclude from version removal (each exclude file starts with a new line)', 'clearfy') . '<br><br><b>' . __('Example', 'clearfy') . ':</b>' . ' http://testwp.dev/wp-includes/js/jquery/jquery.js',
273
- );
274
 
275
  $form_options = array();
276
 
@@ -282,4 +251,4 @@ In particular, the profile is used for the XFN microformat (XHTML Friends Networ
282
 
283
  return apply_filters('wbcr_clr_code_clean_form_options', $form_options, $this);
284
  }
285
- }
16
  * The id of the page in the admin menu.
17
  *
18
  * Mainly used to navigate between pages.
19
+ * @see FactoryPages407_AdminPage
20
  *
21
  * @since 1.0.0
22
  * @var string
125
  'name' => 'remove_jquery_migrate',
126
  'title' => __('Remove jQuery Migrate', 'clearfy'),
127
  'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'red'),
128
+ 'hint' => __('They started adding jQuery migrate in WordPress 3.6. Most up-to-date frontend code and plugins don’t require jquery-migrate.min.js. In most cases, this simply adds unnecessary load to your site. You can see this running if you launch Chrome Devtools console.', 'clearfy') . '<br><br><b>Clearfy: </b>' . __('Removes jQuery Migrate JavaScript file (jquery-migrate.min.js).', 'clearfy') . '<br>--<br><span class="wbcr-factory-light-orange-color">' . __('Warning! If there is a broke on your site, disable this option!', 'clearfy') . '</span>',
129
  'default' => false
130
  );
131
 
240
  ', 'clearfy'),
241
  'default' => false
242
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
243
 
244
  $form_options = array();
245
 
251
 
252
  return apply_filters('wbcr_clr_code_clean_form_options', $form_options, $this);
253
  }
254
+ }
admin/pages/quick-start.php CHANGED
@@ -17,7 +17,7 @@
17
  * The id of the page in the admin menu.
18
  *
19
  * Mainly used to navigate between pages.
20
- * @see FactoryPages401_AdminPage
21
  *
22
  * @since 1.0.0
23
  * @var string
@@ -74,7 +74,7 @@
74
  /**
75
  * Requests assets (js and css) for the page.
76
  *
77
- * @see FactoryPages401_AdminPage
78
  *
79
  * @since 1.0.0
80
  * @return void
@@ -84,12 +84,16 @@
84
  parent::assets($scripts, $styles);
85
 
86
  $this->scripts->add(WCL_PLUGIN_URL . '/admin/assets/js/general.js');
 
 
87
 
88
  $params = array(
89
  'ajaxurl' => admin_url('admin-ajax.php'),
90
  'ajax_nonce' => wp_create_nonce('wbcr_clearfy_ajax_quick_start_nonce'),
91
  );
 
92
  wp_localize_script('jquery', 'wbcr_clearfy_ajax', $params);
 
93
  }
94
 
95
  /**
@@ -180,10 +184,6 @@
180
  public function showPageContent()
181
  {
182
  $allow_mods = apply_filters('wbcr_clearfy_allow_quick_mods', array(
183
- 'recommended' => array(
184
- 'title' => __('Set the recommened for me', 'clearfy'),
185
- 'icon' => 'dashicons-thumbs-up'
186
- ),
187
  'clear_code' => array('title' => __('One click code clearing', 'clearfy'), 'icon' => 'dashicons-yes'),
188
  'defence' => array('title' => __('One click security', 'clearfy'), 'icon' => 'dashicons-shield'),
189
  'seo_optimize' => array(
@@ -281,6 +281,9 @@
281
  <?php _e('During the setup, an unknown error occurred, please try again or contact the plug-in support.', 'clearfy') ?>
282
  </div>
283
  </div>
 
 
 
284
  <div class="col-sm-12">
285
  <div class="wbcr-clearfy-export-import-board wbcr-clearfy-board">
286
  <p>
@@ -317,4 +320,4 @@
317
 
318
  <?php
319
  }
320
- }
17
  * The id of the page in the admin menu.
18
  *
19
  * Mainly used to navigate between pages.
20
+ * @see FactoryPages407_AdminPage
21
  *
22
  * @since 1.0.0
23
  * @var string
74
  /**
75
  * Requests assets (js and css) for the page.
76
  *
77
+ * @see FactoryPages407_AdminPage
78
  *
79
  * @since 1.0.0
80
  * @return void
84
  parent::assets($scripts, $styles);
85
 
86
  $this->scripts->add(WCL_PLUGIN_URL . '/admin/assets/js/general.js');
87
+ //для импорта натсроек нужен стрипт обновления пакета.
88
+ $this->scripts->add(WCL_PLUGIN_URL . '/admin/assets/js/update-package.js');
89
 
90
  $params = array(
91
  'ajaxurl' => admin_url('admin-ajax.php'),
92
  'ajax_nonce' => wp_create_nonce('wbcr_clearfy_ajax_quick_start_nonce'),
93
  );
94
+
95
  wp_localize_script('jquery', 'wbcr_clearfy_ajax', $params);
96
+
97
  }
98
 
99
  /**
184
  public function showPageContent()
185
  {
186
  $allow_mods = apply_filters('wbcr_clearfy_allow_quick_mods', array(
 
 
 
 
187
  'clear_code' => array('title' => __('One click code clearing', 'clearfy'), 'icon' => 'dashicons-yes'),
188
  'defence' => array('title' => __('One click security', 'clearfy'), 'icon' => 'dashicons-shield'),
189
  'seo_optimize' => array(
281
  <?php _e('During the setup, an unknown error occurred, please try again or contact the plug-in support.', 'clearfy') ?>
282
  </div>
283
  </div>
284
+
285
+ <?php do_action('wbcr_clearfy_quick_boards'); ?>
286
+
287
  <div class="col-sm-12">
288
  <div class="wbcr-clearfy-export-import-board wbcr-clearfy-board">
289
  <p>
320
 
321
  <?php
322
  }
323
+ }
admin/pages/seo-double-pages.php CHANGED
@@ -16,7 +16,7 @@
16
  * The id of the page in the admin menu.
17
  *
18
  * Mainly used to navigate between pages.
19
- * @see FactoryPages401_AdminPage
20
  *
21
  * @since 1.0.0
22
  * @var string
@@ -131,7 +131,7 @@
131
  'way' => 'buttons',
132
  'name' => 'remove_single_pagination_duplicate',
133
  'title' => __('Remove post pagination', 'clearfy'),
134
- 'layout' => array('hint-type' => 'icon'),
135
  'hint' => sprintf(__('In WordPress, any post can be divided into parts (pages), each part will have its own address. But this functionality is rarely used, but it can create trouble for you. For example, you can add a number to the address of any entry of your blog, %s - the post itself will open, which will be a duplicate. You can substitute any number.', 'clearfy'), '/privet-mir/1/') . '<br><b>Clearfy: </b>' . sprintf(__('Removes the pagination from the post and puts a redirect. Example: %s', 'clearfy'), '/post-name/number'),
136
  'default' => false
137
  );
16
  * The id of the page in the admin menu.
17
  *
18
  * Mainly used to navigate between pages.
19
+ * @see FactoryPages407_AdminPage
20
  *
21
  * @since 1.0.0
22
  * @var string
131
  'way' => 'buttons',
132
  'name' => 'remove_single_pagination_duplicate',
133
  'title' => __('Remove post pagination', 'clearfy'),
134
+ 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
135
  'hint' => sprintf(__('In WordPress, any post can be divided into parts (pages), each part will have its own address. But this functionality is rarely used, but it can create trouble for you. For example, you can add a number to the address of any entry of your blog, %s - the post itself will open, which will be a duplicate. You can substitute any number.', 'clearfy'), '/privet-mir/1/') . '<br><b>Clearfy: </b>' . sprintf(__('Removes the pagination from the post and puts a redirect. Example: %s', 'clearfy'), '/post-name/number'),
136
  'default' => false
137
  );
admin/pages/seo.php CHANGED
@@ -16,7 +16,7 @@
16
  * The id of the page in the admin menu.
17
  *
18
  * Mainly used to navigate between pages.
19
- * @see FactoryPages401_AdminPage
20
  *
21
  * @since 1.0.0
22
  * @var string
@@ -115,12 +115,20 @@
115
  'title' => __('Automatically insert the Last Modified header', 'clearfy') . ' <span class="wbcr-clearfy-recomended-text">(' . __('Recommended', 'clearfy') . ')</span>',
116
  'default' => false,
117
  'eventsOn' => array(
118
- 'show' => '.factory-control-last_modified_exclude'
119
  ),
120
  'eventsOff' => array(
121
- 'hide' => '.factory-control-last_modified_exclude'
122
  )
123
  );
 
 
 
 
 
 
 
 
124
 
125
  $options[] = array(
126
  'type' => 'textarea',
@@ -161,7 +169,7 @@
161
  'name' => 'yoast_remove_image_from_xml_sitemap',
162
  'title' => sprintf(__('Remove the tag %s from XML site map', 'clearfy'), 'image:image') . ' <span class="wbcr-clearfy-recomended-text">(' . __('Recommended', 'clearfy') . ')</span>',
163
  'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'green'),
164
- 'hint' => __('Yandex.Webmaster swears on a standard XML card from the plugin Yoast, tk. it has a specific tag', 'clearfy') . 'image:image<br><br><b>Clearfy: </b>' . sprintf(__('Remove the tag %s from XML site map of the plugin Yoast SEO.', 'clearfy'), 'image:image') . '<br>--<br><span class="hint-warnign-color">' . __('Attention! After activation, turn off the site map and enable it back to regenerate it.', 'clearfy') . '</span>' . '<br><span class="hint-warnign-color">' . __('In older versions of Yoast SEO may not work - update the plugin Yoast', 'clearfy') . '</span>',
165
  'default' => false,
166
  'eventsOn' => array()
167
  );
16
  * The id of the page in the admin menu.
17
  *
18
  * Mainly used to navigate between pages.
19
+ * @see FactoryPages407_AdminPage
20
  *
21
  * @since 1.0.0
22
  * @var string
115
  'title' => __('Automatically insert the Last Modified header', 'clearfy') . ' <span class="wbcr-clearfy-recomended-text">(' . __('Recommended', 'clearfy') . ')</span>',
116
  'default' => false,
117
  'eventsOn' => array(
118
+ 'show' => '.factory-control-last_modified_exclude, .factory-control-disable_frontpage_last_modified_headers'
119
  ),
120
  'eventsOff' => array(
121
+ 'hide' => '.factory-control-last_modified_exclude, .factory-control-disable_frontpage_last_modified_headers'
122
  )
123
  );
124
+
125
+ $options[] = array(
126
+ 'type' => 'checkbox',
127
+ 'way' => 'buttons',
128
+ 'name' => 'disable_frontpage_last_modified_headers',
129
+ 'title' => __('Disable Last Modified header on front page', 'clearfy') . ' <span class="wbcr-clearfy-recomended-text">(' . __('Recommended', 'clearfy') . ')</span>',
130
+ 'default' => true,
131
+ );
132
 
133
  $options[] = array(
134
  'type' => 'textarea',
169
  'name' => 'yoast_remove_image_from_xml_sitemap',
170
  'title' => sprintf(__('Remove the tag %s from XML site map', 'clearfy'), 'image:image') . ' <span class="wbcr-clearfy-recomended-text">(' . __('Recommended', 'clearfy') . ')</span>',
171
  'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'green'),
172
+ 'hint' => __('Yandex.Webmaster swears on a standard XML card from the plugin Yoast, tk. it has a specific tag', 'clearfy') . 'image:image<br><br><b>Clearfy: </b>' . sprintf(__('Remove the tag %s from XML site map of the plugin Yoast SEO.', 'clearfy'), 'image:image') . '<br>--<br><span class="wbcr-factory-light-orange-color">' . __('Attention! After activation, turn off the site map and enable it back to regenerate it.', 'clearfy') . '</span>' . '<br><span class="wbcr-factory-light-orange-color">' . __('In older versions of Yoast SEO may not work - update the plugin Yoast', 'clearfy') . '</span>',
173
  'default' => false,
174
  'eventsOn' => array()
175
  );
admin/pages/widgets.php CHANGED
@@ -16,7 +16,7 @@
16
  * The id of the page in the admin menu.
17
  *
18
  * Mainly used to navigate between pages.
19
- * @see FactoryPages401_AdminPage
20
  *
21
  * @since 1.0.0
22
  * @var string
16
  * The id of the page in the admin menu.
17
  *
18
  * Mainly used to navigate between pages.
19
+ * @see FactoryPages407_AdminPage
20
  *
21
  * @since 1.0.0
22
  * @var string
assets/css/admin-bar.css ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Admin bar menu
3
+ * @author Webcraftic <wordpress.webraftic@gmail.com>
4
+ * @copyright Webcraftic 01.07.2018
5
+ */
6
+ #wp-admin-bar-clearfy-menu {
7
+ background: #443a54 !important;
8
+ }
9
+ #wp-admin-bar-clearfy-menu #wp-admin-bar-clearfy-menu-default {
10
+ background: #565656 !important;
11
+ }
12
+ #wp-admin-bar-clearfy-menu .wbcr-clearfy-admin-bar-menu-icon {
13
+ display: inline-block !important;
14
+ width: 20px;
15
+ height: 25px;
16
+ margin-right: 5px;
17
+ background: url(../img/webcraftic-plugin-icon.png) 0 0 no-repeat;
18
+ }
19
+ #wp-admin-bar-clearfy-menu .wbcr-clearfy-admin-bar-menu-title {
20
+ display: inline-block !important;
21
+ width: 100px !important;
22
+ overflow: hidden;
23
+ }
assets/css/admin-bar.less ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Admin bar menu
3
+ * @author Webcraftic <wordpress.webraftic@gmail.com>
4
+ * @copyright Webcraftic 01.07.2018
5
+ */
6
+
7
+ #wp-admin-bar-clearfy-menu {
8
+ background: #443a54 !important;
9
+
10
+ #wp-admin-bar-clearfy-menu-default {
11
+ background: #565656 !important;
12
+ }
13
+ .wbcr-clearfy-admin-bar-menu-icon {
14
+ display: inline-block !important;
15
+ width: 20px;
16
+ height: 25px;
17
+ margin-right: 5px;
18
+ background: url(../img/webcraftic-plugin-icon.png) 0 0 no-repeat;
19
+ }
20
+ .wbcr-clearfy-admin-bar-menu-title {
21
+ display: inline-block !important;
22
+ width: 100px !important;
23
+ overflow: hidden;
24
+ }
25
+ }
assets/img/webcraftic-plugin-icon.png ADDED
Binary file
cache/local-ga.js DELETED
@@ -1,59 +0,0 @@
1
- (function(){var $c=function(a){this.w=a||[]};$c.prototype.set=function(a){this.w[a]=!0};$c.prototype.encode=function(){for(var a=[],b=0;b<this.w.length;b++)this.w[b]&&(a[Math.floor(b/6)]^=1<<b%6);for(b=0;b<a.length;b++)a[b]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".charAt(a[b]||0);return a.join("")+"~"};var vd=new $c;function J(a){vd.set(a)}var Td=function(a){a=Dd(a);a=new $c(a);for(var b=vd.w.slice(),c=0;c<a.w.length;c++)b[c]=b[c]||a.w[c];return(new $c(b)).encode()},Dd=function(a){a=a.get(Gd);ka(a)||(a=[]);return a};var ea=function(a){return"function"==typeof a},ka=function(a){return"[object Array]"==Object.prototype.toString.call(Object(a))},qa=function(a){return void 0!=a&&-1<(a.constructor+"").indexOf("String")},D=function(a,b){return 0==a.indexOf(b)},sa=function(a){return a?a.replace(/^[\s\xa0]+|[\s\xa0]+$/g,""):""},ra=function(){for(var a=O.navigator.userAgent+(M.cookie?M.cookie:"")+(M.referrer?M.referrer:""),b=a.length,c=O.history.length;0<c;)a+=c--^b++;return[hd()^La(a)&2147483647,Math.round((new Date).getTime()/
2
- 1E3)].join(".")},ta=function(a){var b=M.createElement("img");b.width=1;b.height=1;b.src=a;return b},ua=function(){},K=function(a){if(encodeURIComponent instanceof Function)return encodeURIComponent(a);J(28);return a},L=function(a,b,c,d){try{a.addEventListener?a.addEventListener(b,c,!!d):a.attachEvent&&a.attachEvent("on"+b,c)}catch(e){J(27)}},f=/^[\w\-:/.?=&%!]+$/,wa=function(a,b,c,d){a&&(c?(d="",b&&f.test(b)&&(d=' id="'+b+'"'),f.test(a)&&M.write("<script"+d+' src="'+a+'">\x3c/script>')):(c=M.createElement("script"),
3
- c.type="text/javascript",c.async=!0,c.src=a,d&&(c.onload=d),b&&(c.id=b),a=M.getElementsByTagName("script")[0],a.parentNode.insertBefore(c,a)))},Ud=function(){return"https:"==M.location.protocol},be=function(a,b){return E(M.location[b?"href":"search"],a)},E=function(a,b){return(a=a.match("(?:&|#|\\?)"+K(b).replace(/([.*+?^=!:${}()|\[\]\/\\])/g,"\\$1")+"=([^&#]*)"))&&2==a.length?a[1]:""},xa=function(){var a=""+M.location.hostname;return 0==a.indexOf("www.")?a.substring(4):a},de=function(a,b){var c=
4
- a.indexOf(b);if(5==c||6==c)if(a=a.charAt(c+b.length),"/"==a||"?"==a||""==a||":"==a)return!0;return!1},ya=function(a,b){var c=M.referrer;if(/^(https?|android-app):\/\//i.test(c)){if(a)return c;a="//"+M.location.hostname;if(!de(c,a))return b&&(b=a.replace(/\./g,"-")+".cdn.ampproject.org",de(c,b))?void 0:c}},za=function(a,b){if(1==b.length&&null!=b[0]&&"object"===typeof b[0])return b[0];for(var c={},d=Math.min(a.length+1,b.length),e=0;e<d;e++)if("object"===typeof b[e]){for(var g in b[e])b[e].hasOwnProperty(g)&&
5
- (c[g]=b[e][g]);break}else e<a.length&&(c[a[e]]=b[e]);return c};var ee=function(){this.keys=[];this.values={};this.m={}};ee.prototype.set=function(a,b,c){this.keys.push(a);c?this.m[":"+a]=b:this.values[":"+a]=b};ee.prototype.get=function(a){return this.m.hasOwnProperty(":"+a)?this.m[":"+a]:this.values[":"+a]};ee.prototype.map=function(a){for(var b=0;b<this.keys.length;b++){var c=this.keys[b],d=this.get(c);d&&a(c,d)}};var O=window,M=document,va=function(a,b){return setTimeout(a,b)};var F=window,Ea=document,G=function(a){var b=F._gaUserPrefs;if(b&&b.ioo&&b.ioo()||a&&!0===F["ga-disable-"+a])return!0;try{var c=F.external;if(c&&c._gaUserPrefs&&"oo"==c._gaUserPrefs)return!0}catch(g){}a=[];b=Ea.cookie.split(";");c=/^\s*AMP_TOKEN=\s*(.*?)\s*$/;for(var d=0;d<b.length;d++){var e=b[d].match(c);e&&a.push(e[1])}for(b=0;b<a.length;b++)if("$OPT_OUT"==decodeURIComponent(a[b]))return!0;return!1};var Ca=function(a){var b=[],c=M.cookie.split(";");a=new RegExp("^\\s*"+a+"=\\s*(.*?)\\s*$");for(var d=0;d<c.length;d++){var e=c[d].match(a);e&&b.push(e[1])}return b},zc=function(a,b,c,d,e,g){e=G(e)?!1:eb.test(M.location.hostname)||"/"==c&&vc.test(d)?!1:!0;if(!e)return!1;b&&1200<b.length&&(b=b.substring(0,1200));c=a+"="+b+"; path="+c+"; ";g&&(c+="expires="+(new Date((new Date).getTime()+g)).toGMTString()+"; ");d&&"none"!=d&&(c+="domain="+d+";");d=M.cookie;M.cookie=c;if(!(d=d!=M.cookie))a:{a=Ca(a);
6
- for(d=0;d<a.length;d++)if(b==a[d]){d=!0;break a}d=!1}return d},Cc=function(a){return encodeURIComponent?encodeURIComponent(a).replace(/\(/g,"%28").replace(/\)/g,"%29"):a},vc=/^(www\.)?google(\.com?)?(\.[a-z]{2})?$/,eb=/(^|\.)doubleclick\.net$/i;var oc,Id=/^.*Version\/?(\d+)[^\d].*$/i,ne=function(){if(void 0!==O.__ga4__)return O.__ga4__;if(void 0===oc){var a=O.navigator.userAgent;if(a){var b=a;try{b=decodeURIComponent(a)}catch(c){}if(a=!(0<=b.indexOf("Chrome"))&&!(0<=b.indexOf("CriOS"))&&(0<=b.indexOf("Safari/")||0<=b.indexOf("Safari,")))b=Id.exec(b),a=11<=(b?Number(b[1]):-1);oc=a}else oc=!1}return oc};var Fa,Ga,fb,Ab,ja=/^https?:\/\/[^/]*cdn\.ampproject\.org\//,Ub=[],ic=function(){Z.D([ua])},tc=function(a,b){var c=Ca("AMP_TOKEN");if(1<c.length)return J(55),!1;c=decodeURIComponent(c[0]||"");if("$OPT_OUT"==c||"$ERROR"==c||G(b))return J(62),!1;if(!ja.test(M.referrer)&&"$NOT_FOUND"==c)return J(68),!1;if(void 0!==Ab)return J(56),va(function(){a(Ab)},0),!0;if(Fa)return Ub.push(a),!0;if("$RETRIEVING"==c)return J(57),va(function(){tc(a,b)},1E4),!0;Fa=!0;c&&"$"!=c[0]||(xc("$RETRIEVING",3E4),setTimeout(Mc,
7
- 3E4),c="");return Pc(c,b)?(Ub.push(a),!0):!1},Pc=function(a,b,c){if(!window.JSON)return J(58),!1;var d=O.XMLHttpRequest;if(!d)return J(59),!1;var e=new d;if(!("withCredentials"in e))return J(60),!1;e.open("POST",(c||"https://ampcid.google.com/v1/publisher:getClientId")+"?key=AIzaSyA65lEHUEizIsNtlbNo-l2K18dT680nsaM",!0);e.withCredentials=!0;e.setRequestHeader("Content-Type","text/plain");e.onload=function(){Fa=!1;if(4==e.readyState){try{200!=e.status&&(J(61),Qc("","$ERROR",3E4));var d=JSON.parse(e.responseText);
8
- d.optOut?(J(63),Qc("","$OPT_OUT",31536E6)):d.clientId?Qc(d.clientId,d.securityToken,31536E6):!c&&d.alternateUrl?(Ga&&clearTimeout(Ga),Fa=!0,Pc(a,b,d.alternateUrl)):(J(64),Qc("","$NOT_FOUND",36E5))}catch(ca){J(65),Qc("","$ERROR",3E4)}e=null}};d={originScope:"AMP_ECID_GOOGLE"};a&&(d.securityToken=a);e.send(JSON.stringify(d));Ga=va(function(){J(66);Qc("","$ERROR",3E4)},1E4);return!0},Mc=function(){Fa=!1},xc=function(a,b){if(void 0===fb){fb="";for(var c=id(),d=0;d<c.length;d++){var e=c[d];if(zc("AMP_TOKEN",
9
- encodeURIComponent(a),"/",e,"",b)){fb=e;return}}}zc("AMP_TOKEN",encodeURIComponent(a),"/",fb,"",b)},Qc=function(a,b,c){Ga&&clearTimeout(Ga);b&&xc(b,c);Ab=a;b=Ub;Ub=[];for(c=0;c<b.length;c++)b[c](a)};var oe=function(){return(Ba||Ud()?"https:":"http:")+"//www.google-analytics.com"},Da=function(a){this.name="len";this.message=a+"-8192"},ba=function(a,b,c){c=c||ua;if(2036>=b.length)wc(a,b,c);else if(8192>=b.length)x(a,b,c)||wd(a,b,c)||wc(a,b,c);else throw ge("len",b.length),new Da(b.length);},pe=function(a,b,c,d){d=d||ua;wd(a+"?"+b,"",d,c)},wc=function(a,b,c){var d=ta(a+"?"+b);d.onload=d.onerror=function(){d.onload=null;d.onerror=null;c()}},wd=function(a,b,c,d){var e=O.XMLHttpRequest;if(!e)return!1;
10
- var g=new e;if(!("withCredentials"in g))return!1;a=a.replace(/^http:/,"https:");g.open("POST",a,!0);g.withCredentials=!0;g.setRequestHeader("Content-Type","text/plain");g.onreadystatechange=function(){if(4==g.readyState){if(d)try{var a=g.responseText;if(1>a.length)ge("xhr","ver","0"),c();else if("1"!=a.charAt(0))ge("xhr","ver",String(a.length)),c();else if(3<d.count++)ge("xhr","tmr",""+d.count),c();else if(1==a.length)c();else{var b=a.charAt(1);if("d"==b)pe("https://stats.g.doubleclick.net/j/collect",
11
- d.U,d,c);else if("g"==b){var e="https://www.google.%/ads/ga-audiences".replace("%","com");wc(e,d.google,c);var w=a.substring(2);if(w)if(/^[a-z.]{1,6}$/.test(w)){var ha="https://www.google.%/ads/ga-audiences".replace("%",w);wc(ha,d.google,ua)}else ge("tld","bcc",w)}else ge("xhr","brc",b),c()}}catch(ue){ge("xhr","rsp"),c()}else c();g=null}};g.send(b);return!0},x=function(a,b,c){return O.navigator.sendBeacon?O.navigator.sendBeacon(a,b)?(c(),!0):!1:!1},ge=function(a,b,c){1<=100*Math.random()||G("?")||
12
- (a=["t=error","_e="+a,"_v=j66","sr=1"],b&&a.push("_f="+b),c&&a.push("_m="+K(c.substring(0,100))),a.push("aip=1"),a.push("z="+hd()),wc(oe()+"/collect",a.join("&"),ua))};var h=function(a){var b=O.gaData=O.gaData||{};return b[a]=b[a]||{}};var Ha=function(){this.M=[]};Ha.prototype.add=function(a){this.M.push(a)};Ha.prototype.D=function(a){try{for(var b=0;b<this.M.length;b++){var c=a.get(this.M[b]);c&&ea(c)&&c.call(O,a)}}catch(d){}b=a.get(Ia);b!=ua&&ea(b)&&(a.set(Ia,ua,!0),setTimeout(b,10))};function Ja(a){if(100!=a.get(Ka)&&La(P(a,Q))%1E4>=100*R(a,Ka))throw"abort";}function Ma(a){if(G(P(a,Na)))throw"abort";}function Oa(){var a=M.location.protocol;if("http:"!=a&&"https:"!=a)throw"abort";}
13
- function Pa(a){try{O.navigator.sendBeacon?J(42):O.XMLHttpRequest&&"withCredentials"in new O.XMLHttpRequest&&J(40)}catch(c){}a.set(ld,Td(a),!0);a.set(Ac,R(a,Ac)+1);var b=[];Qa.map(function(c,d){d.F&&(c=a.get(c),void 0!=c&&c!=d.defaultValue&&("boolean"==typeof c&&(c*=1),b.push(d.F+"="+K(""+c))))});b.push("z="+Bd());a.set(Ra,b.join("&"),!0)}
14
- function Sa(a){var b=P(a,gd)||oe()+"/collect",c=a.get(qe),d=P(a,fa);!d&&a.get(Vd)&&(d="beacon");if(c)pe(b,P(a,Ra),c,a.get(Ia));else if(d){c=d;d=P(a,Ra);var e=a.get(Ia);e=e||ua;"image"==c?wc(b,d,e):"xhr"==c&&wd(b,d,e)||"beacon"==c&&x(b,d,e)||ba(b,d,e)}else ba(b,P(a,Ra),a.get(Ia));b=a.get(Na);b=h(b);c=b.hitcount;b.hitcount=c?c+1:1;b=a.get(Na);delete h(b).pending_experiments;a.set(Ia,ua,!0)}
15
- function Hc(a){(O.gaData=O.gaData||{}).expId&&a.set(Nc,(O.gaData=O.gaData||{}).expId);(O.gaData=O.gaData||{}).expVar&&a.set(Oc,(O.gaData=O.gaData||{}).expVar);var b=a.get(Na);if(b=h(b).pending_experiments){var c=[];for(d in b)b.hasOwnProperty(d)&&b[d]&&c.push(encodeURIComponent(d)+"."+encodeURIComponent(b[d]));var d=c.join("!")}else d=void 0;d&&a.set(m,d,!0)}function cd(){if(O.navigator&&"preview"==O.navigator.loadPurpose)throw"abort";}
16
- function yd(a){var b=O.gaDevIds;ka(b)&&0!=b.length&&a.set("&did",b.join(","),!0)}function vb(a){if(!a.get(Na))throw"abort";};var hd=function(){return Math.round(2147483647*Math.random())},Bd=function(){try{var a=new Uint32Array(1);O.crypto.getRandomValues(a);return a[0]&2147483647}catch(b){return hd()}};function Ta(a){var b=R(a,Ua);500<=b&&J(15);var c=P(a,Va);if("transaction"!=c&&"item"!=c){c=R(a,Wa);var d=(new Date).getTime(),e=R(a,Xa);0==e&&a.set(Xa,d);e=Math.round(2*(d-e)/1E3);0<e&&(c=Math.min(c+e,20),a.set(Xa,d));if(0>=c)throw"abort";a.set(Wa,--c)}a.set(Ua,++b)};var Ya=function(){this.data=new ee},Qa=new ee,Za=[];Ya.prototype.get=function(a){var b=$a(a),c=this.data.get(a);b&&void 0==c&&(c=ea(b.defaultValue)?b.defaultValue():b.defaultValue);return b&&b.Z?b.Z(this,a,c):c};var P=function(a,b){a=a.get(b);return void 0==a?"":""+a},R=function(a,b){a=a.get(b);return void 0==a||""===a?0:1*a};Ya.prototype.set=function(a,b,c){if(a)if("object"==typeof a)for(var d in a)a.hasOwnProperty(d)&&ab(this,d,a[d],c);else ab(this,a,b,c)};
17
- var ab=function(a,b,c,d){if(void 0!=c)switch(b){case Na:wb.test(c)}var e=$a(b);e&&e.o?e.o(a,b,c,d):a.data.set(b,c,d)},bb=function(a,b,c,d,e){this.name=a;this.F=b;this.Z=d;this.o=e;this.defaultValue=c},$a=function(a){var b=Qa.get(a);if(!b)for(var c=0;c<Za.length;c++){var d=Za[c],e=d[0].exec(a);if(e){b=d[1](e);Qa.set(b.name,b);break}}return b},yc=function(a){var b;Qa.map(function(c,d){d.F==a&&(b=d)});return b&&b.name},S=function(a,b,c,d,e){a=new bb(a,b,c,d,e);Qa.set(a.name,a);return a.name},cb=function(a,
18
- b){Za.push([new RegExp("^"+a+"$"),b])},T=function(a,b,c){return S(a,b,c,void 0,db)},db=function(){};var gb=qa(window.GoogleAnalyticsObject)&&sa(window.GoogleAnalyticsObject)||"ga",jd=/^(?:utma\.)?\d+\.\d+$/,kd=/^amp-[\w.-]{22,64}$/,Ba=!1,hb=T("apiVersion","v"),ib=T("clientVersion","_v");S("anonymizeIp","aip");var jb=S("adSenseId","a"),Va=S("hitType","t"),Ia=S("hitCallback"),Ra=S("hitPayload");S("nonInteraction","ni");S("currencyCode","cu");S("dataSource","ds");var Vd=S("useBeacon",void 0,!1),fa=S("transport");S("sessionControl","sc","");S("sessionGroup","sg");S("queueTime","qt");var Ac=S("_s","_s");
19
- S("screenName","cd");var kb=S("location","dl",""),lb=S("referrer","dr"),mb=S("page","dp","");S("hostname","dh");var nb=S("language","ul"),ob=S("encoding","de");S("title","dt",function(){return M.title||void 0});cb("contentGroup([0-9]+)",function(a){return new bb(a[0],"cg"+a[1])});var pb=S("screenColors","sd"),qb=S("screenResolution","sr"),rb=S("viewportSize","vp"),sb=S("javaEnabled","je"),tb=S("flashVersion","fl");S("campaignId","ci");S("campaignName","cn");S("campaignSource","cs");
20
- S("campaignMedium","cm");S("campaignKeyword","ck");S("campaignContent","cc");var ub=S("eventCategory","ec"),xb=S("eventAction","ea"),yb=S("eventLabel","el"),zb=S("eventValue","ev"),Bb=S("socialNetwork","sn"),Cb=S("socialAction","sa"),Db=S("socialTarget","st"),Eb=S("l1","plt"),Fb=S("l2","pdt"),Gb=S("l3","dns"),Hb=S("l4","rrt"),Ib=S("l5","srt"),Jb=S("l6","tcp"),Kb=S("l7","dit"),Lb=S("l8","clt"),Mb=S("timingCategory","utc"),Nb=S("timingVar","utv"),Ob=S("timingLabel","utl"),Pb=S("timingValue","utt");
21
- S("appName","an");S("appVersion","av","");S("appId","aid","");S("appInstallerId","aiid","");S("exDescription","exd");S("exFatal","exf");var Nc=S("expId","xid"),Oc=S("expVar","xvar"),m=S("exp","exp"),Rc=S("_utma","_utma"),Sc=S("_utmz","_utmz"),Tc=S("_utmht","_utmht"),Ua=S("_hc",void 0,0),Xa=S("_ti",void 0,0),Wa=S("_to",void 0,20);cb("dimension([0-9]+)",function(a){return new bb(a[0],"cd"+a[1])});cb("metric([0-9]+)",function(a){return new bb(a[0],"cm"+a[1])});S("linkerParam",void 0,void 0,Bc,db);
22
- var ld=S("usage","_u"),Gd=S("_um");S("forceSSL",void 0,void 0,function(){return Ba},function(a,b,c){J(34);Ba=!!c});var ed=S("_j1","jid"),ia=S("_j2","gjid");cb("\\&(.*)",function(a){var b=new bb(a[0],a[1]),c=yc(a[0].substring(1));c&&(b.Z=function(a){return a.get(c)},b.o=function(a,b,g,ca){a.set(c,g,ca)},b.F=void 0);return b});
23
- var Qb=T("_oot"),dd=S("previewTask"),Rb=S("checkProtocolTask"),md=S("validationTask"),Sb=S("checkStorageTask"),Uc=S("historyImportTask"),Tb=S("samplerTask"),Vb=S("_rlt"),Wb=S("buildHitTask"),Xb=S("sendHitTask"),Vc=S("ceTask"),zd=S("devIdTask"),Cd=S("timingTask"),Ld=S("displayFeaturesTask"),oa=S("customTask"),V=T("name"),Q=T("clientId","cid"),n=T("clientIdTime"),xd=T("storedClientId"),Ad=S("userId","uid"),Na=T("trackingId","tid"),U=T("cookieName",void 0,"_ga"),W=T("cookieDomain"),Yb=T("cookiePath",
24
- void 0,"/"),Zb=T("cookieExpires",void 0,63072E3),Hd=T("cookieUpdate",void 0,!0),$b=T("legacyCookieDomain"),Wc=T("legacyHistoryImport",void 0,!0),ac=T("storage",void 0,"cookie"),bc=T("allowLinker",void 0,!1),cc=T("allowAnchor",void 0,!0),Ka=T("sampleRate","sf",100),dc=T("siteSpeedSampleRate",void 0,1),ec=T("alwaysSendReferrer",void 0,!1),I=T("_gid","_gid"),la=T("_gcn"),Kd=T("useAmpClientId"),ce=T("_gclid"),fe=T("_gt"),he=T("_ge",void 0,7776E6),ie=T("_gclsrc"),je=T("storeGac",void 0,!0),gd=S("transportUrl"),
25
- Md=S("_r","_r"),qe=S("_dp");function X(a,b,c,d){b[a]=function(){try{return d&&J(d),c.apply(this,arguments)}catch(e){throw ge("exc",a,e&&e.name),e;}}};var Od=function(a,b){this.V=1E4;this.fa=a;this.$=!1;this.oa=b;this.ea=1},Ed=function(a,b){var c;if(a.fa&&a.$)return 0;a.$=!0;if(b){if(a.oa&&R(b,a.oa))return R(b,a.oa);if(0==b.get(dc))return 0}if(0==a.V)return 0;void 0===c&&(c=Bd());return 0==c%a.V?Math.floor(c/a.V)%a.ea+1:0};function fc(){var a,b;if((b=(b=O.navigator)?b.plugins:null)&&b.length)for(var c=0;c<b.length&&!a;c++){var d=b[c];-1<d.name.indexOf("Shockwave Flash")&&(a=d.description)}if(!a)try{var e=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");a=e.GetVariable("$version")}catch(g){}if(!a)try{e=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6"),a="WIN 6,0,21,0",e.AllowScriptAccess="always",a=e.GetVariable("$version")}catch(g){}if(!a)try{e=new ActiveXObject("ShockwaveFlash.ShockwaveFlash"),a=e.GetVariable("$version")}catch(g){}a&&
26
- (e=a.match(/[\d]+/g))&&3<=e.length&&(a=e[0]+"."+e[1]+" r"+e[2]);return a||void 0};var aa=function(a){var b=Math.min(R(a,dc),100);return La(P(a,Q))%100>=b?!1:!0},gc=function(a){var b={};if(Ec(b)||Fc(b)){var c=b[Eb];void 0==c||Infinity==c||isNaN(c)||(0<c?(Y(b,Gb),Y(b,Jb),Y(b,Ib),Y(b,Fb),Y(b,Hb),Y(b,Kb),Y(b,Lb),va(function(){a(b)},10)):L(O,"load",function(){gc(a)},!1))}},Ec=function(a){var b=O.performance||O.webkitPerformance;b=b&&b.timing;if(!b)return!1;var c=b.navigationStart;if(0==c)return!1;a[Eb]=b.loadEventStart-c;a[Gb]=b.domainLookupEnd-b.domainLookupStart;a[Jb]=b.connectEnd-
27
- b.connectStart;a[Ib]=b.responseStart-b.requestStart;a[Fb]=b.responseEnd-b.responseStart;a[Hb]=b.fetchStart-c;a[Kb]=b.domInteractive-c;a[Lb]=b.domContentLoadedEventStart-c;return!0},Fc=function(a){if(O.top!=O)return!1;var b=O.external,c=b&&b.onloadT;b&&!b.isValidLoadTime&&(c=void 0);2147483648<c&&(c=void 0);0<c&&b.setPageReadyTime();if(void 0==c)return!1;a[Eb]=c;return!0},Y=function(a,b){var c=a[b];if(isNaN(c)||Infinity==c||0>c)a[b]=void 0},Fd=function(a){return function(b){if("pageview"==b.get(Va)&&
28
- !a.I){a.I=!0;var c=aa(b),d=0<E(b.get(kb),"gclid").length;(c||d)&&gc(function(b){c&&a.send("timing",b);d&&a.send("adtiming",b)})}}};var hc=!1,mc=function(a){if("cookie"==P(a,ac)){if(a.get(Hd)||P(a,xd)!=P(a,Q)){var b=1E3*R(a,Zb);ma(a,Q,U,b)}ma(a,I,la,864E5);if(a.get(je)){var c=a.get(ce);if(c){var d=Math.min(R(a,he),1E3*R(a,Zb));d=Math.min(d,1E3*R(a,fe)+d-(new Date).getTime());a.data.set(he,d);var e=a.get(fe),g=a.get(ie);b=kc(P(a,Yb));var ca=lc(P(a,W));a=P(a,Na);g&&"aw.ds"!=g||(c=["1",e,Cc(c)].join("."),0<d&&zc("_gac_"+Cc(a),c,b,ca,a,d));le({})}}else J(75)}},ma=function(a,b,c,d){var e=nd(a,b);if(e){c=P(a,c);var g=kc(P(a,Yb)),ca=
29
- lc(P(a,W)),l=P(a,Na);if("auto"!=ca)zc(c,e,g,ca,l,d)&&(hc=!0);else{J(32);for(var k=id(),w=0;w<k.length;w++)if(ca=k[w],a.data.set(W,ca),e=nd(a,b),zc(c,e,g,ca,l,d)){hc=!0;return}a.data.set(W,"auto")}}},nc=function(a){if("cookie"==P(a,ac)&&!hc&&(mc(a),!hc))throw"abort";},Yc=function(a){if(a.get(Wc)){var b=P(a,W),c=P(a,$b)||xa(),d=Xc("__utma",c,b);d&&(J(19),a.set(Tc,(new Date).getTime(),!0),a.set(Rc,d.R),(b=Xc("__utmz",c,b))&&d.hash==b.hash&&a.set(Sc,b.R))}},nd=function(a,b){b=Cc(P(a,b));var c=lc(P(a,
30
- W)).split(".").length;a=jc(P(a,Yb));1<a&&(c+="-"+a);return b?["GA1",c,b].join("."):""},Xd=function(a,b){return na(b,P(a,W),P(a,Yb))},na=function(a,b,c){if(!a||1>a.length)J(12);else{for(var d=[],e=0;e<a.length;e++){var g=a[e];var ca=g.split(".");var l=ca.shift();("GA1"==l||"1"==l)&&1<ca.length?(g=ca.shift().split("-"),1==g.length&&(g[1]="1"),g[0]*=1,g[1]*=1,ca={H:g,s:ca.join(".")}):ca=kd.test(g)?{H:[0,0],s:g}:void 0;ca&&d.push(ca)}if(1==d.length)return J(13),d[0].s;if(0==d.length)J(12);else{J(14);
31
- d=Gc(d,lc(b).split(".").length,0);if(1==d.length)return d[0].s;d=Gc(d,jc(c),1);1<d.length&&J(41);return d[0]&&d[0].s}}},Gc=function(a,b,c){for(var d=[],e=[],g,ca=0;ca<a.length;ca++){var l=a[ca];l.H[c]==b?d.push(l):void 0==g||l.H[c]<g?(e=[l],g=l.H[c]):l.H[c]==g&&e.push(l)}return 0<d.length?d:e},lc=function(a){return 0==a.indexOf(".")?a.substr(1):a},id=function(){var a=[],b=xa().split(".");if(4==b.length){var c=b[b.length-1];if(parseInt(c,10)==c)return["none"]}for(c=b.length-2;0<=c;c--)a.push(b.slice(c).join("."));
32
- a.push("none");return a},kc=function(a){if(!a)return"/";1<a.length&&a.lastIndexOf("/")==a.length-1&&(a=a.substr(0,a.length-1));0!=a.indexOf("/")&&(a="/"+a);return a},jc=function(a){a=kc(a);return"/"==a?1:a.split("/").length},le=function(a){a.ta&&J(77);a.na&&J(74);a.pa&&J(73);a.ua&&J(69)};function Xc(a,b,c){"none"==b&&(b="");var d=[],e=Ca(a);a="__utma"==a?6:2;for(var g=0;g<e.length;g++){var ca=(""+e[g]).split(".");ca.length>=a&&d.push({hash:ca[0],R:e[g],O:ca})}if(0!=d.length)return 1==d.length?d[0]:Zc(b,d)||Zc(c,d)||Zc(null,d)||d[0]}function Zc(a,b){if(null==a)var c=a=1;else c=La(a),a=La(D(a,".")?a.substring(1):"."+a);for(var d=0;d<b.length;d++)if(b[d].hash==c||b[d].hash==a)return b[d]};var od=new RegExp(/^https?:\/\/([^\/:]+)/),pd=/(.*)([?&#])(?:_ga=[^&#]*)(?:&?)(.*)/,me=/(.*)([?&#])(?:_gac=[^&#]*)(?:&?)(.*)/;function Bc(a){var b=a.get(Q),c=a.get(I)||"";b="_ga=2."+K(pa(c+b,0)+"."+c+"-"+b);if((c=a.get(ce))&&a.get(je)){var d=R(a,fe);1E3*d+R(a,he)<=(new Date).getTime()?(J(76),a=""):(J(44),a="&_gac=1."+K([pa(c,0),d,c].join(".")))}else a="";return b+a}
33
- function Ic(a,b){var c=new Date,d=O.navigator,e=d.plugins||[];a=[a,d.userAgent,c.getTimezoneOffset(),c.getYear(),c.getDate(),c.getHours(),c.getMinutes()+b];for(b=0;b<e.length;++b)a.push(e[b].description);return La(a.join("."))}function pa(a,b){var c=new Date,d=O.navigator,e=c.getHours()+Math.floor((c.getMinutes()+b)/60);return La([a,d.userAgent,d.language||"",c.getTimezoneOffset(),c.getYear(),c.getDate()+Math.floor(e/24),(24+e)%24,(60+c.getMinutes()+b)%60].join("."))}
34
- var Dc=function(a){J(48);this.target=a;this.T=!1};Dc.prototype.ca=function(a,b){if(a.tagName){if("a"==a.tagName.toLowerCase()){a.href&&(a.href=qd(this,a.href,b));return}if("form"==a.tagName.toLowerCase())return rd(this,a)}if("string"==typeof a)return qd(this,a,b)};
35
- var qd=function(a,b,c){var d=pd.exec(b);d&&3<=d.length&&(b=d[1]+(d[3]?d[2]+d[3]:""));(d=me.exec(b))&&3<=d.length&&(b=d[1]+(d[3]?d[2]+d[3]:""));a=a.target.get("linkerParam");var e=b.indexOf("?");d=b.indexOf("#");c?b+=(-1==d?"#":"&")+a:(c=-1==e?"?":"&",b=-1==d?b+(c+a):b.substring(0,d)+c+a+b.substring(d));b=b.replace(/&+_ga=/,"&_ga=");return b=b.replace(/&+_gac=/,"&_gac=")},rd=function(a,b){if(b&&b.action)if("get"==b.method.toLowerCase()){a=a.target.get("linkerParam").split("&");for(var c=0;c<a.length;c++){var d=
36
- a[c].split("="),e=d[1];d=d[0];for(var g=b.childNodes||[],ca=!1,l=0;l<g.length;l++)if(g[l].name==d){g[l].setAttribute("value",e);ca=!0;break}ca||(g=M.createElement("input"),g.setAttribute("type","hidden"),g.setAttribute("name",d),g.setAttribute("value",e),b.appendChild(g))}}else"post"==b.method.toLowerCase()&&(b.action=qd(a,b.action))};
37
- Dc.prototype.S=function(a,b,c){function d(c){try{c=c||O.event;a:{var d=c.target||c.srcElement;for(c=100;d&&0<c;){if(d.href&&d.nodeName.match(/^a(?:rea)?$/i)){var g=d;break a}d=d.parentNode;c--}g={}}("http:"==g.protocol||"https:"==g.protocol)&&sd(a,g.hostname||"")&&g.href&&(g.href=qd(e,g.href,b))}catch(k){J(26)}}var e=this;this.T||(this.T=!0,L(M,"mousedown",d,!1),L(M,"keyup",d,!1));c&&L(M,"submit",function(b){b=b||O.event;if((b=b.target||b.srcElement)&&b.action){var c=b.action.match(od);c&&sd(a,c[1])&&
38
- rd(e,b)}})};function sd(a,b){if(b==M.location.hostname)return!1;for(var c=0;c<a.length;c++)if(a[c]instanceof RegExp){if(a[c].test(b))return!0}else if(0<=b.indexOf(a[c]))return!0;return!1}function ke(a,b){return b!=Ic(a,0)&&b!=Ic(a,-1)&&b!=Ic(a,-2)&&b!=pa(a,0)&&b!=pa(a,-1)&&b!=pa(a,-2)};var p=/^(GTM|OPT)-[A-Z0-9]+$/,q=/;_gaexp=[^;]*/g,r=/;((__utma=)|([^;=]+=GAX?\d+\.))[^;]*/g,Aa=/^https?:\/\/[\w\-.]+\.google.com(:\d+)?\/optimize\/opt-launch\.html\?.*$/,t=function(a){function b(a,b){b&&(c+="&"+a+"="+K(b))}var c="https://www.google-analytics.com/gtm/js?id="+K(a.id);"dataLayer"!=a.B&&b("l",a.B);b("t",a.target);b("cid",a.clientId);b("cidt",a.ka);b("gac",a.la);b("aip",a.ia);a.sync&&b("m","sync");b("cycle",a.G);a.qa&&b("gclid",a.qa);Aa.test(M.referrer)&&b("cb",String(hd()));return c};var Jd=function(a,b,c){this.aa=b;(b=c)||(b=(b=P(a,V))&&"t0"!=b?Wd.test(b)?"_gat_"+Cc(P(a,Na)):"_gat_"+Cc(b):"_gat");this.Y=b},Rd=function(a,b){var c=b.get(Wb);b.set(Wb,function(b){Pd(a,b,ed);Pd(a,b,ia);var d=c(b);Qd(a,b);return d});var d=b.get(Xb);b.set(Xb,function(b){var c=d(b);if(b.get(ed)){if(ne()){J(80);var e={U:re(a,b,1),google:re(a,b,2),count:0};pe("https://stats.g.doubleclick.net/j/collect",e.U,e)}else ta(re(a,b,0));b.set(ed,"",!0)}return c})},Pd=function(a,b,c){b.get(c)||("1"==Ca(a.Y)[0]?
39
- b.set(c,"",!0):b.set(c,""+hd(),!0))},Qd=function(a,b){b.get(ed)&&zc(a.Y,"1",b.get(Yb),b.get(W),b.get(Na),6E4)},re=function(a,b,c){var d=new ee,e=function(a){$a(a).F&&d.set($a(a).F,b.get(a))};e(hb);e(ib);e(Na);e(Q);e(ed);if(0==c||1==c)e(Ad),e(ia),e(I);d.set($a(ld).F,Td(b));var g="";d.map(function(a,b){g+=K(a)+"=";g+=K(""+b)+"&"});g+="z="+hd();0==c?g=a.aa+g:1==c?g="t=dc&aip=1&_r=3&"+g:2==c&&(g="t=sr&aip=1&_r=4&slf_rd=1&"+g);return g},Wd=/^gtm\d+$/;var fd=function(a,b){a=a.b;if(!a.get("dcLoaded")){var c=new $c(Dd(a));c.set(29);a.set(Gd,c.w);b=b||{};var d;b[U]&&(d=Cc(b[U]));b=new Jd(a,"https://stats.g.doubleclick.net/r/collect?t=dc&aip=1&_r=3&",d);Rd(b,a);a.set("dcLoaded",!0)}};var Sd=function(a){if(!a.get("dcLoaded")&&"cookie"==a.get(ac)){var b=new Jd(a);Pd(b,a,ed);Pd(b,a,ia);Qd(b,a);a.get(ed)&&(a.set(Md,1,!0),ne()?(J(79),a.set(gd,oe()+"/j/collect",!0),a.set(qe,{U:re(b,a,1),google:re(b,a,2),count:0},!0)):a.set(gd,oe()+"/r/collect",!0))}};var Lc=function(){var a=O.gaGlobal=O.gaGlobal||{};return a.hid=a.hid||hd()};var ad,bd=function(a,b,c){if(!ad){var d=M.location.hash;var e=O.name,g=/^#?gaso=([^&]*)/;if(e=(d=(d=d&&d.match(g)||e&&e.match(g))?d[1]:Ca("GASO")[0]||"")&&d.match(/^(?:!([-0-9a-z.]{1,40})!)?([-.\w]{10,1200})$/i))zc("GASO",""+d,c,b,a,0),window._udo||(window._udo=b),window._utcp||(window._utcp=c),a=e[1],wa("https://www.google.com/analytics/web/inpage/pub/inpage.js?"+(a?"prefix="+a+"&":"")+hd(),"_gasojs");ad=!0}};var H=function(a){return a?(1*a).toFixed(3):"0"},da=function(a){var b=O.performance;if(b&&b.getEntriesByName){J(35);var c="https://www.google-analytics.com/analytics.js?wpid="+a;wa(c,void 0,void 0,function(){try{var d=1,e=b.getEntriesByName("https://www.google-analytics.com/analytics.js");e&&0!=e.length||(e=b.getEntriesByName("http://www.google-analytics.com/analytics.js"),d=0);var g=b.getEntriesByName(c);if(e&&1==e.length&&g&&1==g.length){J(37);var ca=e[0],l=g[0],k={tid:a,ad:H(ca.duration),bd:H(l.duration),
40
- ar:H(ca.responseEnd-ca.requestStart),br:H(l.responseEnd-l.requestStart),an:H(ca.domainLookupEnd-ca.domainLookupStart),bn:H(l.domainLookupEnd-l.domainLookupStart),ac:H(ca.connectEnd-ca.connectStart),bc:H(l.connectEnd-l.connectStart),as:d};d=[];d.push("_v=j66");d.push("id=10");for(var w in k)k.hasOwnProperty(w)&&d.push(w+"="+K(k[w]));d.push("z="+hd());wc("https://www.google-analytics.com/u/d",d.join("&"),ua)}}catch(ha){}})}};var wb=/^(UA|YT|MO|GP)-(\d+)-(\d+)$/,pc=function(a){function b(a,b){d.b.data.set(a,b)}function c(a,c){b(a,c);d.filters.add(a)}var d=this;this.b=new Ya;this.filters=new Ha;b(V,a[V]);b(Na,sa(a[Na]));b(U,a[U]);b(W,a[W]||xa());b(Yb,a[Yb]);b(Zb,a[Zb]);b(Hd,a[Hd]);b($b,a[$b]);b(Wc,a[Wc]);b(bc,a[bc]);b(cc,a[cc]);b(Ka,a[Ka]);b(dc,a[dc]);b(ec,a[ec]);b(ac,a[ac]);b(Ad,a[Ad]);b(n,a[n]);b(Kd,a[Kd]);b(je,a[je]);b(hb,1);b(ib,"j66");c(Qb,Ma);c(oa,ua);c(dd,cd);c(Rb,Oa);c(md,vb);c(Sb,nc);c(Uc,Yc);c(Tb,Ja);c(Vb,Ta);
41
- c(Vc,Hc);c(zd,yd);c(Ld,Sd);c(Wb,Pa);c(Xb,Sa);c(Cd,Fd(this));Kc(this.b);Jc(this.b,a[Q]);this.b.set(jb,Lc());bd(this.b.get(Na),this.b.get(W),this.b.get(Yb));this.ra=new Od(!0,"gaexp10")},Jc=function(a,b){var c=P(a,U);a.data.set(la,"_ga"==c?"_gid":c+"_gid");if("cookie"==P(a,ac)){hc=!1;c=Ca(P(a,U));c=Xd(a,c);if(!c){c=P(a,W);var d=P(a,$b)||xa();c=Xc("__utma",d,c);void 0!=c?(J(10),c=c.O[1]+"."+c.O[2]):c=void 0}c&&(hc=!0);if(d=c&&!a.get(Hd))if(d=c.split("."),2!=d.length)d=!1;else if(d=Number(d[1])){var e=
42
- R(a,Zb);d=d+e<(new Date).getTime()/1E3}else d=!1;d&&(c=void 0);c&&(a.data.set(xd,c),a.data.set(Q,c),c=Ca(P(a,la)),(c=Xd(a,c))&&a.data.set(I,c));if(a.get(je)&&(c=a.get(ce),d=a.get(ie),!c||d&&"aw.ds"!=d)){c={};if(M){d=[];e=M.cookie.split(";");for(var g=/^\s*_gac_(UA-\d+-\d+)=\s*(.+?)\s*$/,ca=0;ca<e.length;ca++){var l=e[ca].match(g);l&&d.push({ja:l[1],value:l[2]})}e={};if(d&&d.length)for(g=0;g<d.length;g++)(ca=d[g].value.split("."),"1"!=ca[0]||3!=ca.length)?c&&(c.na=!0):ca[1]&&(e[d[g].ja]?c&&(c.pa=!0):
43
- e[d[g].ja]=[],e[d[g].ja].push({timestamp:ca[1],qa:ca[2]}));d=e}else d={};d=d[P(a,Na)];le(c);d&&0!=d.length&&(c=d[0],a.data.set(fe,c.timestamp),a.data.set(ce,c.qa))}}if(a.get(Hd))a:if(d=be("_ga",a.get(cc)))if(a.get(bc))if(c=d.indexOf("."),-1==c)J(22);else{e=d.substring(0,c);g=d.substring(c+1);c=g.indexOf(".");d=g.substring(0,c);g=g.substring(c+1);if("1"==e){if(c=g,ke(c,d)){J(23);break a}}else if("2"==e){c=g.indexOf("-");e="";0<c?(e=g.substring(0,c),c=g.substring(c+1)):c=g.substring(1);if(ke(e+c,d)){J(53);
44
- break a}e&&(J(2),a.data.set(I,e))}else{J(22);break a}J(11);a.data.set(Q,c);if(c=be("_gac",a.get(cc)))c=c.split("."),"1"!=c[0]||4!=c.length?J(72):ke(c[3],c[1])?J(71):(a.data.set(ce,c[3]),a.data.set(fe,c[2]),J(70))}else J(21);b&&(J(9),a.data.set(Q,K(b)));a.get(Q)||((b=(b=O.gaGlobal&&O.gaGlobal.vid)&&-1!=b.search(jd)?b:void 0)?(J(17),a.data.set(Q,b)):(J(8),a.data.set(Q,ra())));a.get(I)||(J(3),a.data.set(I,ra()));mc(a)},Kc=function(a){var b=O.navigator,c=O.screen,d=M.location;a.set(lb,ya(a.get(ec),a.get(Kd)));
45
- if(d){var e=d.pathname||"";"/"!=e.charAt(0)&&(J(31),e="/"+e);a.set(kb,d.protocol+"//"+d.hostname+e+d.search)}c&&a.set(qb,c.width+"x"+c.height);c&&a.set(pb,c.colorDepth+"-bit");c=M.documentElement;var g=(e=M.body)&&e.clientWidth&&e.clientHeight,ca=[];c&&c.clientWidth&&c.clientHeight&&("CSS1Compat"===M.compatMode||!g)?ca=[c.clientWidth,c.clientHeight]:g&&(ca=[e.clientWidth,e.clientHeight]);c=0>=ca[0]||0>=ca[1]?"":ca.join("x");a.set(rb,c);a.set(tb,fc());a.set(ob,M.characterSet||M.charset);a.set(sb,b&&
46
- "function"===typeof b.javaEnabled&&b.javaEnabled()||!1);a.set(nb,(b&&(b.language||b.browserLanguage)||"").toLowerCase());a.data.set(ce,be("gclid",!0));a.data.set(ie,be("gclsrc",!0));a.data.set(fe,Math.round((new Date).getTime()/1E3));if(d&&a.get(cc)&&(b=M.location.hash)){b=b.split(/[?&#]+/);d=[];for(c=0;c<b.length;++c)(D(b[c],"utm_id")||D(b[c],"utm_campaign")||D(b[c],"utm_source")||D(b[c],"utm_medium")||D(b[c],"utm_term")||D(b[c],"utm_content")||D(b[c],"gclid")||D(b[c],"dclid")||D(b[c],"gclsrc"))&&
47
- d.push(b[c]);0<d.length&&(b="#"+d.join("&"),a.set(kb,a.get(kb)+b))}};pc.prototype.get=function(a){return this.b.get(a)};pc.prototype.set=function(a,b){this.b.set(a,b)};var qc={pageview:[mb],event:[ub,xb,yb,zb],social:[Bb,Cb,Db],timing:[Mb,Nb,Pb,Ob]};
48
- pc.prototype.send=function(a){if(!(1>arguments.length)){if("string"===typeof arguments[0]){var b=arguments[0];var c=[].slice.call(arguments,1)}else b=arguments[0]&&arguments[0][Va],c=arguments;b&&(c=za(qc[b]||[],c),c[Va]=b,this.b.set(c,void 0,!0),this.filters.D(this.b),this.b.data.m={},Ed(this.ra,this.b)&&da(this.b.get(Na)))}};pc.prototype.ma=function(a,b){var c=this;u(a,c,b)||(v(a,function(){u(a,c,b)}),y(String(c.get(V)),a,void 0,b,!0))};var rc=function(a){if("prerender"==M.visibilityState)return!1;a();return!0},z=function(a){if(!rc(a)){J(16);var b=!1,c=function(){if(!b&&rc(a)){b=!0;var d=c,e=M;e.removeEventListener?e.removeEventListener("visibilitychange",d,!1):e.detachEvent&&e.detachEvent("onvisibilitychange",d)}};L(M,"visibilitychange",c)}};var td=/^(?:(\w+)\.)?(?:(\w+):)?(\w+)$/,sc=function(a){if(ea(a[0]))this.u=a[0];else{var b=td.exec(a[0]);null!=b&&4==b.length&&(this.c=b[1]||"t0",this.K=b[2]||"",this.C=b[3],this.a=[].slice.call(a,1),this.K||(this.A="create"==this.C,this.i="require"==this.C,this.g="provide"==this.C,this.ba="remove"==this.C),this.i&&(3<=this.a.length?(this.X=this.a[1],this.W=this.a[2]):this.a[1]&&(qa(this.a[1])?this.X=this.a[1]:this.W=this.a[1])));b=a[1];a=a[2];if(!this.C)throw"abort";if(this.i&&(!qa(b)||""==b))throw"abort";
49
- if(this.g&&(!qa(b)||""==b||!ea(a)))throw"abort";if(ud(this.c)||ud(this.K))throw"abort";if(this.g&&"t0"!=this.c)throw"abort";}};function ud(a){return 0<=a.indexOf(".")||0<=a.indexOf(":")};var Yd,Zd,$d,A;Yd=new ee;$d=new ee;A=new ee;Zd={ec:45,ecommerce:46,linkid:47};
50
- var u=function(a,b,c){b==N||b.get(V);var d=Yd.get(a);if(!ea(d))return!1;b.plugins_=b.plugins_||new ee;if(b.plugins_.get(a))return!0;b.plugins_.set(a,new d(b,c||{}));return!0},y=function(a,b,c,d,e){if(!ea(Yd.get(b))&&!$d.get(b)){Zd.hasOwnProperty(b)&&J(Zd[b]);if(p.test(b)){J(52);a=N.j(a);if(!a)return!0;c=d||{};d={id:b,B:c.dataLayer||"dataLayer",ia:!!a.get("anonymizeIp"),sync:e,G:!1};a.get("&gtm")==b&&(d.G=!0);var g=String(a.get("name"));"t0"!=g&&(d.target=g);G(String(a.get("trackingId")))||(d.clientId=
51
- String(a.get(Q)),d.ka=Number(a.get(n)),c=c.palindrome?r:q,c=(c=M.cookie.replace(/^|(; +)/g,";").match(c))?c.sort().join("").substring(1):void 0,d.la=c,d.qa=E(a.b.get(kb)||"","gclid"));a=d.B;c=(new Date).getTime();O[a]=O[a]||[];c={"gtm.start":c};e||(c.event="gtm.js");O[a].push(c);c=t(d)}!c&&Zd.hasOwnProperty(b)?(J(39),c=b+".js"):J(43);c&&(c&&0<=c.indexOf("/")||(c=(Ba||Ud()?"https:":"http:")+"//www.google-analytics.com/plugins/ua/"+c),d=ae(c),a=d.protocol,c=M.location.protocol,("https:"==a||a==c||("http:"!=
52
- a?0:"http:"==c))&&B(d)&&(wa(d.url,void 0,e),$d.set(b,!0)))}},v=function(a,b){var c=A.get(a)||[];c.push(b);A.set(a,c)},C=function(a,b){Yd.set(a,b);b=A.get(a)||[];for(var c=0;c<b.length;c++)b[c]();A.set(a,[])},B=function(a){var b=ae(M.location.href);if(D(a.url,"https://www.google-analytics.com/gtm/js?id="))return!0;if(a.query||0<=a.url.indexOf("?")||0<=a.path.indexOf("://"))return!1;if(a.host==b.host&&a.port==b.port)return!0;b="http:"==a.protocol?80:443;return"www.google-analytics.com"==a.host&&(a.port||
53
- b)==b&&D(a.path,"/plugins/")?!0:!1},ae=function(a){function b(a){var b=(a.hostname||"").split(":")[0].toLowerCase(),c=(a.protocol||"").toLowerCase();c=1*a.port||("http:"==c?80:"https:"==c?443:"");a=a.pathname||"";D(a,"/")||(a="/"+a);return[b,""+c,a]}var c=M.createElement("a");c.href=M.location.href;var d=(c.protocol||"").toLowerCase(),e=b(c),g=c.search||"",ca=d+"//"+e[0]+(e[1]?":"+e[1]:"");D(a,"//")?a=d+a:D(a,"/")?a=ca+a:!a||D(a,"?")?a=ca+e[2]+(a||g):0>a.split("/")[0].indexOf(":")&&(a=ca+e[2].substring(0,
54
- e[2].lastIndexOf("/"))+"/"+a);c.href=a;d=b(c);return{protocol:(c.protocol||"").toLowerCase(),host:d[0],port:d[1],path:d[2],query:c.search||"",url:a||""}};var Z={ga:function(){Z.f=[]}};Z.ga();Z.D=function(a){var b=Z.J.apply(Z,arguments);b=Z.f.concat(b);for(Z.f=[];0<b.length&&!Z.v(b[0])&&!(b.shift(),0<Z.f.length););Z.f=Z.f.concat(b)};Z.J=function(a){for(var b=[],c=0;c<arguments.length;c++)try{var d=new sc(arguments[c]);d.g?C(d.a[0],d.a[1]):(d.i&&(d.ha=y(d.c,d.a[0],d.X,d.W)),b.push(d))}catch(e){}return b};
55
- Z.v=function(a){try{if(a.u)a.u.call(O,N.j("t0"));else{var b=a.c==gb?N:N.j(a.c);if(a.A){if("t0"==a.c&&(b=N.create.apply(N,a.a),null===b))return!0}else if(a.ba)N.remove(a.c);else if(b)if(a.i){if(a.ha&&(a.ha=y(a.c,a.a[0],a.X,a.W)),!u(a.a[0],b,a.W))return!0}else if(a.K){var c=a.C,d=a.a,e=b.plugins_.get(a.K);e[c].apply(e,d)}else b[a.C].apply(b,a.a)}}catch(g){}};var N=function(a){J(1);Z.D.apply(Z,[arguments])};N.h={};N.P=[];N.L=0;N.answer=42;var uc=[Na,W,V];
56
- N.create=function(a){var b=za(uc,[].slice.call(arguments));b[V]||(b[V]="t0");var c=""+b[V];if(N.h[c])return N.h[c];a:{if(b[Kd]){J(67);if(b[ac]&&"cookie"!=b[ac]){var d=!1;break a}if(void 0!==Ab)b[Q]||(b[Q]=Ab);else{b:{d=String(b[W]||xa());var e=String(b[Yb]||"/"),g=Ca(String(b[U]||"_ga"));d=na(g,d,e);if(!d||jd.test(d))d=!0;else if(d=Ca("AMP_TOKEN"),0==d.length)d=!0;else{if(1==d.length&&(d=decodeURIComponent(d[0]),"$RETRIEVING"==d||"$OPT_OUT"==d||"$ERROR"==d||"$NOT_FOUND"==d)){d=!0;break b}d=!1}}if(d&&
57
- tc(ic,String(b[Na]))){d=!0;break a}}}d=!1}if(d)return null;b=new pc(b);N.h[c]=b;N.P.push(b);return b};N.remove=function(a){for(var b=0;b<N.P.length;b++)if(N.P[b].get(V)==a){N.P.splice(b,1);N.h[a]=null;break}};N.j=function(a){return N.h[a]};N.getAll=function(){return N.P.slice(0)};
58
- N.N=function(){"ga"!=gb&&J(49);var a=O[gb];if(!a||42!=a.answer){N.L=a&&a.l;N.loaded=!0;var b=O[gb]=N;X("create",b,b.create);X("remove",b,b.remove);X("getByName",b,b.j,5);X("getAll",b,b.getAll,6);b=pc.prototype;X("get",b,b.get,7);X("set",b,b.set,4);X("send",b,b.send);X("requireSync",b,b.ma);b=Ya.prototype;X("get",b,b.get);X("set",b,b.set);if(!Ud()&&!Ba){a:{b=M.getElementsByTagName("script");for(var c=0;c<b.length&&100>c;c++){var d=b[c].src;if(d&&0==d.indexOf("https://www.google-analytics.com/analytics")){b=
59
- !0;break a}}b=!1}b&&(Ba=!0)}Ud()||Ba||!Ed(new Od)||(Ba=!0);(O.gaplugins=O.gaplugins||{}).Linker=Dc;b=Dc.prototype;C("linker",Dc);X("decorate",b,b.ca,20);X("autoLink",b,b.S,25);C("displayfeatures",fd);C("adfeatures",fd);a=a&&a.q;ka(a)?Z.D.apply(N,a):J(50)}};N.da=function(){for(var a=N.getAll(),b=0;b<a.length;b++)a[b].get(V)};var Nd=N.N,se=O[gb];se&&se.r?Nd():z(Nd);z(function(){Z.D(["provide","render",ua])});function La(a){var b=1,c;if(a)for(b=0,c=a.length-1;0<=c;c--){var d=a.charCodeAt(c);b=(b<<6&268435455)+d+(d<<14);d=b&266338304;b=0!=d?b^d>>21:b}return b};})(window);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
clearfy.php CHANGED
@@ -4,10 +4,10 @@
4
  * Plugin URI: https://wordpress.org/plugins/clearfy/
5
  * Description: Disables unused Wordpress features, improves performance and increases SEO rankings, using Clearfy, which makes WordPress very easy.
6
  * Author: Webcraftic <wordpress.webraftic@gmail.com>
7
- * Version: 1.2.1
8
  * Text Domain: clearfy
9
  * Domain Path: /languages/
10
- * Author URI: http://webcraftic.com
11
  */
12
 
13
  // Exit if accessed directly
@@ -19,6 +19,7 @@
19
  return;
20
  }
21
  define('WBCR_CLEARFY_PLUGIN_ACTIVE', true);
 
22
 
23
  define('WCL_PLUGIN_DIR', dirname(__FILE__));
24
  define('WCL_PLUGIN_BASE', plugin_basename(__FILE__));
@@ -36,10 +37,14 @@
36
  'prefix' => 'wbcr_clearfy_',
37
  'plugin_name' => 'wbcr_clearfy',
38
  'plugin_title' => __('Clearfy', 'clearfy'),
39
- 'plugin_version' => '1.2.1',
40
  'required_php_version' => '5.2',
41
  'required_wp_version' => '4.2',
 
 
 
42
  'plugin_build' => 'free',
43
- 'updates' => WCL_PLUGIN_DIR . '/updates/'
44
-
 
45
  ));
4
  * Plugin URI: https://wordpress.org/plugins/clearfy/
5
  * Description: Disables unused Wordpress features, improves performance and increases SEO rankings, using Clearfy, which makes WordPress very easy.
6
  * Author: Webcraftic <wordpress.webraftic@gmail.com>
7
+ * Version: 1.3.183
8
  * Text Domain: clearfy
9
  * Domain Path: /languages/
10
+ * Author URI: http://clearfy.pro
11
  */
12
 
13
  // Exit if accessed directly
19
  return;
20
  }
21
  define('WBCR_CLEARFY_PLUGIN_ACTIVE', true);
22
+ define('WBCR_CLEARFY_FRAMEWORK_VER', 'FACTORY_406_VERSION');
23
 
24
  define('WCL_PLUGIN_DIR', dirname(__FILE__));
25
  define('WCL_PLUGIN_BASE', plugin_basename(__FILE__));
37
  'prefix' => 'wbcr_clearfy_',
38
  'plugin_name' => 'wbcr_clearfy',
39
  'plugin_title' => __('Clearfy', 'clearfy'),
40
+ 'plugin_version' => '1.3.183',
41
  'required_php_version' => '5.2',
42
  'required_wp_version' => '4.2',
43
+ 'freemius_plugin_id' => 2315,
44
+ 'freemius_plugin_slug' => 'clearfy',
45
+ 'freemius_public_key' => 'pk_70e226af07d37d2b9a69720e0952c',
46
  'plugin_build' => 'free',
47
+ 'updates' => WCL_PLUGIN_DIR . '/updates/',
48
+ 'author_site_url' => 'https://clearfy.pro',
49
+ 'author_ru_site_url' => 'https://ru.clearfy.pro'
50
  ));
components/assets-manager/admin/assets/css/general.css CHANGED
@@ -19,16 +19,16 @@
19
  font-weight: bold;
20
  padding: 10px;
21
  }
22
- #WBCR .hint-warnign-color {
23
  color: #ffeb3b;
24
  }
25
  #WBCR .wbcr-clearfy-header {
26
  padding: 20px 20px 40px;
27
  }
28
- #WBCR .factory-bootstrap-400 label {
29
  font-weight: normal;
30
  }
31
- #WBCR .factory-bootstrap-400 .form-horizontal .control-label {
32
  max-width: 300px;
33
  }
34
  #WBCR .factory-control-buttons {
19
  font-weight: bold;
20
  padding: 10px;
21
  }
22
+ #WBCR .wbcr-factory-light-orange-color {
23
  color: #ffeb3b;
24
  }
25
  #WBCR .wbcr-clearfy-header {
26
  padding: 20px 20px 40px;
27
  }
28
+ #WBCR .factory-bootstrap-406 label {
29
  font-weight: normal;
30
  }
31
+ #WBCR .factory-bootstrap-406 .form-horizontal .control-label {
32
  max-width: 300px;
33
  }
34
  #WBCR .factory-control-buttons {
components/assets-manager/admin/boot.php CHANGED
@@ -20,7 +20,16 @@
20
  function wbcr_gnz_set_plugin_meta($links, $file)
21
  {
22
  if( $file == WGZ_PLUGIN_BASE ) {
23
- $links[] = '<a href="https://goo.gl/TcMcS4" style="color: #FF5722;font-weight: bold;" target="_blank">' . __('Get ultimate plugin free', 'gonzales') . '</a>';
 
 
 
 
 
 
 
 
 
24
  }
25
 
26
  return $links;
@@ -32,14 +41,14 @@
32
 
33
  function wbcr_gnz_rating_widget_url($page_url, $plugin_name)
34
  {
35
- if( $plugin_name == WGZ_Plugin::app()->getPluginName() ) {
36
  return 'https://goo.gl/zyNV6z';
37
  }
38
 
39
  return $page_url;
40
  }
41
 
42
- add_filter('wbcr_factory_pages_401_imppage_rating_widget_url', 'wbcr_gnz_rating_widget_url', 10, 2);
43
 
44
  function wbcr_gnz_group_options($options)
45
  {
20
  function wbcr_gnz_set_plugin_meta($links, $file)
21
  {
22
  if( $file == WGZ_PLUGIN_BASE ) {
23
+
24
+ $url = 'https://clearfy.pro';
25
+
26
+ if( get_locale() == 'ru_RU' ) {
27
+ $url = 'https://ru.clearfy.pro';
28
+ }
29
+
30
+ $url .= '?utm_source=wordpress.org&utm_campaign=' . WGZ_Plugin::app()->getPluginName();
31
+
32
+ $links[] = '<a href="' . $url . '" style="color: #FF5722;font-weight: bold;" target="_blank">' . __('Get ultimate plugin free', 'gonzales') . '</a>';
33
  }
34
 
35
  return $links;
41
 
42
  function wbcr_gnz_rating_widget_url($page_url, $plugin_name)
43
  {
44
+ if( !defined('LOADING_GONZALES_AS_ADDON') && ($plugin_name == WGZ_Plugin::app()->getPluginName()) ) {
45
  return 'https://goo.gl/zyNV6z';
46
  }
47
 
48
  return $page_url;
49
  }
50
 
51
+ add_filter('wbcr_factory_pages_407_imppage_rating_widget_url', 'wbcr_gnz_rating_widget_url', 10, 2);
52
 
53
  function wbcr_gnz_group_options($options)
54
  {
components/assets-manager/admin/pages/assets-manager.php CHANGED
@@ -11,13 +11,13 @@
11
  exit;
12
  }
13
 
14
- class WbcrGnz_AssetsManagerPage extends Wbcr_FactoryPages401_ImpressiveThemplate {
15
 
16
  /**
17
  * The id of the page in the admin menu.
18
  *
19
  * Mainly used to navigate between pages.
20
- * @see FactoryPages401_AdminPage
21
  *
22
  * @since 1.0.0
23
  * @var string
@@ -35,9 +35,9 @@
35
  public $page_menu_position = 95;
36
 
37
  /**
38
- * @param Wbcr_Factory400_Plugin $plugin
39
  */
40
- public function __construct(Wbcr_Factory400_Plugin $plugin)
41
  {
42
  $this->menu_title = __('Assets manager', 'gonzales');
43
 
@@ -62,6 +62,24 @@
62
  : __('General', 'gonzales');
63
  }
64
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
  /**
66
  * Permalinks options.
67
  *
11
  exit;
12
  }
13
 
14
+ class WbcrGnz_AssetsManagerPage extends Wbcr_FactoryPages407_ImpressiveThemplate {
15
 
16
  /**
17
  * The id of the page in the admin menu.
18
  *
19
  * Mainly used to navigate between pages.
20
+ * @see FactoryPages407_AdminPage
21
  *
22
  * @since 1.0.0
23
  * @var string
35
  public $page_menu_position = 95;
36
 
37
  /**
38
+ * @param Wbcr_Factory406_Plugin $plugin
39
  */
40
+ public function __construct(Wbcr_Factory406_Plugin $plugin)
41
  {
42
  $this->menu_title = __('Assets manager', 'gonzales');
43
 
62
  : __('General', 'gonzales');
63
  }
64
 
65
+ /**
66
+ * Requests assets (js and css) for the page.
67
+ *
68
+ * @see Wbcr_FactoryPages407_AdminPage
69
+ *
70
+ * @since 1.0.0
71
+ * @return void
72
+ */
73
+ public function assets($scripts, $styles)
74
+ {
75
+ parent::assets($scripts, $styles);
76
+
77
+ // Add Clearfy styles for HMWP pages
78
+ if( defined('WBCR_CLEARFY_PLUGIN_ACTIVE') ) {
79
+ $this->styles->add(WCL_PLUGIN_URL . '/admin/assets/css/general.css');
80
+ }
81
+ }
82
+
83
  /**
84
  * Permalinks options.
85
  *
components/assets-manager/admin/pages/more-features.php CHANGED
@@ -11,6 +11,6 @@
11
  exit;
12
  }
13
 
14
- class WbcrGnz_MoreFeaturesPage extends Wbcr_FactoryClearfy200_MoreFeaturesPage {
15
 
16
  }
11
  exit;
12
  }
13
 
14
+ class WbcrGnz_MoreFeaturesPage extends Wbcr_FactoryClearfy203_MoreFeaturesPage {
15
 
16
  }
components/assets-manager/gonzales.php CHANGED
@@ -4,10 +4,10 @@
4
  * Plugin URI: https://wordpress.org/plugins/gonzales/
5
  * Description: Increase the speed of the pages by disabling unused scripts (.JS) and styles (.CSS). Make your website REACTIVE!
6
  * Author: Webcraftic <wordpress.webraftic@gmail.com>
7
- * Version: 1.0.3
8
  * Text Domain: gonzales
9
  * Domain Path: /languages/
10
- * Author URI: http://webcraftic.com
11
  */
12
 
13
  // Exit if accessed directly
@@ -49,11 +49,11 @@
49
  'prefix' => 'wbcr_gnz_',
50
  'plugin_name' => 'wbcr_gonzales',
51
  'plugin_title' => __('Webcraftic assets manager', 'gonzales'),
52
- 'plugin_version' => '1.0.3',
53
  'required_php_version' => '5.2',
54
  'required_wp_version' => '4.2',
55
  'plugin_build' => 'free',
56
- //'updates' => WGZ_PLUGIN_DIR . '/updates/'
57
  ));
58
  }
59
  }
4
  * Plugin URI: https://wordpress.org/plugins/gonzales/
5
  * Description: Increase the speed of the pages by disabling unused scripts (.JS) and styles (.CSS). Make your website REACTIVE!
6
  * Author: Webcraftic <wordpress.webraftic@gmail.com>
7
+ * Version: 1.0.4
8
  * Text Domain: gonzales
9
  * Domain Path: /languages/
10
+ * Author URI: https://clearfy.pro
11
  */
12
 
13
  // Exit if accessed directly
49
  'prefix' => 'wbcr_gnz_',
50
  'plugin_name' => 'wbcr_gonzales',
51
  'plugin_title' => __('Webcraftic assets manager', 'gonzales'),
52
+ 'plugin_version' => '1.0.4',
53
  'required_php_version' => '5.2',
54
  'required_wp_version' => '4.2',
55
  'plugin_build' => 'free',
56
+ 'updates' => WGZ_PLUGIN_DIR . '/updates/'
57
  ));
58
  }
59
  }
components/assets-manager/includes/class.configurate-assets.php CHANGED
@@ -12,7 +12,7 @@
12
  exit;
13
  }
14
 
15
- class WbcrGnz_ConfigAssetsManager extends Wbcr_FactoryClearfy200_Configurate {
16
 
17
  /**
18
  * Stores list of all available assets (used in rendering panel)
@@ -22,9 +22,9 @@
22
  private $collection = array();
23
 
24
  /**
25
- * @param Wbcr_Factory400_Plugin $plugin
26
  */
27
- public function __construct(Wbcr_Factory400_Plugin $plugin)
28
  {
29
  parent::__construct($plugin);
30
  $this->plugin = $plugin;
@@ -70,7 +70,11 @@
70
  }
71
 
72
  if( !$is_panel && ((is_admin() && !$on_backend) || (!is_admin() && !$on_frontend)) ) {
73
- add_action('admin_bar_menu', array($this, 'assetsManagerAdminBar'), 1000);
 
 
 
 
74
  }
75
 
76
  if( !is_admin() && !$on_frontend ) {
@@ -82,6 +86,18 @@
82
  }
83
  }
84
 
 
 
 
 
 
 
 
 
 
 
 
 
85
  /**
86
  * @param WP_Admin_Bar $wp_admin_bar
87
  */
@@ -90,9 +106,9 @@
90
  if( !current_user_can('manage_options') ) {
91
  return;
92
  }
93
-
94
  $current_url = add_query_arg(array('wbcr_assets_manager' => 1));
95
-
96
  $args = array(
97
  'id' => 'assetsManager',
98
  'title' => __('Script Manager', 'gonzales') . ' (Beta)',
12
  exit;
13
  }
14
 
15
+ class WbcrGnz_ConfigAssetsManager extends Wbcr_FactoryClearfy203_Configurate {
16
 
17
  /**
18
  * Stores list of all available assets (used in rendering panel)
22
  private $collection = array();
23
 
24
  /**
25
+ * @param Wbcr_Factory406_Plugin $plugin
26
  */
27
+ public function __construct(Wbcr_Factory406_Plugin $plugin)
28
  {
29
  parent::__construct($plugin);
30
  $this->plugin = $plugin;
70
  }
71
 
72
  if( !$is_panel && ((is_admin() && !$on_backend) || (!is_admin() && !$on_frontend)) ) {
73
+ if( defined('LOADING_GONZALES_AS_ADDON') ) {
74
+ add_action('wbcr_clearfy_admin_bar_menu_items', array($this, 'clearfyAdminBarMenu'));
75
+ } else {
76
+ add_action('admin_bar_menu', array($this, 'assetsManagerAdminBar'), 1000);
77
+ }
78
  }
79
 
80
  if( !is_admin() && !$on_frontend ) {
86
  }
87
  }
88
 
89
+ function clearfyAdminBarMenu($menu_items)
90
+ {
91
+ $current_url = add_query_arg(array('wbcr_assets_manager' => 1));
92
+
93
+ $menu_items['assetsManager'] = array(
94
+ 'title' => __('Script Manager', 'gonzales') . ' (Beta)',
95
+ 'href' => $current_url
96
+ );
97
+
98
+ return $menu_items;
99
+ }
100
+
101
  /**
102
  * @param WP_Admin_Bar $wp_admin_bar
103
  */
106
  if( !current_user_can('manage_options') ) {
107
  return;
108
  }
109
+
110
  $current_url = add_query_arg(array('wbcr_assets_manager' => 1));
111
+
112
  $args = array(
113
  'id' => 'assetsManager',
114
  'title' => __('Script Manager', 'gonzales') . ' (Beta)',
components/assets-manager/includes/class.plugin.php CHANGED
@@ -19,7 +19,7 @@
19
 
20
  }
21
  } else {
22
- class WGZ_PluginFactory extends Wbcr_Factory400_Plugin {
23
 
24
  }
25
  }
@@ -28,7 +28,7 @@
28
  class WGZ_Plugin extends WGZ_PluginFactory {
29
 
30
  /**
31
- * @var Wbcr_Factory400_Plugin
32
  */
33
  private static $app;
34
 
@@ -51,7 +51,7 @@
51
  ? $data['plugin_parent']
52
  : null;
53
 
54
- if( !($plugin_parent instanceof Wbcr_Factory400_Plugin) ) {
55
  throw new Exception('An invalid instance of the class was passed.');
56
  }
57
 
@@ -76,7 +76,7 @@
76
  }
77
 
78
  /**
79
- * @return Wbcr_Factory400_Plugin
80
  */
81
  public static function app()
82
  {
@@ -93,10 +93,10 @@
93
  {
94
  if( !$this->as_addon ) {
95
  self::app()->load(array(
96
- array('libs/factory/bootstrap', 'factory_bootstrap_400', 'admin'),
97
- array('libs/factory/forms', 'factory_forms_400', 'admin'),
98
- array('libs/factory/pages', 'factory_pages_401', 'admin'),
99
- array('libs/factory/clearfy', 'factory_clearfy_200', 'all')
100
  ));
101
  }
102
  }
19
 
20
  }
21
  } else {
22
+ class WGZ_PluginFactory extends Wbcr_Factory406_Plugin {
23
 
24
  }
25
  }
28
  class WGZ_Plugin extends WGZ_PluginFactory {
29
 
30
  /**
31
+ * @var Wbcr_Factory406_Plugin
32
  */
33
  private static $app;
34
 
51
  ? $data['plugin_parent']
52
  : null;
53
 
54
+ if( !($plugin_parent instanceof Wbcr_Factory406_Plugin) ) {
55
  throw new Exception('An invalid instance of the class was passed.');
56
  }
57
 
76
  }
77
 
78
  /**
79
+ * @return Wbcr_Factory406_Plugin
80
  */
81
  public static function app()
82
  {
93
  {
94
  if( !$this->as_addon ) {
95
  self::app()->load(array(
96
+ array('libs/factory/bootstrap', 'factory_bootstrap_406', 'admin'),
97
+ array('libs/factory/forms', 'factory_forms_407', 'admin'),
98
+ array('libs/factory/pages', 'factory_pages_407', 'admin'),
99
+ array('libs/factory/clearfy', 'factory_clearfy_203', 'all')
100
  ));
101
  }
102
  }
components/assets-manager/readme.txt CHANGED
@@ -43,8 +43,10 @@ We invite you to check out a few other related free plugins that our team has al
43
  * [Clearfy – WordPress optimization plugin and disable ultimate tweaker](https://wordpress.org/plugins/clearfy/)
44
  * [Disable Comments for Any Post Types (Remove Comments)](https://wordpress.org/plugins/comments-plus/)
45
  * [Cyrlitera – transliteration of links and file names](https://wordpress.org/plugins/cyrlitera/)
46
- * [Disable updates, Disable automatic updates, Updates manager](https://wordpress.org/plugins/webcraftic-updates-manager/)
47
  * [Disable admin notices individually](https://wordpress.org/plugins/disable-admin-notices/ "Disable admin notices individually")
 
 
48
 
49
  == Installation ==
50
 
@@ -57,6 +59,10 @@ We invite you to check out a few other related free plugins that our team has al
57
  2. Assets manager
58
 
59
  == Changelog ==
 
 
 
 
60
  = 1.0.3 =
61
  * Fixed: Compatibility with Clearfy plugin
62
  * Fixed: The plugin interface did not work and the styles were not loaded due to security settings
43
  * [Clearfy – WordPress optimization plugin and disable ultimate tweaker](https://wordpress.org/plugins/clearfy/)
44
  * [Disable Comments for Any Post Types (Remove Comments)](https://wordpress.org/plugins/comments-plus/)
45
  * [Cyrlitera – transliteration of links and file names](https://wordpress.org/plugins/cyrlitera/)
46
+ * [Cyr-to-lat reloaded transliteration of links and file names](https://wordpress.org/plugins/cyr-and-lat/ "Cyr-to-lat reloaded")
47
  * [Disable admin notices individually](https://wordpress.org/plugins/disable-admin-notices/ "Disable admin notices individually")
48
+ * [Hide login page](https://wordpress.org/plugins/hide-login-page/ "Hide login page")
49
+ * [Disable updates, Disable automatic updates, Updates manager](https://wordpress.org/plugins/webcraftic-updates-manager/)
50
 
51
  == Installation ==
52
 
59
  2. Assets manager
60
 
61
  == Changelog ==
62
+ = 1.0.4 =
63
+ * Fixed: Update core
64
+ * Fixed: Compatibility with others plugin
65
+
66
  = 1.0.3 =
67
  * Fixed: Compatibility with Clearfy plugin
68
  * Fixed: The plugin interface did not work and the styles were not loaded due to security settings
components/assets-manager/updates/010100.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php #comp-page builds: premium
2
+
3
+ /**
4
+ * Updates for altering the table used to store statistics data.
5
+ * Adds new columns and renames existing ones in order to add support for the new social buttons.
6
+ */
7
+ class WGZUpdate010100 extends Wbcr_Factory406_Update {
8
+
9
+ public function install()
10
+ {
11
+ global $wpdb;
12
+
13
+ /*$request = $wpdb->get_results("SELECT option_id, option_name, option_value FROM {$wpdb->prefix}options WHERE option_name LIKE 'wbcr-clearfy_%'");
14
+ if( !empty($request) ) {
15
+ foreach($request as $option) {
16
+ $option_new_name = str_replace('wbcr-clearfy', WCL_Plugin::app()
17
+ ->getPrefix(), $option->option_name);
18
+ if( !get_option($option_new_name, false) ) {
19
+ $wpdb->query("UPDATE {$wpdb->prefix}options SET option_name='$option_new_name' WHERE option_id='{$option->option_id}'");
20
+ } else {
21
+ delete_option($option->option_name);
22
+ }
23
+ }
24
+ }*/
25
+ }
26
+ }
components/comments-plus/admin/assets/css/general.css CHANGED
@@ -19,16 +19,16 @@
19
  font-weight: bold;
20
  padding: 10px;
21
  }
22
- #WBCR .hint-warnign-color {
23
  color: #ffeb3b;
24
  }
25
  #WBCR .wbcr-clearfy-header {
26
  padding: 20px 20px 40px;
27
  }
28
- #WBCR .factory-bootstrap-400 label {
29
  font-weight: normal;
30
  }
31
- #WBCR .factory-bootstrap-400 .form-horizontal .control-label {
32
  max-width: 300px;
33
  }
34
  #WBCR .factory-control-buttons {
19
  font-weight: bold;
20
  padding: 10px;
21
  }
22
+ #WBCR .wbcr-factory-light-orange-color {
23
  color: #ffeb3b;
24
  }
25
  #WBCR .wbcr-clearfy-header {
26
  padding: 20px 20px 40px;
27
  }
28
+ #WBCR .factory-bootstrap-406 label {
29
  font-weight: normal;
30
  }
31
+ #WBCR .factory-bootstrap-406 .form-horizontal .control-label {
32
  max-width: 300px;
33
  }
34
  #WBCR .factory-control-buttons {
components/comments-plus/admin/boot.php CHANGED
@@ -11,17 +11,6 @@
11
  exit;
12
  }
13
 
14
- function wbcr_cmp_rating_widget_url($page_url, $plugin_name)
15
- {
16
- if( $plugin_name == WCM_Plugin::app()->getPluginName() ) {
17
- return 'https://goo.gl/v4QkW5';
18
- }
19
-
20
- return $page_url;
21
- }
22
-
23
- add_filter('wbcr_factory_pages_401_imppage_rating_widget_url', 'wbcr_cmp_rating_widget_url', 10, 2);
24
-
25
  function wbcr_cmp_group_options($options)
26
  {
27
  $options[] = array(
@@ -48,7 +37,7 @@
48
  $options[] = array(
49
  'name' => 'remove_x_pingback',
50
  'title' => __('Disable X-Pingback', 'comments-plus'),
51
- 'tags' => array('recommended', 'defence', 'disable_all_comments')
52
  );
53
  $options[] = array(
54
  'name' => 'remove_url_from_comment_form',
@@ -76,7 +65,16 @@
76
  function wbcr_cmp_set_plugin_meta($links, $file)
77
  {
78
  if( $file == WCM_PLUGIN_BASE ) {
79
- $links[] = '<a href="https://goo.gl/TcMcS4" style="color: #FF5722;font-weight: bold;" target="_blank">' . __('Get ultimate plugin free', 'comments-plus') . '</a>';
 
 
 
 
 
 
 
 
 
80
  }
81
 
82
  return $links;
@@ -86,5 +84,16 @@
86
  add_filter('plugin_row_meta', 'wbcr_cmp_set_plugin_meta', 10, 2);
87
  }
88
 
 
 
 
 
 
 
 
 
 
 
 
89
 
90
 
11
  exit;
12
  }
13
 
 
 
 
 
 
 
 
 
 
 
 
14
  function wbcr_cmp_group_options($options)
15
  {
16
  $options[] = array(
37
  $options[] = array(
38
  'name' => 'remove_x_pingback',
39
  'title' => __('Disable X-Pingback', 'comments-plus'),
40
+ 'tags' => array('recommended', 'defence', 'disable_all_comments', 'hide_my_wp')
41
  );
42
  $options[] = array(
43
  'name' => 'remove_url_from_comment_form',
65
  function wbcr_cmp_set_plugin_meta($links, $file)
66
  {
67
  if( $file == WCM_PLUGIN_BASE ) {
68
+
69
+ $url = 'https://clearfy.pro';
70
+
71
+ if( get_locale() == 'ru_RU' ) {
72
+ $url = 'https://ru.clearfy.pro';
73
+ }
74
+
75
+ $url .= '?utm_source=wordpress.org&utm_campaign=' . WCM_Plugin::app()->getPluginName();
76
+
77
+ $links[] = '<a href="' . $url . '" style="color: #FF5722;font-weight: bold;" target="_blank">' . __('Get ultimate plugin free', 'comments-plus') . '</a>';
78
  }
79
 
80
  return $links;
84
  add_filter('plugin_row_meta', 'wbcr_cmp_set_plugin_meta', 10, 2);
85
  }
86
 
87
+ function wbcr_cmp_rating_widget_url($page_url, $plugin_name)
88
+ {
89
+ if( !defined('LOADING_COMMENTS_PLUS_AS_ADDON') && ($plugin_name == WCM_Plugin::app()->getPluginName()) ) {
90
+ return 'https://goo.gl/v4QkW5';
91
+ }
92
+
93
+ return $page_url;
94
+ }
95
+
96
+ add_filter('wbcr_factory_pages_407_imppage_rating_widget_url', 'wbcr_cmp_rating_widget_url', 10, 2);
97
+
98
 
99
 
components/comments-plus/admin/pages/comments.php CHANGED
@@ -11,13 +11,13 @@
11
  exit;
12
  }
13
 
14
- class WbcrCmp_CommentsPage extends Wbcr_FactoryPages401_ImpressiveThemplate {
15
 
16
  /**
17
  * The id of the page in the admin menu.
18
  *
19
  * Mainly used to navigate between pages.
20
- * @see FactoryPages401_AdminPage
21
  *
22
  * @since 1.0.0
23
  * @var string
@@ -26,9 +26,9 @@
26
  public $page_menu_dashicon = 'dashicons-testimonial';
27
 
28
  /**
29
- * @param Wbcr_Factory400_Plugin $plugin
30
  */
31
- public function __construct(Wbcr_Factory400_Plugin $plugin)
32
  {
33
  $this->menu_title = __('Disable comments', 'comments-plus');
34
 
@@ -47,7 +47,24 @@
47
  ? __('Comments', 'comments-plus')
48
  : __('General', 'comments-plus');
49
  }
50
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
 
52
  /**
53
  * Permalinks options.
@@ -130,7 +147,7 @@
130
  'name' => 'remove_url_from_comment_form',
131
  'title' => __('Remove field "site" in comment form', 'comments-plus'),
132
  'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
133
- 'hint' => __('Tired of spam in the comments? Do visitors leave "blank" comments for the sake of a link to their site?', 'comments-plus') . '<br><b>Clearfy: </b>' . __('Removes the "Site" field from the comment form.', 'comments-plus') . '<br>--<br><span class="hint-warnign-color"> *' . __('Works with the standard comment form, if the form is manually written in your theme-it probably will not work!', 'comments-plus') . '</span>',
134
  'default' => false
135
  ),
136
  array(
11
  exit;
12
  }
13
 
14
+ class WbcrCmp_CommentsPage extends Wbcr_FactoryPages407_ImpressiveThemplate {
15
 
16
  /**
17
  * The id of the page in the admin menu.
18
  *
19
  * Mainly used to navigate between pages.
20
+ * @see FactoryPages407_AdminPage
21
  *
22
  * @since 1.0.0
23
  * @var string
26
  public $page_menu_dashicon = 'dashicons-testimonial';
27
 
28
  /**
29
+ * @param Wbcr_Factory406_Plugin $plugin
30
  */
31
+ public function __construct(Wbcr_Factory406_Plugin $plugin)
32
  {
33
  $this->menu_title = __('Disable comments', 'comments-plus');
34
 
47
  ? __('Comments', 'comments-plus')
48
  : __('General', 'comments-plus');
49
  }
50
+
51
+ /**
52
+ * Requests assets (js and css) for the page.
53
+ *
54
+ * @see Wbcr_FactoryPages407_AdminPage
55
+ *
56
+ * @since 1.0.0
57
+ * @return void
58
+ */
59
+ public function assets($scripts, $styles)
60
+ {
61
+ parent::assets($scripts, $styles);
62
+
63
+ // Add Clearfy styles for HMWP pages
64
+ if( defined('WBCR_CLEARFY_PLUGIN_ACTIVE') ) {
65
+ $this->styles->add(WCL_PLUGIN_URL . '/admin/assets/css/general.css');
66
+ }
67
+ }
68
 
69
  /**
70
  * Permalinks options.
147
  'name' => 'remove_url_from_comment_form',
148
  'title' => __('Remove field "site" in comment form', 'comments-plus'),
149
  'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
150
+ 'hint' => __('Tired of spam in the comments? Do visitors leave "blank" comments for the sake of a link to their site?', 'comments-plus') . '<br><b>Clearfy: </b>' . __('Removes the "Site" field from the comment form.', 'comments-plus') . '<br>--<br><span class="wbcr-factory-light-orange-color"> *' . __('Works with the standard comment form, if the form is manually written in your theme-it probably will not work!', 'comments-plus') . '</span>',
151
  'default' => false
152
  ),
153
  array(
components/comments-plus/admin/pages/delete-comments.php CHANGED
@@ -12,13 +12,13 @@
12
  }
13
 
14
 
15
- class WbcrCmp_DeleteCommentsPage extends Wbcr_FactoryPages401_ImpressiveThemplate {
16
 
17
  /**
18
  * The id of the page in the admin menu.
19
  *
20
  * Mainly used to navigate between pages.
21
- * @see FactoryPages401_AdminPage
22
  *
23
  * @since 1.0.0
24
  * @var string
@@ -29,21 +29,39 @@
29
  public $page_menu_dashicon = 'dashicons-testimonial';
30
 
31
  /**
32
- * @param Wbcr_Factory400_Plugin $plugin
33
  */
34
- public function __construct(Wbcr_Factory400_Plugin $plugin)
35
  {
36
  $this->menu_title = __('Comments cleaner', 'comments-plus');
37
 
38
  parent::__construct($plugin);
39
  }
40
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
  /**
42
  * We register notifications for some actions
43
  *
44
- * @see libs\factory\pages\themplates\FactoryPages401_ImpressiveThemplate
45
  * @param $notices
46
- * @param Wbcr_Factory400_Plugin $plugin
47
  * @return array
48
  */
49
  public function getActionNotices($notices)
@@ -72,7 +90,7 @@
72
  /**
73
  * Prints the content of the page
74
  *
75
- * @see libs\factory\pages\themplates\FactoryPages401_ImpressiveThemplate
76
  */
77
  public function showPageContent()
78
  {
@@ -112,15 +130,24 @@
112
  * Select all types by one click.
113
  */
114
  jQuery(document).ready(function($) {
 
 
115
  var allTypesCheckbox = $('#wbcr-cmp-all-types-checkbox');
 
116
  allTypesCheckbox.click(function() {
117
  $('.wbcr-cmp-post-type-checkbox').prop("checked", $(this).prop("checked"));
 
118
  });
119
 
120
  $('.wbcr-cmp-post-type-checkbox').click(function() {
121
  if( !$(this).prop("checked") ) {
122
  allTypesCheckbox.prop("checked", false);
123
  }
 
 
 
 
 
124
  });
125
 
126
  $('.wbcr-cmp-delete-comments-button').click(function() {
@@ -132,6 +159,15 @@
132
 
133
  $(this).submit();
134
  });
 
 
 
 
 
 
 
 
 
135
  });
136
  </script>
137
 
@@ -159,22 +195,24 @@
159
  <?php foreach((array)$post_types as $key => $type): ?>
160
  <p>
161
  <label>
162
- <input type="checkbox" class="wbcr-cmp-post-type-checkbox" name="wbcr_cmp_post_type[]" value="<?= esc_attr($key) ?>" checked/> <?= $type['label'] ?>
163
  (<?= $type['comments_count'] ?>)
164
  </label>
165
  </p>
166
  <?php endforeach; ?>
167
  </div>
168
 
169
- <?php if( class_exists('WooCommerce') ): ?>
 
170
  <p style="margin:15px 0 0">
171
  <label>
172
- <input type="checkbox" name="wbcr_cmp_delete_order_notes" value="1"/> <?php printf(__('Delete Woocommerce order notices? (%d)', 'comments-plus'), $stat_data[0]->order_notes_count); ?>
173
  </label>
174
  </p>
175
- <?php endif; ?>
 
176
  <p style="margin-top:15px;">
177
- <input type="submit" name="wbcr_cmp_delete_all" class="button button-default wbcr-cmp-delete-comments-button" value="<?php printf(__('Delete (%d)', 'comments-plus'), $stat_data[0]->total_comments); ?>">
178
  </p>
179
  <?php wp_nonce_field($this->getResultId() . '_delete_all_comments') ?>
180
  </form>
12
  }
13
 
14
 
15
+ class WbcrCmp_DeleteCommentsPage extends Wbcr_FactoryPages407_ImpressiveThemplate {
16
 
17
  /**
18
  * The id of the page in the admin menu.
19
  *
20
  * Mainly used to navigate between pages.
21
+ * @see FactoryPages407_AdminPage
22
  *
23
  * @since 1.0.0
24
  * @var string
29
  public $page_menu_dashicon = 'dashicons-testimonial';
30
 
31
  /**
32
+ * @param Wbcr_Factory406_Plugin $plugin
33
  */
34
+ public function __construct(Wbcr_Factory406_Plugin $plugin)
35
  {
36
  $this->menu_title = __('Comments cleaner', 'comments-plus');
37
 
38
  parent::__construct($plugin);
39
  }
40
 
41
+ /**
42
+ * Requests assets (js and css) for the page.
43
+ *
44
+ * @see Wbcr_FactoryPages407_AdminPage
45
+ *
46
+ * @since 1.0.0
47
+ * @return void
48
+ */
49
+ public function assets($scripts, $styles)
50
+ {
51
+ parent::assets($scripts, $styles);
52
+
53
+ // Add Clearfy styles for HMWP pages
54
+ if( defined('WBCR_CLEARFY_PLUGIN_ACTIVE') ) {
55
+ $this->styles->add(WCL_PLUGIN_URL . '/admin/assets/css/general.css');
56
+ }
57
+ }
58
+
59
  /**
60
  * We register notifications for some actions
61
  *
62
+ * @see libs\factory\pages\themplates\FactoryPages407_ImpressiveThemplate
63
  * @param $notices
64
+ * @param Wbcr_Factory406_Plugin $plugin
65
  * @return array
66
  */
67
  public function getActionNotices($notices)
90
  /**
91
  * Prints the content of the page
92
  *
93
+ * @see libs\factory\pages\themplates\FactoryPages407_ImpressiveThemplate
94
  */
95
  public function showPageContent()
96
  {
130
  * Select all types by one click.
131
  */
132
  jQuery(document).ready(function($) {
133
+ updateCommentsCounter();
134
+
135
  var allTypesCheckbox = $('#wbcr-cmp-all-types-checkbox');
136
+
137
  allTypesCheckbox.click(function() {
138
  $('.wbcr-cmp-post-type-checkbox').prop("checked", $(this).prop("checked"));
139
+ updateCommentsCounter()
140
  });
141
 
142
  $('.wbcr-cmp-post-type-checkbox').click(function() {
143
  if( !$(this).prop("checked") ) {
144
  allTypesCheckbox.prop("checked", false);
145
  }
146
+ updateCommentsCounter();
147
+ });
148
+
149
+ $('input[name="wbcr_cmp_delete_order_notes"]').click(function() {
150
+ updateCommentsCounter();
151
  });
152
 
153
  $('.wbcr-cmp-delete-comments-button').click(function() {
159
 
160
  $(this).submit();
161
  });
162
+
163
+ function updateCommentsCounter() {
164
+ var commentsCount = 0;
165
+ $('.wbcr-cmp-post-type-checkbox:checked, input[name="wbcr_cmp_delete_order_notes"]:checked').each(function() {
166
+ commentsCount += $(this).data('comments-number');
167
+ });
168
+
169
+ $('.wbcr-cmp-delete-comments-button').val('<?php _e('Delete ', 'comments-plus') ?>(' + commentsCount + ')');
170
+ }
171
  });
172
  </script>
173
 
195
  <?php foreach((array)$post_types as $key => $type): ?>
196
  <p>
197
  <label>
198
+ <input type="checkbox" data-comments-number="<?= $type['comments_count'] ?>" class="wbcr-cmp-post-type-checkbox" name="wbcr_cmp_post_type[]" value="<?= esc_attr($key) ?>" checked/> <?= $type['label'] ?>
199
  (<?= $type['comments_count'] ?>)
200
  </label>
201
  </p>
202
  <?php endforeach; ?>
203
  </div>
204
 
205
+ <?php if( class_exists('WooCommerce') ):
206
+ ?>
207
  <p style="margin:15px 0 0">
208
  <label>
209
+ <input type="checkbox" data-comments-number="<?= $stat_data[0]->order_notes_count ?>" name="wbcr_cmp_delete_order_notes" value="1"/> <?php printf(__('Delete Woocommerce order notices? (%d)', 'comments-plus'), $stat_data[0]->order_notes_count); ?>
210
  </label>
211
  </p>
212
+ <?php endif;
213
+ ?>
214
  <p style="margin-top:15px;">
215
+ <input type="submit" name="wbcr_cmp_delete_all" class="button button-default wbcr-cmp-delete-comments-button" value="<?php printf(__('Delete (%s)', 'comments-plus'), $stat_data[0]->total_comments); ?>">
216
  </p>
217
  <?php wp_nonce_field($this->getResultId() . '_delete_all_comments') ?>
218
  </form>
components/comments-plus/admin/pages/more-features.php CHANGED
@@ -11,6 +11,6 @@
11
  exit;
12
  }
13
 
14
- class WbcrCmp_MoreFeaturesPage extends Wbcr_FactoryClearfy200_MoreFeaturesPage {
15
 
16
  }
11
  exit;
12
  }
13
 
14
+ class WbcrCmp_MoreFeaturesPage extends Wbcr_FactoryClearfy203_MoreFeaturesPage {
15
 
16
  }
components/comments-plus/comments-plus.php CHANGED
@@ -4,10 +4,10 @@
4
  * Plugin URI: https://wordpress.org/plugins/comments-plus/
5
  * Description: Allows administrators to globally disable comments on their site. Comments can be disabled for individual record types.
6
  * Author: Webcraftic <wordpress.webraftic@gmail.com>
7
- * Version: 1.0.7
8
  * Text Domain: comments-plus
9
  * Domain Path: /languages/
10
- * Author URI: http://webcraftic.com
11
  */
12
 
13
  // Exit if accessed directly
@@ -50,7 +50,7 @@
50
  'prefix' => 'wbcr_comments_plus_', // wbcr_cmp
51
  'plugin_name' => 'wbcr_comments_plus',
52
  'plugin_title' => __('Webcraftic Disable comments', 'comments-plus'),
53
- 'plugin_version' => '1.0.7',
54
  'required_php_version' => '5.2',
55
  'required_wp_version' => '4.2',
56
  'plugin_build' => 'free',
4
  * Plugin URI: https://wordpress.org/plugins/comments-plus/
5
  * Description: Allows administrators to globally disable comments on their site. Comments can be disabled for individual record types.
6
  * Author: Webcraftic <wordpress.webraftic@gmail.com>
7
+ * Version: 1.0.9
8
  * Text Domain: comments-plus
9
  * Domain Path: /languages/
10
+ * Author URI: https://clearfy.pro
11
  */
12
 
13
  // Exit if accessed directly
50
  'prefix' => 'wbcr_comments_plus_', // wbcr_cmp
51
  'plugin_name' => 'wbcr_comments_plus',
52
  'plugin_title' => __('Webcraftic Disable comments', 'comments-plus'),
53
+ 'plugin_version' => '1.0.9',
54
  'required_php_version' => '5.2',
55
  'required_wp_version' => '4.2',
56
  'plugin_build' => 'free',
components/comments-plus/includes/class.plugin.php CHANGED
@@ -19,7 +19,7 @@
19
 
20
  }
21
  } else {
22
- class WCM_PluginFactory extends Wbcr_Factory400_Plugin {
23
 
24
  }
25
  }
@@ -28,7 +28,7 @@
28
  class WCM_Plugin extends WCM_PluginFactory {
29
 
30
  /**
31
- * @var Wbcr_Factory400_Plugin
32
  */
33
  private static $app;
34
 
@@ -51,7 +51,7 @@
51
  ? $data['plugin_parent']
52
  : null;
53
 
54
- if( !($plugin_parent instanceof Wbcr_Factory400_Plugin) ) {
55
  throw new Exception('An invalid instance of the class was passed.');
56
  }
57
 
@@ -76,7 +76,7 @@
76
  }
77
 
78
  /**
79
- * @return Wbcr_Factory400_Plugin
80
  */
81
  public static function app()
82
  {
@@ -93,10 +93,10 @@
93
  {
94
  if( !$this->as_addon ) {
95
  self::app()->load(array(
96
- array('libs/factory/bootstrap', 'factory_bootstrap_400', 'admin'),
97
- array('libs/factory/forms', 'factory_forms_400', 'admin'),
98
- array('libs/factory/pages', 'factory_pages_401', 'admin'),
99
- array('libs/factory/clearfy', 'factory_clearfy_200', 'all')
100
  ));
101
  }
102
  }
19
 
20
  }
21
  } else {
22
+ class WCM_PluginFactory extends Wbcr_Factory406_Plugin {
23
 
24
  }
25
  }
28
  class WCM_Plugin extends WCM_PluginFactory {
29
 
30
  /**
31
+ * @var Wbcr_Factory406_Plugin
32
  */
33
  private static $app;
34
 
51
  ? $data['plugin_parent']
52
  : null;
53
 
54
+ if( !($plugin_parent instanceof Wbcr_Factory406_Plugin) ) {
55
  throw new Exception('An invalid instance of the class was passed.');
56
  }
57
 
76
  }
77
 
78
  /**
79
+ * @return Wbcr_Factory406_Plugin
80
  */
81
  public static function app()
82
  {
93
  {
94
  if( !$this->as_addon ) {
95
  self::app()->load(array(
96
+ array('libs/factory/bootstrap', 'factory_bootstrap_406', 'admin'),
97
+ array('libs/factory/forms', 'factory_forms_407', 'admin'),
98
+ array('libs/factory/pages', 'factory_pages_407', 'admin'),
99
+ array('libs/factory/clearfy', 'factory_clearfy_203', 'all')
100
  ));
101
  }
102
  }
components/comments-plus/includes/classes/class.configurate-comments.php CHANGED
@@ -12,14 +12,14 @@
12
  exit;
13
  }
14
 
15
- class WbcrCmp_ConfigComments extends Wbcr_FactoryClearfy200_Configurate {
16
 
17
  private $modified_types = array();
18
 
19
  /**
20
- * @param Wbcr_Factory400_Plugin $plugin
21
  */
22
- public function __construct(Wbcr_Factory400_Plugin $plugin)
23
  {
24
  parent::__construct($plugin);
25
  $this->plugin = $plugin;
@@ -396,6 +396,7 @@
396
  ob_flush();
397
  }
398
 
 
399
  public function assetsUrlSpanScripts()
400
  {
401
  if( !is_singular() ) {
12
  exit;
13
  }
14
 
15
+ class WbcrCmp_ConfigComments extends Wbcr_FactoryClearfy203_Configurate {
16
 
17
  private $modified_types = array();
18
 
19
  /**
20
+ * @param Wbcr_Factory406_Plugin $plugin
21
  */
22
+ public function __construct(Wbcr_Factory406_Plugin $plugin)
23
  {
24
  parent::__construct($plugin);
25
  $this->plugin = $plugin;
396
  ob_flush();
397
  }
398
 
399
+ // todo: Убрать это грязное решение со скриптами.
400
  public function assetsUrlSpanScripts()
401
  {
402
  if( !is_singular() ) {
components/comments-plus/readme.txt CHANGED
@@ -93,16 +93,20 @@ Define DISABLE_COMMENTS_REMOVE_COMMENTS_TEMPLATE and set it to false to prevent
93
 
94
  These definitions can be make either in your main wp-config.php or in your theme’s functions.php file.
95
 
 
 
 
96
  * [Clearfy – WordPress optimization plugin and disable ultimate tweaker](https://wordpress.org/plugins/clearfy/)
97
- * [WordPress Assets manager, dequeue scripts, dequeue styles](https://wordpress.org/plugins/gonzales/)
98
- * [Cyrlitera – transliteration of links and file names](https://wordpress.org/plugins/cyrlitera/)
99
  * [Disable updates, Disable automatic updates, Updates manager](https://wordpress.org/plugins/webcraftic-updates-manager/)
 
 
100
  * [Disable admin notices individually](https://wordpress.org/plugins/disable-admin-notices/ "Disable admin notices individually")
 
 
101
 
102
  == Translations ==
103
 
104
  * English - default, always included
105
- * French - Thank you very much to user (kingteamdunet)
106
  * Russian
107
 
108
  If you want to help with the translation, please contact me through this site or through the contacts inside the plugin.
@@ -118,6 +122,14 @@ If you want to help with the translation, please contact me through this site or
118
  2. Control panel (Remove comments)
119
 
120
  == Changelog ==
 
 
 
 
 
 
 
 
121
  = 1.0.7 =
122
  * Fixed: Update core
123
  * ADDED: Plugin options caching to reduce database queries for 90%. Clearfy became lighter and faster.
93
 
94
  These definitions can be make either in your main wp-config.php or in your theme’s functions.php file.
95
 
96
+ #### RECOMMENDED SEPARATE MODULES ####
97
+ We invite you to check out a few other related free plugins that our team has also produced that you may find especially useful:
98
+
99
  * [Clearfy – WordPress optimization plugin and disable ultimate tweaker](https://wordpress.org/plugins/clearfy/)
 
 
100
  * [Disable updates, Disable automatic updates, Updates manager](https://wordpress.org/plugins/webcraftic-updates-manager/)
101
+ * [Cyrlitera – transliteration of links and file names](https://wordpress.org/plugins/cyrlitera/)
102
+ * [Cyr-to-lat reloaded – transliteration of links and file names](https://wordpress.org/plugins/cyr-and-lat/ "Cyr-to-lat reloaded")
103
  * [Disable admin notices individually](https://wordpress.org/plugins/disable-admin-notices/ "Disable admin notices individually")
104
+ * [WordPress Assets manager, dequeue scripts, dequeue styles](https://wordpress.org/plugins/gonzales/ "WordPress Assets manager, dequeue scripts, dequeue styles")
105
+ * [Hide login page](https://wordpress.org/plugins/hide-login-page/ "Hide login page")
106
 
107
  == Translations ==
108
 
109
  * English - default, always included
 
110
  * Russian
111
 
112
  If you want to help with the translation, please contact me through this site or through the contacts inside the plugin.
122
  2. Control panel (Remove comments)
123
 
124
  == Changelog ==
125
+ = 1.0.9 =
126
+ * Fixed: Update core
127
+
128
+ = 1.0.8 =
129
+ * Fixed: Update core
130
+ * Fixed: Small bugs
131
+ * Fixed: Translations
132
+
133
  = 1.0.7 =
134
  * Fixed: Update core
135
  * ADDED: Plugin options caching to reduce database queries for 90%. Clearfy became lighter and faster.
components/cyrlitera/admin/activation.php CHANGED
@@ -4,7 +4,7 @@
4
  * Activator for the cyrlitera
5
  * @author Webcraftic <wordpress.webraftic@gmail.com>
6
  * @copyright (c) 09.03.2018, Webcraftic
7
- * @see Wbcr_Factory400_Activator
8
  * @version 1.0
9
  */
10
 
@@ -13,7 +13,7 @@
13
  exit;
14
  }
15
 
16
- class WCTR_Activation extends Wbcr_Factory400_Activator {
17
 
18
  /**
19
  * Runs activation actions.
4
  * Activator for the cyrlitera
5
  * @author Webcraftic <wordpress.webraftic@gmail.com>
6
  * @copyright (c) 09.03.2018, Webcraftic
7
+ * @see Wbcr_Factory406_Activator
8
  * @version 1.0
9
  */
10
 
13
  exit;
14
  }
15
 
16
+ class WCTR_Activation extends Wbcr_Factory406_Activator {
17
 
18
  /**
19
  * Runs activation actions.
components/cyrlitera/admin/boot.php CHANGED
@@ -70,46 +70,36 @@
70
  add_filter('wbcr_clr_seo_page_warnings', 'wbcr_cyrlitera_get_conflict_notices_error');
71
 
72
  /**
73
- * Ошибки совместимости с похожими плагинами
74
  */
75
- function wbcr_cyrlitera_admin_conflict_notices_error()
76
  {
77
- $notices = wbcr_cyrlitera_get_conflict_notices_error();
78
-
79
- if( empty($notices) ) {
80
- return;
81
  }
82
 
83
- ?>
84
- <div id="wbcr-cyrlitera-conflict-error" class="notice notice-error is-dismissible">
85
- <?php foreach((array)$notices as $notice): ?>
86
- <p>
87
- <?= $notice ?>
88
- </p>
89
- <?php endforeach; ?>
90
- </div>
91
- <?php
92
- }
93
-
94
- add_action('admin_notices', 'wbcr_cyrlitera_admin_conflict_notices_error');
95
 
96
- /**
97
- * Виджет отзывов
98
- *
99
- * @param string $page_url
100
- * @param string $plugin_name
101
- * @return string
102
- */
103
- function wbcr_cyrlitera_rating_widget_url($page_url, $plugin_name)
104
- {
105
- if( $plugin_name == WCTR_Plugin::app()->getPluginName() ) {
106
- return 'https://goo.gl/ecaj2V';
107
  }
108
 
109
- return $page_url;
 
 
 
 
 
 
 
 
110
  }
111
 
112
- add_filter('wbcr_factory_pages_401_imppage_rating_widget_url', 'wbcr_cyrlitera_rating_widget_url', 10, 2);
113
 
114
  function wbcr_cyrlitera_group_options($options)
115
  {
@@ -134,6 +124,12 @@
134
  'tags' => array()
135
  );
136
 
 
 
 
 
 
 
137
  $options[] = array(
138
  'name' => 'use_transliteration_filename',
139
  'title' => __('Convert file names', 'cyrlitera'),
@@ -166,7 +162,16 @@
166
  function wbcr_cyrlitera_set_plugin_meta($links, $file)
167
  {
168
  if( $file == WCTR_PLUGIN_BASE ) {
169
- $links[] = '<a href="https://goo.gl/TcMcS4" style="color: #FF5722;font-weight: bold;" target="_blank">' . __('Get ultimate plugin free', 'cyrlitera') . '</a>';
 
 
 
 
 
 
 
 
 
170
  }
171
 
172
  return $links;
@@ -177,4 +182,23 @@
177
  }
178
 
179
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
180
 
70
  add_filter('wbcr_clr_seo_page_warnings', 'wbcr_cyrlitera_get_conflict_notices_error');
71
 
72
  /**
73
+ * Печатает ошибки совместимости с похожими плагинами
74
  */
75
+ function wbcr_cyrlitera_admin_conflict_notices_error($notices, $plugin_name)
76
  {
77
+ if( $plugin_name != WCTR_Plugin::app()->getPluginName() ) {
78
+ return $notices;
 
 
79
  }
80
 
81
+ $warnings = wbcr_cyrlitera_get_conflict_notices_error();
 
 
 
 
 
 
 
 
 
 
 
82
 
83
+ if( empty($warnings) ) {
84
+ return $notices;
85
+ }
86
+ $notice_text = '';
87
+ foreach((array)$warnings as $warning) {
88
+ $notice_text .= '<p>' . $warning . '</p>';
 
 
 
 
 
89
  }
90
 
91
+ $notices[] = array(
92
+ 'id' => 'cyrlitera_plugin_compatibility',
93
+ 'type' => 'error',
94
+ 'dismissible' => true,
95
+ 'dismiss_expires' => 0,
96
+ 'text' => $notice_text
97
+ );
98
+
99
+ return $notices;
100
  }
101
 
102
+ add_action('wbcr_factory_notices_405_list', 'wbcr_cyrlitera_admin_conflict_notices_error', 10, 2);
103
 
104
  function wbcr_cyrlitera_group_options($options)
105
  {
124
  'tags' => array()
125
  );
126
 
127
+ $options[] = array(
128
+ 'name' => 'dont_use_transliteration_on_frontend',
129
+ 'title' => __('Don\'t use transliteration in frontend', 'cyrlitera'),
130
+ 'tags' => array()
131
+ );
132
+
133
  $options[] = array(
134
  'name' => 'use_transliteration_filename',
135
  'title' => __('Convert file names', 'cyrlitera'),
162
  function wbcr_cyrlitera_set_plugin_meta($links, $file)
163
  {
164
  if( $file == WCTR_PLUGIN_BASE ) {
165
+
166
+ $url = 'https://clearfy.pro';
167
+
168
+ if( get_locale() == 'ru_RU' ) {
169
+ $url = 'https://ru.clearfy.pro';
170
+ }
171
+
172
+ $url .= '?utm_source=wordpress.org&utm_campaign=' . WCTR_Plugin::app()->getPluginName();
173
+
174
+ $links[] = '<a href="' . $url . '" style="color: #FF5722;font-weight: bold;" target="_blank">' . __('Get ultimate plugin free', 'cyrlitera') . '</a>';
175
  }
176
 
177
  return $links;
182
  }
183
 
184
 
185
+ /**
186
+ * Виджет отзывов
187
+ *
188
+ * @param string $page_url
189
+ * @param string $plugin_name
190
+ * @return string
191
+ */
192
+ function wbcr_cyrlitera_rating_widget_url($page_url, $plugin_name)
193
+ {
194
+ if( !defined('LOADING_CYRLITERA_AS_ADDON') && ($plugin_name == WCTR_Plugin::app()->getPluginName()) ) {
195
+ return 'https://goo.gl/ecaj2V';
196
+ }
197
+
198
+ return $page_url;
199
+ }
200
+
201
+ add_filter('wbcr_factory_pages_407_imppage_rating_widget_url', 'wbcr_cyrlitera_rating_widget_url', 10, 2);
202
+
203
+
204
 
components/cyrlitera/admin/options.php CHANGED
@@ -71,6 +71,16 @@
71
  'default' => false
72
  );
73
 
 
 
 
 
 
 
 
 
 
 
74
  $options[] = array(
75
  'type' => 'textarea',
76
  'way' => 'buttons',
@@ -88,7 +98,7 @@
88
  }
89
 
90
  /**
91
- * @param $html_builder Wbcr_FactoryForms400_Html
92
  */
93
  function wbcr_cyrlitera_rollback_button($html_builder)
94
  {
@@ -153,7 +163,7 @@
153
  $sanitized_slug = WCTR_Helper::sanitizeTitle(urldecode($term->slug));
154
 
155
  if( $term->slug != $sanitized_slug ) {
156
- update_option('wbcr_wp_term_' . $term->term_id . '_old_slug', $term->slug);
157
  $wpdb->update($wpdb->terms, array('slug' => $sanitized_slug), array('term_id' => $term->term_id), array('%s'), array('%d'));
158
  }
159
  }
@@ -208,7 +218,7 @@
208
 
209
  /**
210
  * @param $form
211
- * @param $page Wbcr_FactoryPages401_ImpressiveThemplate
212
  * @return mixed
213
  */
214
  function wbcr_cyrlitera_seo_form_options($form, $page)
71
  'default' => false
72
  );
73
 
74
+ $options[] = array(
75
+ 'type' => 'checkbox',
76
+ 'way' => 'buttons',
77
+ 'name' => 'dont_use_transliteration_on_frontend',
78
+ 'title' => __('Don\'t use transliteration in frontend', 'cyrlitera'),
79
+ 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
80
+ 'hint' => __('Enable when have a problem in frontend.', 'cyrlitera'),
81
+ 'default' => false
82
+ );
83
+
84
  $options[] = array(
85
  'type' => 'textarea',
86
  'way' => 'buttons',
98
  }
99
 
100
  /**
101
+ * @param $html_builder Wbcr_FactoryForms407_Html
102
  */
103
  function wbcr_cyrlitera_rollback_button($html_builder)
104
  {
163
  $sanitized_slug = WCTR_Helper::sanitizeTitle(urldecode($term->slug));
164
 
165
  if( $term->slug != $sanitized_slug ) {
166
+ update_option('wbcr_wp_term_' . $term->term_id . '_old_slug', $term->slug, false);
167
  $wpdb->update($wpdb->terms, array('slug' => $sanitized_slug), array('term_id' => $term->term_id), array('%s'), array('%d'));
168
  }
169
  }
218
 
219
  /**
220
  * @param $form
221
+ * @param $page Wbcr_FactoryPages407_ImpressiveThemplate
222
  * @return mixed
223
  */
224
  function wbcr_cyrlitera_seo_form_options($form, $page)
components/cyrlitera/admin/pages/cyrlitera.php CHANGED
@@ -11,13 +11,13 @@
11
  exit;
12
  }
13
 
14
- class WCTR_CyrliteraPage extends Wbcr_FactoryPages401_ImpressiveThemplate {
15
 
16
  /**
17
  * The id of the page in the admin menu.
18
  *
19
  * Mainly used to navigate between pages.
20
- * @see FactoryPages401_AdminPage
21
  *
22
  * @since 1.0.0
23
  * @var string
@@ -26,9 +26,9 @@
26
  public $page_menu_dashicon = 'dashicons-testimonial';
27
 
28
  /**
29
- * @param Wbcr_Factory400_Plugin $plugin
30
  */
31
- public function __construct(Wbcr_Factory400_Plugin $plugin)
32
  {
33
  $this->menu_title = __('Transliteration', 'cyrlitera');
34
 
@@ -50,6 +50,24 @@
50
  : __('General', 'cyrlitera');
51
  }
52
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  /*protected function afterFormSave()
54
  {
55
  $use_transliterations = $this->plugin->getOption('use_transliterations');
11
  exit;
12
  }
13
 
14
+ class WCTR_CyrliteraPage extends Wbcr_FactoryPages407_ImpressiveThemplate {
15
 
16
  /**
17
  * The id of the page in the admin menu.
18
  *
19
  * Mainly used to navigate between pages.
20
+ * @see FactoryPages407_AdminPage
21
  *
22
  * @since 1.0.0
23
  * @var string
26
  public $page_menu_dashicon = 'dashicons-testimonial';
27
 
28
  /**
29
+ * @param Wbcr_Factory406_Plugin $plugin
30
  */
31
+ public function __construct(Wbcr_Factory406_Plugin $plugin)
32
  {
33
  $this->menu_title = __('Transliteration', 'cyrlitera');
34
 
50
  : __('General', 'cyrlitera');
51
  }
52
 
53
+ /**
54
+ * Requests assets (js and css) for the page.
55
+ *
56
+ * @see Wbcr_FactoryPages407_AdminPage
57
+ *
58
+ * @since 1.0.0
59
+ * @return void
60
+ */
61
+ public function assets($scripts, $styles)
62
+ {
63
+ parent::assets($scripts, $styles);
64
+
65
+ // Add Clearfy styles for HMWP pages
66
+ if( defined('WBCR_CLEARFY_PLUGIN_ACTIVE') ) {
67
+ $this->styles->add(WCL_PLUGIN_URL . '/admin/assets/css/general.css');
68
+ }
69
+ }
70
+
71
  /*protected function afterFormSave()
72
  {
73
  $use_transliterations = $this->plugin->getOption('use_transliterations');
components/cyrlitera/admin/pages/more-features.php CHANGED
@@ -11,6 +11,6 @@
11
  exit;
12
  }
13
 
14
- class WCTR_MoreFeaturesPage extends Wbcr_FactoryClearfy200_MoreFeaturesPage {
15
 
16
  }
11
  exit;
12
  }
13
 
14
+ class WCTR_MoreFeaturesPage extends Wbcr_FactoryClearfy203_MoreFeaturesPage {
15
 
16
  }
components/cyrlitera/cyrlitera.php CHANGED
@@ -4,10 +4,10 @@
4
  * Plugin URI: https://wordpress.org/plugins/cyrlitera/
5
  * Description: The plugin converts Cyrillic, Georgian links, filenames into Latin. It is necessary for correct work of WordPress plugins and improve links readability.
6
  * Author: Webcraftic <wordpress.webraftic@gmail.com>
7
- * Version: 1.0.4
8
  * Text Domain: cyrlitera
9
  * Domain Path: /languages/
10
- * Author URI: http://webcraftic.com
11
  */
12
 
13
  // Exit if accessed directly
@@ -50,7 +50,7 @@
50
  'prefix' => 'wbcr_cyrlitera_',
51
  'plugin_name' => 'wbcr_cyrlitera',
52
  'plugin_title' => __('Webcraftic Cyrlitera', 'cyrlitera'),
53
- 'plugin_version' => '1.0.4',
54
  'required_php_version' => '5.2',
55
  'required_wp_version' => '4.2',
56
  'plugin_build' => 'free',
4
  * Plugin URI: https://wordpress.org/plugins/cyrlitera/
5
  * Description: The plugin converts Cyrillic, Georgian links, filenames into Latin. It is necessary for correct work of WordPress plugins and improve links readability.
6
  * Author: Webcraftic <wordpress.webraftic@gmail.com>
7
+ * Version: 1.0.5
8
  * Text Domain: cyrlitera
9
  * Domain Path: /languages/
10
+ * Author URI: http://clearfy.pro
11
  */
12
 
13
  // Exit if accessed directly
50
  'prefix' => 'wbcr_cyrlitera_',
51
  'plugin_name' => 'wbcr_cyrlitera',
52
  'plugin_title' => __('Webcraftic Cyrlitera', 'cyrlitera'),
53
+ 'plugin_version' => '1.0.5',
54
  'required_php_version' => '5.2',
55
  'required_wp_version' => '4.2',
56
  'plugin_build' => 'free',
components/cyrlitera/includes/class.plugin.php CHANGED
@@ -19,7 +19,7 @@
19
 
20
  }
21
  } else {
22
- class WCTR_PluginFactory extends Wbcr_Factory400_Plugin {
23
 
24
  }
25
  }
@@ -28,7 +28,7 @@
28
  class WCTR_Plugin extends WCTR_PluginFactory {
29
 
30
  /**
31
- * @var Wbcr_Factory400_Plugin
32
  */
33
  private static $app;
34
 
@@ -51,7 +51,7 @@
51
  ? $data['plugin_parent']
52
  : null;
53
 
54
- if( !($plugin_parent instanceof Wbcr_Factory400_Plugin) ) {
55
  throw new Exception('An invalid instance of the class was passed.');
56
  }
57
 
@@ -75,7 +75,7 @@
75
  }
76
 
77
  /**
78
- * @return Wbcr_Factory400_Plugin
79
  */
80
  public static function app()
81
  {
@@ -92,10 +92,11 @@
92
  {
93
  if( !$this->as_addon ) {
94
  self::app()->load(array(
95
- array('libs/factory/bootstrap', 'factory_bootstrap_400', 'admin'),
96
- array('libs/factory/forms', 'factory_forms_400', 'admin'),
97
- array('libs/factory/pages', 'factory_pages_401', 'admin'),
98
- array('libs/factory/clearfy', 'factory_clearfy_200', 'all')
 
99
  ));
100
  }
101
  }
19
 
20
  }
21
  } else {
22
+ class WCTR_PluginFactory extends Wbcr_Factory406_Plugin {
23
 
24
  }
25
  }
28
  class WCTR_Plugin extends WCTR_PluginFactory {
29
 
30
  /**
31
+ * @var Wbcr_Factory406_Plugin
32
  */
33
  private static $app;
34
 
51
  ? $data['plugin_parent']
52
  : null;
53
 
54
+ if( !($plugin_parent instanceof Wbcr_Factory406_Plugin) ) {
55
  throw new Exception('An invalid instance of the class was passed.');
56
  }
57
 
75
  }
76
 
77
  /**
78
+ * @return Wbcr_Factory406_Plugin
79
  */
80
  public static function app()
81
  {
92
  {
93
  if( !$this->as_addon ) {
94
  self::app()->load(array(
95
+ array('libs/factory/bootstrap', 'factory_bootstrap_406', 'admin'),
96
+ array('libs/factory/forms', 'factory_forms_407', 'admin'),
97
+ array('libs/factory/pages', 'factory_pages_407', 'admin'),
98
+ array('libs/factory/clearfy', 'factory_clearfy_203', 'all'),
99
+ array('libs/factory/notices', 'factory_notices_405', 'admin')
100
  ));
101
  }
102
  }
components/cyrlitera/includes/classes/class.configurate-cyrlitera.php CHANGED
@@ -11,11 +11,11 @@
11
  exit;
12
  }
13
 
14
- class WCTR_ConfigСyrlitera extends Wbcr_FactoryClearfy200_Configurate {
15
 
16
  public function registerActionsAndFilters()
17
  {
18
- if( is_admin() || (defined('XMLRPC_REQUEST') && XMLRPC_REQUEST) ) {
19
  if( $this->getOption('use_transliteration') ) {
20
  if( !$this->getOption('use_force_transliteration') ) {
21
  add_filter('sanitize_title', 'WCTR_Helper::sanitizeTitle', 0);
@@ -201,7 +201,7 @@
201
  */
202
  public function redirectFromOldUrls()
203
  {
204
- if( !WbcrFactoryClearfy200_Helpers::isPermalink() ) {
205
  return;
206
  }
207
  $is404 = is_404();
11
  exit;
12
  }
13
 
14
+ class WCTR_ConfigСyrlitera extends Wbcr_FactoryClearfy203_Configurate {
15
 
16
  public function registerActionsAndFilters()
17
  {
18
+ if( is_admin() || !$this->getOption('dont_use_transliteration_on_frontend') ) {
19
  if( $this->getOption('use_transliteration') ) {
20
  if( !$this->getOption('use_force_transliteration') ) {
21
  add_filter('sanitize_title', 'WCTR_Helper::sanitizeTitle', 0);
201
  */
202
  public function redirectFromOldUrls()
203
  {
204
+ if( !WbcrFactoryClearfy203_Helpers::isPermalink() ) {
205
  return;
206
  }
207
  $is404 = is_404();
components/cyrlitera/languages/cyrlitera-ru_RU.mo CHANGED
Binary file
components/cyrlitera/languages/cyrlitera-ru_RU.po CHANGED
@@ -1,8 +1,8 @@
1
  msgid ""
2
  msgstr ""
3
  "Project-Id-Version: clearfy\n"
4
- "POT-Creation-Date: 2018-03-23 17:57+0300\n"
5
- "PO-Revision-Date: 2018-03-23 17:57+0300\n"
6
  "Last-Translator: alex.kovalevv@gmail.com <alex.kovalevv@gmail.com>\n"
7
  "Language-Team: Alex Kovalev <alex.kovalevv@gmail.com>\n"
8
  "Language: ru_RU\n"
@@ -39,31 +39,35 @@ msgstr ""
39
  "настоятельно рекомендуем не использовать похожие функции плагинов "
40
  "одновременно!"
41
 
42
- #: admin/boot.php:127 admin/options.php:30
43
  msgid "Use transliteration"
44
  msgstr "Использовать транслитерацию"
45
 
46
- #: admin/boot.php:133 admin/options.php:48
47
  msgid "Force transliteration"
48
  msgstr "Принудильная траслитерация"
49
 
50
- #: admin/boot.php:139 admin/options.php:39
 
 
 
 
51
  msgid "Convert file names"
52
  msgstr "Конвертировать имена файлов"
53
 
54
- #: admin/boot.php:145 admin/options.php:58
55
  msgid "Convert file names into lowercase"
56
  msgstr "Преобразовывать имена файлов в нижний регистр"
57
 
58
- #: admin/boot.php:151 admin/options.php:68
59
  msgid "Redirection old URLs to new ones"
60
  msgstr "Перенаправление со старых URL на новые"
61
 
62
- #: admin/boot.php:157 admin/options.php:78
63
  msgid "Character Sets"
64
  msgstr "Наборы символов"
65
 
66
- #: admin/boot.php:169
67
  msgid "Get ultimate plugin free"
68
  msgstr "Получите полную версию плагина бесплатно"
69
 
@@ -129,7 +133,11 @@ msgstr ""
129
  "ссылками, используйте эту опцию, чтобы пользователи, перешедшие по старым "
130
  "ссылкам, были перенаправлены на новые URL на латинице."
131
 
132
- #: admin/options.php:79
 
 
 
 
133
  msgid ""
134
  "You can supplement current base of transliteration characters. Write pairs "
135
  "of values separated by commas. Example:"
@@ -137,7 +145,7 @@ msgstr ""
137
  "Вы можете дополнить текущую базу символов транслитерации, пишите пары "
138
  "значений через запятую. Пример: "
139
 
140
- #: admin/options.php:168
141
  msgid ""
142
  "If at the time of the plugin installation you already had posts, pages, tags "
143
  "and categories, click on this button and the plugin will automatically "
@@ -148,17 +156,17 @@ msgstr ""
148
  "метки и рубрики, то нажмите на эту кнопку и плагин автоматически преобразует "
149
  "URLы в латинские. Внимание! Ранее загруженные файлы преобразованы не будут."
150
 
151
- #: admin/options.php:177
152
  msgid "Convert already created posts and categories"
153
  msgstr "Преобразовать уже созданные записи и рубрики"
154
 
155
- #: admin/options.php:179
156
  msgid "Url of old posts, pages,terms,tags successfully converted into Latin!"
157
  msgstr ""
158
  "Url старых записей, страниц, тегов и рубрик были успешно конвертированы в "
159
  "литинские!"
160
 
161
- #: admin/options.php:189
162
  msgid ""
163
  "Allows you to restore converted URLs by using the \"Convert already created "
164
  "posts and categories\" button. This can be useful in case of incorrect URLs "
@@ -171,11 +179,11 @@ msgstr ""
171
  "символов. У вас есть возможность откатить изменения и изменить наборы "
172
  "символов выше, чтобы скорректировать работу плагина."
173
 
174
- #: admin/options.php:198
175
  msgid "Rollback changes"
176
  msgstr "Откатить изменения"
177
 
178
- #: admin/options.php:200
179
  msgid "The rollback of new changes was successful!"
180
  msgstr "Откат новых изменений прошел успешно!"
181
 
1
  msgid ""
2
  msgstr ""
3
  "Project-Id-Version: clearfy\n"
4
+ "POT-Creation-Date: 2018-05-13 16:31+0300\n"
5
+ "PO-Revision-Date: 2018-05-13 16:32+0300\n"
6
  "Last-Translator: alex.kovalevv@gmail.com <alex.kovalevv@gmail.com>\n"
7
  "Language-Team: Alex Kovalev <alex.kovalevv@gmail.com>\n"
8
  "Language: ru_RU\n"
39
  "настоятельно рекомендуем не использовать похожие функции плагинов "
40
  "одновременно!"
41
 
42
+ #: admin/boot.php:135 admin/options.php:30
43
  msgid "Use transliteration"
44
  msgstr "Использовать транслитерацию"
45
 
46
+ #: admin/boot.php:141 admin/options.php:48
47
  msgid "Force transliteration"
48
  msgstr "Принудильная траслитерация"
49
 
50
+ #: admin/boot.php:147 admin/options.php:78
51
+ msgid "Don't use transliteration in frontend"
52
+ msgstr "Не использовать транслитерацию на фронтенде"
53
+
54
+ #: admin/boot.php:153 admin/options.php:39
55
  msgid "Convert file names"
56
  msgstr "Конвертировать имена файлов"
57
 
58
+ #: admin/boot.php:159 admin/options.php:58
59
  msgid "Convert file names into lowercase"
60
  msgstr "Преобразовывать имена файлов в нижний регистр"
61
 
62
+ #: admin/boot.php:165 admin/options.php:68
63
  msgid "Redirection old URLs to new ones"
64
  msgstr "Перенаправление со старых URL на новые"
65
 
66
+ #: admin/boot.php:171 admin/options.php:88
67
  msgid "Character Sets"
68
  msgstr "Наборы символов"
69
 
70
+ #: admin/boot.php:192
71
  msgid "Get ultimate plugin free"
72
  msgstr "Получите полную версию плагина бесплатно"
73
 
133
  "ссылками, используйте эту опцию, чтобы пользователи, перешедшие по старым "
134
  "ссылкам, были перенаправлены на новые URL на латинице."
135
 
136
+ #: admin/options.php:80
137
+ msgid "Enable when have a problem in frontend."
138
+ msgstr "Включите эту опцию, если у вас есть проблемы с внешней стороны сайта."
139
+
140
+ #: admin/options.php:89
141
  msgid ""
142
  "You can supplement current base of transliteration characters. Write pairs "
143
  "of values separated by commas. Example:"
145
  "Вы можете дополнить текущую базу символов транслитерации, пишите пары "
146
  "значений через запятую. Пример: "
147
 
148
+ #: admin/options.php:178
149
  msgid ""
150
  "If at the time of the plugin installation you already had posts, pages, tags "
151
  "and categories, click on this button and the plugin will automatically "
156
  "метки и рубрики, то нажмите на эту кнопку и плагин автоматически преобразует "
157
  "URLы в латинские. Внимание! Ранее загруженные файлы преобразованы не будут."
158
 
159
+ #: admin/options.php:187
160
  msgid "Convert already created posts and categories"
161
  msgstr "Преобразовать уже созданные записи и рубрики"
162
 
163
+ #: admin/options.php:189
164
  msgid "Url of old posts, pages,terms,tags successfully converted into Latin!"
165
  msgstr ""
166
  "Url старых записей, страниц, тегов и рубрик были успешно конвертированы в "
167
  "литинские!"
168
 
169
+ #: admin/options.php:199
170
  msgid ""
171
  "Allows you to restore converted URLs by using the \"Convert already created "
172
  "posts and categories\" button. This can be useful in case of incorrect URLs "
179
  "символов. У вас есть возможность откатить изменения и изменить наборы "
180
  "символов выше, чтобы скорректировать работу плагина."
181
 
182
+ #: admin/options.php:208
183
  msgid "Rollback changes"
184
  msgstr "Откатить изменения"
185
 
186
+ #: admin/options.php:210
187
  msgid "The rollback of new changes was successful!"
188
  msgstr "Откат новых изменений прошел успешно!"
189
 
components/cyrlitera/readme.txt CHANGED
@@ -62,10 +62,12 @@ We used some plugins functions:
62
  We invite you to check out a few other related free plugins that our team has also produced that you may find especially useful:
63
 
64
  * [Clearfy – WordPress optimization plugin and disable ultimate tweaker](https://wordpress.org/plugins/clearfy/)
65
- * [WordPress Assets manager, dequeue scripts, dequeue styles](https://wordpress.org/plugins/gonzales/)
66
  * [Disable Comments for Any Post Types (Remove Comments)](https://wordpress.org/plugins/comments-plus/)
67
  * [Disable updates, Disable automatic updates, Updates manager](https://wordpress.org/plugins/webcraftic-updates-manager/)
 
68
  * [Disable admin notices individually](https://wordpress.org/plugins/disable-admin-notices/ "Disable admin notices individually")
 
 
69
 
70
  == Installation ==
71
 
@@ -89,6 +91,12 @@ There is a "Rollback changes" button in the plugin settings. This option works o
89
  2. Simple for filenames
90
 
91
  == Changelog ==
 
 
 
 
 
 
92
  = 1.0.4 =
93
  Fixed: Bug with transliteration of file names
94
  Added: Compatibility with PHP 7.2
62
  We invite you to check out a few other related free plugins that our team has also produced that you may find especially useful:
63
 
64
  * [Clearfy – WordPress optimization plugin and disable ultimate tweaker](https://wordpress.org/plugins/clearfy/)
 
65
  * [Disable Comments for Any Post Types (Remove Comments)](https://wordpress.org/plugins/comments-plus/)
66
  * [Disable updates, Disable automatic updates, Updates manager](https://wordpress.org/plugins/webcraftic-updates-manager/)
67
+ * [Cyr-to-lat reloaded – transliteration of links and file names](https://wordpress.org/plugins/cyr-and-lat/ "Cyr-to-lat reloaded")
68
  * [Disable admin notices individually](https://wordpress.org/plugins/disable-admin-notices/ "Disable admin notices individually")
69
+ * [WordPress Assets manager, dequeue scripts, dequeue styles](https://wordpress.org/plugins/gonzales/ "WordPress Assets manager, dequeue scripts, dequeue styles")
70
+ * [Hide login page](https://wordpress.org/plugins/hide-login-page/ "Hide login page")
71
 
72
  == Installation ==
73
 
91
  2. Simple for filenames
92
 
93
  == Changelog ==
94
+ = 1.0.5 =
95
+ Fixed: Update core
96
+ Fixed: Bug with bodypress
97
+ Fixed: Transliteration on the frontend
98
+ Fixed: Added option to disable transliteration on frontend
99
+
100
  = 1.0.4 =
101
  Fixed: Bug with transliteration of file names
102
  Added: Compatibility with PHP 7.2
components/cyrlitera/updates/010004.php CHANGED
@@ -4,7 +4,7 @@
4
  * Updates for altering the table used to store statistics data.
5
  * Adds new columns and renames existing ones in order to add support for the new social buttons.
6
  */
7
- class WCTR_Update010004 extends Wbcr_Factory400_Update {
8
 
9
  public function install()
10
  {
4
  * Updates for altering the table used to store statistics data.
5
  * Adds new columns and renames existing ones in order to add support for the new social buttons.
6
  */
7
+ class WCTR_Update010004 extends Wbcr_Factory406_Update {
8
 
9
  public function install()
10
  {
components/disable-admin-notices/admin/ajax/hide-notice.php CHANGED
@@ -15,7 +15,7 @@
15
  {
16
  check_ajax_referer(WDN_Plugin::app()->getPluginName() . '_ajax_hide_notices_nonce', 'security');
17
 
18
- if( !current_user_can('update_plugins') ) {
19
  echo json_encode(array('error' => __('You don\'t have enough capability to edit this information.', 'disable-admin-notices')));
20
  exit;
21
  }
15
  {
16
  check_ajax_referer(WDN_Plugin::app()->getPluginName() . '_ajax_hide_notices_nonce', 'security');
17
 
18
+ if( !current_user_can('manage_options') ) {
19
  echo json_encode(array('error' => __('You don\'t have enough capability to edit this information.', 'disable-admin-notices')));
20
  exit;
21
  }
components/disable-admin-notices/admin/ajax/restore-notice.php CHANGED
@@ -15,7 +15,7 @@
15
  {
16
  check_ajax_referer(WDN_Plugin::app()->getPluginName() . '_ajax_restore_notice_nonce', 'security');
17
 
18
- if( !current_user_can('update_plugins') ) {
19
  echo json_encode(array('error' => __('You don\'t have enough capability to edit this information.', 'disable-admin-notices')));
20
  exit;
21
  }
15
  {
16
  check_ajax_referer(WDN_Plugin::app()->getPluginName() . '_ajax_restore_notice_nonce', 'security');
17
 
18
+ if( !current_user_can('manage_options') ) {
19
  echo json_encode(array('error' => __('You don\'t have enough capability to edit this information.', 'disable-admin-notices')));
20
  exit;
21
  }
components/disable-admin-notices/admin/assets/js/notifications-panel.js CHANGED
@@ -10,6 +10,7 @@
10
 
11
  $(document).ready(function() {
12
  $(document).on('click', '.wbcr-han-panel-restore-notify-link', function() {
 
13
  var self = $(this),
14
  noticeID = $(this).data('notice-id'),
15
  counterEl = $('.wbcr-han-adminbar-counter');
10
 
11
  $(document).ready(function() {
12
  $(document).on('click', '.wbcr-han-panel-restore-notify-link', function() {
13
+
14
  var self = $(this),
15
  noticeID = $(this).data('notice-id'),
16
  counterEl = $('.wbcr-han-adminbar-counter');
components/disable-admin-notices/admin/boot.php CHANGED
@@ -11,17 +11,6 @@
11
  exit;
12
  }
13
 
14
- function wbcr_dan_rating_widget_url($page_url, $plugin_name)
15
- {
16
- if( $plugin_name == WDN_Plugin::app()->getPluginName() ) {
17
- return 'https://goo.gl/68ucHp';
18
- }
19
-
20
- return $page_url;
21
- }
22
-
23
- add_filter('wbcr_factory_pages_401_imppage_rating_widget_url', 'wbcr_dan_rating_widget_url', 10, 2);
24
-
25
  function wbcr_dan_group_options($options)
26
  {
27
  $options[] = array(
@@ -48,7 +37,13 @@
48
  function wbcr_dan_set_plugin_meta($links, $file)
49
  {
50
  if( $file == WDN_PLUGIN_BASE ) {
51
- $links[] = '<a href="https://goo.gl/TcMcS4" style="color: #FF5722;font-weight: bold;" target="_blank">' . __('Get ultimate plugin free', 'disable-admin-notices') . '</a>';
 
 
 
 
 
 
52
  }
53
 
54
  return $links;
@@ -60,5 +55,16 @@
60
  add_filter('plugin_row_meta', 'wbcr_dan_set_plugin_meta', 10, 2);
61
  }
62
 
 
 
 
 
 
 
 
 
 
 
 
63
 
64
 
11
  exit;
12
  }
13
 
 
 
 
 
 
 
 
 
 
 
 
14
  function wbcr_dan_group_options($options)
15
  {
16
  $options[] = array(
37
  function wbcr_dan_set_plugin_meta($links, $file)
38
  {
39
  if( $file == WDN_PLUGIN_BASE ) {
40
+ $url = 'https://clearfy.pro';
41
+
42
+ if( get_locale() == 'ru_RU' ) {
43
+ $url = 'https://ru.clearfy.pro';
44
+ }
45
+ $url .= '?utm_source=wordpress.org&utm_campaign=' . WDN_Plugin::app()->getPluginName();
46
+ $links[] = '<a href="' . $url . '" style="color: #FF5722;font-weight: bold;" target="_blank">' . __('Get ultimate plugin free', 'disable-admin-notices') . '</a>';
47
  }
48
 
49
  return $links;
55
  add_filter('plugin_row_meta', 'wbcr_dan_set_plugin_meta', 10, 2);
56
  }
57
 
58
+ function wbcr_dan_rating_widget_url($page_url, $plugin_name)
59
+ {
60
+ if( !defined('LOADING_DISABLE_ADMIN_NOTICES_AS_ADDON') && ($plugin_name == WDN_Plugin::app()->getPluginName()) ) {
61
+ return 'https://goo.gl/68ucHp';
62
+ }
63
+
64
+ return $page_url;
65
+ }
66
+
67
+ add_filter('wbcr_factory_pages_407_imppage_rating_widget_url', 'wbcr_dan_rating_widget_url', 10, 2);
68
+
69
 
70
 
components/disable-admin-notices/admin/options.php CHANGED
@@ -87,7 +87,7 @@
87
 
88
  /**
89
  * @param $form
90
- * @param $page Wbcr_FactoryPages401_ImpressiveThemplate
91
  * @return mixed
92
  */
93
  function wbcr_dan_additionally_form_options($form, $page)
@@ -108,7 +108,7 @@
108
  add_filter('wbcr_clr_additionally_form_options', 'wbcr_dan_additionally_form_options', 10, 2);
109
 
110
  /**
111
- * @param $html_builder Wbcr_FactoryForms400_Html
112
  */
113
  function wbcr_dan_reset_notices_button($html_builder)
114
  {
87
 
88
  /**
89
  * @param $form
90
+ * @param $page Wbcr_FactoryPages407_ImpressiveThemplate
91
  * @return mixed
92
  */
93
  function wbcr_dan_additionally_form_options($form, $page)
108
  add_filter('wbcr_clr_additionally_form_options', 'wbcr_dan_additionally_form_options', 10, 2);
109
 
110
  /**
111
+ * @param $html_builder Wbcr_FactoryForms407_Html
112
  */
113
  function wbcr_dan_reset_notices_button($html_builder)
114
  {
components/disable-admin-notices/admin/pages/more-features.php CHANGED
@@ -11,6 +11,6 @@
11
  exit;
12
  }
13
 
14
- class WDN_MoreFeaturesPage extends Wbcr_FactoryClearfy200_MoreFeaturesPage {
15
 
16
  }
11
  exit;
12
  }
13
 
14
+ class WDN_MoreFeaturesPage extends Wbcr_FactoryClearfy203_MoreFeaturesPage {
15
 
16
  }
components/disable-admin-notices/admin/pages/notices.php CHANGED
@@ -11,13 +11,13 @@
11
  exit;
12
  }
13
 
14
- class WDN_NoticesPage extends Wbcr_FactoryPages401_ImpressiveThemplate {
15
 
16
  /**
17
  * The id of the page in the admin menu.
18
  *
19
  * Mainly used to navigate between pages.
20
- * @see FactoryPages401_AdminPage
21
  *
22
  * @since 1.0.0
23
  * @var string
@@ -26,9 +26,9 @@
26
  public $page_menu_dashicon = 'dashicons-testimonial';
27
 
28
  /**
29
- * @param Wbcr_Factory400_Plugin $plugin
30
  */
31
- public function __construct(Wbcr_Factory400_Plugin $plugin)
32
  {
33
  $this->menu_title = __('Hide admin notices', 'disable-admin-notices');
34
 
@@ -50,11 +50,29 @@
50
  : __('General', 'disable-admin-notices');
51
  }
52
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
 
54
  /**
55
  * We register notifications for some actions
56
  * @param array $notices
57
- * @param Wbcr_Factory400_Plugin $plugin
58
  * @return array
59
  */
60
  public function actionsNotice($notices)
@@ -73,7 +91,7 @@
73
  'wbcr_dan_code' => 'interal_error'
74
  ),
75
  'type' => 'danger',
76
- 'message' => __('An error occurred while trying to delete comments. Internal error occured. Please try again later.', 'factory_pages_401')
77
  );*/
78
 
79
  return $notices;
11
  exit;
12
  }
13
 
14
+ class WDN_NoticesPage extends Wbcr_FactoryPages407_ImpressiveThemplate {
15
 
16
  /**
17
  * The id of the page in the admin menu.
18
  *
19
  * Mainly used to navigate between pages.
20
+ * @see FactoryPages407_AdminPage
21
  *
22
  * @since 1.0.0
23
  * @var string
26
  public $page_menu_dashicon = 'dashicons-testimonial';
27
 
28
  /**
29
+ * @param Wbcr_Factory406_Plugin $plugin
30
  */
31
+ public function __construct(Wbcr_Factory406_Plugin $plugin)
32
  {
33
  $this->menu_title = __('Hide admin notices', 'disable-admin-notices');
34
 
50
  : __('General', 'disable-admin-notices');
51
  }
52
 
53
+ /**
54
+ * Requests assets (js and css) for the page.
55
+ *
56
+ * @see Wbcr_FactoryPages407_AdminPage
57
+ *
58
+ * @since 1.0.0
59
+ * @return void
60
+ */
61
+ public function assets($scripts, $styles)
62
+ {
63
+ parent::assets($scripts, $styles);
64
+
65
+ // Add Clearfy styles for HMWP pages
66
+ if( defined('WBCR_CLEARFY_PLUGIN_ACTIVE') ) {
67
+ $this->styles->add(WCL_PLUGIN_URL . '/admin/assets/css/general.css');
68
+ }
69
+ }
70
+
71
 
72
  /**
73
  * We register notifications for some actions
74
  * @param array $notices
75
+ * @param Wbcr_Factory406_Plugin $plugin
76
  * @return array
77
  */
78
  public function actionsNotice($notices)
91
  'wbcr_dan_code' => 'interal_error'
92
  ),
93
  'type' => 'danger',
94
+ 'message' => __('An error occurred while trying to delete comments. Internal error occured. Please try again later.', 'factory_pages_407')
95
  );*/
96
 
97
  return $notices;
components/disable-admin-notices/disable-admin-notices.php CHANGED
@@ -4,10 +4,10 @@
4
  * Plugin URI: https://wordpress.org/plugins/disable-admin-notices/
5
  * Description: Disable admin notices plugin gives you the option to hide updates warnings and inline notices in the admin panel.
6
  * Author: Webcraftic <wordpress.webraftic@gmail.com>
7
- * Version: 1.0.5
8
  * Text Domain: disable-admin-notices
9
  * Domain Path: /languages/
10
- * Author URI: http://webcraftic.com
11
  */
12
 
13
  // Exit if accessed directly
@@ -49,7 +49,7 @@
49
  'prefix' => 'wbcr_dan_',
50
  'plugin_name' => 'wbcr_dan',
51
  'plugin_title' => __('Webcraftic disable admin notices', 'disable-admin-notices'),
52
- 'plugin_version' => '1.0.5',
53
  'required_php_version' => '5.2',
54
  'required_wp_version' => '4.2',
55
  'plugin_build' => 'free',
4
  * Plugin URI: https://wordpress.org/plugins/disable-admin-notices/
5
  * Description: Disable admin notices plugin gives you the option to hide updates warnings and inline notices in the admin panel.
6
  * Author: Webcraftic <wordpress.webraftic@gmail.com>
7
+ * Version: 1.0.6
8
  * Text Domain: disable-admin-notices
9
  * Domain Path: /languages/
10
+ * Author URI: https://clearfy.pro
11
  */
12
 
13
  // Exit if accessed directly
49
  'prefix' => 'wbcr_dan_',
50
  'plugin_name' => 'wbcr_dan',
51
  'plugin_title' => __('Webcraftic disable admin notices', 'disable-admin-notices'),
52
+ 'plugin_version' => '1.0.6',
53
  'required_php_version' => '5.2',
54
  'required_wp_version' => '4.2',
55
  'plugin_build' => 'free',
components/disable-admin-notices/includes/class.plugin.php CHANGED
@@ -14,12 +14,12 @@
14
  if( !class_exists('WDN_Plugin') ) {
15
 
16
  if( !class_exists('WDN_PluginFactory') ) {
17
- if( defined('LOADING_CYRLITERA_AS_ADDON') ) {
18
  class WDN_PluginFactory {
19
 
20
  }
21
  } else {
22
- class WDN_PluginFactory extends Wbcr_Factory400_Plugin {
23
 
24
  }
25
  }
@@ -28,7 +28,7 @@
28
  class WDN_Plugin extends WDN_PluginFactory {
29
 
30
  /**
31
- * @var Wbcr_Factory400_Plugin
32
  */
33
  private static $app;
34
 
@@ -51,7 +51,7 @@
51
  ? $data['plugin_parent']
52
  : null;
53
 
54
- if( !($plugin_parent instanceof Wbcr_Factory400_Plugin) ) {
55
  throw new Exception('An invalid instance of the class was passed.');
56
  }
57
 
@@ -75,7 +75,7 @@
75
  }
76
 
77
  /**
78
- * @return Wbcr_Factory400_Plugin
79
  */
80
  public static function app()
81
  {
@@ -92,10 +92,10 @@
92
  {
93
  if( !$this->as_addon ) {
94
  self::app()->load(array(
95
- array('libs/factory/bootstrap', 'factory_bootstrap_400', 'admin'),
96
- array('libs/factory/forms', 'factory_forms_400', 'admin'),
97
- array('libs/factory/pages', 'factory_pages_401', 'admin'),
98
- array('libs/factory/clearfy', 'factory_clearfy_200', 'all')
99
  ));
100
  }
101
  }
14
  if( !class_exists('WDN_Plugin') ) {
15
 
16
  if( !class_exists('WDN_PluginFactory') ) {
17
+ if( defined('LOADING_DISABLE_ADMIN_NOTICES_AS_ADDON') ) {
18
  class WDN_PluginFactory {
19
 
20
  }
21
  } else {
22
+ class WDN_PluginFactory extends Wbcr_Factory406_Plugin {
23
 
24
  }
25
  }
28
  class WDN_Plugin extends WDN_PluginFactory {
29
 
30
  /**
31
+ * @var Wbcr_Factory406_Plugin
32
  */
33
  private static $app;
34
 
51
  ? $data['plugin_parent']
52
  : null;
53
 
54
+ if( !($plugin_parent instanceof Wbcr_Factory406_Plugin) ) {
55
  throw new Exception('An invalid instance of the class was passed.');
56
  }
57
 
75
  }
76
 
77
  /**
78
+ * @return Wbcr_Factory406_Plugin
79
  */
80
  public static function app()
81
  {
92
  {
93
  if( !$this->as_addon ) {
94
  self::app()->load(array(
95
+ array('libs/factory/bootstrap', 'factory_bootstrap_406', 'admin'),
96
+ array('libs/factory/forms', 'factory_forms_407', 'admin'),
97
+ array('libs/factory/pages', 'factory_pages_407', 'admin'),
98
+ array('libs/factory/clearfy', 'factory_clearfy_203', 'all')
99
  ));
100
  }
101
  }
components/disable-admin-notices/includes/classes/class.configurate-notices.php CHANGED
@@ -12,7 +12,7 @@
12
  exit;
13
  }
14
 
15
- class WDN_ConfigHideNotices extends Wbcr_FactoryClearfy200_Configurate {
16
 
17
  public function registerActionsAndFilters()
18
  {
@@ -235,6 +235,10 @@
235
  $class_name = get_class($class);
236
  $method_name = $callback['function'][1];
237
  $uniq_id2 = md5($class_name . ':' . $method_name);
 
 
 
 
238
  }
239
  }
240
  //838339d1a188e17fec838c2df3058603
@@ -281,13 +285,41 @@
281
  unset($wp_filter['user_admin_notices']);
282
  }
283
  } elseif( isset($wp_filter['admin_notices']) ) {
284
- unset($wp_filter['admin_notices']);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
285
  }
286
  if( isset($wp_filter['all_admin_notices']) ) {
287
- unset($wp_filter['all_admin_notices']);
 
 
 
 
 
 
 
 
 
 
288
  }
289
  }
290
 
 
291
  /**
292
  * Get excerpt from string
293
  *
@@ -296,7 +328,7 @@
296
  * @param Integer $maxLength Maximum length the excerpt may be
297
  * @return String excerpt
298
  */
299
- function getExcerpt($str, $startPos = 0, $maxLength = 100)
300
  {
301
  if( strlen($str) > $maxLength ) {
302
  $excerpt = substr($str, $startPos, $maxLength - 3);
12
  exit;
13
  }
14
 
15
+ class WDN_ConfigHideNotices extends Wbcr_FactoryClearfy203_Configurate {
16
 
17
  public function registerActionsAndFilters()
18
  {
235
  $class_name = get_class($class);
236
  $method_name = $callback['function'][1];
237
  $uniq_id2 = md5($class_name . ':' . $method_name);
238
+
239
+ if( strpos($class_name, 'Wbcr_FactoryNotices') !== false ) {
240
+ continue;
241
+ }
242
  }
243
  }
244
  //838339d1a188e17fec838c2df3058603
285
  unset($wp_filter['user_admin_notices']);
286
  }
287
  } elseif( isset($wp_filter['admin_notices']) ) {
288
+ foreach($wp_filter['admin_notices']->callbacks as $f_key => $f) {
289
+ foreach($f as $c_name => $clback) {
290
+ if( is_array($clback['function']) && sizeof($clback['function']) == 2 ) {
291
+ $class = $clback['function'][0];
292
+ if( is_object($class) ) {
293
+ $class_name = get_class($class);
294
+ if( strpos($class_name, 'Wbcr_FactoryNotices') !== false ) {
295
+ continue;
296
+ }
297
+ }
298
+ }
299
+
300
+ unset($wp_filter['admin_notices']->callbacks[$f_key][$c_name]);
301
+ }
302
+ }
303
+
304
+ unset($f_key);
305
+ unset($f);
306
  }
307
  if( isset($wp_filter['all_admin_notices']) ) {
308
+ foreach($wp_filter['all_admin_notices']->callbacks as $f_key => $f) {
309
+ foreach($f as $c_name => $clback) {
310
+ #Fix for Divi theme
311
+ if( $c_name != 'et_pb_export_layouts_interface' ) {
312
+ unset($wp_filter['all_admin_notices']->callbacks[$f_key][$c_name]);
313
+ }
314
+ }
315
+ }
316
+
317
+ unset($f_key);
318
+ unset($f);
319
  }
320
  }
321
 
322
+
323
  /**
324
  * Get excerpt from string
325
  *
328
  * @param Integer $maxLength Maximum length the excerpt may be
329
  * @return String excerpt
330
  */
331
+ public function getExcerpt($str, $startPos = 0, $maxLength = 100)
332
  {
333
  if( strlen($str) > $maxLength ) {
334
  $excerpt = substr($str, $startPos, $maxLength - 3);
components/disable-admin-notices/readme.txt CHANGED
@@ -33,6 +33,7 @@ We invite you to check out a few other related free plugins that our team has al
33
  * [Disable Comments for Any Post Types (Remove Comments)](https://wordpress.org/plugins/comments-plus/)
34
  * [Cyrlitera – transliteration of links and file names](https://wordpress.org/plugins/cyrlitera/)
35
  * [Disable updates, Disable automatic updates, Updates manager](https://wordpress.org/plugins/webcraftic-updates-manager/)
 
36
 
37
  == Translations ==
38
 
@@ -53,9 +54,10 @@ If you want to help with the translation, please contact me through this site or
53
  3. Notifications panel (optional)
54
 
55
  == Changelog ==
 
 
56
  = 1.0.5 =
57
  * Fixed: Prefix bug
58
-
59
  = 1.0.4 =
60
  * Fixed: Compatibility with Clearfy plugin
61
  * ADDED: Plugin options caching to reduce database queries for 90%. Clearfy became lighter and faster.
33
  * [Disable Comments for Any Post Types (Remove Comments)](https://wordpress.org/plugins/comments-plus/)
34
  * [Cyrlitera – transliteration of links and file names](https://wordpress.org/plugins/cyrlitera/)
35
  * [Disable updates, Disable automatic updates, Updates manager](https://wordpress.org/plugins/webcraftic-updates-manager/)
36
+ * [Hide login page, Hide wp admin – stop attack on login page](https://wordpress.org/plugins/hide-login-page//)
37
 
38
  == Translations ==
39
 
54
  3. Notifications panel (optional)
55
 
56
  == Changelog ==
57
+ = 1.0.6 =
58
+ * Fixed: compatibility with some plugins and themes
59
  = 1.0.5 =
60
  * Fixed: Prefix bug
 
61
  = 1.0.4 =
62
  * Fixed: Compatibility with Clearfy plugin
63
  * ADDED: Plugin options caching to reduce database queries for 90%. Clearfy became lighter and faster.
components/ga-cache/admin/activation.php ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Activator for the GA cache
5
+ * @author Webcraftic <wordpress.webraftic@gmail.com>
6
+ * @copyright (c) 09.09.2017, Webcraftic
7
+ * @see Factory406_Activator
8
+ * @version 1.0
9
+ */
10
+
11
+ // Exit if accessed directly
12
+ if( !defined('ABSPATH') ) {
13
+ exit;
14
+ }
15
+
16
+ class WGA_Activation extends Wbcr_Factory406_Activator {
17
+
18
+ /**
19
+ * Runs activation actions.
20
+ *
21
+ * @since 1.0.0
22
+ */
23
+ public function activate()
24
+ {
25
+ // -------------
26
+ // Caching google analytics on a schedule
27
+ // -------------
28
+
29
+ $ga_cache = WGA_Plugin::app()->getOption('ga_cache');
30
+
31
+ if( $ga_cache ) {
32
+ wp_clear_scheduled_hook('wbcr_clearfy_update_local_ga');
33
+
34
+ if( !wp_next_scheduled('wbcr_clearfy_update_local_ga') ) {
35
+ $ga_caos_remove_wp_cron = WGA_Plugin::app()->getOption('ga_caos_remove_wp_cron');
36
+
37
+ if( !$ga_caos_remove_wp_cron ) {
38
+ wp_schedule_event(time(), 'daily', 'wbcr_clearfy_update_local_ga');
39
+ }
40
+ }
41
+ }
42
+ }
43
+
44
+ /**
45
+ * Runs activation actions.
46
+ *
47
+ * @since 1.0.0
48
+ */
49
+ public function deactivate()
50
+ {
51
+ WGA_Plugin::app()->updateOption('ga_cache', 0);
52
+
53
+ if( wp_next_scheduled('wbcr_clearfy_update_local_ga') ) {
54
+ wp_clear_scheduled_hook('wbcr_clearfy_update_local_ga');
55
+ }
56
+ }
57
+ }
components/{hide-login-page/admin → ga-cache/admin/ajax}/index.php RENAMED
File without changes
components/{hide-login-page/admin/pages → ga-cache/admin/assets/css}/index.php RENAMED
File without changes
components/ga-cache/admin/assets/css/notifications-panel.css ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Notification panel in admin bar
3
+ * @author Alex Kovalev <alex.kovalevv@gmail.com>
4
+ * @copyright Alex Kovalev 23.08.2017
5
+ */
6
+ #wp-admin-bar-wbcr-han-notify-panel .wbcr-han-adminbar-counter {
7
+ background-color: #0073aa;
8
+ border-radius: 50%;
9
+ color: #fff;
10
+ font-weight: bold;
11
+ padding: 2px 6px;
12
+ font-size: 0.85em;
13
+ margin-left: 5px;
14
+ }
15
+ #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper {
16
+ max-height: 500px;
17
+ overflow-y: scroll;
18
+ }
19
+ #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper ul.ab-submenu {
20
+ width: 400px;
21
+ padding: 0;
22
+ }
23
+ #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper ul.ab-submenu > li {
24
+ border-left: 4px solid #26292b;
25
+ padding: 0;
26
+ }
27
+ #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper ul.ab-submenu > li.wpnc-updated {
28
+ border-left-color: #7ad03a;
29
+ }
30
+ #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper ul.ab-submenu > li.wpnc-update-nag {
31
+ border-left-color: #ffba00;
32
+ }
33
+ #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper ul.ab-submenu > li.wpnc-error {
34
+ border-left-color: #dd3d36;
35
+ }
36
+ #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper ul.ab-submenu > li .wbcr-han-panel-restore-notify-line {
37
+ text-align: right;
38
+ }
39
+ #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper ul.ab-submenu > li .wbcr-han-panel-restore-notify-line a {
40
+ color: #ffba00 !important;
41
+ text-decoration: none !important;
42
+ }
43
+ #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper ul.ab-submenu > li .wbcr-han-panel-restore-notify-line a:hover {
44
+ text-decoration: underline !important;
45
+ color: #ffc11a !important;
46
+ }
47
+ #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper ul.ab-submenu > li .ab-item {
48
+ height: 100% !important;
49
+ white-space: normal !important;
50
+ padding: .5em 1em;
51
+ border-bottom: 1px solid #4a4f55;
52
+ color: #949494;
53
+ line-height: .5em;
54
+ }
55
+ #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper ul.ab-submenu > li .ab-item a {
56
+ display: inline;
57
+ padding: 0;
58
+ margin: 0;
59
+ text-decoration: underline;
60
+ line-height: .5em;
61
+ color: #949494;
62
+ }
63
+ #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper ul.ab-submenu li:nth-child(2n) {
64
+ background: #26292b;
65
+ }
components/ga-cache/admin/assets/css/notifications-panel.less ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Notification panel in admin bar
3
+ * @author Alex Kovalev <alex.kovalevv@gmail.com>
4
+ * @copyright Alex Kovalev 23.08.2017
5
+ */
6
+
7
+ #wp-admin-bar-wbcr-han-notify-panel {
8
+
9
+ .wbcr-han-adminbar-counter {
10
+ background-color: #0073aa;
11
+ border-radius: 50%;
12
+ color: #fff;
13
+ font-weight: bold;
14
+ padding: 2px 6px;
15
+ font-size: 0.85em;
16
+ margin-left: 5px;
17
+ }
18
+
19
+ .ab-sub-wrapper {
20
+
21
+ max-height: 500px;
22
+ overflow-y: scroll;
23
+
24
+ ul.ab-submenu {
25
+ width: 400px;
26
+ padding: 0;
27
+
28
+ & > li {
29
+ border-left: 4px solid #26292b;
30
+ padding: 0;
31
+
32
+ &.wpnc-updated {
33
+ border-left-color: #7ad03a;
34
+ }
35
+ &.wpnc-update-nag {
36
+ border-left-color: #ffba00;
37
+ }
38
+ &.wpnc-error {
39
+ border-left-color: #dd3d36;
40
+ }
41
+
42
+ .wbcr-han-panel-restore-notify-line {
43
+ text-align: right;
44
+ a {
45
+ color: #ffba00 !important;
46
+ text-decoration: none !important;
47
+ &:hover {
48
+ text-decoration: underline !important;
49
+ color: lighten(#ffba00, 5%) !important;
50
+ }
51
+ }
52
+ }
53
+
54
+ .ab-item {
55
+ height: 100% !important;
56
+ white-space: normal !important;
57
+ padding: .5em 1em;
58
+ border-bottom: 1px solid #4a4f55;
59
+ color: #949494;
60
+ line-height: .5em;
61
+ a {
62
+ display: inline;
63
+ padding: 0;
64
+ margin: 0;
65
+ text-decoration: underline;
66
+ line-height: .5em;
67
+ color: #949494;
68
+ }
69
+ }
70
+ }
71
+
72
+ li:nth-child(2n) {
73
+ background: #26292b;
74
+ }
75
+ }
76
+ }
77
+ }
components/{hide-login-page/includes/classes → ga-cache/admin/assets}/index.php RENAMED
File without changes
components/{hide-login-page/includes → ga-cache/admin/assets/js}/index.php RENAMED
File without changes
components/ga-cache/admin/assets/js/notifications-panel.js ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Notification panel
3
+ * @author Webcraftic <wordpress.webraftic@gmail.com>
4
+ * @copyright (c) 10.09.2017, Webcraftic
5
+ * @version 1.0
6
+ */
7
+
8
+ (function($) {
9
+ 'use strict';
10
+
11
+ $(document).ready(function() {
12
+ $(document).on('click', '.wbcr-han-panel-restore-notify-link', function() {
13
+ var self = $(this),
14
+ noticeID = $(this).data('notice-id'),
15
+ counterEl = $('.wbcr-han-adminbar-counter');
16
+
17
+ if( !noticeID ) {
18
+ alert('Undefinded error. Please report the bug to our support forum.');
19
+ }
20
+
21
+ self.closest('li').hide();
22
+
23
+ $.ajax(ajaxurl, {
24
+ type: 'post',
25
+ dataType: 'json',
26
+ data: {
27
+ action: 'wbcr_dan_restore_notice',
28
+ security: wbcr_dan_ajax_restore_nonce,
29
+ notice_id: noticeID
30
+ },
31
+ success: function(data, textStatus, jqXHR) {
32
+ if( data == 'error' && data.error ) {
33
+ alert(data.error);
34
+ self.closest('li').show();
35
+ return;
36
+ }
37
+
38
+ counterEl.text(counterEl.text() - 1);
39
+ self.closest('li').remove();
40
+ }
41
+ });
42
+ });
43
+ });
44
+ })(jQuery);
components/ga-cache/admin/boot.php ADDED
@@ -0,0 +1,214 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Admin boot
4
+ * @author Webcraftic <wordpress.webraftic@gmail.com>
5
+ * @copyright Webcraftic 25.05.2017
6
+ * @version 1.0
7
+ */
8
+
9
+ // Exit if accessed directly
10
+ if( !defined('ABSPATH') ) {
11
+ exit;
12
+ }
13
+
14
+ /**
15
+ * Notice that the plugin has been seriously updated!
16
+ *
17
+ * @param array $notices
18
+ * @param string $plugin_name
19
+ * @return array
20
+ */
21
+ function wbcr_ga_admin_conflict_notices_error($notices, $plugin_name)
22
+ {
23
+ if( defined('LOADING_GA_CACHE_AS_ADDON') || $plugin_name != WGA_Plugin::app()->getPluginName() ) {
24
+ return $notices;
25
+ }
26
+
27
+ $text = '<p>' . __('The <b>Simple Google Analytics</b> plugin has some major changes!', 'simple-google-analytics') . '</p>';
28
+ $text .= '<p>' . __('Unfortunately, the old version of the plugin (2.2.2) is no longer supported, but you still can download it from the WordPress repository in case if the new release doesn’t work for you.', 'simple-google-analytics') . '</p>';
29
+ $text .= '<p>' . __('We’ve updated the code and fixed the compatibility issue for the latest WordPress and PHP versions. We’ve also added additional feature of the Local Google Analytics – this way your website will load faster. The plugin’s name has been changed to Local Google Analytics, but all features remained the same.', 'simple-google-analytics') . '</p>';
30
+ $text .= '<p>' . sprintf(__('Please, check <a href="%s">plugin settings</a> and its performance on your website. We do care about you and want to avoid any problems with the new version.', 'simple-google-analytics') . '</p>', admin_url('options-general.php?page=ga_cache-' . WGA_Plugin::app()
31
+ ->getPluginName())) . '</p>';
32
+ $text .= '<p>' . sprintf(__('We are aimed to pay more attention to the speed and security aspects of your website. That’s why you should definitely try our basic WordPress optimization plugin as well. Clearfy includes functionality of this plugin and has many additional features for the website optimization:
33
+ <a href="%s">Donwload Clearfy for free</a>', 'simple-google-analytics'), 'https://clearfy.pro?utm_source=wordpress.org&utm_campaign=' . WGA_Plugin::app()
34
+ ->getPluginName()) . '</p>';
35
+
36
+ $notices[] = array(
37
+ 'id' => 'ga_plugin_upgrade_notice1',
38
+ 'type' => 'warning',
39
+ 'dismissible' => true,
40
+ 'dismiss_expires' => 0,
41
+ 'text' => $text
42
+ );
43
+
44
+ return $notices;
45
+ }
46
+
47
+ add_filter('wbcr_factory_notices_405_list', 'wbcr_ga_admin_conflict_notices_error', 10, 2);
48
+
49
+ /**
50
+ * Migrate settings from the old plugin to the new one.
51
+ */
52
+ function wbcr_ga_upgrade()
53
+ {
54
+ global $wpdb;
55
+
56
+ if( defined('LOADING_GA_CACHE_AS_ADDON') ) {
57
+ return;
58
+ }
59
+
60
+ $is_migrate_up_to_230 = WGA_Plugin::app()->getOption('is_migrate_up_to_230', false);
61
+
62
+ if( !$is_migrate_up_to_230 ) {
63
+ $old_plugin_tracking_id = get_option('sga_analytics_id');
64
+ $old_plugin_code_location = get_option('sga_code_location');
65
+ $old_plugin_demographic_and_interest = (int)get_option('sga_demographic_and_interest');
66
+ $old_plugin_sga_render_when_loggedin = (int)get_option('sga_render_when_loggedin');
67
+
68
+ if( !empty($old_plugin_tracking_id) ) {
69
+ WGA_Plugin::app()->updateOption('ga_cache', 1);
70
+ WGA_Plugin::app()->updateOption('ga_tracking_id', $old_plugin_tracking_id);
71
+
72
+ $script_position = 'footer';
73
+
74
+ if( $old_plugin_code_location == 'head' ) {
75
+ $script_position = 'header';
76
+ }
77
+
78
+ WGA_Plugin::app()->updateOption('ga_script_position', $script_position);
79
+ WGA_Plugin::app()->updateOption('ga_anonymize_ip', $old_plugin_demographic_and_interest);
80
+ WGA_Plugin::app()->updateOption('ga_track_admin', $old_plugin_sga_render_when_loggedin);
81
+
82
+ $wpdb->query("DELETE FROM {$wpdb->prefix}options WHERE option_name LIKE 'sga_%';");
83
+ }
84
+
85
+ WGA_Plugin::app()->updateOption('is_migrate_up_to_230', 1);
86
+ }
87
+ }
88
+
89
+ add_action('init', 'wbcr_ga_upgrade');
90
+
91
+ /**
92
+ * This action is executed when the component of the Clearfy plugin is activate and if this component is name ga_cache
93
+ */
94
+ add_action('wbcr_clearfy_activated_component', function ($component_name) {
95
+ if( $component_name == 'ga_cache' ) {
96
+ require_once WGA_PLUGIN_DIR . '/admin/activation.php';
97
+ $plugin = new WGA_Activation(WGA_Plugin::app());
98
+ $plugin->activate();
99
+ }
100
+ });
101
+
102
+ /**
103
+ * This action is executed when the component of the Clearfy plugin is deactivated and if this component is name ga_cache
104
+ */
105
+ add_action('wbcr_clearfy_pre_deactivate_component', function ($component_name) {
106
+ if( $component_name == 'ga_cache' ) {
107
+ require_once WGA_PLUGIN_DIR . '/admin/activation.php';
108
+ $plugin = new WGA_Activation(WGA_Plugin::app());
109
+ $plugin->deactivate();
110
+ }
111
+ });
112
+
113
+ /**
114
+ * @param $options
115
+ * @return array
116
+ */
117
+ function wbcr_ga_group_options($options)
118
+ {
119
+ $options[] = array(
120
+ 'name' => 'ga_cache',
121
+ 'title' => __('Google Analytics Cache', 'simple-google-analytics'),
122
+ 'tags' => array()
123
+ );
124
+
125
+ $options[] = array(
126
+ 'name' => 'ga_tracking_id',
127
+ 'title' => __('Google analytic Code', 'clearfy'),
128
+ 'tags' => array()
129
+ );
130
+ $options[] = array(
131
+ 'name' => 'ga_adjusted_bounce_rate',
132
+ 'title' => __('Use adjusted bounce rate?', 'clearfy'),
133
+ 'tags' => array()
134
+ );
135
+ $options[] = array(
136
+ 'name' => 'ga_enqueue_order',
137
+ 'title' => __('Change enqueue order?', 'clearfy'),
138
+ 'tags' => array()
139
+ );
140
+ $options[] = array(
141
+ 'name' => 'ga_caos_disable_display_features',
142
+ 'title' => __('Disable all display features functionality?', 'clearfy'),
143
+ 'tags' => array()
144
+ );
145
+ $options[] = array(
146
+ 'name' => 'ga_anonymize_ip',
147
+ 'title' => __('Use Anonymize IP? (Required by law for some countries)', 'clearfy'),
148
+ 'tags' => array()
149
+ );
150
+ $options[] = array(
151
+ 'name' => 'ga_track_admin',
152
+ 'title' => __('Track logged in Administrators?', 'clearfy'),
153
+ 'tags' => array()
154
+ );
155
+ $options[] = array(
156
+ 'name' => 'ga_caos_remove_wp_cron',
157
+ 'title' => __('Remove script from wp-cron?', 'clearfy'),
158
+ 'tags' => array()
159
+ );
160
+
161
+ return $options;
162
+ }
163
+
164
+ add_filter("wbcr_clearfy_group_options", 'wbcr_ga_group_options');
165
+
166
+ /**
167
+ * Download ultimate plugin link
168
+ *
169
+ * @param $links
170
+ * @param $file
171
+ * @return array
172
+ */
173
+ function wbcr_ga_set_plugin_meta($links, $file)
174
+ {
175
+ if( $file == WGA_PLUGIN_BASE ) {
176
+
177
+ $url = 'https://clearfy.pro';
178
+
179
+ if( get_locale() == 'ru_RU' ) {
180
+ $url = 'https://ru.clearfy.pro';
181
+ }
182
+
183
+ $url .= '?utm_source=wordpress.org&utm_campaign=' . WGA_Plugin::app()->getPluginName();
184
+
185
+ $links[] = '<a href="' . $url . '" style="color: #FF5722;font-weight: bold;" target="_blank">' . __('Get ultimate plugin free', 'simple-google-analytics') . '</a>';
186
+ }
187
+
188
+ return $links;
189
+ }
190
+
191
+ if( !defined('LOADING_GA_CACHE_AS_ADDON') ) {
192
+ add_filter('plugin_row_meta', 'wbcr_ga_set_plugin_meta', 10, 2);
193
+ }
194
+
195
+ /**
196
+ * Rating widget url
197
+ *
198
+ * @param string $page_url
199
+ * @param string $plugin_name
200
+ * @return string
201
+ */
202
+ function wbcr_ga_rating_widget_url($page_url, $plugin_name)
203
+ {
204
+ if( !defined('LOADING_GA_CACHE_AS_ADDON') && ($plugin_name == WGA_Plugin::app()->getPluginName()) ) {
205
+ return 'https://wordpress.org/support/plugin/simple-google-analytics/reviews/#new-post';
206
+ }
207
+
208
+ return $page_url;
209
+ }
210
+
211
+ add_filter('wbcr_factory_imppage_rating_widget_url', 'wbcr_ga_rating_widget_url', 10, 2);
212
+
213
+
214
+
components/ga-cache/admin/options.php ADDED
@@ -0,0 +1,148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Options for additionally form
4
+ * @author Webcraftic <wordpress.webraftic@gmail.com>
5
+ * @copyright (c) 21.01.2018, Webcraftic
6
+ * @version 1.0
7
+ */
8
+
9
+ // Exit if accessed directly
10
+ if( !defined('ABSPATH') ) {
11
+ exit;
12
+ }
13
+
14
+ /**
15
+ * @return array
16
+ */
17
+ function wbcr_ga_get_plugin_options()
18
+ {
19
+ $options = array();
20
+
21
+ $options[] = array(
22
+ 'type' => 'html',
23
+ 'html' => '<div class="wbcr-factory-page-group-header">' . __('<strong>Google Analytics cache</strong>.', 'simple-google-analytics') . '<p>' . __('To improve Google Page Speed indicators Analytics caching is needed. However, it can also slightly increase your website loading speed, because Analytics js files will load locally. The second case that you might need these settings is the usual Google Analytics connection to your website. You do not need to do this with other plugins or insert the tracking code into your theme.', 'simple-google-analytics') . '</p></div>'
24
+ );
25
+
26
+ $options[] = array(
27
+ 'type' => 'checkbox',
28
+ 'way' => 'buttons',
29
+ 'name' => 'ga_cache',
30
+ 'title' => __('Google Analytics Cache', 'simple-google-analytics'),
31
+ 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
32
+ 'hint' => __('If you enable this option, the plugin will begin to save a local copy of Google Analytics to speed up the loading of your website and improve Google Page Speed.', 'simple-google-analytics') . '<br>--<br><span class="wbcr-factory-light-orange-color">' . __('ATTENTION! Before using this option, remove the previously installed Google Analytics code inside your theme or plugins associated with this feature!', 'simple-google-analytics') . '</span>',
33
+ 'default' => false,
34
+ 'eventsOn' => array(
35
+ 'show' => '#wbcr-clearfy-performance-ga-block'
36
+ ),
37
+ 'eventsOff' => array(
38
+ 'hide' => '#wbcr-clearfy-performance-ga-block'
39
+ )
40
+
41
+ );
42
+ $options[] = array(
43
+ 'type' => 'div',
44
+ 'id' => 'wbcr-clearfy-performance-ga-block',
45
+ 'items' => array(
46
+ array(
47
+ 'type' => 'textbox',
48
+ 'way' => 'buttons',
49
+ 'name' => 'ga_tracking_id',
50
+ 'title' => __('Google analytic Code', 'simple-google-analytics'),
51
+ 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
52
+ 'hint' => __('Set the Google Analytics tracking code.', 'simple-google-analytics'),
53
+ 'placeholder' => 'UA-XXXXX-Y'
54
+ ),
55
+ array(
56
+ 'type' => 'dropdown',
57
+ 'way' => 'buttons',
58
+ 'name' => 'ga_script_position',
59
+ 'data' => array(
60
+ array('header', 'Header'),
61
+ array('footer', 'Footer'),
62
+ ),
63
+ 'title' => __('Save GA in', 'simple-google-analytics'),
64
+ 'hint' => __('Select location for the Google Analytics code.', 'simple-google-analytics'),
65
+ 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
66
+ 'default' => 'footer'
67
+ ),
68
+ array(
69
+ 'type' => 'integer',
70
+ 'name' => 'ga_adjusted_bounce_rate',
71
+ 'title' => __('Use adjusted bounce rate?', 'simple-google-analytics'),
72
+ 'default' => 0,
73
+ 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
74
+ 'hint' => __('Essentially, you set up an event which is triggered after a user spends a certain amount of time on the landing page, telling Google Analytics not to count these users as bounces. A user may come to your website, find all of the information they need (a phone number, for example) and then leave the site without visiting another page. Without adjusted bounce rate, such a user would be considered a bounce, even though they had a successful experience. By defining a time limit after which you can consider a user to be "engaged," that user would no longer count as a bounce, and you\'d get a more accurate idea of whether they found what they were looking for.', 'simple-google-analytics')
75
+ ),
76
+ array(
77
+ 'type' => 'integer',
78
+ 'way' => 'buttons',
79
+ 'name' => 'ga_enqueue_order',
80
+ 'title' => __('Change enqueue order?', 'simple-google-analytics'),
81
+ 'default' => 0,
82
+ 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
83
+ 'hint' => __('By default, Google Analytics code is loaded before other scripts and javasscript code, but if you set the value to 100, the GA code will be loaded after all other scripts. By changing the priority, you can set code position on the page.', 'simple-google-analytics')
84
+ ),
85
+ array(
86
+ 'type' => 'checkbox',
87
+ 'way' => 'buttons',
88
+ 'name' => 'ga_caos_disable_display_features',
89
+ 'title' => __('Disable all display features functionality?', 'simple-google-analytics'),
90
+ //'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
91
+ 'hint' => sprintf(__('Disable all <a href="%s">display features functionality?</a>', 'simple-google-analytics'), 'https://developers.google.com/analytics/devguides/collection/analyticsjs/display-features'),
92
+ 'default' => false
93
+ ),
94
+ array(
95
+ 'type' => 'checkbox',
96
+ 'way' => 'buttons',
97
+ 'name' => 'ga_anonymize_ip',
98
+ 'title' => __('Use Anonymize IP? (Required by law for some countries)', 'simple-google-analytics'),
99
+ //'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
100
+ 'hint' => sprintf(__('Use <a href="%s">Anonymize IP?</a> (Required by law for some countries)', 'simple-google-analytics'), 'https://support.google.com/analytics/answer/2763052'),
101
+ 'default' => false
102
+ ),
103
+ array(
104
+ 'type' => 'checkbox',
105
+ 'way' => 'buttons',
106
+ 'name' => 'ga_track_admin',
107
+ 'title' => __('Track logged in Administrators?', 'simple-google-analytics'),
108
+ 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
109
+ 'hint' => __('Track logged in Administrators?', 'simple-google-analytics'),
110
+ 'default' => false
111
+ ),
112
+ array(
113
+ 'type' => 'checkbox',
114
+ 'way' => 'buttons',
115
+ 'name' => 'ga_caos_remove_wp_cron',
116
+ 'title' => __('Remove script from wp-cron?', 'simple-google-analytics'),
117
+ 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
118
+ 'hint' => __('Clearfy creates a cron job to daily update Google Analytics cache scripts. After enabling this option, the plugin will not update Google Analytics cache file. Do not use this option if you do not understand why you need it!', 'simple-google-analytics'),
119
+ 'default' => false
120
+ )
121
+ )
122
+ );
123
+
124
+ return $options;
125
+ }
126
+
127
+ /**
128
+ * @param $form
129
+ * @param $page FactoryPages407_ImpressiveThemplate
130
+ * @return mixed
131
+ */
132
+ function wbcr_ga_additionally_form_options($form, $page)
133
+ {
134
+ if( empty($form) ) {
135
+ return $form;
136
+ }
137
+
138
+ $options = wbcr_ga_get_plugin_options();
139
+
140
+ foreach(array_reverse($options) as $option) {
141
+ array_unshift($form[0]['items'], $option);
142
+ }
143
+
144
+ return $form;
145
+ }
146
+
147
+ add_filter('wbcr_clr_google_performance_form_options', 'wbcr_ga_additionally_form_options', 10, 2);
148
+
components/ga-cache/admin/pages/ga_cache.php ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * The page Settings.
5
+ *
6
+ * @since 1.0.0
7
+ */
8
+
9
+ // Exit if accessed directly
10
+ if( !defined('ABSPATH') ) {
11
+ exit;
12
+ }
13
+
14
+ class WGA_CachePage extends Wbcr_FactoryPages407_ImpressiveThemplate {
15
+
16
+ /**
17
+ * The id of the page in the admin menu.
18
+ *
19
+ * Mainly used to navigate between pages.
20
+ * @see FactoryPages407_AdminPage
21
+ *
22
+ * @since 1.0.0
23
+ * @var string
24
+ */
25
+ public $id = "ga_cache";
26
+ public $page_menu_dashicon = 'dashicons-testimonial';
27
+
28
+ /**
29
+ * @param Wbcr_Factory406_Plugin $plugin
30
+ */
31
+ public function __construct(Wbcr_Factory406_Plugin $plugin)
32
+ {
33
+ $this->menu_title = __('Local Google Analytics', 'simple-google-analytics');
34
+
35
+ if( !defined('LOADING_GA_CACHE_AS_ADDON') ) {
36
+ $this->internal = false;
37
+ $this->menu_target = 'options-general.php';
38
+ $this->add_link_to_plugin_actions = true;
39
+ }
40
+
41
+ parent::__construct($plugin);
42
+
43
+ $this->plugin = $plugin;
44
+ }
45
+
46
+ public function getMenuTitle()
47
+ {
48
+ return defined('LOADING_GA_CACHE_AS_ADDON')
49
+ ? __('Google Analytics Cache', 'simple-google-analytics')
50
+ : __('General', 'simple-google-analytics');
51
+ }
52
+
53
+ /**
54
+ * Requests assets (js and css) for the page.
55
+ *
56
+ * @see Wbcr_FactoryPages407_AdminPage
57
+ *
58
+ * @since 1.0.0
59
+ * @return void
60
+ */
61
+ public function assets($scripts, $styles)
62
+ {
63
+ parent::assets($scripts, $styles);
64
+
65
+ // Add Clearfy styles for HMWP pages
66
+ if( defined('WBCR_CLEARFY_PLUGIN_ACTIVE') ) {
67
+ $this->styles->add(WCL_PLUGIN_URL . '/admin/assets/css/general.css');
68
+ }
69
+ }
70
+
71
+
72
+ /**
73
+ * Permalinks options.
74
+ *
75
+ * @since 1.0.0
76
+ * @return mixed[]
77
+ */
78
+ public function getOptions()
79
+ {
80
+ $options = wbcr_ga_get_plugin_options();
81
+
82
+ $formOptions = array();
83
+
84
+ $formOptions[] = array(
85
+ 'type' => 'form-group',
86
+ 'items' => $options,
87
+ //'cssClass' => 'postbox'
88
+ );
89
+
90
+ return apply_filters('wbcr_ga_notices_form_options', $formOptions, $this);
91
+ }
92
+ }
components/{hide-login-page → ga-cache/admin/pages}/index.php RENAMED
File without changes
components/{hide-login-page → ga-cache}/admin/pages/more-features.php RENAMED
@@ -11,6 +11,6 @@
11
  exit;
12
  }
13
 
14
- class WHLP_MoreFeaturesPage extends Wbcr_FactoryClearfy200_MoreFeaturesPage {
15
 
16
  }
11
  exit;
12
  }
13
 
14
+ class WGA_MoreFeaturesPage extends Wbcr_FactoryClearfy203_MoreFeaturesPage {
15
 
16
  }
components/ga-cache/cache/local-ga.js ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (function(){var $c=function(a){this.w=a||[]};$c.prototype.set=function(a){this.w[a]=!0};$c.prototype.encode=function(){for(var a=[],b=0;b<this.w.length;b++)this.w[b]&&(a[Math.floor(b/6)]^=1<<b%6);for(b=0;b<a.length;b++)a[b]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".charAt(a[b]||0);return a.join("")+"~"};var vd=new $c;function J(a){vd.set(a)}var Td=function(a){a=Dd(a);a=new $c(a);for(var b=vd.w.slice(),c=0;c<a.w.length;c++)b[c]=b[c]||a.w[c];return(new $c(b)).encode()},Dd=function(a){a=a.get(Gd);ka(a)||(a=[]);return a};var ea=function(a){return"function"==typeof a},ka=function(a){return"[object Array]"==Object.prototype.toString.call(Object(a))},qa=function(a){return void 0!=a&&-1<(a.constructor+"").indexOf("String")},D=function(a,b){return 0==a.indexOf(b)},sa=function(a){return a?a.replace(/^[\s\xa0]+|[\s\xa0]+$/g,""):""},ra=function(){for(var a=O.navigator.userAgent+(M.cookie?M.cookie:"")+(M.referrer?M.referrer:""),b=a.length,c=O.history.length;0<c;)a+=c--^b++;return[hd()^La(a)&2147483647,Math.round((new Date).getTime()/
2
+ 1E3)].join(".")},ta=function(a){var b=M.createElement("img");b.width=1;b.height=1;b.src=a;return b},ua=function(){},K=function(a){if(encodeURIComponent instanceof Function)return encodeURIComponent(a);J(28);return a},L=function(a,b,c,d){try{a.addEventListener?a.addEventListener(b,c,!!d):a.attachEvent&&a.attachEvent("on"+b,c)}catch(e){J(27)}},f=/^[\w\-:/.?=&%!]+$/,wa=function(a,b,c){a&&(c?(c="",b&&f.test(b)&&(c=' id="'+b+'"'),f.test(a)&&M.write("<script"+c+' src="'+a+'">\x3c/script>')):(c=M.createElement("script"),
3
+ c.type="text/javascript",c.async=!0,c.src=a,b&&(c.id=b),a=M.getElementsByTagName("script")[0],a.parentNode.insertBefore(c,a)))},be=function(a,b){return E(M.location[b?"href":"search"],a)},E=function(a,b){return(a=a.match("(?:&|#|\\?)"+K(b).replace(/([.*+?^=!:${}()|\[\]\/\\])/g,"\\$1")+"=([^&#]*)"))&&2==a.length?a[1]:""},xa=function(){var a=""+M.location.hostname;return 0==a.indexOf("www.")?a.substring(4):a},de=function(a,b){var c=a.indexOf(b);if(5==c||6==c)if(a=a.charAt(c+b.length),"/"==a||"?"==a||
4
+ ""==a||":"==a)return!0;return!1},ya=function(a,b){var c=M.referrer;if(/^(https?|android-app):\/\//i.test(c)){if(a)return c;a="//"+M.location.hostname;if(!de(c,a))return b&&(b=a.replace(/\./g,"-")+".cdn.ampproject.org",de(c,b))?void 0:c}},za=function(a,b){if(1==b.length&&null!=b[0]&&"object"===typeof b[0])return b[0];for(var c={},d=Math.min(a.length+1,b.length),e=0;e<d;e++)if("object"===typeof b[e]){for(var g in b[e])b[e].hasOwnProperty(g)&&(c[g]=b[e][g]);break}else e<a.length&&(c[a[e]]=b[e]);return c};var ee=function(){this.keys=[];this.values={};this.m={}};ee.prototype.set=function(a,b,c){this.keys.push(a);c?this.m[":"+a]=b:this.values[":"+a]=b};ee.prototype.get=function(a){return this.m.hasOwnProperty(":"+a)?this.m[":"+a]:this.values[":"+a]};ee.prototype.map=function(a){for(var b=0;b<this.keys.length;b++){var c=this.keys[b],d=this.get(c);d&&a(c,d)}};var O=window,M=document,va=function(a,b){return setTimeout(a,b)};var F=window,Ea=document,G=function(a){var b=F._gaUserPrefs;if(b&&b.ioo&&b.ioo()||a&&!0===F["ga-disable-"+a])return!0;try{var c=F.external;if(c&&c._gaUserPrefs&&"oo"==c._gaUserPrefs)return!0}catch(g){}a=[];b=Ea.cookie.split(";");c=/^\s*AMP_TOKEN=\s*(.*?)\s*$/;for(var d=0;d<b.length;d++){var e=b[d].match(c);e&&a.push(e[1])}for(b=0;b<a.length;b++)if("$OPT_OUT"==decodeURIComponent(a[b]))return!0;return!1};var Ca=function(a){var b=[],c=M.cookie.split(";");a=new RegExp("^\\s*"+a+"=\\s*(.*?)\\s*$");for(var d=0;d<c.length;d++){var e=c[d].match(a);e&&b.push(e[1])}return b},zc=function(a,b,c,d,e,g){e=G(e)?!1:eb.test(M.location.hostname)||"/"==c&&vc.test(d)?!1:!0;if(!e)return!1;b&&1200<b.length&&(b=b.substring(0,1200));c=a+"="+b+"; path="+c+"; ";g&&(c+="expires="+(new Date((new Date).getTime()+g)).toGMTString()+"; ");d&&"none"!==d&&(c+="domain="+d+";");d=M.cookie;M.cookie=c;if(!(d=d!=M.cookie))a:{a=Ca(a);
5
+ for(d=0;d<a.length;d++)if(b==a[d]){d=!0;break a}d=!1}return d},Cc=function(a){return encodeURIComponent?encodeURIComponent(a).replace(/\(/g,"%28").replace(/\)/g,"%29"):a},vc=/^(www\.)?google(\.com?)?(\.[a-z]{2})?$/,eb=/(^|\.)doubleclick\.net$/i;var oc,Id=/^.*Version\/?(\d+)[^\d].*$/i,ne=function(){if(void 0!==O.__ga4__)return O.__ga4__;if(void 0===oc){var a=O.navigator.userAgent;if(a){var b=a;try{b=decodeURIComponent(a)}catch(c){}if(a=!(0<=b.indexOf("Chrome"))&&!(0<=b.indexOf("CriOS"))&&(0<=b.indexOf("Safari/")||0<=b.indexOf("Safari,")))b=Id.exec(b),a=11<=(b?Number(b[1]):-1);oc=a}else oc=!1}return oc};var Fa,Ga,fb,Ab,ja=/^https?:\/\/[^/]*cdn\.ampproject\.org\//,Ub=[],ic=function(){Z.D([ua])},tc=function(a,b){var c=Ca("AMP_TOKEN");if(1<c.length)return J(55),!1;c=decodeURIComponent(c[0]||"");if("$OPT_OUT"==c||"$ERROR"==c||G(b))return J(62),!1;if(!ja.test(M.referrer)&&"$NOT_FOUND"==c)return J(68),!1;if(void 0!==Ab)return J(56),va(function(){a(Ab)},0),!0;if(Fa)return Ub.push(a),!0;if("$RETRIEVING"==c)return J(57),va(function(){tc(a,b)},1E4),!0;Fa=!0;c&&"$"!=c[0]||(xc("$RETRIEVING",3E4),setTimeout(Mc,
6
+ 3E4),c="");return Pc(c,b)?(Ub.push(a),!0):!1},Pc=function(a,b,c){if(!window.JSON)return J(58),!1;var d=O.XMLHttpRequest;if(!d)return J(59),!1;var e=new d;if(!("withCredentials"in e))return J(60),!1;e.open("POST",(c||"https://ampcid.google.com/v1/publisher:getClientId")+"?key=AIzaSyA65lEHUEizIsNtlbNo-l2K18dT680nsaM",!0);e.withCredentials=!0;e.setRequestHeader("Content-Type","text/plain");e.onload=function(){Fa=!1;if(4==e.readyState){try{200!=e.status&&(J(61),Qc("","$ERROR",3E4));var d=JSON.parse(e.responseText);
7
+ d.optOut?(J(63),Qc("","$OPT_OUT",31536E6)):d.clientId?Qc(d.clientId,d.securityToken,31536E6):!c&&d.alternateUrl?(Ga&&clearTimeout(Ga),Fa=!0,Pc(a,b,d.alternateUrl)):(J(64),Qc("","$NOT_FOUND",36E5))}catch(ca){J(65),Qc("","$ERROR",3E4)}e=null}};d={originScope:"AMP_ECID_GOOGLE"};a&&(d.securityToken=a);e.send(JSON.stringify(d));Ga=va(function(){J(66);Qc("","$ERROR",3E4)},1E4);return!0},Mc=function(){Fa=!1},xc=function(a,b){if(void 0===fb){fb="";for(var c=id(),d=0;d<c.length;d++){var e=c[d];if(zc("AMP_TOKEN",
8
+ encodeURIComponent(a),"/",e,"",b)){fb=e;return}}}zc("AMP_TOKEN",encodeURIComponent(a),"/",fb,"",b)},Qc=function(a,b,c){Ga&&clearTimeout(Ga);b&&xc(b,c);Ab=a;b=Ub;Ub=[];for(c=0;c<b.length;c++)b[c](a)};var oe=function(){return(Ba||"https:"==M.location.protocol?"https:":"http:")+"//www.google-analytics.com"},Da=function(a){this.name="len";this.message=a+"-8192"},ba=function(a,b,c){c=c||ua;if(2036>=b.length)wc(a,b,c);else if(8192>=b.length)x(a,b,c)||wd(a,b,c)||wc(a,b,c);else throw ge("len",b.length),new Da(b.length);},pe=function(a,b,c,d){d=d||ua;wd(a+"?"+b,"",d,c)},wc=function(a,b,c){var d=ta(a+"?"+b);d.onload=d.onerror=function(){d.onload=null;d.onerror=null;c()}},wd=function(a,b,c,d){var e=O.XMLHttpRequest;
9
+ if(!e)return!1;var g=new e;if(!("withCredentials"in g))return!1;a=a.replace(/^http:/,"https:");g.open("POST",a,!0);g.withCredentials=!0;g.setRequestHeader("Content-Type","text/plain");g.onreadystatechange=function(){if(4==g.readyState){if(d)try{var a=g.responseText;if(1>a.length)ge("xhr","ver","0"),c();else if("1"!=a.charAt(0))ge("xhr","ver",String(a.length)),c();else if(3<d.count++)ge("xhr","tmr",""+d.count),c();else if(1==a.length)c();else{var b=a.charAt(1);if("d"==b)pe("https://stats.g.doubleclick.net/j/collect",
10
+ d.U,d,c);else if("g"==b){var e="https://www.google.%/ads/ga-audiences".replace("%","com");wc(e,d.google,c);var w=a.substring(2);if(w)if(/^[a-z.]{1,6}$/.test(w)){var ha="https://www.google.%/ads/ga-audiences".replace("%",w);wc(ha,d.google,ua)}else ge("tld","bcc",w)}else ge("xhr","brc",b),c()}}catch(ue){ge("xhr","rsp"),c()}else c();g=null}};g.send(b);return!0},x=function(a,b,c){return O.navigator.sendBeacon?O.navigator.sendBeacon(a,b)?(c(),!0):!1:!1},ge=function(a,b,c){1<=100*Math.random()||G("?")||
11
+ (a=["t=error","_e="+a,"_v=j68","sr=1"],b&&a.push("_f="+b),c&&a.push("_m="+K(c.substring(0,100))),a.push("aip=1"),a.push("z="+hd()),wc("https://www.google-analytics.com/u/d",a.join("&"),ua))};var h=function(a){var b=O.gaData=O.gaData||{};return b[a]=b[a]||{}};var Ha=function(){this.M=[]};Ha.prototype.add=function(a){this.M.push(a)};Ha.prototype.D=function(a){try{for(var b=0;b<this.M.length;b++){var c=a.get(this.M[b]);c&&ea(c)&&c.call(O,a)}}catch(d){}b=a.get(Ia);b!=ua&&ea(b)&&(a.set(Ia,ua,!0),setTimeout(b,10))};function Ja(a){if(100!=a.get(Ka)&&La(P(a,Q))%1E4>=100*R(a,Ka))throw"abort";}function Ma(a){if(G(P(a,Na)))throw"abort";}function Oa(){var a=M.location.protocol;if("http:"!=a&&"https:"!=a)throw"abort";}
12
+ function Pa(a){try{O.navigator.sendBeacon?J(42):O.XMLHttpRequest&&"withCredentials"in new O.XMLHttpRequest&&J(40)}catch(c){}a.set(ld,Td(a),!0);a.set(Ac,R(a,Ac)+1);var b=[];Qa.map(function(c,d){d.F&&(c=a.get(c),void 0!=c&&c!=d.defaultValue&&("boolean"==typeof c&&(c*=1),b.push(d.F+"="+K(""+c))))});b.push("z="+Bd());a.set(Ra,b.join("&"),!0)}
13
+ function Sa(a){var b=P(a,gd)||oe()+"/collect",c=a.get(qe),d=P(a,fa);!d&&a.get(Vd)&&(d="beacon");if(c)pe(b,P(a,Ra),c,a.get(Ia));else if(d){c=d;d=P(a,Ra);var e=a.get(Ia);e=e||ua;"image"==c?wc(b,d,e):"xhr"==c&&wd(b,d,e)||"beacon"==c&&x(b,d,e)||ba(b,d,e)}else ba(b,P(a,Ra),a.get(Ia));b=a.get(Na);b=h(b);c=b.hitcount;b.hitcount=c?c+1:1;b=a.get(Na);delete h(b).pending_experiments;a.set(Ia,ua,!0)}
14
+ function Hc(a){(O.gaData=O.gaData||{}).expId&&a.set(Nc,(O.gaData=O.gaData||{}).expId);(O.gaData=O.gaData||{}).expVar&&a.set(Oc,(O.gaData=O.gaData||{}).expVar);var b=a.get(Na);if(b=h(b).pending_experiments){var c=[];for(d in b)b.hasOwnProperty(d)&&b[d]&&c.push(encodeURIComponent(d)+"."+encodeURIComponent(b[d]));var d=c.join("!")}else d=void 0;d&&a.set(m,d,!0)}function cd(){if(O.navigator&&"preview"==O.navigator.loadPurpose)throw"abort";}
15
+ function yd(a){var b=O.gaDevIds;ka(b)&&0!=b.length&&a.set("&did",b.join(","),!0)}function vb(a){if(!a.get(Na))throw"abort";};var hd=function(){return Math.round(2147483647*Math.random())},Bd=function(){try{var a=new Uint32Array(1);O.crypto.getRandomValues(a);return a[0]&2147483647}catch(b){return hd()}};function Ta(a){var b=R(a,Ua);500<=b&&J(15);var c=P(a,Va);if("transaction"!=c&&"item"!=c){c=R(a,Wa);var d=(new Date).getTime(),e=R(a,Xa);0==e&&a.set(Xa,d);e=Math.round(2*(d-e)/1E3);0<e&&(c=Math.min(c+e,20),a.set(Xa,d));if(0>=c)throw"abort";a.set(Wa,--c)}a.set(Ua,++b)};var Ya=function(){this.data=new ee},Qa=new ee,Za=[];Ya.prototype.get=function(a){var b=$a(a),c=this.data.get(a);b&&void 0==c&&(c=ea(b.defaultValue)?b.defaultValue():b.defaultValue);return b&&b.Z?b.Z(this,a,c):c};var P=function(a,b){a=a.get(b);return void 0==a?"":""+a},R=function(a,b){a=a.get(b);return void 0==a||""===a?0:1*a};Ya.prototype.set=function(a,b,c){if(a)if("object"==typeof a)for(var d in a)a.hasOwnProperty(d)&&ab(this,d,a[d],c);else ab(this,a,b,c)};
16
+ var ab=function(a,b,c,d){if(void 0!=c)switch(b){case Na:wb.test(c)}var e=$a(b);e&&e.o?e.o(a,b,c,d):a.data.set(b,c,d)},bb=function(a,b,c,d,e){this.name=a;this.F=b;this.Z=d;this.o=e;this.defaultValue=c},$a=function(a){var b=Qa.get(a);if(!b)for(var c=0;c<Za.length;c++){var d=Za[c],e=d[0].exec(a);if(e){b=d[1](e);Qa.set(b.name,b);break}}return b},yc=function(a){var b;Qa.map(function(c,d){d.F==a&&(b=d)});return b&&b.name},S=function(a,b,c,d,e){a=new bb(a,b,c,d,e);Qa.set(a.name,a);return a.name},cb=function(a,
17
+ b){Za.push([new RegExp("^"+a+"$"),b])},T=function(a,b,c){return S(a,b,c,void 0,db)},db=function(){};var gb=qa(window.GoogleAnalyticsObject)&&sa(window.GoogleAnalyticsObject)||"ga",jd=/^(?:utma\.)?\d+\.\d+$/,kd=/^amp-[\w.-]{22,64}$/,Ba=!1,hb=T("apiVersion","v"),ib=T("clientVersion","_v");S("anonymizeIp","aip");var jb=S("adSenseId","a"),Va=S("hitType","t"),Ia=S("hitCallback"),Ra=S("hitPayload");S("nonInteraction","ni");S("currencyCode","cu");S("dataSource","ds");var Vd=S("useBeacon",void 0,!1),fa=S("transport");S("sessionControl","sc","");S("sessionGroup","sg");S("queueTime","qt");var Ac=S("_s","_s");
18
+ S("screenName","cd");var kb=S("location","dl",""),lb=S("referrer","dr"),mb=S("page","dp","");S("hostname","dh");var nb=S("language","ul"),ob=S("encoding","de");S("title","dt",function(){return M.title||void 0});cb("contentGroup([0-9]+)",function(a){return new bb(a[0],"cg"+a[1])});var pb=S("screenColors","sd"),qb=S("screenResolution","sr"),rb=S("viewportSize","vp"),sb=S("javaEnabled","je"),tb=S("flashVersion","fl");S("campaignId","ci");S("campaignName","cn");S("campaignSource","cs");
19
+ S("campaignMedium","cm");S("campaignKeyword","ck");S("campaignContent","cc");var ub=S("eventCategory","ec"),xb=S("eventAction","ea"),yb=S("eventLabel","el"),zb=S("eventValue","ev"),Bb=S("socialNetwork","sn"),Cb=S("socialAction","sa"),Db=S("socialTarget","st"),Eb=S("l1","plt"),Fb=S("l2","pdt"),Gb=S("l3","dns"),Hb=S("l4","rrt"),Ib=S("l5","srt"),Jb=S("l6","tcp"),Kb=S("l7","dit"),Lb=S("l8","clt"),Mb=S("timingCategory","utc"),Nb=S("timingVar","utv"),Ob=S("timingLabel","utl"),Pb=S("timingValue","utt");
20
+ S("appName","an");S("appVersion","av","");S("appId","aid","");S("appInstallerId","aiid","");S("exDescription","exd");S("exFatal","exf");var Nc=S("expId","xid"),Oc=S("expVar","xvar"),m=S("exp","exp"),Rc=S("_utma","_utma"),Sc=S("_utmz","_utmz"),Tc=S("_utmht","_utmht"),Ua=S("_hc",void 0,0),Xa=S("_ti",void 0,0),Wa=S("_to",void 0,20);cb("dimension([0-9]+)",function(a){return new bb(a[0],"cd"+a[1])});cb("metric([0-9]+)",function(a){return new bb(a[0],"cm"+a[1])});S("linkerParam",void 0,void 0,Bc,db);
21
+ var ld=S("usage","_u"),Gd=S("_um");S("forceSSL",void 0,void 0,function(){return Ba},function(a,b,c){J(34);Ba=!!c});var ed=S("_j1","jid"),ia=S("_j2","gjid");cb("\\&(.*)",function(a){var b=new bb(a[0],a[1]),c=yc(a[0].substring(1));c&&(b.Z=function(a){return a.get(c)},b.o=function(a,b,g,ca){a.set(c,g,ca)},b.F=void 0);return b});
22
+ var Qb=T("_oot"),dd=S("previewTask"),Rb=S("checkProtocolTask"),md=S("validationTask"),Sb=S("checkStorageTask"),Uc=S("historyImportTask"),Tb=S("samplerTask"),Vb=S("_rlt"),Wb=S("buildHitTask"),Xb=S("sendHitTask"),Vc=S("ceTask"),zd=S("devIdTask"),Cd=S("timingTask"),Ld=S("displayFeaturesTask"),oa=S("customTask"),V=T("name"),Q=T("clientId","cid"),n=T("clientIdTime"),xd=T("storedClientId"),Ad=S("userId","uid"),Na=T("trackingId","tid"),U=T("cookieName",void 0,"_ga"),W=T("cookieDomain"),Yb=T("cookiePath",
23
+ void 0,"/"),Zb=T("cookieExpires",void 0,63072E3),Hd=T("cookieUpdate",void 0,!0),$b=T("legacyCookieDomain"),Wc=T("legacyHistoryImport",void 0,!0),ac=T("storage",void 0,"cookie"),bc=T("allowLinker",void 0,!1),cc=T("allowAnchor",void 0,!0),Ka=T("sampleRate","sf",100),dc=T("siteSpeedSampleRate",void 0,1),ec=T("alwaysSendReferrer",void 0,!1),I=T("_gid","_gid"),la=T("_gcn"),Kd=T("useAmpClientId"),ce=T("_gclid"),fe=T("_gt"),he=T("_ge",void 0,7776E6),ie=T("_gclsrc"),je=T("storeGac",void 0,!0),gd=S("transportUrl"),
24
+ Md=S("_r","_r"),qe=S("_dp"),Ud=S("allowAdFeatures",void 0,!0);function X(a,b,c,d){b[a]=function(){try{return d&&J(d),c.apply(this,arguments)}catch(e){throw ge("exc",a,e&&e.name),e;}}};var Od=function(){this.V=100;this.$=this.fa=!1;this.oa="detourexp";this.groups=1},Ed=function(a){var b=new Od,c;if(b.fa&&b.$)return 0;b.$=!0;if(a){if(b.oa&&void 0!==a.get(b.oa))return R(a,b.oa);if(0==a.get(dc))return 0}if(0==b.V)return 0;void 0===c&&(c=Bd());return 0==c%b.V?Math.floor(c/b.V)%b.groups+1:0};function fc(){var a,b;if((b=(b=O.navigator)?b.plugins:null)&&b.length)for(var c=0;c<b.length&&!a;c++){var d=b[c];-1<d.name.indexOf("Shockwave Flash")&&(a=d.description)}if(!a)try{var e=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");a=e.GetVariable("$version")}catch(g){}if(!a)try{e=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6"),a="WIN 6,0,21,0",e.AllowScriptAccess="always",a=e.GetVariable("$version")}catch(g){}if(!a)try{e=new ActiveXObject("ShockwaveFlash.ShockwaveFlash"),a=e.GetVariable("$version")}catch(g){}a&&
25
+ (e=a.match(/[\d]+/g))&&3<=e.length&&(a=e[0]+"."+e[1]+" r"+e[2]);return a||void 0};var aa=function(a){var b=Math.min(R(a,dc),100);return La(P(a,Q))%100>=b?!1:!0},gc=function(a){var b={};if(Ec(b)||Fc(b)){var c=b[Eb];void 0==c||Infinity==c||isNaN(c)||(0<c?(Y(b,Gb),Y(b,Jb),Y(b,Ib),Y(b,Fb),Y(b,Hb),Y(b,Kb),Y(b,Lb),va(function(){a(b)},10)):L(O,"load",function(){gc(a)},!1))}},Ec=function(a){var b=O.performance||O.webkitPerformance;b=b&&b.timing;if(!b)return!1;var c=b.navigationStart;if(0==c)return!1;a[Eb]=b.loadEventStart-c;a[Gb]=b.domainLookupEnd-b.domainLookupStart;a[Jb]=b.connectEnd-
26
+ b.connectStart;a[Ib]=b.responseStart-b.requestStart;a[Fb]=b.responseEnd-b.responseStart;a[Hb]=b.fetchStart-c;a[Kb]=b.domInteractive-c;a[Lb]=b.domContentLoadedEventStart-c;return!0},Fc=function(a){if(O.top!=O)return!1;var b=O.external,c=b&&b.onloadT;b&&!b.isValidLoadTime&&(c=void 0);2147483648<c&&(c=void 0);0<c&&b.setPageReadyTime();if(void 0==c)return!1;a[Eb]=c;return!0},Y=function(a,b){var c=a[b];if(isNaN(c)||Infinity==c||0>c)a[b]=void 0},Fd=function(a){return function(b){if("pageview"==b.get(Va)&&
27
+ !a.I){a.I=!0;var c=aa(b),d=0<E(b.get(kb),"gclid").length;(c||d)&&gc(function(b){c&&a.send("timing",b);d&&a.send("adtiming",b)})}}};var hc=!1,mc=function(a){if("cookie"==P(a,ac)){if(a.get(Hd)||P(a,xd)!=P(a,Q)){var b=1E3*R(a,Zb);ma(a,Q,U,b)}ma(a,I,la,864E5);if(a.get(je)){var c=a.get(ce);if(c){var d=Math.min(R(a,he),1E3*R(a,Zb));d=Math.min(d,1E3*R(a,fe)+d-(new Date).getTime());a.data.set(he,d);b={};var e=a.get(fe),g=a.get(ie),ca=kc(P(a,Yb)),l=lc(P(a,W)),k=P(a,Na);g&&"aw.ds"!=g?b&&(b.ua=!0):(c=["1",e,Cc(c)].join("."),0<d&&(b&&(b.ta=!0),zc("_gac_"+Cc(k),c,ca,l,k,d)));le(b)}}else J(75);if(a="none"===lc(P(a,W)))a=M.location.hostname,
28
+ a=eb.test(a)||vc.test(a);a&&J(30)}},ma=function(a,b,c,d){var e=nd(a,b);if(e){c=P(a,c);var g=kc(P(a,Yb)),ca=lc(P(a,W)),l=P(a,Na);if("auto"!=ca)zc(c,e,g,ca,l,d)&&(hc=!0);else{J(32);for(var k=id(),w=0;w<k.length;w++)if(ca=k[w],a.data.set(W,ca),e=nd(a,b),zc(c,e,g,ca,l,d)){hc=!0;return}a.data.set(W,"auto")}}},nc=function(a){if("cookie"==P(a,ac)&&!hc&&(mc(a),!hc))throw"abort";},Yc=function(a){if(a.get(Wc)){var b=P(a,W),c=P(a,$b)||xa(),d=Xc("__utma",c,b);d&&(J(19),a.set(Tc,(new Date).getTime(),!0),a.set(Rc,
29
+ d.R),(b=Xc("__utmz",c,b))&&d.hash==b.hash&&a.set(Sc,b.R))}},nd=function(a,b){b=Cc(P(a,b));var c=lc(P(a,W)).split(".").length;a=jc(P(a,Yb));1<a&&(c+="-"+a);return b?["GA1",c,b].join("."):""},Xd=function(a,b){return na(b,P(a,W),P(a,Yb))},na=function(a,b,c){if(!a||1>a.length)J(12);else{for(var d=[],e=0;e<a.length;e++){var g=a[e];var ca=g.split(".");var l=ca.shift();("GA1"==l||"1"==l)&&1<ca.length?(g=ca.shift().split("-"),1==g.length&&(g[1]="1"),g[0]*=1,g[1]*=1,ca={H:g,s:ca.join(".")}):ca=kd.test(g)?
30
+ {H:[0,0],s:g}:void 0;ca&&d.push(ca)}if(1==d.length)return J(13),d[0].s;if(0==d.length)J(12);else{J(14);d=Gc(d,lc(b).split(".").length,0);if(1==d.length)return d[0].s;d=Gc(d,jc(c),1);1<d.length&&J(41);return d[0]&&d[0].s}}},Gc=function(a,b,c){for(var d=[],e=[],g,ca=0;ca<a.length;ca++){var l=a[ca];l.H[c]==b?d.push(l):void 0==g||l.H[c]<g?(e=[l],g=l.H[c]):l.H[c]==g&&e.push(l)}return 0<d.length?d:e},lc=function(a){return 0==a.indexOf(".")?a.substr(1):a},id=function(){var a=[],b=xa().split(".");if(4==b.length){var c=
31
+ b[b.length-1];if(parseInt(c,10)==c)return["none"]}for(c=b.length-2;0<=c;c--)a.push(b.slice(c).join("."));a.push("none");return a},kc=function(a){if(!a)return"/";1<a.length&&a.lastIndexOf("/")==a.length-1&&(a=a.substr(0,a.length-1));0!=a.indexOf("/")&&(a="/"+a);return a},jc=function(a){a=kc(a);return"/"==a?1:a.split("/").length},le=function(a){a.ta&&J(77);a.na&&J(74);a.pa&&J(73);a.ua&&J(69)};function Xc(a,b,c){"none"==b&&(b="");var d=[],e=Ca(a);a="__utma"==a?6:2;for(var g=0;g<e.length;g++){var ca=(""+e[g]).split(".");ca.length>=a&&d.push({hash:ca[0],R:e[g],O:ca})}if(0!=d.length)return 1==d.length?d[0]:Zc(b,d)||Zc(c,d)||Zc(null,d)||d[0]}function Zc(a,b){if(null==a)var c=a=1;else c=La(a),a=La(D(a,".")?a.substring(1):"."+a);for(var d=0;d<b.length;d++)if(b[d].hash==c||b[d].hash==a)return b[d]};var od=new RegExp(/^https?:\/\/([^\/:]+)/),pd=/(.*)([?&#])(?:_ga=[^&#]*)(?:&?)(.*)/,me=/(.*)([?&#])(?:_gac=[^&#]*)(?:&?)(.*)/;function Bc(a){var b=a.get(Q),c=a.get(I)||"";b="_ga=2."+K(pa(c+b,0)+"."+c+"-"+b);if((c=a.get(ce))&&a.get(je)){var d=R(a,fe);1E3*d+R(a,he)<=(new Date).getTime()?(J(76),a=""):(J(44),a="&_gac=1."+K([pa(c,0),d,c].join(".")))}else a="";return b+a}
32
+ function Ic(a,b){var c=new Date,d=O.navigator,e=d.plugins||[];a=[a,d.userAgent,c.getTimezoneOffset(),c.getYear(),c.getDate(),c.getHours(),c.getMinutes()+b];for(b=0;b<e.length;++b)a.push(e[b].description);return La(a.join("."))}function pa(a,b){var c=new Date,d=O.navigator,e=c.getHours()+Math.floor((c.getMinutes()+b)/60);return La([a,d.userAgent,d.language||"",c.getTimezoneOffset(),c.getYear(),c.getDate()+Math.floor(e/24),(24+e)%24,(60+c.getMinutes()+b)%60].join("."))}
33
+ var Dc=function(a){J(48);this.target=a;this.T=!1};Dc.prototype.ca=function(a,b){if(a.tagName){if("a"==a.tagName.toLowerCase()){a.href&&(a.href=qd(this,a.href,b));return}if("form"==a.tagName.toLowerCase())return rd(this,a)}if("string"==typeof a)return qd(this,a,b)};
34
+ var qd=function(a,b,c){var d=pd.exec(b);d&&3<=d.length&&(b=d[1]+(d[3]?d[2]+d[3]:""));(d=me.exec(b))&&3<=d.length&&(b=d[1]+(d[3]?d[2]+d[3]:""));a=a.target.get("linkerParam");var e=b.indexOf("?");d=b.indexOf("#");c?b+=(-1==d?"#":"&")+a:(c=-1==e?"?":"&",b=-1==d?b+(c+a):b.substring(0,d)+c+a+b.substring(d));b=b.replace(/&+_ga=/,"&_ga=");return b=b.replace(/&+_gac=/,"&_gac=")},rd=function(a,b){if(b&&b.action)if("get"==b.method.toLowerCase()){a=a.target.get("linkerParam").split("&");for(var c=0;c<a.length;c++){var d=
35
+ a[c].split("="),e=d[1];d=d[0];for(var g=b.childNodes||[],ca=!1,l=0;l<g.length;l++)if(g[l].name==d){g[l].setAttribute("value",e);ca=!0;break}ca||(g=M.createElement("input"),g.setAttribute("type","hidden"),g.setAttribute("name",d),g.setAttribute("value",e),b.appendChild(g))}}else"post"==b.method.toLowerCase()&&(b.action=qd(a,b.action))};
36
+ Dc.prototype.S=function(a,b,c){function d(c){try{c=c||O.event;a:{var d=c.target||c.srcElement;for(c=100;d&&0<c;){if(d.href&&d.nodeName.match(/^a(?:rea)?$/i)){var g=d;break a}d=d.parentNode;c--}g={}}("http:"==g.protocol||"https:"==g.protocol)&&sd(a,g.hostname||"")&&g.href&&(g.href=qd(e,g.href,b))}catch(k){J(26)}}var e=this;this.T||(this.T=!0,L(M,"mousedown",d,!1),L(M,"keyup",d,!1));c&&L(M,"submit",function(b){b=b||O.event;if((b=b.target||b.srcElement)&&b.action){var c=b.action.match(od);c&&sd(a,c[1])&&
37
+ rd(e,b)}})};function sd(a,b){if(b==M.location.hostname)return!1;for(var c=0;c<a.length;c++)if(a[c]instanceof RegExp){if(a[c].test(b))return!0}else if(0<=b.indexOf(a[c]))return!0;return!1}function ke(a,b){return b!=Ic(a,0)&&b!=Ic(a,-1)&&b!=Ic(a,-2)&&b!=pa(a,0)&&b!=pa(a,-1)&&b!=pa(a,-2)};var p=/^(GTM|OPT)-[A-Z0-9]+$/,q=/;_gaexp=[^;]*/g,r=/;((__utma=)|([^;=]+=GAX?\d+\.))[^;]*/g,Aa=/^https?:\/\/[\w\-.]+\.google.com(:\d+)?\/optimize\/opt-launch\.html\?.*$/,t=function(a){function b(a,b){b&&(c+="&"+a+"="+K(b))}var c="https://www.google-analytics.com/gtm/js?id="+K(a.id);"dataLayer"!=a.B&&b("l",a.B);b("t",a.target);b("cid",a.clientId);b("cidt",a.ka);b("gac",a.la);b("aip",a.ia);a.sync&&b("m","sync");b("cycle",a.G);a.qa&&b("gclid",a.qa);Aa.test(M.referrer)&&b("cb",String(hd()));return c};var Jd=function(a,b,c){this.aa=b;(b=c)||(b=(b=P(a,V))&&"t0"!=b?Wd.test(b)?"_gat_"+Cc(P(a,Na)):"_gat_"+Cc(b):"_gat");this.Y=b;this.ra=null},Rd=function(a,b){var c=b.get(Wb);b.set(Wb,function(b){Pd(a,b,ed);Pd(a,b,ia);var d=c(b);Qd(a,b);return d});var d=b.get(Xb);b.set(Xb,function(b){var c=d(b);if(se(b)){if(ne()!==H(a,b)){J(80);var e={U:re(a,b,1),google:re(a,b,2),count:0};pe("https://stats.g.doubleclick.net/j/collect",e.U,e)}else ta(re(a,b,0));b.set(ed,"",!0)}return c})},Pd=function(a,b,c){!1===b.get(Ud)||
38
+ b.get(c)||("1"==Ca(a.Y)[0]?b.set(c,"",!0):b.set(c,""+hd(),!0))},Qd=function(a,b){se(b)&&zc(a.Y,"1",b.get(Yb),b.get(W),b.get(Na),6E4)},se=function(a){return!!a.get(ed)&&a.get(Ud)},re=function(a,b,c){var d=new ee,e=function(a){$a(a).F&&d.set($a(a).F,b.get(a))};e(hb);e(ib);e(Na);e(Q);e(ed);if(0==c||1==c)e(Ad),e(ia),e(I);d.set($a(ld).F,Td(b));var g="";d.map(function(a,b){g+=K(a)+"=";g+=K(""+b)+"&"});g+="z="+hd();0==c?g=a.aa+g:1==c?g="t=dc&aip=1&_r=3&"+g:2==c&&(g="t=sr&aip=1&_r=4&slf_rd=1&"+g);return g},
39
+ H=function(a,b){null===a.ra&&(a.ra=1===Ed(b),a.ra&&J(33));return a.ra},Wd=/^gtm\d+$/;var fd=function(a,b){a=a.b;if(!a.get("dcLoaded")){var c=new $c(Dd(a));c.set(29);a.set(Gd,c.w);b=b||{};var d;b[U]&&(d=Cc(b[U]));b=new Jd(a,"https://stats.g.doubleclick.net/r/collect?t=dc&aip=1&_r=3&",d);Rd(b,a);a.set("dcLoaded",!0)}};var Sd=function(a){if(!a.get("dcLoaded")&&"cookie"==a.get(ac)){var b=new Jd(a);Pd(b,a,ed);Pd(b,a,ia);Qd(b,a);if(se(a)){var c=ne()!==H(b,a);a.set(Md,1,!0);c?(J(79),a.set(gd,oe()+"/j/collect",!0),a.set(qe,{U:re(b,a,1),google:re(b,a,2),count:0},!0)):a.set(gd,oe()+"/r/collect",!0)}}};var Lc=function(){var a=O.gaGlobal=O.gaGlobal||{};return a.hid=a.hid||hd()};var ad,bd=function(a,b,c){if(!ad){var d=M.location.hash;var e=O.name,g=/^#?gaso=([^&]*)/;if(e=(d=(d=d&&d.match(g)||e&&e.match(g))?d[1]:Ca("GASO")[0]||"")&&d.match(/^(?:!([-0-9a-z.]{1,40})!)?([-.\w]{10,1200})$/i))zc("GASO",""+d,c,b,a,0),window._udo||(window._udo=b),window._utcp||(window._utcp=c),a=e[1],wa("https://www.google.com/analytics/web/inpage/pub/inpage.js?"+(a?"prefix="+a+"&":"")+hd(),"_gasojs");ad=!0}};var wb=/^(UA|YT|MO|GP)-(\d+)-(\d+)$/,pc=function(a){function b(a,b){d.b.data.set(a,b)}function c(a,c){b(a,c);d.filters.add(a)}var d=this;this.b=new Ya;this.filters=new Ha;b(V,a[V]);b(Na,sa(a[Na]));b(U,a[U]);b(W,a[W]||xa());b(Yb,a[Yb]);b(Zb,a[Zb]);b(Hd,a[Hd]);b($b,a[$b]);b(Wc,a[Wc]);b(bc,a[bc]);b(cc,a[cc]);b(Ka,a[Ka]);b(dc,a[dc]);b(ec,a[ec]);b(ac,a[ac]);b(Ad,a[Ad]);b(n,a[n]);b(Kd,a[Kd]);b(je,a[je]);b(hb,1);b(ib,"j68");c(Qb,Ma);c(oa,ua);c(dd,cd);c(Rb,Oa);c(md,vb);c(Sb,nc);c(Uc,Yc);c(Tb,Ja);c(Vb,Ta);
40
+ c(Vc,Hc);c(zd,yd);c(Ld,Sd);c(Wb,Pa);c(Xb,Sa);c(Cd,Fd(this));Kc(this.b);Jc(this.b,a[Q]);this.b.set(jb,Lc());bd(this.b.get(Na),this.b.get(W),this.b.get(Yb))},Jc=function(a,b){var c=P(a,U);a.data.set(la,"_ga"==c?"_gid":c+"_gid");if("cookie"==P(a,ac)){hc=!1;c=Ca(P(a,U));c=Xd(a,c);if(!c){c=P(a,W);var d=P(a,$b)||xa();c=Xc("__utma",d,c);void 0!=c?(J(10),c=c.O[1]+"."+c.O[2]):c=void 0}c&&(hc=!0);if(d=c&&!a.get(Hd))if(d=c.split("."),2!=d.length)d=!1;else if(d=Number(d[1])){var e=R(a,Zb);d=d+e<(new Date).getTime()/
41
+ 1E3}else d=!1;d&&(c=void 0);c&&(a.data.set(xd,c),a.data.set(Q,c),c=Ca(P(a,la)),(c=Xd(a,c))&&a.data.set(I,c));if(a.get(je)&&(c=a.get(ce),d=a.get(ie),!c||d&&"aw.ds"!=d)){c={};if(M){d=[];e=M.cookie.split(";");for(var g=/^\s*_gac_(UA-\d+-\d+)=\s*(.+?)\s*$/,ca=0;ca<e.length;ca++){var l=e[ca].match(g);l&&d.push({ja:l[1],value:l[2]})}e={};if(d&&d.length)for(g=0;g<d.length;g++)(ca=d[g].value.split("."),"1"!=ca[0]||3!=ca.length)?c&&(c.na=!0):ca[1]&&(e[d[g].ja]?c&&(c.pa=!0):e[d[g].ja]=[],e[d[g].ja].push({timestamp:ca[1],
42
+ qa:ca[2]}));d=e}else d={};d=d[P(a,Na)];le(c);d&&0!=d.length&&(c=d[0],a.data.set(fe,c.timestamp),a.data.set(ce,c.qa))}}if(a.get(Hd))a:if(d=be("_ga",a.get(cc)))if(a.get(bc))if(c=d.indexOf("."),-1==c)J(22);else{e=d.substring(0,c);g=d.substring(c+1);c=g.indexOf(".");d=g.substring(0,c);g=g.substring(c+1);if("1"==e){if(c=g,ke(c,d)){J(23);break a}}else if("2"==e){c=g.indexOf("-");e="";0<c?(e=g.substring(0,c),c=g.substring(c+1)):c=g.substring(1);if(ke(e+c,d)){J(53);break a}e&&(J(2),a.data.set(I,e))}else{J(22);
43
+ break a}J(11);a.data.set(Q,c);if(c=be("_gac",a.get(cc)))c=c.split("."),"1"!=c[0]||4!=c.length?J(72):ke(c[3],c[1])?J(71):(a.data.set(ce,c[3]),a.data.set(fe,c[2]),J(70))}else J(21);b&&(J(9),a.data.set(Q,K(b)));a.get(Q)||((b=(b=O.gaGlobal&&O.gaGlobal.vid)&&-1!=b.search(jd)?b:void 0)?(J(17),a.data.set(Q,b)):(J(8),a.data.set(Q,ra())));a.get(I)||(J(3),a.data.set(I,ra()));mc(a)},Kc=function(a){var b=O.navigator,c=O.screen,d=M.location;a.set(lb,ya(a.get(ec),a.get(Kd)));if(d){var e=d.pathname||"";"/"!=e.charAt(0)&&
44
+ (J(31),e="/"+e);a.set(kb,d.protocol+"//"+d.hostname+e+d.search)}c&&a.set(qb,c.width+"x"+c.height);c&&a.set(pb,c.colorDepth+"-bit");c=M.documentElement;var g=(e=M.body)&&e.clientWidth&&e.clientHeight,ca=[];c&&c.clientWidth&&c.clientHeight&&("CSS1Compat"===M.compatMode||!g)?ca=[c.clientWidth,c.clientHeight]:g&&(ca=[e.clientWidth,e.clientHeight]);c=0>=ca[0]||0>=ca[1]?"":ca.join("x");a.set(rb,c);a.set(tb,fc());a.set(ob,M.characterSet||M.charset);a.set(sb,b&&"function"===typeof b.javaEnabled&&b.javaEnabled()||
45
+ !1);a.set(nb,(b&&(b.language||b.browserLanguage)||"").toLowerCase());a.data.set(ce,be("gclid",!0));a.data.set(ie,be("gclsrc",!0));a.data.set(fe,Math.round((new Date).getTime()/1E3));if(d&&a.get(cc)&&(b=M.location.hash)){b=b.split(/[?&#]+/);d=[];for(c=0;c<b.length;++c)(D(b[c],"utm_id")||D(b[c],"utm_campaign")||D(b[c],"utm_source")||D(b[c],"utm_medium")||D(b[c],"utm_term")||D(b[c],"utm_content")||D(b[c],"gclid")||D(b[c],"dclid")||D(b[c],"gclsrc"))&&d.push(b[c]);0<d.length&&(b="#"+d.join("&"),a.set(kb,
46
+ a.get(kb)+b))}};pc.prototype.get=function(a){return this.b.get(a)};pc.prototype.set=function(a,b){this.b.set(a,b)};var qc={pageview:[mb],event:[ub,xb,yb,zb],social:[Bb,Cb,Db],timing:[Mb,Nb,Pb,Ob]};pc.prototype.send=function(a){if(!(1>arguments.length)){if("string"===typeof arguments[0]){var b=arguments[0];var c=[].slice.call(arguments,1)}else b=arguments[0]&&arguments[0][Va],c=arguments;b&&(c=za(qc[b]||[],c),c[Va]=b,this.b.set(c,void 0,!0),this.filters.D(this.b),this.b.data.m={})}};
47
+ pc.prototype.ma=function(a,b){var c=this;u(a,c,b)||(v(a,function(){u(a,c,b)}),y(String(c.get(V)),a,void 0,b,!0))};var rc=function(a){if("prerender"==M.visibilityState)return!1;a();return!0},z=function(a){if(!rc(a)){J(16);var b=!1,c=function(){if(!b&&rc(a)){b=!0;var d=c,e=M;e.removeEventListener?e.removeEventListener("visibilitychange",d,!1):e.detachEvent&&e.detachEvent("onvisibilitychange",d)}};L(M,"visibilitychange",c)}};var td=/^(?:(\w+)\.)?(?:(\w+):)?(\w+)$/,sc=function(a){if(ea(a[0]))this.u=a[0];else{var b=td.exec(a[0]);null!=b&&4==b.length&&(this.c=b[1]||"t0",this.K=b[2]||"",this.C=b[3],this.a=[].slice.call(a,1),this.K||(this.A="create"==this.C,this.i="require"==this.C,this.g="provide"==this.C,this.ba="remove"==this.C),this.i&&(3<=this.a.length?(this.X=this.a[1],this.W=this.a[2]):this.a[1]&&(qa(this.a[1])?this.X=this.a[1]:this.W=this.a[1])));b=a[1];a=a[2];if(!this.C)throw"abort";if(this.i&&(!qa(b)||""==b))throw"abort";
48
+ if(this.g&&(!qa(b)||""==b||!ea(a)))throw"abort";if(ud(this.c)||ud(this.K))throw"abort";if(this.g&&"t0"!=this.c)throw"abort";}};function ud(a){return 0<=a.indexOf(".")||0<=a.indexOf(":")};var Yd,Zd,$d,A;Yd=new ee;$d=new ee;A=new ee;Zd={ec:45,ecommerce:46,linkid:47};
49
+ var u=function(a,b,c){b==N||b.get(V);var d=Yd.get(a);if(!ea(d))return!1;b.plugins_=b.plugins_||new ee;if(b.plugins_.get(a))return!0;b.plugins_.set(a,new d(b,c||{}));return!0},y=function(a,b,c,d,e){if(!ea(Yd.get(b))&&!$d.get(b)){Zd.hasOwnProperty(b)&&J(Zd[b]);if(p.test(b)){J(52);a=N.j(a);if(!a)return!0;c=d||{};d={id:b,B:c.dataLayer||"dataLayer",ia:!!a.get("anonymizeIp"),sync:e,G:!1};a.get("&gtm")==b&&(d.G=!0);var g=String(a.get("name"));"t0"!=g&&(d.target=g);G(String(a.get("trackingId")))||(d.clientId=
50
+ String(a.get(Q)),d.ka=Number(a.get(n)),c=c.palindrome?r:q,c=(c=M.cookie.replace(/^|(; +)/g,";").match(c))?c.sort().join("").substring(1):void 0,d.la=c,d.qa=E(a.b.get(kb)||"","gclid"));a=d.B;c=(new Date).getTime();O[a]=O[a]||[];c={"gtm.start":c};e||(c.event="gtm.js");O[a].push(c);c=t(d)}!c&&Zd.hasOwnProperty(b)?(J(39),c=b+".js"):J(43);c&&(c&&0<=c.indexOf("/")||(c=(Ba||"https:"==M.location.protocol?"https:":"http:")+"//www.google-analytics.com/plugins/ua/"+c),d=ae(c),a=d.protocol,c=M.location.protocol,
51
+ ("https:"==a||a==c||("http:"!=a?0:"http:"==c))&&B(d)&&(wa(d.url,void 0,e),$d.set(b,!0)))}},v=function(a,b){var c=A.get(a)||[];c.push(b);A.set(a,c)},C=function(a,b){Yd.set(a,b);b=A.get(a)||[];for(var c=0;c<b.length;c++)b[c]();A.set(a,[])},B=function(a){var b=ae(M.location.href);if(D(a.url,"https://www.google-analytics.com/gtm/js?id="))return!0;if(a.query||0<=a.url.indexOf("?")||0<=a.path.indexOf("://"))return!1;if(a.host==b.host&&a.port==b.port)return!0;b="http:"==a.protocol?80:443;return"www.google-analytics.com"==
52
+ a.host&&(a.port||b)==b&&D(a.path,"/plugins/")?!0:!1},ae=function(a){function b(a){var b=(a.hostname||"").split(":")[0].toLowerCase(),c=(a.protocol||"").toLowerCase();c=1*a.port||("http:"==c?80:"https:"==c?443:"");a=a.pathname||"";D(a,"/")||(a="/"+a);return[b,""+c,a]}var c=M.createElement("a");c.href=M.location.href;var d=(c.protocol||"").toLowerCase(),e=b(c),g=c.search||"",ca=d+"//"+e[0]+(e[1]?":"+e[1]:"");D(a,"//")?a=d+a:D(a,"/")?a=ca+a:!a||D(a,"?")?a=ca+e[2]+(a||g):0>a.split("/")[0].indexOf(":")&&
53
+ (a=ca+e[2].substring(0,e[2].lastIndexOf("/"))+"/"+a);c.href=a;d=b(c);return{protocol:(c.protocol||"").toLowerCase(),host:d[0],port:d[1],path:d[2],query:c.search||"",url:a||""}};var Z={ga:function(){Z.f=[]}};Z.ga();Z.D=function(a){var b=Z.J.apply(Z,arguments);b=Z.f.concat(b);for(Z.f=[];0<b.length&&!Z.v(b[0])&&!(b.shift(),0<Z.f.length););Z.f=Z.f.concat(b)};Z.J=function(a){for(var b=[],c=0;c<arguments.length;c++)try{var d=new sc(arguments[c]);d.g?C(d.a[0],d.a[1]):(d.i&&(d.ha=y(d.c,d.a[0],d.X,d.W)),b.push(d))}catch(e){}return b};
54
+ Z.v=function(a){try{if(a.u)a.u.call(O,N.j("t0"));else{var b=a.c==gb?N:N.j(a.c);if(a.A){if("t0"==a.c&&(b=N.create.apply(N,a.a),null===b))return!0}else if(a.ba)N.remove(a.c);else if(b)if(a.i){if(a.ha&&(a.ha=y(a.c,a.a[0],a.X,a.W)),!u(a.a[0],b,a.W))return!0}else if(a.K){var c=a.C,d=a.a,e=b.plugins_.get(a.K);e[c].apply(e,d)}else b[a.C].apply(b,a.a)}}catch(g){}};var N=function(a){J(1);Z.D.apply(Z,[arguments])};N.h={};N.P=[];N.L=0;N.answer=42;var uc=[Na,W,V];
55
+ N.create=function(a){var b=za(uc,[].slice.call(arguments));b[V]||(b[V]="t0");var c=""+b[V];if(N.h[c])return N.h[c];a:{if(b[Kd]){J(67);if(b[ac]&&"cookie"!=b[ac]){var d=!1;break a}if(void 0!==Ab)b[Q]||(b[Q]=Ab);else{b:{d=String(b[W]||xa());var e=String(b[Yb]||"/"),g=Ca(String(b[U]||"_ga"));d=na(g,d,e);if(!d||jd.test(d))d=!0;else if(d=Ca("AMP_TOKEN"),0==d.length)d=!0;else{if(1==d.length&&(d=decodeURIComponent(d[0]),"$RETRIEVING"==d||"$OPT_OUT"==d||"$ERROR"==d||"$NOT_FOUND"==d)){d=!0;break b}d=!1}}if(d&&
56
+ tc(ic,String(b[Na]))){d=!0;break a}}}d=!1}if(d)return null;b=new pc(b);N.h[c]=b;N.P.push(b);return b};N.remove=function(a){for(var b=0;b<N.P.length;b++)if(N.P[b].get(V)==a){N.P.splice(b,1);N.h[a]=null;break}};N.j=function(a){return N.h[a]};N.getAll=function(){return N.P.slice(0)};
57
+ N.N=function(){"ga"!=gb&&J(49);var a=O[gb];if(!a||42!=a.answer){N.L=a&&a.l;N.loaded=!0;var b=O[gb]=N;X("create",b,b.create);X("remove",b,b.remove);X("getByName",b,b.j,5);X("getAll",b,b.getAll,6);b=pc.prototype;X("get",b,b.get,7);X("set",b,b.set,4);X("send",b,b.send);X("requireSync",b,b.ma);b=Ya.prototype;X("get",b,b.get);X("set",b,b.set);if("https:"!=M.location.protocol&&!Ba){a:{b=M.getElementsByTagName("script");for(var c=0;c<b.length&&100>c;c++){var d=b[c].src;if(d&&0==d.indexOf("https://www.google-analytics.com/analytics")){b=
58
+ !0;break a}}b=!1}b&&(Ba=!0)}(O.gaplugins=O.gaplugins||{}).Linker=Dc;b=Dc.prototype;C("linker",Dc);X("decorate",b,b.ca,20);X("autoLink",b,b.S,25);C("displayfeatures",fd);C("adfeatures",fd);a=a&&a.q;ka(a)?Z.D.apply(N,a):J(50)}};N.da=function(){for(var a=N.getAll(),b=0;b<a.length;b++)a[b].get(V)};var da=N.N,Nd=O[gb];Nd&&Nd.r?da():z(da);z(function(){Z.D(["provide","render",ua])});function La(a){var b=1,c;if(a)for(b=0,c=a.length-1;0<=c;c--){var d=a.charCodeAt(c);b=(b<<6&268435455)+d+(d<<14);d=b&266338304;b=0!=d?b^d>>21:b}return b};})(window);
components/ga-cache/includes/class.plugin.php ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Hide my wp core class
4
+ * @author Webcraftic <wordpress.webraftic@gmail.com>
5
+ * @copyright (c) 19.02.2018, Webcraftic
6
+ * @version 1.0
7
+ */
8
+
9
+ // Exit if accessed directly
10
+ if( !defined('ABSPATH') ) {
11
+ exit;
12
+ }
13
+
14
+ if( !class_exists('WGA_Plugin') ) {
15
+
16
+ if( !class_exists('WGA_PluginFactory') ) {
17
+ if( defined('LOADING_CYRLITERA_AS_ADDON') ) {
18
+ class WGA_PluginFactory {
19
+
20
+ }
21
+ } else {
22
+ class WGA_PluginFactory extends Wbcr_Factory406_Plugin {
23
+
24
+ }
25
+ }
26
+ }
27
+
28
+ class WGA_Plugin extends WGA_PluginFactory {
29
+
30
+ /**
31
+ * @var Wbcr_Factory406_Plugin
32
+ */
33
+ private static $app;
34
+
35
+ /**
36
+ * @var bool
37
+ */
38
+ private $as_addon;
39
+
40
+ /**
41
+ * @param string $plugin_path
42
+ * @param array $data
43
+ * @throws Exception
44
+ */
45
+ public function __construct($plugin_path, $data)
46
+ {
47
+ $this->as_addon = isset($data['as_addon']);
48
+
49
+ if( $this->as_addon ) {
50
+ $plugin_parent = isset($data['plugin_parent'])
51
+ ? $data['plugin_parent']
52
+ : null;
53
+
54
+ if( !($plugin_parent instanceof Wbcr_Factory406_Plugin) ) {
55
+ throw new Exception('An invalid instance of the class was passed.');
56
+ }
57
+
58
+ self::$app = $plugin_parent;
59
+ } else {
60
+ self::$app = $this;
61
+ }
62
+
63
+ if( !$this->as_addon ) {
64
+ parent::__construct($plugin_path, $data);
65
+ }
66
+
67
+ $this->setTextDomain();
68
+ $this->setModules();
69
+
70
+ $this->globalScripts();
71
+
72
+ if( is_admin() ) {
73
+ $this->initActivation();
74
+ $this->adminScripts();
75
+ }
76
+ }
77
+
78
+ /**
79
+ * @return Wbcr_Factory406_Plugin
80
+ */
81
+ public static function app()
82
+ {
83
+ return self::$app;
84
+ }
85
+
86
+ protected function setTextDomain()
87
+ {
88
+ // Localization plugin
89
+ load_plugin_textdomain('simple-google-analytics', false, dirname(WGA_PLUGIN_BASE) . '/languages/');
90
+ }
91
+
92
+ protected function setModules()
93
+ {
94
+ if( !$this->as_addon ) {
95
+ self::app()->load(array(
96
+ array('libs/factory/bootstrap', 'factory_bootstrap_406', 'admin'),
97
+ array('libs/factory/forms', 'factory_forms_407', 'admin'),
98
+ array('libs/factory/pages', 'factory_pages_407', 'admin'),
99
+ array('libs/factory/notices', 'factory_notices_405', 'admin'),
100
+ array('libs/factory/clearfy', 'factory_clearfy_203', 'all')
101
+
102
+ ));
103
+ }
104
+ }
105
+
106
+ protected function initActivation()
107
+ {
108
+ require_once(WGA_PLUGIN_DIR . '/admin/activation.php');
109
+ self::app()->registerActivation('WGA_Activation');
110
+ }
111
+
112
+ private function registerPages()
113
+ {
114
+ if( $this->as_addon ) {
115
+ return;
116
+ }
117
+ self::app()->registerPage('WGA_CachePage', WGA_PLUGIN_DIR . '/admin/pages/ga_cache.php');
118
+ self::app()->registerPage('WGA_MoreFeaturesPage', WGA_PLUGIN_DIR . '/admin/pages/more-features.php');
119
+ }
120
+
121
+ private function adminScripts()
122
+ {
123
+ require(WGA_PLUGIN_DIR . '/admin/options.php');
124
+ require(WGA_PLUGIN_DIR . '/admin/boot.php');
125
+
126
+ $this->registerPages();
127
+ }
128
+
129
+ private function globalScripts()
130
+ {
131
+ require(WGA_PLUGIN_DIR . '/includes/classes/class.configurate-ga.php');
132
+ new WGA_ConfigGACache(self::$app);
133
+ }
134
+ }
135
+ }
components/ga-cache/includes/classes/class.configurate-ga.php ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This class configures the google analytics cache
4
+ * @author Webcraftic <wordpress.webraftic@gmail.com>
5
+ * @copyright (c) 2017 Webraftic Ltd
6
+ * @version 1.0
7
+ */
8
+
9
+ // Exit if accessed directly
10
+ if( !defined('ABSPATH') ) {
11
+ exit;
12
+ }
13
+
14
+ class WGA_ConfigGACache extends Wbcr_FactoryClearfy203_Configurate {
15
+
16
+
17
+ public function registerActionsAndFilters()
18
+ {
19
+
20
+ if( $this->getOption('ga_cache') ) {
21
+ add_filter('cron_schedules', array($this, 'cronAdditions'));
22
+
23
+ // Load update script to schedule in wp_cron.
24
+ add_action('wbcr_ga_update_local_script', array($this, 'updateLocalGoogleAnaliticScript'));
25
+
26
+ if( !is_admin() ) {
27
+ $this->addGoogleAnaliticsScript();
28
+ }
29
+ }
30
+ }
31
+
32
+
33
+ public function cronAdditions($schedules)
34
+ {
35
+ $schedules['weekly'] = array(
36
+ 'interval' => DAY_IN_SECONDS * 7,
37
+ 'display' => __('Once Weekly'),
38
+ );
39
+
40
+ $schedules['twicemonthly'] = array(
41
+ 'interval' => DAY_IN_SECONDS * 14,
42
+ 'display' => __('Twice Monthly'),
43
+ );
44
+
45
+ $schedules['monthly'] = array(
46
+ 'interval' => DAY_IN_SECONDS * 30,
47
+ 'display' => __('Once Monthly'),
48
+ );
49
+
50
+ return $schedules;
51
+ }
52
+
53
+ public function updateLocalGoogleAnaliticScript()
54
+ {
55
+ include(WGA_PLUGIN_DIR . '/includes/update-local-ga.php');
56
+ }
57
+
58
+ private function addGoogleAnaliticsScript()
59
+ {
60
+ $ga_tracking_id = $this->getOption('ga_tracking_id');
61
+
62
+ if( !empty($ga_tracking_id) ) {
63
+ $local_ga_file = WGA_PLUGIN_DIR . '/cache/local-ga.js';
64
+ // If file is not created yet, create now!
65
+ if( !file_exists($local_ga_file) ) {
66
+ ob_start();
67
+ do_action('wbcr_ga_update_local_script');
68
+ ob_end_clean();
69
+ }
70
+
71
+ $ga_script_position = $this->getOption('ga_script_position', 'footer');
72
+ $ga_enqueue_order = $this->getOption('ga_enqueue_order', 0);
73
+
74
+ switch( $ga_script_position ) {
75
+ case 'header':
76
+ add_action('wp_head', array($this, 'printGoogleAnalitics'), $ga_enqueue_order);
77
+ break;
78
+ default:
79
+ add_action('wp_footer', array($this, 'printGoogleAnalitics'), $ga_enqueue_order);
80
+ }
81
+ }
82
+ }
83
+
84
+ /**
85
+ * Generate tracking code and add to header/footer (default is header).
86
+ */
87
+ public function printGoogleAnalitics()
88
+ {
89
+ $ga_tracking_id = $this->getOption('ga_tracking_id');
90
+ $ga_track_admin = $this->getOption('ga_track_admin');
91
+
92
+ // If user is admin we don't want to render the tracking code, when option is disabled.
93
+ if( empty($ga_tracking_id) || (current_user_can('manage_options') && (!$ga_track_admin)) ) {
94
+ return;
95
+ }
96
+
97
+ $ga_adjusted_bounce_rate = $this->getOption('ga_adjusted_bounce_rate', 0);
98
+ $ga_anonymize_ip = $this->getOption('ga_anonymize_ip', false);
99
+ $ga_caos_disable_display_features = $this->getOption('ga_caos_disable_display_features', false);
100
+
101
+ echo "<!-- Google Analytics Local by " . $this->plugin->getPluginTitle() . " -->" . PHP_EOL;
102
+
103
+ echo "<script>" . PHP_EOL;
104
+ echo "(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
105
+ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
106
+ m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
107
+ })(window,document,'script','" . WGA_PLUGIN_URL . "/cache/local-ga.js','ga');" . PHP_EOL;
108
+
109
+ echo "ga('create', '" . $ga_tracking_id . "', 'auto');" . PHP_EOL;
110
+
111
+ echo $ga_caos_disable_display_features
112
+ ? "ga('set', 'displayFeaturesTask', null);" . PHP_EOL
113
+ : '';
114
+
115
+ echo $ga_anonymize_ip
116
+ ? "ga('set', 'anonymizeIp', true);" . PHP_EOL
117
+ : '';
118
+
119
+ echo "ga('send', 'pageview');";
120
+
121
+ echo $ga_adjusted_bounce_rate
122
+ ? PHP_EOL . 'setTimeout("ga(' . "'send','event','adjusted bounce rate','" . $ga_adjusted_bounce_rate . " seconds')" . '"' . ',' . $ga_adjusted_bounce_rate * 1000 . ');'
123
+ : '';
124
+
125
+ echo PHP_EOL . '</script>' . PHP_EOL;
126
+
127
+ echo "<!-- end Google Analytics Local by " . $this->plugin->getPluginTitle() . " -->" . PHP_EOL;
128
+ }
129
+ }
components/{hide-login-page/languages → ga-cache/includes/classes}/index.php RENAMED
File without changes
components/{hide-login-page/libs → ga-cache/includes}/index.php RENAMED
File without changes
{includes → components/ga-cache/includes}/update-local-ga.php RENAMED
@@ -12,7 +12,7 @@
12
 
13
  // Remote file to download.
14
  $remote_file = 'https://www.google-analytics.com/analytics.js';
15
- $local_file = WCL_PLUGIN_DIR . '/cache/local-ga.js';
16
 
17
  // Connection time out.
18
  $conn_timeout = 10;
12
 
13
  // Remote file to download.
14
  $remote_file = 'https://www.google-analytics.com/analytics.js';
15
+ $local_file = WGA_PLUGIN_DIR . '/cache/local-ga.js';
16
 
17
  // Connection time out.
18
  $conn_timeout = 10;
components/ga-cache/languages/index.php ADDED
File without changes
components/ga-cache/languages/simple-google-analytics-ru_RU.mo ADDED
Binary file
components/ga-cache/languages/simple-google-analytics-ru_RU.po ADDED
@@ -0,0 +1,198 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: \n"
4
+ "POT-Creation-Date: 2018-04-17 02:28+0400\n"
5
+ "PO-Revision-Date: 2018-04-17 02:35+0400\n"
6
+ "Last-Translator: \n"
7
+ "Language-Team: \n"
8
+ "Language: ru_RU\n"
9
+ "MIME-Version: 1.0\n"
10
+ "Content-Type: text/plain; charset=UTF-8\n"
11
+ "Content-Transfer-Encoding: 8bit\n"
12
+ "X-Generator: Poedit 2.0.6\n"
13
+ "X-Poedit-Basepath: ga-cache\n"
14
+ "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
15
+ "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
16
+ "X-Poedit-SourceCharset: UTF-8\n"
17
+ "X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c\n"
18
+ "X-Poedit-SearchPath-0: google-analytics-cache.php\n"
19
+ "X-Poedit-SearchPath-1: includes/class.plugin.php\n"
20
+ "X-Poedit-SearchPath-2: admin/options.php\n"
21
+ "X-Poedit-SearchPath-3: includes/classes/class.configurate-ga.php\n"
22
+ "X-Poedit-SearchPath-4: admin/pages/ga_cache.php\n"
23
+
24
+ #: admin/options.php:23
25
+ msgid "<strong>Google Analytics cache</strong>."
26
+ msgstr ""
27
+
28
+ #: admin/options.php:23
29
+ msgid ""
30
+ "To improve Google Page Speed indicators Analytics caching is needed. "
31
+ "However, it can also slightly increase your website loading speed, because "
32
+ "Analytics js files will load locally. The second case that you might need "
33
+ "these settings is the usual Google Analytics connection to your website. You "
34
+ "do not need to do this with other plugins or insert the tracking code into "
35
+ "your theme."
36
+ msgstr ""
37
+ "Кеширование Analytics нужно для улучшения показателей Google Page Speed, но\n"
38
+ "это также может незначительно повысить скорость загрузки вашего сайта, \n"
39
+ "потому что js файлы Analytics будут подгружаться локально. Второй случай, \n"
40
+ "когда вам могут понадобиться эти настройки — обычное подключение Google \n"
41
+ "Analytics к сайту. Вам не нужно делать это с помощью других плагинов или \n"
42
+ "просто вставлять код отслеживания в вашу тему."
43
+
44
+ #: admin/options.php:31 admin/pages/ga_cache.php:33 admin/pages/ga_cache.php:49
45
+ msgid "Google Analytics Cache"
46
+ msgstr ""
47
+
48
+ #: admin/options.php:33
49
+ msgid ""
50
+ "If you enable this option, the plugin will begin to save a local copy of "
51
+ "Google Analytics to speed up the loading of your website and improve Google "
52
+ "Page Speed."
53
+ msgstr ""
54
+ "Если включить эту опцию, плагин начнет сохранять локальную копию Google \n"
55
+ "Analytics, чтобы ускорить загрузку вашего сайта и улучшить показатели "
56
+ "Google \n"
57
+ "Page speed. ВНИМАНИЕ! Перед использованием этой опции, удалите ранее \n"
58
+ "установленный код Google Analytics в вашей теме или плагины, связанные с \n"
59
+ "этой функцией!"
60
+
61
+ #: admin/options.php:33
62
+ msgid ""
63
+ "ATTENTION! Before using this option, remove the previously installed Google "
64
+ "Analytics code inside your theme or plugins associated with this feature!"
65
+ msgstr ""
66
+ "ВНИМАНИЕ! Перед использованием этой опции, удалите ранее установленный код \n"
67
+ "Google Analytics в вашей теме или плагины, связанные с этой функцией!"
68
+
69
+ #: admin/options.php:51
70
+ msgid "Google analytic Code"
71
+ msgstr "Код Google аналитики"
72
+
73
+ #: admin/options.php:53
74
+ msgid "Set the Google Analytics tracking code."
75
+ msgstr "Установите код отслеживания Google Analytics."
76
+
77
+ #: admin/options.php:64
78
+ msgid "Save GA in"
79
+ msgstr "Использовать код аналитики в"
80
+
81
+ #: admin/options.php:65
82
+ msgid "Select location for the Google Analytics code."
83
+ msgstr "Выберите местоположение для кода Google Analytics."
84
+
85
+ #: admin/options.php:72
86
+ msgid "Use adjusted bounce rate?"
87
+ msgstr "Показатель отказов?"
88
+
89
+ #: admin/options.php:75
90
+ msgid ""
91
+ "Essentially, you set up an event which is triggered after a user spends a "
92
+ "certain amount of time on the landing page, telling Google Analytics not to "
93
+ "count these users as bounces. A user may come to your website, find all of "
94
+ "the information they need (a phone number, for example) and then leave the "
95
+ "site without visiting another page. Without adjusted bounce rate, such a "
96
+ "user would be considered a bounce, even though they had a successful "
97
+ "experience. By defining a time limit after which you can consider a user to "
98
+ "be \"engaged,\" that user would no longer count as a bounce, and you'd get a "
99
+ "more accurate idea of whether they found what they were looking for."
100
+ msgstr ""
101
+ "По сути, вы настраиваете событие, которое запускается после того, как \n"
102
+ "пользователь тратит определенное количество времени на целевую страницу, \n"
103
+ "сообщая Google Analytics не считать этих пользователей как отказы. \n"
104
+ "Пользователь может зайти на ваш сайт, найти всю необходимую информацию \n"
105
+ "(например, номер телефона), а затем покинуть сайт, не посещая другую \n"
106
+ "страницу. Без скорректированного коэффициента отказов такой пользователь \n"
107
+ "будет считаться отказом, хотя у них был успешный опыт. Определив лимит \n"
108
+ "времени, после которого вы можете считать пользователя «включенным», этот \n"
109
+ "пользователь больше не будет считаться отказом, и вы получите более точное \n"
110
+ "представление о том, нашли ли они то, что искали."
111
+
112
+ #: admin/options.php:81
113
+ msgid "Change enqueue order?"
114
+ msgstr "Сортировка скрипта?"
115
+
116
+ #: admin/options.php:84
117
+ msgid ""
118
+ "By default, Google Analytics code is loaded before other scripts and "
119
+ "javasscript code, but if you set the value to 100, the GA code will be "
120
+ "loaded after all other scripts. By changing the priority, you can set code "
121
+ "position on the page."
122
+ msgstr ""
123
+ "По умолчанию код Google Analytics загружается раньше остальных скриптов и \n"
124
+ "javasscript кода, но если вы установите к примеру значение 100, то код GA \n"
125
+ "будет загружен после всех остальных скриптов. Изменяя приоритет, вы можете \n"
126
+ "задавать положение кода на странице."
127
+
128
+ #: admin/options.php:90
129
+ msgid "Disable all display features functionality?"
130
+ msgstr "Отключить все функции для контекстно-медийной сети?"
131
+
132
+ #: admin/options.php:92
133
+ #, php-format
134
+ msgid "Disable all <a href=\"%s\">display features functionality?</a>"
135
+ msgstr "Отключить <a href=\"%s\">все функции для контекстно-медийной сети?</a>"
136
+
137
+ #: admin/options.php:99
138
+ msgid "Use Anonymize IP? (Required by law for some countries)"
139
+ msgstr ""
140
+ "Использовать анонимный IP-адрес? (Требуется по закону для некоторых стран)"
141
+
142
+ #: admin/options.php:101
143
+ #, php-format
144
+ msgid ""
145
+ "Use <a href=\"%s\">Anonymize IP?</a> (Required by law for some countries)"
146
+ msgstr ""
147
+ "Использовать <a href=\"%s\">анонимный IP-адрес?</a> (Требуется по закону "
148
+ "для \n"
149
+ "некоторых стран)"
150
+
151
+ #: admin/options.php:108 admin/options.php:110
152
+ msgid "Track logged in Administrators?"
153
+ msgstr "Отслеживать, если вы авторизованы под администратором?"
154
+
155
+ #: admin/options.php:117
156
+ msgid "Remove script from wp-cron?"
157
+ msgstr "Удалить кеширования скрипта из крона?"
158
+
159
+ #: admin/options.php:119
160
+ msgid ""
161
+ "Clearfy creates a cron job to daily update Google Analytics cache scripts. "
162
+ "After enabling this option, the plugin will not update Google Analytics "
163
+ "cache file. Do not use this option if you do not understand why you need it!"
164
+ msgstr ""
165
+ "Плагин создает cron задание, чтобы ежедневно обновлять кеш скриптов Google \n"
166
+ "Analytics. После включения этой опции, плагин не будет обновлять кэш файл \n"
167
+ "Google Analytics. Не используйте эту опцию, если вы не понимаете, для чего \n"
168
+ "вам это нужно!"
169
+
170
+ #: admin/pages/ga_cache.php:50
171
+ msgid "General"
172
+ msgstr "Основные"
173
+
174
+ #: google-analytics-cache.php:22
175
+ msgid ""
176
+ "We found that you have the \"Clearfy - disable unused features\" plugin "
177
+ "installed, this plugin already has Google Analytics cache functions, so you "
178
+ "can deactivate plugin \"Google Analytics Cache\"!"
179
+ msgstr ""
180
+ "Мы обнаружили, что у вас установлен плагин «Clearfy - отключить \n"
181
+ "неиспользуемые функции», этот плагин уже имеет функцию кеширования Google "
182
+ "Analytics, поэтому вы можете отключить плагин «Google Analytics Cache»!"
183
+
184
+ #: google-analytics-cache.php:50
185
+ msgid "Webcraftic Google Analytics Cache"
186
+ msgstr ""
187
+
188
+ #: includes/classes/class.configurate-ga.php:40
189
+ msgid "Once Weekly"
190
+ msgstr ""
191
+
192
+ #: includes/classes/class.configurate-ga.php:45
193
+ msgid "Twice Monthly"
194
+ msgstr ""
195
+
196
+ #: includes/classes/class.configurate-ga.php:50
197
+ msgid "Once Monthly"
198
+ msgstr ""
components/ga-cache/readme.txt ADDED
@@ -0,0 +1,137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ === Local Google Analytics for Wordpress - caches external requests ===
2
+ Tags: analytics,google analytics,google analytics dashboard,google analytics plugin,google analytics widget,gtag
3
+ Contributors: webcraftic, JeromeMeyer62
4
+ Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=VDX7JNTQPNPFW
5
+ Requires at least: 4.2
6
+ Tested up to: 4.9
7
+ Requires PHP: 5.2
8
+ Stable tag: trunk
9
+ License: GPLv2
10
+
11
+ Plugs in Google Analytics code to your website pages and caches it, so the website loads faster.
12
+
13
+ == Description ==
14
+
15
+ This plugin helps to plug in Google Analytics code to the website pages without affecting the theme code. All you have to do is to enter the tracking code. That’s all. Unlike other plugins, this one cares about your website performance and caches Google Analytics scripts.
16
+
17
+ #### How does plugin cache Google Analytics scripts and why? ####
18
+
19
+ When you activate and fill in plugin settings, it downloads remote file named analytics.js and places it to the Cache folder on your hosting (server). This file is updated once a day – it helps to avoid external requests to the Google remote server and speeds up the website pages.
20
+ Also if you want to gain 100 performance rating on Google Pagespeed Insights, then you’ll definitely need to cache Google Analytics, otherwise you’ll get a warning.
21
+
22
+ #### PLUGIN FEATURES ####
23
+
24
+ * <strong>Helps to place analytics code to the website header or footer.</strong>
25
+ * <strong>Monitors bounce rates.</strong> The point is that you set up the event triggered after a user spends a certain amount of time on the landing page, telling Google Analytics not to consider these users as a bounce. The user can visit your website, find all necessary information (for example, phone number), and then – simply close the website without visiting other pages. If the bounce rate hasn’t been adjusted, then this user is considered as a bounce, even though he had a successful experience. By defining time limits as from when the user should be considered as a bounce, you get more accurate performance of the user experience (for example, whether he's been able to find what he was looking for or not).
26
+ * <strong>Define the analytics code position.</strong> Google Analytics code loads prior to other scripts and JavaScript code by default. But if you set up the value 100, for example, then the Google Analytics code will be loaded after all scripts. Adjusting the priority helps to set up the code’s position on the page.
27
+ * <strong>Disable all Display Network functions.</strong> Find more: https://developers.google.com/analytics/devguides/collection/analyticsjs/display-features
28
+ * <strong>Use anonymous IP address (required by the law in some countries).</strong> More details: (https://support.google.com/analytics/answer/2763052)
29
+ * <strong>Track administrators.</strong> You can disable tracking for administrators’ activities and get more accurate statistics.
30
+ * <strong>Do not update the analytics.js local script.</strong> Plugin creates cron task to update cache of Google Analytics scripts daily. Once this feature is enabled, the plugin won’t update the Google Analytics cache file.
31
+
32
+ == Translations ==
33
+
34
+ * English - default, always included
35
+ * Russian
36
+
37
+ If you want to help with the translation, please contact me through this site or through the contacts inside the plugin.
38
+
39
+ #### BIG THANKS ####
40
+ Many thanks to [Jerome Meyer](http://www.arobase62.fr/2011/03/23/simple-google-analytics/), for his great contribution to the development of this plugin.
41
+
42
+ #### THANKS TO THE PLUGINS' AUTHORS ####
43
+ We used some plugins functions:
44
+ <strong>GA Google Analytics</strong>, <strong>NK Google Analytics</strong>, <strong>Complete Analytics Optimization Suite (CAOS)</strong>, <strong>Clearfy — WordPress optimization plugin and disable ultimate tweaker</strong>, <strong>Enhanced Ecommerce Google Analytics Plugin for WooCommerce</strong>
45
+
46
+ #### Recommended separate modules ####
47
+
48
+ We invite you to check out a few other related free plugins that our team has also produced that you may find especially useful:
49
+
50
+ * [Clearfy – WordPress optimization plugin and disable ultimate tweaker](https://wordpress.org/plugins/clearfy/)
51
+ * [Disable Comments for Any Post Types (Remove Comments)](https://wordpress.org/plugins/comments-plus/)
52
+ * [Cyrlitera – transliteration of links and file names](https://wordpress.org/plugins/cyrlitera/)
53
+ * [Cyr-to-lat reloaded – transliteration of links and file names](https://wordpress.org/plugins/cyr-and-lat/ "Cyr-to-lat reloaded")
54
+ * [Disable admin notices individually](https://wordpress.org/plugins/disable-admin-notices/ "Disable admin notices individually")
55
+ * [Hide login page](https://wordpress.org/plugins/hide-login-page/ "Hide login page")
56
+ * [Disable updates, Disable automatic updates, Updates manager](https://wordpress.org/plugins/webcraftic-updates-manager/)
57
+ * [WordPress Assets manager, dequeue scripts, dequeue styles](https://wordpress.org/plugins/gonzales/ "WordPress Assets manager, dequeue scripts, dequeue styles")
58
+
59
+ == Installation ==
60
+
61
+ 1. Upload the ‘simple-google-analytics.zip’ file to the /wp-content/plugins/ directory using wget, curl of ftp.
62
+
63
+ 2. ‘unzip’ the ‘simple-google-analytics.zip’ which will create the folder to the directory /wp-content/plugins/simple-google-analytics
64
+
65
+ 3. Activate the plugin through the ‘Plugins’ menu in WordPress
66
+
67
+ 4. Configure the plugin through ‘Local Google Analytics’ submenu in the the ‘Settings’ section of the WordPress admin menu
68
+
69
+ 5. Add your google analytics ID there. An example of Google Analytics ID –> UA-0000000-0.
70
+
71
+ 6. Choose if your blog is on a sub-domain or not. This option is defined in your Google Analytics settings page. Do not change if you don’t know.
72
+
73
+ 7. Enter the domain where your WordPress is.
74
+
75
+ 8. Save it & your done.
76
+
77
+ == Screenshots ==
78
+ 1. Control panel
79
+
80
+ == Frequently Asked Questions ==
81
+ = Does plugin work with multisite? =
82
+ No plugin does not support multisites. This is temporary and we will try to add support for networks in the future.
83
+
84
+ == Changelog ==
85
+ = version 3.0.1 =
86
+ * Fixed small bugs
87
+ = version 3.0.0 =
88
+ * The Simple Google Analytics plugin has some major changes. Unfortunately, the old version of the plugin (2.2.2) is no longer supported, but you still can download it from the WordPress repository in case if the new release doesn’t work for you.
89
+ We’ve updated the code and fixed the compatibility issue for the latest WordPress and PHP versions. We’ve also added additional feature of the Google Analytics cache – this way your website will load faster. The plugin’s name has been changed to Google Analytics cache, but all features remained the same.
90
+ Please, check plugin settings and its performance on your website. We do care about you and want to avoid any problems with the new version.
91
+ = version 2.2.3 =
92
+ * Author change
93
+ = version 2.2.2 =
94
+ * Add a comment when the code isn't loaded while being logged
95
+ = version 2.2.1 =
96
+ * Corrected the analytics code to prevent non-detection from Google
97
+ = version 2.2.0 =
98
+ * Add the demographic / interests reports
99
+ = version 2.1.0 =
100
+ * Corrected a bug with wp_enqueue_script
101
+ * Change the JS loading method
102
+ * Add the external links / downloads tracking
103
+ = version 2.0.5 =
104
+ * Added the option to not render when logged in
105
+ = version 2.0.4 =
106
+ * Corrected a bug where the JS file was loading before jQuery. Thanks to MrZebra for finding that.
107
+ = version 2.0.3 =
108
+ * Corrected a bug that made all settings link on extension page going to Simple Google Analytics settings page.
109
+ = version 2.0.2 =
110
+ * Google Code has returned to the original. The optimized code have issues with some users having no stats. All should be fine now.
111
+ = version 2.0 =
112
+ * Code has been fully rewritten.
113
+ * Google Analytics code has been rewritten to load faster.
114
+ = version 1.1.6 =
115
+ * Code is not showing only when logged as Admin.
116
+ * Add option to select where you want to place the code (Header or Footer)
117
+ = version 1.1.5 =
118
+ * Add settings in the extensions page (Thanks to Vladimir Pavlikov)
119
+ * Add Russian Translation (Thanks to Vladimir Pavlikov)
120
+ = version 1.1.4 =
121
+ * Version 1.1.3 doesn't shows in the repository...
122
+ = version 1.1.3 =
123
+ * Added a translation for 'Simple Google Analytics Settings'
124
+ = version 1.1.2 =
125
+ * French Translation Bug
126
+ = version 1.1.1 =
127
+ * Fixed annoying bug
128
+ = version 1.1.0 =
129
+ * Added new Site Speed setting from Google
130
+ = version 1.0.4 =
131
+ * Corriged a bug if you use the Papercite plugin
132
+ = version 1.0.3 =
133
+ * Clean Readme file and clean code
134
+ = version 1.0.2 =
135
+ * Added French Translation
136
+ = version 1.0 =
137
+ * Add multi-subdomain option
components/ga-cache/simple_google_analytics.php ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Plugin Name: Webcraftic Local Google Analytics
4
+ * Plugin URI: https://wordpress.org/plugins/simple-google-analytics/
5
+ * Description: Old plugin name: Simple Google Analytics. To improve Google Page Speed indicators Analytics caching is needed. However, it can also slightly increase your website loading speed, because Analytics js files will load locally. The second case that you might need these settings is the usual Google Analytics connection to your website. You do not need to do this with other plugins or insert the tracking code into your theme.
6
+ * Author: Webcraftic <wordpress.webraftic@gmail.com>, JeromeMeyer62<jerome.meyer@hollywoud.net>
7
+ * Version: 3.0.1
8
+ * Text Domain: simple-google-analytics
9
+ * Domain Path: /languages/
10
+ * Author URI: http://clearfy.pro
11
+ */
12
+
13
+ // Exit if accessed directly
14
+ if( !defined('ABSPATH') ) {
15
+ exit;
16
+ }
17
+
18
+ // If the plugin is already in use, as an add-on or has already been installed.
19
+ $conflict_error = defined('WGA_PLUGIN_ACTIVE') || (defined('WCL_PLUGIN_ACTIVE') && !defined('LOADING_GA_CACHE_AS_ADDON'));
20
+
21
+ // If the user is using an old version of Wordpress
22
+ $old_wp_version_error = version_compare(get_bloginfo('version'), '4.2.0') <= 0;
23
+
24
+ if( $conflict_error || $old_wp_version_error ) {
25
+ function wbcr_ga_admin_notice_error()
26
+ {
27
+ global $conflict_error, $old_wp_version_error;
28
+
29
+ if( $conflict_error ) {
30
+ ?>
31
+ <div class="notice notice-error">
32
+ <p><?php _e('We found that you have the "Clearfy - disable unused features" plugin installed, this plugin already has Google Analytics cache functions, so you can deactivate plugin "Google Analytics Cache"!', 'simple-google-analytics'); ?></p>
33
+ </div>
34
+ <?php
35
+ }
36
+
37
+ if( $old_wp_version_error ) {
38
+ ?>
39
+ <div class="notice notice-error">
40
+ <p><?php _e('You use the old version of Wordpress to use the <b>Webcraftic Local Google Analytics (Old name: Simple Google Analytics)</b> plugin, you must upgrade your Wordpress to the minimum version 4.2!', 'simple-google-analytics'); ?></p>
41
+ </div>
42
+ <?php
43
+ }
44
+ }
45
+
46
+ add_action('admin_notices', 'wbcr_ga_admin_notice_error');
47
+ } else {
48
+
49
+ define('WGA_PLUGIN_ACTIVE', true);
50
+ define('WGA_PLUGIN_DIR', dirname(__FILE__));
51
+ define('WGA_PLUGIN_BASE', plugin_basename(__FILE__));
52
+ define('WGA_PLUGIN_URL', plugins_url(null, __FILE__));
53
+
54
+ if( !defined('LOADING_GA_CACHE_AS_ADDON') ) {
55
+ require_once(WGA_PLUGIN_DIR . '/libs/factory/core/boot.php');
56
+ }
57
+
58
+ require_once(WGA_PLUGIN_DIR . '/includes/class.plugin.php');
59
+
60
+ if( !defined('LOADING_GA_CACHE_AS_ADDON') ) {
61
+
62
+ new WGA_Plugin(__FILE__, array(
63
+ 'prefix' => 'wbcr_gac_',
64
+ 'plugin_name' => 'wbcr_gac',
65
+ 'plugin_title' => __('Webcraftic Local Google Analytics', 'simple-google-analytics'),
66
+ 'plugin_version' => '3.0.1',
67
+ 'required_php_version' => '5.2',
68
+ 'required_wp_version' => '4.2',
69
+ 'plugin_build' => 'free',
70
+ //'updates' => WGA_PLUGIN_DIR . '/updates/'
71
+ ));
72
+ }
73
+ }
components/{hide-login-page → ga-cache}/uninstall.php RENAMED
@@ -8,6 +8,6 @@
8
  // remove plugin options
9
  global $wpdb;
10
 
11
- $wpdb->query("DELETE FROM {$wpdb->prefix}options WHERE option_name LIKE 'wbcr_hlp_%';");
12
 
13
 
8
  // remove plugin options
9
  global $wpdb;
10
 
11
+ $wpdb->query("DELETE FROM {$wpdb->prefix}options WHERE option_name LIKE 'wbcr_gac%';");
12
 
13
 
components/hide-login-page/admin/boot.php DELETED
@@ -1,136 +0,0 @@
1
- <?php
2
- /**
3
- * Admin boot
4
- * @author Webcraftic <wordpress.webraftic@gmail.com>
5
- * @copyright Webcraftic 25.05.2017
6
- * @version 1.0
7
- */
8
-
9
- // Exit if accessed directly
10
- if( !defined('ABSPATH') ) {
11
- exit;
12
- }
13
-
14
- /**
15
- * @return array
16
- */
17
- function wbcr_hlp_install_conflict_plugins()
18
- {
19
- // fist array item 0 - conflict
20
- // fist array item 1 - maybe conflict
21
- $install_plugins = array();
22
-
23
- if( is_plugin_active('hide-my-wp/index.php') ) {
24
- $install_plugins[] = array(0, 'Hide My WP');
25
- }
26
- if( is_plugin_active('clearfy/hide-my-wp.php') ) {
27
- $install_plugins[] = array(1, 'Hide My WP');
28
- }
29
- if( is_plugin_active('rename-wp-login/rename-wp-login.php') ) {
30
- $install_plugins[] = array(0, 'Rename wp-login.php');
31
- }
32
- if( is_plugin_active('wps-hide-login/wps-hide-login.php') ) {
33
- $install_plugins[] = array(0, 'WPS Hide Login');
34
- }
35
- if( is_plugin_active('wp-cerber/wp-cerber.php') ) {
36
- $install_plugins[] = array(1, 'WP Cerber Security & Antispam');
37
- }
38
- if( is_plugin_active('all-in-one-wp-security-and-firewall/wp-security.php') ) {
39
- $install_plugins[] = array(1, 'All In One WP Security');
40
- }
41
- if( is_plugin_active('wp-hide-security-enhancer/wp-hide.php') ) {
42
- $install_plugins[] = array(1, 'WP Hide & Security Enhancer');
43
- }
44
-
45
- return $install_plugins;
46
- }
47
-
48
- /**
49
- *
50
- * @param Wbcr_Factory400_Plugin $plugin
51
- * @param Wbcr_FactoryPages401_ImpressiveThemplate $page
52
- * @return array
53
- */
54
- function wbcr_hlp_get_conflict_notices_error($plugin, $page)
55
- {
56
- $is_form_page = in_array($page->id, array(
57
- 'hide_login',
58
- 'defence'
59
- ));
60
-
61
- if( $plugin->getPluginName() == WHLP_Plugin::app()->getPluginName() && $is_form_page ) {
62
-
63
- $install_conflict_plugins = wbcr_hlp_install_conflict_plugins();
64
-
65
- if( !empty($install_conflict_plugins) ) {
66
- foreach((array)$install_conflict_plugins as $plugin) {
67
- if( sizeof($plugin) == 2 ) {
68
- if( $plugin[0] === 0 ) {
69
- $page->printWarningNotice(sprintf(__("We found that you are use the (%s) plugin to change wp-login.php page address. Please delete it, because Clearfy already contains these functions and you do not need to use two plugins. If you do not want to remove (%s) plugin for some reason, please do not use wp-login.php page address change feature in the Clearfy plugin, to avoid conflicts.", 'hide_login_page'), $plugin[1], $plugin[1]));
70
- } else {
71
- $page->printWarningNotice(sprintf(__("We found that you are use the (%s) plugin. Please do not use its wp-login.php page address change and the same feature in the Clearfy plugin, to avoid conflicts.", 'hide_login_page'), $plugin[1], $plugin[1]));
72
- }
73
- }
74
- }
75
- }
76
- }
77
- }
78
-
79
- add_filter('wbcr_factory_pages_401_imppage_print_all_notices', 'wbcr_hlp_get_conflict_notices_error', 10, 2);
80
-
81
- /**
82
- * Виджет отзывов
83
- *
84
- * @param string $page_url
85
- * @param string $plugin_name
86
- * @return string
87
- */
88
- function wbcr_hlp_rating_widget_url($page_url, $plugin_name)
89
- {
90
- if( $plugin_name == WHLP_Plugin::app()->getPluginName() ) {
91
- return 'https://goo.gl/ecaj2V';
92
- }
93
-
94
- return $page_url;
95
- }
96
-
97
- add_filter('wbcr_factory_pages_401_imppage_rating_widget_url', 'wbcr_hlp_rating_widget_url', 10, 2);
98
-
99
- function wbcr_hlp_group_options($options)
100
- {
101
- $options[] = array(
102
- 'name' => 'hide_wp_admin',
103
- 'title' => __('Hide wp-admin', 'hide_login_page'),
104
- 'tags' => array()
105
- );
106
- $options[] = array(
107
- 'name' => 'hide_login_path',
108
- 'title' => __('Hide Login Page', 'hide_login_page'),
109
- 'tags' => array()
110
- );
111
- $options[] = array(
112
- 'name' => 'login_path',
113
- 'title' => __('New login page', 'hide_login_page'),
114
- 'tags' => array()
115
- );
116
-
117
- return $options;
118
- }
119
-
120
- add_filter("wbcr_clearfy_group_options", 'wbcr_hlp_group_options');
121
-
122
- function wbcr_hlp_set_plugin_meta($links, $file)
123
- {
124
- if( $file == WHLP_PLUGIN_BASE ) {
125
- $links[] = '<a href="https://goo.gl/TcMcS4" style="color: #FF5722;font-weight: bold;" target="_blank">' . __('Get ultimate plugin free', 'hide_login_page') . '</a>';
126
- }
127
-
128
- return $links;
129
- }
130
-
131
- if( !defined('LOADING_HIDE_LOGIN_PAGE_AS_ADDON') ) {
132
- add_filter('plugin_row_meta', 'wbcr_hlp_set_plugin_meta', 10, 2);
133
- }
134
-
135
-
136
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
components/hide-login-page/admin/options.php DELETED
@@ -1,255 +0,0 @@
1
- <?php
2
- /**
3
- * Options for additionally form
4
- * @author Webcraftic <wordpress.webraftic@gmail.com>
5
- * @copyright (c) 21.01.2018, Webcraftic
6
- * @version 1.0
7
- */
8
-
9
- // Exit if accessed directly
10
- if( !defined('ABSPATH') ) {
11
- exit;
12
- }
13
-
14
- /**
15
- * We register notifications for some actions
16
- *
17
- * @see libs\factory\pages\themplates\FactoryPages401_ImpressiveThemplate
18
- * @param $notices
19
- * @param Wbcr_Factory400_Plugin $plugin
20
- * @return array
21
- */
22
- function wbcr_hlp_get_action_notices($notices)
23
- {
24
- $notices[] = array(
25
- 'conditions' => array(
26
- 'wbcr_hlp_login_path_incorrect' => 1,
27
- ),
28
- 'type' => 'danger',
29
- 'message' => __('You entered an incorrect part of the path to your login page. The path to the login page can not consist only of digits, at least 3 characters, you must use only the characters [0-9A-z_-]!', 'hide_login_page')
30
- );
31
- $notices[] = array(
32
- 'conditions' => array(
33
- 'wbcr_hlp_login_path_exists' => 1,
34
- ),
35
- 'type' => 'danger',
36
- 'message' => __('The entered login page name is already used for one of your pages. Try to choose a different login page name!', 'hide_login_page')
37
- );
38
-
39
- return $notices;
40
- }
41
-
42
- add_filter('wbcr_factory_pages_401_imppage_actions_notice', 'wbcr_hlp_get_action_notices');
43
-
44
- /**
45
- * @return array
46
- */
47
- function wbcr_hlp_get_plugin_options()
48
- {
49
- $options = array();
50
-
51
- $options[] = array(
52
- 'type' => 'html',
53
- 'html' => '<div class="wbcr-factory-page-group-header">' . __('<strong>Protect your admin login</strong>.', 'hide_login_page') . '<p>' . __('Dozens of bots attack your login page at /wp-login.php and /wp-admin/daily. Bruteforce and want to access your admin panel. Even if you\'re sure that you have created a complex and reliable password, this does not guarantee security and does not relieve your login page load. The easiest way is to protect the login page by simply changing its address to your own and unique.', 'hide_login_page') . '</p></div>'
54
- );
55
-
56
- $options[] = array(
57
- 'type' => 'checkbox',
58
- 'way' => 'buttons',
59
- 'name' => 'hide_wp_admin',
60
- 'title' => __('Hide wp-admin', 'hide_login_page'),
61
- 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
62
- 'hint' => __("Hides the /wp-admin directory for unauthorized users. If the option is disabled, when you request the page /wp-admin you will be redirected to the login page, even if you changed its address. Therefore, for protection purposes enable this option.", 'hide_login_page')
63
- );
64
-
65
- $options[] = array(
66
- 'type' => 'checkbox',
67
- 'way' => 'buttons',
68
- 'name' => 'hide_login_path',
69
- 'title' => __('Hide Login Page', 'hide_login_page'),
70
- 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'red'),
71
- 'hint' => __("Hides the wp-login.php and wp-signup.php pages.", 'hide_login_page') . '<br>--<br><span class="hint-warnign-color">' . __("Use this option carefully! If you forget the new login page address, you can not get into the admin panel.", 'hide_login_page') . '</span>'
72
- );
73
-
74
- $recovery_url = wbcr_hlp_get_recovery_url();
75
- $recovery_url = !empty($recovery_url)
76
- ? '<br><br>' . sprintf(__("If unable to access the login/admin section anymore, use the Recovery Link which reset links to default: \n%s", 'hide_login_page'), $recovery_url)
77
- : '';
78
- $new_login_url = wbcr_hlp_get_new_login_url();
79
-
80
- $options[] = array(
81
- 'type' => 'textbox',
82
- 'name' => 'login_path',
83
- 'placeholder' => 'secure/auth.php',
84
- 'title' => __('New login page', 'hide_login_page'),
85
- 'hint' => __('Set a new login page name without slash. Example: mysecretlogin', 'hide_login_page') . '<br><span style="color:red">' . __("IMPORTANT! Be sure that you wrote down the new login page address", 'hide_login_page') . '</span>: <b><a href="' . $new_login_url . '" target="_blank">' . $new_login_url . '</a></b>' . $recovery_url,
86
- //'units' => '<i class="fa fa-unlock" title="' . __('This option will protect your blog against unauthorized access.', 'hide_login_page') . '"></i>',
87
- //'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'red')
88
- );
89
-
90
- return $options;
91
- }
92
-
93
- /**
94
- * @param $form
95
- * @param $page Wbcr_FactoryPages401_ImpressiveThemplate
96
- * @return mixed
97
- */
98
- function wbcr_hlp_defence_form_options($form, $page)
99
- {
100
- if( empty($form) ) {
101
- return $form;
102
- }
103
-
104
- $options = wbcr_hlp_get_plugin_options();
105
-
106
- foreach($options as $option) {
107
- $form[0]['items'][] = $option;
108
- }
109
-
110
- return $form;
111
- }
112
-
113
- add_filter('wbcr_clr_defence_form_options', 'wbcr_hlp_defence_form_options', 10, 2);
114
-
115
- /**
116
- * Предотвращаем попытки убить доступ к админ панели
117
- *
118
- * @param Wbcr_Factory400_Plugin $plugin
119
- * @param Wbcr_FactoryPages401_ImpressiveThemplate $page
120
- */
121
- function wbcr_hlp_after_form_save($plugin, $page)
122
- {
123
- $is_form_page = in_array($page->id, array(
124
- 'hide_login',
125
- 'defence'
126
- ));
127
-
128
- if( $plugin->getPluginName() == WHLP_Plugin::app()->getPluginName() && $is_form_page ) {
129
-
130
- $login_path = WHLP_Plugin::app()->getOption('login_path');
131
- $valid_path = !is_numeric($login_path) && preg_match('/^[0-9A-z_-]{3,}$/', $login_path);
132
-
133
- if( !empty($login_path) ) {
134
- if( !$valid_path ) {
135
- WHLP_Plugin::app()->deleteOption('login_path');
136
- WHLP_Plugin::app()->deleteOption('hide_login_path');
137
-
138
- $page->redirectToAction('index', array('wbcr_hlp_login_path_incorrect' => 1));
139
- }
140
-
141
- $args = array(
142
- 'name' => $login_path,
143
- 'post_type' => array('page', 'post', 'attachment'),
144
- 'numberposts' => 1
145
- );
146
-
147
- $posts = get_posts($args);
148
-
149
- if( !empty($posts) ) {
150
- WHLP_Plugin::app()->deleteOption('login_path');
151
- WHLP_Plugin::app()->deleteOption('hide_login_path');
152
-
153
- $page->redirectToAction('index', array('wbcr_hlp_login_path_exists' => 1));
154
- }
155
-
156
- $old_login_path = WHLP_Plugin::app()->getOption('old_login_path');
157
-
158
- if( !$old_login_path || $login_path != $old_login_path ) {
159
-
160
- $recovery_code = md5(rand(1, 9999) . microtime());
161
-
162
- $body = __("Hi,\nThis is %s plugin. Here is your new WordPress login address:\nURL: %s", 'hide_login_page') . PHP_EOL . PHP_EOL;
163
- $body .= __("IMPORTANT! Be sure that you wrote down the new login page address", 'hide_login_page') . '!' . PHP_EOL . PHP_EOL;
164
- $body .= __("If unable to access the login/admin section anymore, use the Recovery Link which reset links to default: \n%s", 'hide_login_page') . PHP_EOL . PHP_EOL;
165
- $body .= __("Best Regards,\n%s", 'hide_login_page') . PHP_EOL;
166
-
167
- $new_url = site_url('wp-login.php');
168
-
169
- $body = sprintf($body, WHLP_Plugin::app()
170
- ->getPluginTitle(), $new_url, wbcr_hlp_get_recovery_url($recovery_code), WHLP_Plugin::app()
171
- ->getPluginTitle()) . PHP_EOL;
172
-
173
- $subject = sprintf(__('[%s] Your New WP Login!', 'hide_login_page'), WHLP_Plugin::app()
174
- ->getPluginTitle());
175
-
176
- wp_mail(get_option('admin_email'), $subject, $body);
177
-
178
- WHLP_Plugin::app()->updateOption('old_login_path', $login_path);
179
- WHLP_Plugin::app()->updateOption('login_recovery_code', $recovery_code);
180
- }
181
- } else {
182
-
183
- // if new login path is empty
184
- WHLP_Plugin::app()->deleteOption('old_login_path');
185
- WHLP_Plugin::app()->deleteOption('login_recovery_code');
186
- }
187
- }
188
- }
189
-
190
- add_action('wbcr_factory_400_imppage_after_form_save', 'wbcr_hlp_after_form_save', 10, 2);
191
-
192
- /**
193
- * It is not possible to create a page with the same slugs as the login page
194
- *
195
- * @param string $slug
196
- * @param int $post_ID
197
- * @param string $post_status
198
- * @param string $post_type
199
- * @return string
200
- */
201
- function wbcr_hlp_login_path_noconflict($slug, $post_ID, $post_status, $post_type)
202
- {
203
- if( in_array($post_type, array('post', 'page', 'attachment')) ) {
204
- $login_path = WHLP_Plugin::app()->getOption('login_path');
205
-
206
- if( !empty($login_path) ) {
207
- if( $slug == trim($login_path) ) {
208
- $slug = $slug . rand(10, 99);
209
- }
210
- }
211
- }
212
-
213
- return $slug;
214
- }
215
-
216
- add_filter('wp_unique_post_slug', 'wbcr_hlp_login_path_noconflict', 10, 4);
217
-
218
- /**
219
- * Get the new address of the login page
220
- *
221
- * @return string
222
- */
223
- function wbcr_hlp_get_new_login_url()
224
- {
225
- $login_path = WHLP_Plugin::app()->getOption('login_path');
226
-
227
- if( empty($login_path) ) {
228
- return home_url('/') . 'wp-login.php';
229
- }
230
-
231
- if( WbcrFactoryClearfy200_Helpers::isPermalink() ) {
232
- return WbcrFactoryClearfy200_Helpers::userTrailingslashit(home_url('/') . $login_path);
233
- } else {
234
- return home_url('/') . '?' . $login_path;
235
- }
236
- }
237
-
238
- /**
239
- * Allows you to get a link to reset settings
240
- *
241
- * @param string|null $recovery_code
242
- * @return string|void
243
- */
244
- function wbcr_hlp_get_recovery_url($recovery_code = null)
245
- {
246
- $recovery_code = empty($recovery_code)
247
- ? WHLP_Plugin::app()->getOption('login_recovery_code')
248
- : $recovery_code;
249
-
250
- if( empty($recovery_code) ) {
251
- return '';
252
- }
253
-
254
- return home_url('/?wbcr_hlp_login_recovery=' . $recovery_code);
255
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
components/hide-login-page/admin/pages/hide-login.php DELETED
@@ -1,73 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * The page Settings.
5
- *
6
- * @since 1.0.0
7
- */
8
-
9
- // Exit if accessed directly
10
- if( !defined('ABSPATH') ) {
11
- exit;
12
- }
13
-
14
- class WHLP_HideLoginPage extends Wbcr_FactoryPages401_ImpressiveThemplate {
15
-
16
- /**
17
- * The id of the page in the admin menu.
18
- *
19
- * Mainly used to navigate between pages.
20
- * @see FactoryPages401_AdminPage
21
- *
22
- * @since 1.0.0
23
- * @var string
24
- */
25
- public $id = "hide_login";
26
- public $page_menu_dashicon = 'dashicons-testimonial';
27
-
28
- /**
29
- * @param Wbcr_Factory400_Plugin $plugin
30
- */
31
- public function __construct(Wbcr_Factory400_Plugin $plugin)
32
- {
33
- $this->menu_title = __('Hide login page', 'hide_login_page');
34
-
35
- if( !defined('LOADING_HIDE_LOGIN_PAGE_AS_ADDON') ) {
36
- $this->internal = false;
37
- $this->menu_target = 'options-general.php';
38
- $this->add_link_to_plugin_actions = true;
39
- }
40
-
41
- parent::__construct($plugin);
42
-
43
- $this->plugin = $plugin;
44
- }
45
-
46
- public function getMenuTitle()
47
- {
48
- return defined('LOADING_HIDE_LOGIN_PAGE_AS_ADDON')
49
- ? __('Hide login page', 'hide_login_page')
50
- : __('General', 'hide_login_page');
51
- }
52
-
53
- /**
54
- * Permalinks options.
55
- *
56
- * @since 1.0.0
57
- * @return mixed[]
58
- */
59
- public function getOptions()
60
- {
61
- $options = wbcr_hlp_get_plugin_options();
62
-
63
- $formOptions = array();
64
-
65
- $formOptions[] = array(
66
- 'type' => 'form-group',
67
- 'items' => $options,
68
- //'cssClass' => 'postbox'
69
- );
70
-
71
- return apply_filters('wbcr_hlp_general_form_options', $formOptions, $this);
72
- }
73
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
components/hide-login-page/hide-login-page.php DELETED
@@ -1,59 +0,0 @@
1
- <?php
2
- /**
3
- * Plugin Name: Webcraftic Hide Login Page
4
- * Plugin URI: https://wordpress.org/plugins/hide-login-page/
5
- * Description: Hide Login Page is a very light plugin that lets you easily and safely change the url of the login form page to anything you want.
6
- * Author: Webcraftic <wordpress.webraftic@gmail.com>
7
- * Version: 1.0.0
8
- * Text Domain: cyrlitera
9
- * Domain Path: /languages/
10
- * Author URI: http://webcraftic.com
11
- */
12
-
13
- // Exit if accessed directly
14
- if( !defined('ABSPATH') ) {
15
- exit;
16
- }
17
-
18
- if( defined('WHLP_PLUGIN_ACTIVE') || (defined('WCL_PLUGIN_ACTIVE') && !defined('LOADING_HIDE_LOGIN_PAGE_AS_ADDON')) ) {
19
- function wbcr_hlp_admin_notice_error()
20
- {
21
- ?>
22
- <div class="notice notice-error">
23
- <p><?php _e('We found that you have the "Clearfy - disable unused features" plugin installed, this plugin already has disable comments functions, so you can deactivate plugin "Hide Login Page"!', 'hide_login_page'); ?></p>
24
- </div>
25
- <?php
26
- }
27
-
28
- add_action('admin_notices', 'wbcr_hlp_admin_notice_error');
29
-
30
- return;
31
- } else {
32
-
33
- define('WHLP_PLUGIN_ACTIVE', true);
34
- define('WHLP_PLUGIN_DIR', dirname(__FILE__));
35
- define('WHLP_PLUGIN_BASE', plugin_basename(__FILE__));
36
- define('WHLP_PLUGIN_URL', plugins_url(null, __FILE__));
37
-
38
-
39
-
40
- if( !defined('LOADING_HIDE_LOGIN_PAGE_AS_ADDON') ) {
41
- require_once(WHLP_PLUGIN_DIR . '/libs/factory/core/boot.php');
42
- }
43
-
44
- require_once(WHLP_PLUGIN_DIR . '/includes/class.plugin.php');
45
-
46
- if( !defined('LOADING_HIDE_LOGIN_PAGE_AS_ADDON') ) {
47
-
48
- new WHLP_Plugin(__FILE__, array(
49
- 'prefix' => 'wbcr_hlp_',
50
- 'plugin_name' => 'wbcr_hide_login_page',
51
- 'plugin_title' => __('Webcraftic Hide login page', 'hide_login_page'),
52
- 'plugin_version' => '1.0.0',
53
- 'required_php_version' => '5.2',
54
- 'required_wp_version' => '4.2',
55
- 'plugin_build' => 'free',
56
- //'updates' => WHLP_PLUGIN_DIR . '/updates/'
57
- ));
58
- }
59
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
components/hide-login-page/includes/class.plugin.php DELETED
@@ -1,127 +0,0 @@
1
- <?php
2
- /**
3
- * Hide login page core class
4
- * @author Webcraftic <wordpress.webraftic@gmail.com>
5
- * @copyright (c) 19.02.2018, Webcraftic
6
- * @version 1.0
7
- */
8
-
9
- // Exit if accessed directly
10
- if( !defined('ABSPATH') ) {
11
- exit;
12
- }
13
-
14
- if( !class_exists('WHLP_Plugin') ) {
15
-
16
- if( !class_exists('WHLP_PluginFactory') ) {
17
- if( defined('LOADING_HIDE_LOGIN_PAGE_AS_ADDON') ) {
18
- class WHLP_PluginFactory {
19
-
20
- }
21
- } else {
22
- class WHLP_PluginFactory extends Wbcr_Factory400_Plugin {
23
-
24
- }
25
- }
26
- }
27
-
28
- class WHLP_Plugin extends WHLP_PluginFactory {
29
-
30
- /**
31
- * @var Wbcr_Factory400_Plugin
32
- */
33
- private static $app;
34
-
35
- /**
36
- * @var bool
37
- */
38
- private $as_addon;
39
-
40
- /**
41
- * @param string $plugin_path
42
- * @param array $data
43
- * @throws Exception
44
- */
45
- public function __construct($plugin_path, $data)
46
- {
47
- $this->as_addon = isset($data['as_addon']);
48
-
49
- if( $this->as_addon ) {
50
- $plugin_parent = isset($data['plugin_parent'])
51
- ? $data['plugin_parent']
52
- : null;
53
-
54
- if( !($plugin_parent instanceof Wbcr_Factory400_Plugin) ) {
55
- throw new Exception('An invalid instance of the class was passed.');
56
- }
57
-
58
- self::$app = $plugin_parent;
59
- } else {
60
- self::$app = $this;
61
- }
62
-
63
- if( !$this->as_addon ) {
64
- parent::__construct($plugin_path, $data);
65
- }
66
-
67
- $this->setTextDomain();
68
- $this->setModules();
69
-
70
- $this->globalScripts();
71
-
72
- if( is_admin() ) {
73
- $this->adminScripts();
74
- }
75
- }
76
-
77
- /**
78
- * @return Wbcr_Factory400_Plugin
79
- */
80
- public static function app()
81
- {
82
- return self::$app;
83
- }
84
-
85
- protected function setTextDomain()
86
- {
87
-
88
- load_plugin_textdomain('hide_login_page', false, dirname(WHLP_PLUGIN_BASE) . '/languages/');
89
- }
90
-
91
- protected function setModules()
92
- {
93
- if( !$this->as_addon ) {
94
- self::app()->load(array(
95
- array('libs/factory/bootstrap', 'factory_bootstrap_400', 'admin'),
96
- array('libs/factory/forms', 'factory_forms_400', 'admin'),
97
- array('libs/factory/pages', 'factory_pages_401', 'admin'),
98
- array('libs/factory/clearfy', 'factory_clearfy_200', 'all')
99
- ));
100
- }
101
- }
102
-
103
- private function registerPages()
104
- {
105
- if( $this->as_addon ) {
106
- return;
107
- }
108
-
109
- self::app()->registerPage('WHLP_HideLoginPage', WHLP_PLUGIN_DIR . '/admin/pages/hide-login.php');
110
- self::app()->registerPage('WHLP_MoreFeaturesPage', WHLP_PLUGIN_DIR . '/admin/pages/more-features.php');
111
- }
112
-
113
- private function adminScripts()
114
- {
115
- require_once(WHLP_PLUGIN_DIR . '/admin/boot.php');
116
- require_once(WHLP_PLUGIN_DIR . '/admin/options.php');
117
-
118
- $this->registerPages();
119
- }
120
-
121
- private function globalScripts()
122
- {
123
- require_once(WHLP_PLUGIN_DIR . '/includes/classes/class.configurate-hide-login-page.php');
124
- new WHLP_ConfigHideLoginPage(self::$app);
125
- }
126
- }
127
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
components/hide-login-page/includes/classes/class.configurate-hide-login-page.php DELETED
@@ -1,247 +0,0 @@
1
- <?php
2
- /**
3
- * This class configures hide login page
4
- * @author Webcraftic <wordpress.webraftic@gmail.com>
5
- * @copyright (c) 2017 Webraftic Ltd
6
- * @version 1.0
7
- */
8
-
9
- // Exit if accessed directly
10
- if( !defined('ABSPATH') ) {
11
- exit;
12
- }
13
-
14
- class WHLP_ConfigHideLoginPage extends Wbcr_FactoryClearfy200_Configurate {
15
-
16
- /**
17
- * @var bool
18
- */
19
- private $wp_login_php;
20
-
21
- /**
22
- * @var bool
23
- */
24
- private $disable_wp_admin;
25
-
26
- /**
27
- * @var bool
28
- */
29
- private $disable_wp_login;
30
-
31
- /**
32
- * @var string
33
- */
34
- private $login_path;
35
-
36
-
37
- public function registerActionsAndFilters()
38
- {
39
- $this->disable_wp_admin = WHLP_Plugin::app()->getOption('hide_wp_admin');
40
- $this->disable_wp_login = WHLP_Plugin::app()->getOption('hide_login_path');
41
- $this->login_path = WHLP_Plugin::app()->getOption('login_path');
42
-
43
- add_filter('init', array($this, 'init'));
44
-
45
- if( $this->disable_wp_admin ) {
46
- add_filter('auth_redirect_scheme', array($this, 'stopRedirect'), 9999);
47
- }
48
-
49
- if( $this->login_path ) {
50
- add_action('plugins_loaded', array($this, 'pluginsLoaded'), 9999);
51
- add_action('wp_loaded', array($this, 'wpLoaded'));
52
- add_filter('site_url', array($this, 'siteUrl'), 10, 4);
53
- add_filter('wp_redirect', array($this, 'wpRedirect'), 10, 2);
54
- add_filter('site_option_welcome_email', array($this, 'welcomeEmail'));
55
- }
56
- }
57
-
58
-
59
- public function init()
60
- {
61
- if( $this->disable_wp_admin ) {
62
- remove_action('template_redirect', 'wp_redirect_admin_locations', 9999);
63
- }
64
-
65
- //check for recovery link run
66
- if( !empty($this->login_path) && isset($_GET['wbcr_hlp_login_recovery']) ) {
67
- $user_recovery_code = sanitize_text_field($_GET['wbcr_hlp_login_recovery']);
68
- $plugin_recovery_code = $this->getOption('login_recovery_code');
69
-
70
- if( empty($plugin_recovery_code) || empty($user_recovery_code) || $user_recovery_code !== $plugin_recovery_code ) {
71
- return;
72
- }
73
-
74
- $this->plugin->deleteOption('hide_wp_admin');
75
- $this->plugin->deleteOption('login_path');
76
- $this->plugin->deleteOption('hide_login_path');
77
- $this->plugin->deleteOption('old_login_path');
78
- $this->plugin->deleteOption('login_recovery_code');
79
-
80
- $this->login_path = null;
81
- $this->disable_wp_login = null;
82
- $this->disable_wp_admin = null;
83
- $this->wp_login_php = false;
84
-
85
- wp_safe_redirect(admin_url());
86
- exit;
87
- }
88
- }
89
-
90
-
91
- function stopRedirect($scheme)
92
- {
93
- if( $user_id = wp_validate_auth_cookie('', $scheme) ) {
94
- return $scheme;
95
- }
96
-
97
- WbcrFactoryClearfy200_Helpers::setError404();
98
- }
99
-
100
- public function pluginsLoaded()
101
- {
102
- global $pagenow;
103
-
104
- $request = parse_url($_SERVER['REQUEST_URI']);
105
-
106
- $is_login = WbcrFactoryClearfy200_Helpers::strContains(rawurldecode($_SERVER['REQUEST_URI']), 'wp-login.php') || untrailingslashit($request['path']) === site_url('wp-login', 'relative');
107
- $is_signup = WbcrFactoryClearfy200_Helpers::strContains(rawurldecode($_SERVER['REQUEST_URI']), 'wp-signup');
108
- $is_activate = WbcrFactoryClearfy200_Helpers::strContains(rawurldecode($_SERVER['REQUEST_URI']), 'wp-activate');
109
-
110
- if( ($is_login || $is_signup || $is_activate) && !is_admin() ) {
111
- $this->wp_login_php = true;
112
- $pagenow = 'index.php';
113
- } elseif( (untrailingslashit($request['path']) === home_url($this->login_path, 'relative')) || (!get_option('permalink_structure') && isset($_GET[$this->login_path]) && empty($_GET[$this->login_path])) ) {
114
- $pagenow = 'wp-login.php';
115
- }
116
- }
117
-
118
- public function wpLoaded()
119
- {
120
- global $pagenow;
121
-
122
- if( is_admin() && !is_user_logged_in() && !defined('DOING_AJAX') && $pagenow !== 'admin-post.php' ) {
123
- $ddisable_wp_admin = WHLP_Plugin::app()->getOption('hide_wp_admin');
124
-
125
- if( !$ddisable_wp_admin ) {
126
- $redirect_uri = untrailingslashit(home_url($this->login_path));
127
-
128
- if( !get_option('permalink_structure') ) {
129
- $redirect_uri = add_query_arg(array(
130
- $this->login_path => ''
131
- ), home_url());
132
- }
133
-
134
- wp_safe_redirect($redirect_uri);
135
- die();
136
- }
137
-
138
- return;
139
- }
140
-
141
- $request = parse_url($_SERVER['REQUEST_URI']);
142
-
143
- if( $pagenow === 'wp-login.php' && $request['path'] !== WbcrFactoryClearfy200_Helpers::userTrailingslashit($request['path']) && get_option('permalink_structure') ) {
144
- $query_string = !empty($_SERVER['QUERY_STRING'])
145
- ? '?' . $_SERVER['QUERY_STRING']
146
- : '';
147
-
148
- wp_safe_redirect(WbcrFactoryClearfy200_Helpers::userTrailingslashit($this->login_path) . $query_string);
149
- die();
150
- } elseif( $this->wp_login_php ) {
151
- $new_login_redirect = false;
152
- $referer = wp_get_referer();
153
- $parse_referer = parse_url($referer);
154
-
155
- if( $referer && WbcrFactoryClearfy200_Helpers::strContains($referer, 'wp-activate.php') && $parse_referer && !empty($parse_referer['query']) ) {
156
-
157
- parse_str($parse_referer['query'], $parse_referer);
158
-
159
- if( !empty($parse_referer['key']) && ($result = wpmu_activate_signup($parse_referer['key'])) && is_wp_error($result) && ($result->get_error_code() === 'already_active' || $result->get_error_code() === 'blog_taken') ) {
160
- $new_login_redirect = true;
161
- }
162
- }
163
-
164
- if( !$this->disable_wp_login || $new_login_redirect ) {
165
- $query_string = !empty($_SERVER['QUERY_STRING'])
166
- ? '?' . $_SERVER['QUERY_STRING']
167
- : '';
168
-
169
- if( WbcrFactoryClearfy200_Helpers::isPermalink() ) {
170
- $redirect_uri = $this->login_path . $query_string;
171
- } else {
172
- $redirect_uri = home_url() . '/' . add_query_arg(array(
173
- $this->login_path => ''
174
- ), $query_string);
175
- }
176
-
177
- if( WbcrFactoryClearfy200_Helpers::strContains($_SERVER['REQUEST_URI'], 'wp-signup') ) {
178
- $redirect_uri = add_query_arg(array(
179
- 'action' => 'register'
180
- ), $redirect_uri);
181
- }
182
-
183
- wp_safe_redirect($redirect_uri);
184
- die();
185
- }
186
-
187
- WbcrFactoryClearfy200_Helpers::setError404();
188
- } elseif( $pagenow === 'wp-login.php' ) {
189
- if( is_user_logged_in() && !isset($_REQUEST['action']) ) {
190
- wp_safe_redirect(admin_url());
191
- die();
192
- }
193
-
194
- if( !defined('DONOTCACHEPAGE') ) {
195
- define('DONOTCACHEPAGE', true);
196
- }
197
-
198
- @require_once ABSPATH . 'wp-login.php';
199
-
200
- die();
201
- }
202
- }
203
-
204
- public function siteUrl($url, $path, $scheme, $blog_id)
205
- {
206
- return $this->filterWpLoginPhp($url, $scheme);
207
- }
208
-
209
- public function wpRedirect($location, $status)
210
- {
211
- return $this->filterWpLoginPhp($location);
212
- }
213
-
214
- public function filterWpLoginPhp($url, $scheme = null)
215
- {
216
- if( strpos($url, 'wp-login.php') !== false ) {
217
- if( is_ssl() ) {
218
- $scheme = 'https';
219
- }
220
-
221
- $args = explode('?', $url);
222
-
223
- if( isset($args[1]) ) {
224
- parse_str($args[1], $args);
225
- $url = add_query_arg($args, $this->newLoginUrl($scheme));
226
- } else {
227
- $url = $this->newLoginUrl($scheme);
228
- }
229
- }
230
-
231
- return $url;
232
- }
233
-
234
- public function welcomeEmail($value)
235
- {
236
- return $value = str_replace('wp-login.php', WbcrFactoryClearfy200_Helpers::userTrailingslashit($this->login_path), $value);
237
- }
238
-
239
- public function newLoginUrl($scheme = null)
240
- {
241
- if( WbcrFactoryClearfy200_Helpers::isPermalink() ) {
242
- return WbcrFactoryClearfy200_Helpers::userTrailingslashit(home_url('/', $scheme) . $this->login_path);
243
- } else {
244
- return home_url('/', $scheme) . '?' . $this->login_path;
245
- }
246
- }
247
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
components/hide-login-page/languages/hide_login_page-ru_RU.mo DELETED
Binary file
components/hide-login-page/languages/hide_login_page-ru_RU.po DELETED
@@ -1,191 +0,0 @@
1
- msgid ""
2
- msgstr ""
3
- "Project-Id-Version: clearfy\n"
4
- "POT-Creation-Date: 2018-03-23 03:15+0300\n"
5
- "PO-Revision-Date: 2018-03-23 03:17+0300\n"
6
- "Last-Translator: alex.kovalevv@gmail.com <alex.kovalevv@gmail.com>\n"
7
- "Language-Team: Alex Kovalev <alex.kovalevv@gmail.com>\n"
8
- "Language: ru_RU\n"
9
- "MIME-Version: 1.0\n"
10
- "Content-Type: text/plain; charset=UTF-8\n"
11
- "Content-Transfer-Encoding: 8bit\n"
12
- "X-Generator: Poedit 1.8.8\n"
13
- "X-Poedit-Basepath: ..\n"
14
- "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
15
- "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
16
- "X-Poedit-SourceCharset: UTF-8\n"
17
- "X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c\n"
18
- "X-Poedit-SearchPath-0: .\n"
19
- "X-Poedit-SearchPathExcluded-0: libs\n"
20
- "X-Poedit-SearchPathExcluded-1: components\n"
21
- "X-Poedit-SearchPathExcluded-2: cache\n"
22
-
23
- #: admin/boot.php:69
24
- #, php-format
25
- msgid ""
26
- "We found that you are use the (%s) plugin to change wp-login.php page "
27
- "address. Please delete it, because Clearfy already contains these functions "
28
- "and you do not need to use two plugins. If you do not want to remove (%s) "
29
- "plugin for some reason, please do not use wp-login.php page address change "
30
- "feature in the Clearfy plugin, to avoid conflicts."
31
- msgstr ""
32
- "Мы обнаружили, что вы используете плагин (%s) для изменения адреса страницы "
33
- "wp-login.php. Пожалуйста удалите его, так как Clearfy уже содержит эти "
34
- "функции и вам незачем использовать два плагина. Если вы по каким-то причинам "
35
- "не хотите удалять плагин (%s), пожалуйста не используйте функции по "
36
- "изменению адреса страницы wp-login.php в плагине Clearfy, во избежание "
37
- "конфликтов."
38
-
39
- #: admin/boot.php:71
40
- #, php-format
41
- msgid ""
42
- "We found that you are use the (%s) plugin. Please do not use its wp-login."
43
- "php page address change and the same feature in the Clearfy plugin, to avoid "
44
- "conflicts."
45
- msgstr ""
46
- "Мы обнаружили, что вы используете плагин (%s). Пожалуйста не используйте его "
47
- "функции по изменению адреса страницы wp-login.php и схожие функции в плагине "
48
- "Clearfy, во избежание конфликтов."
49
-
50
- #: admin/boot.php:103 admin/options.php:60
51
- msgid "Hide wp-admin"
52
- msgstr "Скрыть wp-admin"
53
-
54
- #: admin/boot.php:108 admin/options.php:69
55
- msgid "Hide Login Page"
56
- msgstr "Скрыть страницу логина"
57
-
58
- #: admin/boot.php:113 admin/options.php:84
59
- msgid "New login page"
60
- msgstr "Новый адрес страницы логина"
61
-
62
- #: admin/boot.php:125
63
- msgid "Get ultimate plugin free"
64
- msgstr "Получите полную версию плагина бесплатно"
65
-
66
- #: admin/options.php:29
67
- msgid ""
68
- "You entered an incorrect part of the path to your login page. The path to "
69
- "the login page can not consist only of digits, at least 3 characters, you "
70
- "must use only the characters [0-9A-z_-]!"
71
- msgstr ""
72
- "Вы ввели неправильную часть пути к своей странице входа. Путь к странице "
73
- "входа не может состоять только из цифр, не менее 3 символов, вы должны "
74
- "использовать только символы [0-9A-z_-]!"
75
-
76
- #: admin/options.php:36
77
- msgid ""
78
- "The entered login page name is already used for one of your pages. Try to "
79
- "choose a different login page name!"
80
- msgstr ""
81
- "Введенное имя учетной записи уже используется для одной из ваших страниц. "
82
- "Попробуйте выбрать другое имя учетной записи!"
83
-
84
- #: admin/options.php:53
85
- msgid "<strong>Protect your admin login</strong>."
86
- msgstr "<strong>Защитите вашу страницу логина</strong>."
87
-
88
- #: admin/options.php:53
89
- msgid ""
90
- "Dozens of bots attack your login page at /wp-login.php and /wp-admin/daily. "
91
- "Bruteforce and want to access your admin panel. Even if you're sure that you "
92
- "have created a complex and reliable password, this does not guarantee "
93
- "security and does not relieve your login page load. The easiest way is to "
94
- "protect the login page by simply changing its address to your own and unique."
95
- msgstr ""
96
- "Десятки ботов ежедневно атакуют вашу страницу логина по адресам /wp-login."
97
- "php и /wp-admin/, перебирая пароли, желая получить доступ в вашу админ "
98
- "панель. Даже если вы уверены, что создали сложный и надежный пароль, это не "
99
- "гарантирует безопасность и не избавляет от нагрузки вашу страницу логина. "
100
- "Проще всего защитить страницу логина, просто изменив её адрес на собственный "
101
- "и уникальный."
102
-
103
- #: admin/options.php:62
104
- msgid ""
105
- "Hides the /wp-admin directory for unauthorized users. If the option is "
106
- "disabled, when you request the page /wp-admin you will be redirected to the "
107
- "login page, even if you changed its address. Therefore, for protection "
108
- "purposes enable this option."
109
- msgstr ""
110
- "Скрывает каталог /wp-admin для неавторизованных пользователей. Если опция "
111
- "отключена, при запросе страницы /wp-admin вы будете перенаправлены на "
112
- "страницу логина, даже если вы изменили ее адрес. Поэтому в целях защиты, "
113
- "включите эту опцию."
114
-
115
- #: admin/options.php:71
116
- msgid "Hides the wp-login.php and wp-signup.php pages."
117
- msgstr "Скрывает страницу wp-login.php, wp-signup.php."
118
-
119
- #: admin/options.php:71
120
- msgid ""
121
- "Use this option carefully! If you forget the new login page address, you can "
122
- "not get into the admin panel."
123
- msgstr ""
124
- "Используйте эту опцию осторожно, если вы забудете новый адрес страницы "
125
- "логина, вы не сможете попасть в админ панель."
126
-
127
- #: admin/options.php:76 admin/options.php:164
128
- #, php-format
129
- msgid ""
130
- "If unable to access the login/admin section anymore, use the Recovery Link "
131
- "which reset links to default: \n"
132
- "%s"
133
- msgstr ""
134
- "Если вы больше не можете получить доступ к разделу login/admin, используйте "
135
- "ссылку восстановления, которая восстанавливает ссылки по умолчанию: \n"
136
- "%s"
137
-
138
- #: admin/options.php:85
139
- msgid "Set a new login page name without slash. Example: mysecretlogin"
140
- msgstr "Задайте новое имя страницы логина без слешей. Пример: mysecretlogin"
141
-
142
- #: admin/options.php:85 admin/options.php:163
143
- msgid "IMPORTANT! Be sure that you wrote down the new login page address"
144
- msgstr "ВАЖНО! Обязательно запишите новый адрес страницы логина"
145
-
146
- #: admin/options.php:162
147
- #, php-format
148
- msgid ""
149
- "Hi,\n"
150
- "This is %s plugin. Here is your new WordPress login address:\n"
151
- "URL: %s"
152
- msgstr ""
153
- "Здравствуйте!\n"
154
- "Это плагин %s. Вы изменили адрес страницы логина на:\n"
155
- "URL: %s"
156
-
157
- #: admin/options.php:165
158
- #, php-format
159
- msgid ""
160
- "Best Regards,\n"
161
- "%s"
162
- msgstr ""
163
- "С уважением,\n"
164
- "%s"
165
-
166
- #: admin/options.php:173
167
- #, php-format
168
- msgid "[%s] Your New WP Login!"
169
- msgstr "[%s] Измен адрес страницы логина!"
170
-
171
- #: admin/pages/hide-login.php:33 admin/pages/hide-login.php:49
172
- msgid "Hide login page"
173
- msgstr "Скрыть страницу логина"
174
-
175
- #: admin/pages/hide-login.php:50
176
- msgid "General"
177
- msgstr "Основные"
178
-
179
- #: hide-login-page.php:23
180
- msgid ""
181
- "We found that you have the \"Clearfy - disable unused features\" plugin "
182
- "installed, this plugin already has disable comments functions, so you can "
183
- "deactivate plugin \"Hide Login Page\"!"
184
- msgstr ""
185
- "Мы обнаружили, что у вас установлен плагин «Clearfy - отключить "
186
- "неиспользуемые функции», этот плагин уже имеет функции отключения "
187
- "комментариев, поэтому вы можете отключить плагин «Hide Login Page»!"
188
-
189
- #: hide-login-page.php:80
190
- msgid "Webcraftic Hide login page"
191
- msgstr "Webcraftic Скрыть страницу логина"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
components/hide-login-page/readme.txt DELETED
@@ -1,34 +0,0 @@
1
- === Webcraftic Hide Login Page ===
2
- Tags: rename, login, wp-login, wp-login.php, custom login url
3
- Contributors: webcraftic
4
- Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=VDX7JNTQPNPFW
5
- Requires at least: 4.2
6
- Tested up to: 4.9
7
- Requires PHP: 5.2
8
- Stable tag: trunk
9
- License: GPLv2
10
-
11
- Hide Login Page is a very light plugin that lets you easily and safely change the url of the login form page to anything you want.
12
-
13
- == Description ==
14
-
15
- Hide Login Page is a very light plugin that lets you easily and safely change the url of the login form page to anything you want.
16
-
17
- #### RECOMMENDED SEPARATE MODULES ####
18
- We invite you to check out a few other related free plugins that our team has also produced that you may find especially useful:
19
-
20
- * [Clearfy – WordPress optimization plugin and disable ultimate tweaker](https://wordpress.org/plugins/clearfy/)
21
- * [WordPress Assets manager, dequeue scripts, dequeue styles](https://wordpress.org/plugins/gonzales/)
22
- * [Disable Comments for Any Post Types (Remove Comments)](https://wordpress.org/plugins/comments-plus/)
23
- * [Disable updates, Disable automatic updates, Updates manager](https://wordpress.org/plugins/webcraftic-updates-manager/)
24
- * [Disable admin notices individually](https://wordpress.org/plugins/disable-admin-notices/ "Disable admin notices individually")
25
-
26
- == Installation ==
27
-
28
- 1. Upload the plugin files to the `/wp-content/plugins/plugin-name` directory, or install the plugin through the WordPress plugins screen directly.
29
- 2. Activate the plugin through the 'Plugins' screen in WordPress
30
- 3. Go to the general settings and click on the "Hide login page" tab, activate the options and save the settings.
31
-
32
- == Changelog ==
33
- = 1.0.0 =
34
- * Plugin release
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
components/html-minify/admin/boot.php ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Admin boot
4
+ * @author Webcraftic <wordpress.webraftic@gmail.com>
5
+ * @copyright Webcraftic 25.05.2017
6
+ * @version 1.0
7
+ */
8
+
9
+ // Exit if accessed directly
10
+ if( !defined('ABSPATH') ) {
11
+ exit;
12
+ }
13
+
14
+ /**
15
+ * Печатает ошибки совместимости с похожими плагинами
16
+ */
17
+ add_action('wbcr_factory_notices_405_list', function ($notices, $plugin_name) {
18
+ if( $plugin_name != WHTM_Plugin::app()->getPluginName() ) {
19
+ return $notices;
20
+ }
21
+
22
+ if( is_plugin_active('autoptimize/autoptimize.php') ) {
23
+ $notice_text = __('Clearfy: Html minify component is not compatible with the Autoptimize plugin, please do not use them together to avoid conflicts. Please disable the Html minify component', 'html-minify');
24
+
25
+ if( class_exists('WCL_Plugin') ) {
26
+ $component_button = WCL_Plugin::app()->getInstallComponentsButton('internal', 'html_minify');
27
+ $notice_text .= ' ' . $component_button->getLink();
28
+ }
29
+
30
+ $notices[] = array(
31
+ 'id' => 'mac_plugin_compatibility',
32
+ 'type' => 'error',
33
+ 'classes' => array('wbcr-hide-after-action'),
34
+ 'dismissible' => false,
35
+ 'dismiss_expires' => 0,
36
+ 'text' => '<p>' . $notice_text . '</p>'
37
+ );
38
+ }
39
+
40
+ return $notices;
41
+ }, 10, 2);
42
+
43
+ add_filter("wbcr_clearfy_group_options", function ($options) {
44
+ $options[] = array(
45
+ 'name' => 'html_optimize',
46
+ 'title' => __('Optimize HTML Code?', 'html-minify'),
47
+ 'tags' => array('optimize_html', 'optimize_code', 'hide_my_wp'),
48
+ 'values' => array()
49
+ );
50
+ $options[] = array(
51
+ 'name' => 'html_keepcomments',
52
+ 'title' => __('Keep HTML comments?', 'html-minify'),
53
+ 'tags' => array(),
54
+ 'values' => array()
55
+ );
56
+
57
+ return $options;
58
+ });
59
+
60
+ /**
61
+ * Adds a new mode to the Quick Setup page
62
+ *
63
+ * @param array $mods
64
+ * @return mixed
65
+ */
66
+
67
+ add_filter("wbcr_clearfy_allow_quick_mods", function ($mods) {
68
+ if( !defined('WMAC_PLUGIN_ACTIVE') ) {
69
+ $title = __('One click optimize html code', 'html-minify');
70
+ } else {
71
+ $title = __('One click optimize html code and scripts', 'html-minify');
72
+ }
73
+
74
+ $mod['optimize_code'] = array(
75
+ 'title' => $title,
76
+ 'icon' => 'dashicons-performance'
77
+ );
78
+
79
+ return $mod + $mods;
80
+ });
81
+
82
+
components/html-minify/admin/index.php ADDED
File without changes
components/html-minify/admin/pages/index.php ADDED
File without changes
components/html-minify/admin/pages/settings.php ADDED
@@ -0,0 +1,127 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * The page Settings.
5
+ *
6
+ * @since 1.0.0
7
+ */
8
+
9
+ // Exit if accessed directly
10
+ if( !defined('ABSPATH') ) {
11
+ exit;
12
+ }
13
+
14
+ class WHTM_SettingsPage extends Wbcr_FactoryPages407_ImpressiveThemplate {
15
+
16
+ /**
17
+ * The id of the page in the admin menu.
18
+ *
19
+ * Mainly used to navigate between pages.
20
+ * @see Wbcr_FactoryPages407_AdminPage
21
+ *
22
+ * @since 1.0.0
23
+ * @var string
24
+ */
25
+ public $id = "html_minify"; // Уникальный идентификатор страницы
26
+ public $page_menu_dashicon = 'dashicons-testimonial'; // Иконка для закладки страницы, дашикон
27
+ public $page_parent_page = "performance"; // Уникальный идентификатор родительской страницы
28
+
29
+ /**
30
+ * @param Wbcr_Factory406_Plugin $plugin
31
+ */
32
+ public function __construct(Wbcr_Factory406_Plugin $plugin)
33
+ {
34
+ // Заголовок страницы
35
+ $this->menu_title = __('HTML Minify', 'html-minify');
36
+
37
+ // Если плагин загружен, как самостоятельный, то мы меняем настройки страницы и делаем ее внешней,
38
+ // а не внутренней страницей родительского плагина. Внешнии страницы добавляются в Wordpress меню "Общие"
39
+
40
+ if( !defined('LOADING_HTML_MINIFY_AS_ADDON') ) {
41
+ // true - внутреняя, false- внешняя страница
42
+ $this->internal = false;
43
+ // меню к которому, нужно прикрепить ссылку на страницу
44
+ $this->menu_target = 'options-general.php';
45
+ // Если true, добавляет ссылку "Настройки", рядом с действиями активации, деактивации плагина, на странице плагинов.
46
+ $this->add_link_to_plugin_actions = true;
47
+
48
+ $this->page_parent_page = null;
49
+ }
50
+
51
+ parent::__construct($plugin);
52
+ }
53
+
54
+ // Метод позволяет менять заголовок меню, в зависимости от сборки плагина.
55
+ public function getMenuTitle()
56
+ {
57
+ return defined('LOADING_HTML_MINIFY_AS_ADDON')
58
+ ? __('HTML Minify', 'html-minify')
59
+ : __('General', 'html-minify');
60
+ }
61
+
62
+ /**
63
+ * Requests assets (js and css) for the page.
64
+ *
65
+ * @see Wbcr_FactoryPages407_AdminPage
66
+ *
67
+ * @since 1.0.0
68
+ * @return void
69
+ */
70
+ public function assets($scripts, $styles)
71
+ {
72
+ parent::assets($scripts, $styles);
73
+
74
+ // Add Clearfy styles for HMWP pages
75
+ if( defined('WBCR_CLEARFY_PLUGIN_ACTIVE') ) {
76
+ $this->styles->add(WCL_PLUGIN_URL . '/admin/assets/css/general.css');
77
+ }
78
+ }
79
+
80
+ /**
81
+ * Метод должен передать массив опций для создания формы с полями.
82
+ * Созданием страницы и формы занимается фреймворк
83
+ *
84
+ * @since 1.0.0
85
+ * @return mixed[]
86
+ */
87
+ public function getOptions()
88
+ {
89
+ $options = array();
90
+
91
+ $options[] = array(
92
+ 'type' => 'html',
93
+ 'html' => '<div class="wbcr-factory-page-group-header"><strong>' . __('HTML Options', 'html-minify') . '</strong><p>' . __('Ever look at the HTML markup of your website and notice how sloppy and amateurish it looks? The Minify HTML options cleans up sloppy looking markup and minifies, which also speeds up download.', 'html-minify') . '</p></div>'
94
+ );
95
+
96
+ // Переключатель
97
+ $options[] = array(
98
+ 'type' => 'checkbox',
99
+ 'way' => 'buttons',
100
+ 'name' => 'html_optimize',
101
+ 'title' => __('Optimize HTML Code?', 'html-minify'),
102
+ 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
103
+ 'default' => false,
104
+ );
105
+
106
+ // Переключатель
107
+ $options[] = array(
108
+ 'type' => 'checkbox',
109
+ 'way' => 'buttons',
110
+ 'name' => 'html_keepcomments',
111
+ 'title' => __('Keep HTML comments?', 'html-minify'),
112
+ 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
113
+ 'hint' => __('Enable this if you want HTML comments to remain in the page.', 'html-minify'),
114
+ 'default' => false
115
+ );
116
+
117
+ $formOptions = array();
118
+
119
+ $formOptions[] = array(
120
+ 'type' => 'form-group',
121
+ 'items' => $options,
122
+ //'cssClass' => 'postbox'
123
+ );
124
+
125
+ return apply_filters('wbcr_htm_settings_form_options', $formOptions);
126
+ }
127
+ }
components/html-minify/html-minify.php ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Plugin Name: HTML Мinify
4
+ * Plugin URI: https://clearfy.pro/html-minify/
5
+ * Description: Ever look at the HTML markup of your website and notice how sloppy and amateurish it looks? The HTML Мinify options cleans up sloppy looking markup and minifies, which also speeds up download.
6
+ * Author: Webcraftic <wordpress.webraftic@gmail.com>
7
+ * Version: 1.0.1
8
+ * Text Domain: html-minify
9
+ * Domain Path: /languages/
10
+ * Author URI: https://clearfy.pro
11
+ */
12
+
13
+ /*
14
+ * #### CREDITS ####
15
+ * This plugin is based on the plugin Autoptimize by the author Frank Goossens, we have finalized this code for our project and our goals.
16
+ * Many thanks to Frank Goossens for the quality solution for optimizing scripts in Wordpress.
17
+ *
18
+ * Public License is a GPLv2 compatible license allowing you to change and use this version of the plugin for free.
19
+ */
20
+
21
+ // Exit if accessed directly
22
+ if( !defined('ABSPATH') ) {
23
+ exit;
24
+ }
25
+
26
+ /**
27
+ * Troubleshoot old versions of PHP on the client server
28
+ */
29
+ if( version_compare(PHP_VERSION, '5.4.0', '<') ) {
30
+ function wbcr_htm_admin_notice_php_error()
31
+ {
32
+ ?>
33
+ <div class="notice notice-error">
34
+ <p><?php _e('The job of the component "Html minify" component has been suspended! You are using the old version of PHP. Please update the PHP version to 5.4 or later to continue to use this component!', 'html-minify'); ?></p>
35
+ </div>
36
+ <?php
37
+ }
38
+
39
+ add_action('admin_notices', 'wbcr_htm_admin_notice_php_error');
40
+ return;
41
+ }
42
+
43
+ /**
44
+ * Уведомление о том, что этот плагин используется уже в составе плагина Clearfy, как его компонент.
45
+ * Мы блокируем работу этого плагина, чтобы не вызывать конфликт.
46
+ */
47
+ if( defined('WHTM_PLUGIN_ACTIVE') || (defined('WHTM_PLUGIN_ACTIVE') && !defined('LOADING_HTML_MINIFY_AS_ADDON')) ) {
48
+ function wbcr_htm_admin_notice_error()
49
+ {
50
+ ?>
51
+ <div class="notice notice-error">
52
+ <p><?php _e('We found that you have the "Clearfy - wordpress optimization plugin" plugin installed, this plugin already has Html minify functions, so you can deactivate plugin "Html minify"!', 'html-minify'); ?></p>
53
+ </div>
54
+ <?php
55
+ }
56
+
57
+ add_action('admin_notices', 'wbcr_htm_admin_notice_error');
58
+
59
+ return;
60
+ } else {
61
+
62
+ // Устанавливаем контстанту, что плагин уже используется
63
+ define('WHTM_PLUGIN_ACTIVE', true);
64
+
65
+ // Директория плагина
66
+ define('WHTM_PLUGIN_DIR', dirname(__FILE__));
67
+
68
+ // Относительный путь к плагину
69
+ define('WHTM_PLUGIN_BASE', plugin_basename(__FILE__));
70
+
71
+ // Ссылка к директории плагина
72
+ define('WHTM_PLUGIN_URL', plugins_url(null, __FILE__));
73
+
74
+
75
+
76
+ // Этот плагин может быть аддоном плагина Clearfy, если он загружен, как аддон, то мы не подключаем фреймворк,
77
+ // а наследуем функции фреймворка от плагина Clearfy. Если плагин скомпилирован, как отдельный плагин, то он использует собственный фреймворк для работы.
78
+ // Константа LOADING_HTML_MINIFY_AS_ADDON утсанавливается в классе libs/factory/core/includes/Wbcr_Factory406_Plugin
79
+
80
+ if( !defined('LOADING_HTML_MINIFY_AS_ADDON') ) {
81
+ // Фреймворк - отвечает за интерфейс, содержит общие функции для серии плагинов и готовые шаблоны для быстрого развертывания плагина.
82
+ require_once(WHTM_PLUGIN_DIR . '/libs/factory/core/boot.php');
83
+ }
84
+
85
+ // Основной класс плагина
86
+ require_once(WHTM_PLUGIN_DIR . '/includes/class.plugin.php');
87
+
88
+ // Класс WHTM_Plugin создается только, если этот плагин работает, как самостоятельный плагин.
89
+ // Если плагин работает, как аддон, то класс создается родительским плагином.
90
+
91
+ if( !defined('LOADING_HTML_MINIFY_AS_ADDON') ) {
92
+ new WHTM_Plugin(__FILE__, array(
93
+ 'prefix' => 'wbcr_htm_', // префикс для базы данных и полей формы
94
+ 'plugin_name' => 'wbcr_html_minify', // имя плагина, как уникальный идентификатор
95
+ 'plugin_title' => __('Webcraftic HTML Minify', 'html-minify'), // заголовок плагина
96
+ 'plugin_version' => '1.0.1', // текущая версия плагина
97
+ 'required_php_version' => '5.2', // минимальная версия php для работы плагина
98
+ 'required_wp_version' => '4.2', // минимальная версия wp для работы плагина
99
+ 'plugin_build' => 'free', // сборка плагина
100
+ //'updates' => WHTM_PLUGIN_DIR . '/updates/' в этой папке хранятся миграции для разных версий плагина
101
+ ));
102
+ }
103
+ }
components/html-minify/includes/class.plugin.php ADDED
@@ -0,0 +1,174 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Основной класс плагина
4
+ * @author Webcraftic <wordpress.webraftic@gmail.com>
5
+ * @copyright (c) 19.02.2018, Webcraftic
6
+ * @version 1.0
7
+ */
8
+
9
+ // Exit if accessed directly
10
+ if( !defined('ABSPATH') ) {
11
+ exit;
12
+ }
13
+
14
+ if( !class_exists('WHTM_Plugin') ) {
15
+ if( !class_exists('WHTM_PluginFactory') ) {
16
+ // Этот плагин может быть аддоном плагина Clearfy, если он загружен, как аддон, то мы не подключаем фреймворк,
17
+ // а наследуем функции фреймворка от плагина Clearfy. Если плагин скомпилирован, как отдельный плагин, то он использует собственный фреймворк для работы.
18
+ // Константа LOADING_HTML_MINIFY_AS_ADDON утсанавливается в классе libs/factory/core/includes/Wbcr_Factory406_Plugin
19
+
20
+ if( defined('LOADING_HTML_MINIFY_AS_ADDON') ) {
21
+ class WHTM_PluginFactory {
22
+
23
+ }
24
+ } else {
25
+ class WHTM_PluginFactory extends Wbcr_Factory406_Plugin {
26
+
27
+ }
28
+ }
29
+ }
30
+
31
+ class WHTM_Plugin extends WHTM_PluginFactory {
32
+
33
+ /**
34
+ * @var Wbcr_Factory406_Plugin
35
+ */
36
+ private static $app;
37
+
38
+ /**
39
+ * @var bool
40
+ */
41
+ private $as_addon;
42
+
43
+ /**
44
+ * @param string $plugin_path
45
+ * @param array $data
46
+ * @throws Exception
47
+ */
48
+ public function __construct($plugin_path, $data)
49
+ {
50
+ $this->as_addon = isset($data['as_addon']);
51
+
52
+ if( $this->as_addon ) {
53
+ $plugin_parent = isset($data['plugin_parent'])
54
+ ? $data['plugin_parent']
55
+ : null;
56
+
57
+ if( !($plugin_parent instanceof Wbcr_Factory406_Plugin) ) {
58
+ throw new Exception('An invalid instance of the class was passed.');
59
+ }
60
+
61
+ // Если плагин загружен, как аддон, то мы передаем в app ссылку на класс родителя
62
+ self::$app = $plugin_parent;
63
+ } else {
64
+ // Если плагин самостоятельный, то записываем в app сслыку на текущий класс
65
+ self::$app = $this;
66
+
67
+ parent::__construct($plugin_path, $data);
68
+ }
69
+
70
+ $this->setTextDomain();
71
+ $this->setModules();
72
+ $this->globalScripts();
73
+
74
+ if( is_admin() ) {
75
+ $this->adminScripts();
76
+ }
77
+
78
+ add_action('plugins_loaded', array($this, 'pluginsLoaded'));
79
+ }
80
+
81
+ /**
82
+ * Статический метод для быстрого доступа к информации о плагине, а также часто использумых методах.
83
+ *
84
+ * Пример:
85
+ * WHTM_Plugin::app()->getOption()
86
+ * WHTM_Plugin::app()->updateOption()
87
+ * WHTM_Plugin::app()->deleteOption()
88
+ * WHTM_Plugin::app()->getPluginName()
89
+ *
90
+ * @return Wbcr_Factory406_Plugin
91
+ */
92
+ public static function app()
93
+ {
94
+ return self::$app;
95
+ }
96
+
97
+ /**
98
+ * Устанавливаем текстовый домен
99
+ */
100
+ protected function setTextDomain()
101
+ {
102
+ // Localization plugin
103
+ load_plugin_textdomain('html-minify', false, dirname(WHTM_PLUGIN_BASE) . '/languages/');
104
+ }
105
+
106
+ /**
107
+ * Подключаем модули фреймворка
108
+ */
109
+ protected function setModules()
110
+ {
111
+ if( !$this->as_addon ) {
112
+ self::app()->load(array(
113
+ // Модуль отвечает за подключение скриптов и стилей для интерфейса
114
+ array('libs/factory/bootstrap', 'factory_bootstrap_406', 'admin'),
115
+ // Модуль отвечает за создание форм и полей
116
+ array('libs/factory/forms', 'factory_forms_407', 'admin'),
117
+ // Модуль отвечает за создание шаблонов страниц плагина
118
+ array('libs/factory/pages', 'factory_pages_407', 'admin'),
119
+ // Модуль в котором хранится общий функционал плагина Clearfy и его аддонов
120
+ array('libs/factory/clearfy', 'factory_clearfy_203', 'all')
121
+ ));
122
+ }
123
+ }
124
+
125
+ /**
126
+ * Регистрируем страницы плагина
127
+ */
128
+ private function registerPages()
129
+ {
130
+
131
+ $admin_path = WHTM_PLUGIN_DIR . '/admin/pages';
132
+
133
+ // Пример основной страницы настроек
134
+ self::app()->registerPage('WHTM_SettingsPage', $admin_path . '/settings.php');
135
+
136
+ // Пример внутренней страницы настроек
137
+ //self::app()->registerPage('WHTM_StatisticPage', $admin_path . '/statistic.php');
138
+ }
139
+
140
+ /**
141
+ * Подключаем функции бекенда
142
+ */
143
+ private function adminScripts()
144
+ {
145
+ require(WHTM_PLUGIN_DIR . '/admin/boot.php');
146
+ $this->registerPages();
147
+ }
148
+
149
+ /**
150
+ * Подключаем глобальные функции
151
+ */
152
+ private function globalScripts()
153
+ {
154
+ //require(WHTM_PLUGIN_DIR . '/includes/classes/class.configurate-comments.php');
155
+ //new WHTM_ConfigComments(self::$app);
156
+ }
157
+
158
+ /**
159
+ * Выполнение действий после загрузки плагина
160
+ * Подключаем все классы оптимизации и запускаем процесс
161
+ */
162
+ public function pluginsLoaded()
163
+ {
164
+ require_once(WHTM_PLUGIN_DIR . '/includes/classes/class.mac-base.php');
165
+ require_once(WHTM_PLUGIN_DIR . '/includes/classes/class.mac-html.php');
166
+ require_once(WHTM_PLUGIN_DIR . '/includes/classes/class.mac-main.php');
167
+
168
+ require_once(WHTM_PLUGIN_DIR . '/includes/classes/ext/php/minify-html.php');
169
+
170
+ $plugin = new WHTM_PluginMain();
171
+ $plugin->start();
172
+ }
173
+ }
174
+ }
components/html-minify/includes/classes/class.mac-base.php ADDED
@@ -0,0 +1,260 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Base class
4
+ * @author Webcraftic <wordpress.webraftic@gmail.com>
5
+ * @copyright (c) 2018 Webraftic Ltd
6
+ * @version 1.0
7
+ */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit;
11
+ }
12
+
13
+ /**
14
+ * Class WHTM_PluginBase
15
+ */
16
+ abstract class WHTM_PluginBase
17
+ {
18
+ /**
19
+ * Holds content being processed (html, scripts, styles)
20
+ *
21
+ * @var string
22
+ */
23
+ protected $content = '';
24
+
25
+ /**
26
+ * Controls debug logging.
27
+ *
28
+ * @var bool
29
+ */
30
+ public $debug_log = false;
31
+
32
+ /**
33
+ * WHTM_PluginBase constructor.
34
+ *
35
+ * @param $content
36
+ */
37
+ public function __construct( $content )
38
+ {
39
+ $this->content = $content;
40
+ }
41
+
42
+ /**
43
+ * Reads the page and collects tags.
44
+ *
45
+ * @param array $options Options.
46
+ *
47
+ * @return bool
48
+ */
49
+ abstract public function read( $options );
50
+
51
+ /**
52
+ * Joins and optimizes collected things.
53
+ *
54
+ * @return bool
55
+ */
56
+ abstract public function minify();
57
+
58
+ /**
59
+ * Returns the content
60
+ *
61
+ * @return string
62
+ */
63
+ abstract public function getContent();
64
+
65
+ /**
66
+ * Hides everything between noptimize-comment tags.
67
+ *
68
+ * @param string $markup Markup to process.
69
+ *
70
+ * @return string
71
+ */
72
+ protected function hideNoptimize( $markup )
73
+ {
74
+ return $this->replaceContentsWithMarkerIfExists(
75
+ 'NOPTIMIZE',
76
+ '/<!--\s?noptimize\s?-->/',
77
+ '#<!--\s?noptimize\s?-->.*?<!--\s?/\s?noptimize\s?-->#is',
78
+ $markup
79
+ );
80
+ }
81
+
82
+ /**
83
+ * Unhide noptimize-tags.
84
+ *
85
+ * @param string $markup Markup to process.
86
+ *
87
+ * @return string
88
+ */
89
+ protected function restoreNoptimize( $markup )
90
+ {
91
+ return $this->restoreMarkedContent( 'NOPTIMIZE', $markup );
92
+ }
93
+
94
+ /**
95
+ * Hides "iehacks" content.
96
+ *
97
+ * @param string $markup Markup to process.
98
+ *
99
+ * @return string
100
+ */
101
+ protected function hideIEhacks( $markup )
102
+ {
103
+ return $this->replaceContentsWithMarkerIfExists(
104
+ 'IEHACK', // Marker name...
105
+ '<!--[if', // Invalid regex, will fallback to search using strpos()...
106
+ '#<!--\[if.*?\[endif\]-->#is', // Replacement regex...
107
+ $markup
108
+ );
109
+ }
110
+
111
+ /**
112
+ * Restores "hidden" iehacks content.
113
+ *
114
+ * @param string $markup Markup to process.
115
+ *
116
+ * @return string
117
+ */
118
+ protected function restoreIEhacks( $markup )
119
+ {
120
+ return $this->restoreMarkedContent( 'IEHACK', $markup );
121
+ }
122
+
123
+ /**
124
+ * "Hides" content within HTML comments using a regex-based replacement
125
+ * if HTML comment markers are found.
126
+ * `<!--example-->` becomes `%%COMMENTS%%ZXhhbXBsZQ==%%COMMENTS%%`
127
+ *
128
+ * @param string $markup Markup to process.
129
+ *
130
+ * @return string
131
+ */
132
+ protected function hideComments( $markup )
133
+ {
134
+ return $this->replaceContentsWithMarkerIfExists(
135
+ 'COMMENTS',
136
+ '<!--',
137
+ '#<!--.*?-->#is',
138
+ $markup
139
+ );
140
+ }
141
+
142
+ /**
143
+ * Restores original HTML comment markers inside a string whose HTML
144
+ * comments have been "hidden" by using `hideComments()`.
145
+ *
146
+ * @param string $markup Markup to process.
147
+ *
148
+ * @return string
149
+ */
150
+ protected function restoreComments( $markup )
151
+ {
152
+ return $this->restoreMarkedContent( 'COMMENTS', $markup );
153
+ }
154
+
155
+ /**
156
+ * Creates and returns a `%%`-style named marker which holds
157
+ * the base64 encoded `$data`.
158
+ * If `$hash` is provided, it's appended to the base64 encoded string
159
+ * using `|` as the separator (in order to support building the
160
+ * somewhat special/different INJECTLATER marker).
161
+ *
162
+ * @param string $name Marker name.
163
+ * @param string $data Marker data which will be base64-encoded.
164
+ * @param string|null $hash Optional.
165
+ *
166
+ * @return string
167
+ */
168
+ public static function buildMarker( $name, $data, $hash = null )
169
+ {
170
+ // Start the marker, add the data.
171
+ $marker = '%%' . $name . WHTM_HASH . '%%' . base64_encode( $data );
172
+
173
+ // Add the hash if provided.
174
+ if ( null !== $hash ) {
175
+ $marker .= '|' . $hash;
176
+ }
177
+
178
+ // Close the marker.
179
+ $marker .= '%%' . $name . '%%';
180
+
181
+ return $marker;
182
+ }
183
+
184
+ /**
185
+ * Returns true if the string is a valid regex.
186
+ *
187
+ * @param string $string String, duh.
188
+ *
189
+ * @return bool
190
+ */
191
+ protected function strIsValidRegex( $string )
192
+ {
193
+ set_error_handler( function() {}, E_WARNING );
194
+ $is_regex = ( false !== preg_match( $string, '' ) );
195
+ restore_error_handler();
196
+
197
+ return $is_regex;
198
+ }
199
+
200
+ /**
201
+ * Searches for `$search` in `$content` (using either `preg_match()`
202
+ * or `strpos()`, depending on whether `$search` is a valid regex pattern or not).
203
+ * If something is found, it replaces `$content` using `$re_replace_pattern`,
204
+ * effectively creating our named markers (`%%{$marker}%%`.
205
+ * These are then at some point replaced back to their actual/original/modified
206
+ * contents using `WHTM_PluginBase::restoreMarkedContent()`.
207
+ *
208
+ * @param string $marker Marker name (without percent characters).
209
+ * @param string $search A string or full blown regex pattern to search for in $content. Uses `strpos()` or `preg_match()`.
210
+ * @param string $re_replace_pattern Regex pattern to use when replacing contents.
211
+ * @param string $content Content to work on.
212
+ *
213
+ * @return string
214
+ */
215
+ protected function replaceContentsWithMarkerIfExists( $marker, $search, $re_replace_pattern, $content )
216
+ {
217
+ $is_regex = $this->strIsValidRegex( $search );
218
+ if ( $is_regex ) {
219
+ $found = preg_match( $search, $content );
220
+ } else {
221
+ $found = ( false !== strpos( $content, $search ) );
222
+ }
223
+
224
+ if ( $found ) {
225
+ $content = preg_replace_callback(
226
+ $re_replace_pattern,
227
+ function( $matches ) use ( $marker ) {
228
+ return WHTM_PluginBase::buildMarker( $marker, $matches[0] );
229
+ },
230
+ $content
231
+ );
232
+ }
233
+
234
+ return $content;
235
+ }
236
+
237
+ /**
238
+ * Complements `WHTM_PluginBase::replaceContentsWithMarkerIfExists()`.
239
+ *
240
+ * @param string $marker Marker.
241
+ * @param string $content Markup.
242
+ *
243
+ * @return string
244
+ */
245
+ protected function restoreMarkedContent( $marker, $content )
246
+ {
247
+ if ( false !== strpos( $content, $marker ) ) {
248
+ $content = preg_replace_callback(
249
+ '#%%' . $marker . WHTM_HASH . '%%(.*?)%%' . $marker . '%%#is',
250
+ function ( $matches ) {
251
+ return base64_decode( $matches[1] );
252
+ },
253
+ $content
254
+ );
255
+ }
256
+
257
+ return $content;
258
+ }
259
+
260
+ }
components/html-minify/includes/classes/class.mac-html.php ADDED
@@ -0,0 +1,126 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Operations with HTML
4
+ *
5
+ * @author Webcraftic <wordpress.webraftic@gmail.com>
6
+ * @copyright (c) 2018 Webraftic Ltd
7
+ * @version 1.0
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) {
11
+ exit;
12
+ }
13
+
14
+ /**
15
+ * Class WHTM_PluginHTML
16
+ */
17
+ class WHTM_PluginHTML extends WHTM_PluginBase
18
+ {
19
+ /**
20
+ * Force xhtml.
21
+ *
22
+ * @var bool
23
+ */
24
+ private $forcexhtml = false;
25
+
26
+ /**
27
+ * Whether HTML comments are kept.
28
+ *
29
+ * @var bool
30
+ */
31
+ private $keepcomments = false;
32
+
33
+ /**
34
+ * Things to exclude from being minifed.
35
+ *
36
+ * @var array
37
+ */
38
+ private $exclude = array(
39
+ '<!-- ngg_resource_manager_marker -->',
40
+ '<!--noindex-->',
41
+ '<!--/noindex-->',
42
+ );
43
+
44
+ public function read( $options )
45
+ {
46
+ // Remove the HTML comments?
47
+ $this->keepcomments = (bool) $options['keepcomments'];
48
+
49
+ // Filter to force xhtml.
50
+ $this->forcexhtml = (bool) apply_filters( 'whm_filter_html_forcexhtml', false );
51
+
52
+ // Filterable strings to be excluded from HTML minification.
53
+ $exclude = apply_filters( 'whm_filter_html_exclude', '' );
54
+ if ( '' !== $exclude ) {
55
+ $exclude_arr = array_filter( array_map( 'trim', explode( ',', $exclude ) ) );
56
+ $this->exclude = array_merge( $exclude_arr, $this->exclude );
57
+ }
58
+
59
+ return true;
60
+ }
61
+
62
+ /**
63
+ * Minifies HTML.
64
+ *
65
+ * @return bool
66
+ */
67
+ public function minify()
68
+ {
69
+ $noptimize = apply_filters( 'whm_filter_html_noptimize', false, $this->content );
70
+ if ( $noptimize ) {
71
+ return false;
72
+ }
73
+
74
+ // Wrap the to-be-excluded strings in no optimize tags.
75
+ foreach ( $this->exclude as $str ) {
76
+ if ( false !== strpos( $this->content, $str ) ) {
77
+ $replacement = '<!--noptimize-->' . $str . '<!--/noptimize-->';
78
+ $this->content = str_replace( $str, $replacement, $this->content );
79
+ }
80
+ }
81
+
82
+ // No optimize.
83
+ $this->content = $this->hideNoptimize( $this->content );
84
+
85
+ // Preparing options for Minify_HTML.
86
+ $options = array( 'keepComments' => $this->keepcomments );
87
+ if ( $this->forcexhtml ) {
88
+ $options['xhtml'] = true;
89
+ }
90
+
91
+ $tmp_content = Minify_HTML::minify( $this->content, $options );
92
+ if ( ! empty( $tmp_content ) ) {
93
+ $this->content = $tmp_content;
94
+ unset( $tmp_content );
95
+ }
96
+
97
+ // Restore no optimize.
98
+ $this->content = $this->restoreNoptimize( $this->content );
99
+
100
+ // Remove the noptimize-wrapper from around the excluded strings.
101
+ foreach ( $this->exclude as $str ) {
102
+ $replacement = '<!--noptimize-->' . $str . '<!--/noptimize-->';
103
+ if ( false !== strpos( $this->content, $replacement ) ) {
104
+ $this->content = str_replace( $replacement, $str, $this->content );
105
+ }
106
+ }
107
+
108
+ // Revslider data attribs somehow suffer from HTML optimization, this fixes that!
109
+ if ( class_exists( 'RevSlider' ) && apply_filters( 'whm_filter_html_dataattrib_cleanup', false ) ) {
110
+ $this->content = preg_replace( '#\n(data-.*$)\n#Um', ' $1 ', $this->content );
111
+ $this->content = preg_replace( '#<[^>]*(=\"[^"\'<>\s]*\")(\w)#', '$1 $2', $this->content );
112
+ }
113
+
114
+ return true;
115
+ }
116
+
117
+ /**
118
+ * Returns the HTML markup.
119
+ *
120
+ * @return string
121
+ */
122
+ public function getContent()
123
+ {
124
+ return $this->content;
125
+ }
126
+ }
components/html-minify/includes/classes/class.mac-main.php ADDED
@@ -0,0 +1,270 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Main class
4
+ * @author Webcraftic <wordpress.webraftic@gmail.com>
5
+ * @copyright (c) 2018 Webraftic Ltd
6
+ * @version 1.0
7
+ */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit;
11
+ }
12
+
13
+ /**
14
+ * Class WHTM_PluginMain
15
+ */
16
+ class WHTM_PluginMain
17
+ {
18
+ const INIT_EARLIER_PRIORITY = -1;
19
+ const DEFAULT_HOOK_PRIORITY = 2;
20
+
21
+ /**
22
+ * Constructor.
23
+ */
24
+ public function __construct()
25
+ {
26
+ }
27
+
28
+ /**
29
+ * Start processing
30
+ */
31
+ public function start()
32
+ {
33
+ $this->setup();
34
+ $this->run();
35
+ }
36
+
37
+ /**
38
+ * Setting the parameters
39
+ */
40
+ public function setup()
41
+ {
42
+ // These can be overridden by specifying them in wp-config.php or such.
43
+ if ( ! defined( 'WHTM_WP_CONTENT_NAME' ) ) {
44
+ define( 'WHTM_WP_CONTENT_NAME', '/' . wp_basename( WP_CONTENT_DIR ) );
45
+ }
46
+
47
+ define( 'WHTM_ROOT_DIR', substr( WP_CONTENT_DIR, 0, strlen( WP_CONTENT_DIR ) - strlen( WHTM_WP_CONTENT_NAME ) ) );
48
+
49
+ if ( ! defined( 'WHTM_WP_SITE_URL' ) ) {
50
+ // domain_mapping_siteurl функция из плагина, который позволяет задавать свой домен для подсайта
51
+ if ( function_exists( 'domain_mapping_siteurl' ) ) {
52
+ define( 'WHTM_WP_SITE_URL', domain_mapping_siteurl( get_current_blog_id() ) );
53
+ } else {
54
+ define( 'WHTM_WP_SITE_URL', site_url() );
55
+ }
56
+ }
57
+
58
+ if ( ! defined( 'WHTM_WP_CONTENT_URL' ) ) {
59
+ // get_original_url функция из плагина, который позволяет задавать свой домен для подсайта
60
+ if ( function_exists( 'get_original_url' ) ) {
61
+ define( 'WHTM_WP_CONTENT_URL', str_replace( get_original_url( WHTM_WP_SITE_URL ), WHTM_WP_SITE_URL, content_url() ) );
62
+ } else {
63
+ define( 'WHTM_WP_CONTENT_URL', content_url() );
64
+ }
65
+ }
66
+
67
+ if ( ! defined( 'WHTM_WP_ROOT_URL' ) ) {
68
+ define( 'WHTM_WP_ROOT_URL', str_replace( WHTM_WP_CONTENT_NAME, '', WHTM_WP_CONTENT_URL ) );
69
+ }
70
+
71
+ if ( ! defined( 'WHTM_HASH' ) ) {
72
+ define( 'WHTM_HASH', wp_hash( time() ) );
73
+ }
74
+ }
75
+
76
+ /**
77
+ * Run
78
+ */
79
+ public function run()
80
+ {
81
+ if ( WHTM_Plugin::app()->getOption('html_optimize') ) {
82
+ // Hook into WordPress frontend.
83
+ if ( defined( 'WHTM_INIT_EARLIER' ) ) {
84
+ add_action( 'init', array( $this, 'startBuffering' ), self::INIT_EARLIER_PRIORITY );
85
+ } else {
86
+ if ( ! defined( 'WHTM_HOOK_INTO' ) ) {
87
+ define( 'WHTM_HOOK_INTO', 'template_redirect' );
88
+ }
89
+ add_action(
90
+ constant( 'WHTM_HOOK_INTO' ),
91
+ array( $this, 'startBuffering' ),
92
+ self::DEFAULT_HOOK_PRIORITY
93
+ );
94
+ }
95
+ }
96
+ }
97
+
98
+ /**
99
+ * Setup output buffering if needed.
100
+ *
101
+ * @return void
102
+ */
103
+ public function startBuffering()
104
+ {
105
+ if ( $this->shouldBuffer() ) {
106
+
107
+ if ( apply_filters( 'whm_filter_obkiller', false ) ) {
108
+ while ( ob_get_level() > 0 ) {
109
+ ob_end_clean();
110
+ }
111
+ }
112
+
113
+ // Now, start the real thing!
114
+ ob_start( array( $this, 'endBuffering' ) );
115
+ }
116
+ }
117
+
118
+ /**
119
+ * Returns true if all the conditions to start output buffering are satisfied.
120
+ *
121
+ * @param bool $doing_tests Allows overriding the optimization of only
122
+ * deciding once per request (for use in tests).
123
+ * @return bool
124
+ */
125
+ public function shouldBuffer( $doing_tests = false )
126
+ {
127
+ static $do_buffering = null;
128
+
129
+ // Only check once in case we're called multiple times by others but
130
+ // still allows multiple calls when doing tests.
131
+ if ( null === $do_buffering || $doing_tests ) {
132
+ $whm_noptimize = false;
133
+
134
+ // Checking for DONOTMINIFY constant as used by e.g. WooCommerce POS.
135
+ if (
136
+ defined( 'DONOTMINIFY' )
137
+ && ( constant( 'DONOTMINIFY' ) === true || constant( 'DONOTMINIFY' ) === 'true' )
138
+ ) {
139
+ $whm_noptimize = true;
140
+ }
141
+
142
+ // Skip checking query strings if they're disabled.
143
+ if ( apply_filters( 'whm_filter_honor_qs_noptimize', true ) ) {
144
+ // Check for `whm_noptimize` (and other) keys in the query string
145
+ // to get non-optimized page for debugging.
146
+ $keys = array(
147
+ 'whm_noptimize',
148
+ 'whm_noptirocket',
149
+ );
150
+ foreach ( $keys as $key ) {
151
+ if ( array_key_exists( $key, $_GET ) && '1' === $_GET[ $key ] ) {
152
+ $whm_noptimize = true;
153
+ break;
154
+ }
155
+ }
156
+ }
157
+
158
+ // Allows blocking of auto optimization on your own terms regardless of above decisions.
159
+ $whm_noptimize = (bool) apply_filters( 'whm_filter_noptimize', $whm_noptimize );
160
+
161
+ // Check for site being previewed in the Customizer (available since WP 4.0).
162
+ $is_customize_preview = false;
163
+ if ( function_exists( 'is_customize_preview' ) && is_customize_preview() ) {
164
+ $is_customize_preview = is_customize_preview();
165
+ }
166
+
167
+ /**
168
+ * We only buffer the frontend requests (and then only if not a feed
169
+ * and not turned off explicitly and not when being previewed in Customizer)!
170
+ * NOTE: Tests throw a notice here due to is_feed() being called
171
+ * while the main query hasn't been ran yet. Thats why we use
172
+ * WHTM_INIT_EARLIER in tests.
173
+ */
174
+ $do_buffering = ( ! is_admin() && ! is_feed() && ! $whm_noptimize && ! $is_customize_preview );
175
+ }
176
+
177
+ return $do_buffering;
178
+ }
179
+
180
+ /**
181
+ * Returns true if given markup is considered valid/processable/optimizable.
182
+ *
183
+ * @param string $content Markup.
184
+ *
185
+ * @return bool
186
+ */
187
+ public function isValidBuffer( $content )
188
+ {
189
+ // Defaults to true.
190
+ $valid = true;
191
+
192
+ $has_no_html_tag = ( false === stripos( $content, '<html' ) );
193
+ $has_xsl_stylesheet = ( false !== stripos( $content, '<xsl:stylesheet' ) );
194
+ $has_html5_doctype = ( preg_match( '/^<!DOCTYPE.+html>/i', $content ) > 0 );
195
+
196
+ if ( $has_no_html_tag ) {
197
+ // Can't be valid amp markup without an html tag preceding it.
198
+ $is_amp_markup = false;
199
+ } else {
200
+ $is_amp_markup = self::isAmpMarkup( $content );
201
+ }
202
+
203
+ // If it's not html, or if it's amp or contains xsl stylesheets we don't touch it.
204
+ if ( $has_no_html_tag && ! $has_html5_doctype || $is_amp_markup || $has_xsl_stylesheet ) {
205
+ $valid = false;
206
+ }
207
+
208
+ return $valid;
209
+ }
210
+
211
+ /**
212
+ * Returns true if given $content is considered to be AMP markup.
213
+ * This is far from actual validation against AMP spec, but it'll do for now.
214
+ *
215
+ * @param string $content Markup to check.
216
+ *
217
+ * @return bool
218
+ */
219
+ public static function isAmpMarkup( $content )
220
+ {
221
+ $is_amp_markup = preg_match( '/<html[^>]*(?:amp|⚡)/i', $content );
222
+
223
+ return (bool) $is_amp_markup;
224
+ }
225
+
226
+ /**
227
+ * Processes/optimizes the output-buffered content and returns it.
228
+ * If the content is not processable, it is returned unmodified.
229
+ *
230
+ * @param string $content Buffered content.
231
+ *
232
+ * @return string
233
+ */
234
+ public function endBuffering( $content )
235
+ {
236
+ // Bail early without modifying anything if we can't handle the content.
237
+ if ( ! $this->isValidBuffer( $content ) ) {
238
+ return $content;
239
+ }
240
+
241
+ // Determine what needs to be ran.
242
+ $classes = array();
243
+ if ( WHTM_Plugin::app()->getOption( 'html_optimize' ) ) {
244
+ $classes[] = 'WHTM_PluginHTML';
245
+ }
246
+
247
+ $classoptions = array(
248
+ 'WHTM_PluginHTML' => array(
249
+ 'keepcomments' => WHTM_Plugin::app()->getOption( 'html_keepcomments' ),
250
+ ),
251
+ );
252
+
253
+ $content = apply_filters( 'whm_filter_html_before_minify', $content );
254
+
255
+ // Run the classes!
256
+ foreach ( $classes as $name ) {
257
+ $instance = new $name( $content );
258
+ if ( $instance->read( $classoptions[ $name ] ) ) {
259
+ $instance->minify();
260
+ $content = $instance->getContent();
261
+ }
262
+ unset( $instance );
263
+ }
264
+
265
+ $content = apply_filters( 'whm_html_after_minify', $content );
266
+
267
+ return $content;
268
+ }
269
+
270
+ }
components/html-minify/includes/classes/ext/php/minify-html.php ADDED
@@ -0,0 +1,270 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Class Minify_HTML
4
+ * @package Minify
5
+ */
6
+
7
+ /**
8
+ * Compress HTML
9
+ *
10
+ * This is a heavy regex-based removal of whitespace, unnecessary comments and
11
+ * tokens. IE conditional comments are preserved. There are also options to have
12
+ * STYLE and SCRIPT blocks compressed by callback functions.
13
+ *
14
+ * A test suite is available.
15
+ *
16
+ * @package Minify
17
+ * @author Stephen Clay <steve@mrclay.org>
18
+ */
19
+ class Minify_HTML {
20
+
21
+ /**
22
+ * "Minify" an HTML page
23
+ *
24
+ * @param string $html
25
+ *
26
+ * @param array $options
27
+ *
28
+ * 'cssMinifier' : (optional) callback function to process content of STYLE
29
+ * elements.
30
+ *
31
+ * 'jsMinifier' : (optional) callback function to process content of SCRIPT
32
+ * elements. Note: the type attribute is ignored.
33
+ *
34
+ * 'xhtml' : (optional boolean) should content be treated as XHTML1.0? If
35
+ * unset, minify will sniff for an XHTML doctype.
36
+ *
37
+ * 'keepComments' : (optional boolean) should the HTML comments be kept
38
+ * in the HTML Code?
39
+ *
40
+ * @return string
41
+ */
42
+ public static function minify($html, $options = array()) {
43
+ $min = new Minify_HTML($html, $options);
44
+ return $min->process();
45
+ }
46
+
47
+
48
+ /**
49
+ * Create a minifier object
50
+ *
51
+ * @param string $html
52
+ *
53
+ * @param array $options
54
+ *
55
+ * 'cssMinifier' : (optional) callback function to process content of STYLE
56
+ * elements.
57
+ *
58
+ * 'jsMinifier' : (optional) callback function to process content of SCRIPT
59
+ * elements. Note: the type attribute is ignored.
60
+ *
61
+ * 'xhtml' : (optional boolean) should content be treated as XHTML1.0? If
62
+ * unset, minify will sniff for an XHTML doctype.
63
+ *
64
+ * 'xhtml' : (optional boolean) should content be treated as XHTML1.0? If
65
+ * unset, minify will sniff for an XHTML doctype.
66
+ *
67
+ * @return null
68
+ */
69
+ public function __construct($html, $options = array())
70
+ {
71
+ $this->_html = str_replace("\r\n", "\n", trim($html));
72
+ if (isset($options['xhtml'])) {
73
+ $this->_isXhtml = (bool)$options['xhtml'];
74
+ }
75
+ if (isset($options['cssMinifier'])) {
76
+ $this->_cssMinifier = $options['cssMinifier'];
77
+ }
78
+ if (isset($options['jsMinifier'])) {
79
+ $this->_jsMinifier = $options['jsMinifier'];
80
+ }
81
+ if (isset($options['keepComments'])) {
82
+ $this->_keepComments = $options['keepComments'];
83
+ }
84
+ }
85
+
86
+
87
+ /**
88
+ * Minify the markeup given in the constructor
89
+ *
90
+ * @return string
91
+ */
92
+ public function process()
93
+ {
94
+ if ($this->_isXhtml === null) {
95
+ $this->_isXhtml = (false !== strpos($this->_html, '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML'));
96
+ }
97
+
98
+ $this->_replacementHash = 'MINIFYHTML' . md5($_SERVER['REQUEST_TIME']);
99
+ $this->_placeholders = array();
100
+
101
+ // replace SCRIPTs (and minify) with placeholders
102
+ $this->_html = preg_replace_callback(
103
+ '/(\\s*)(<script\\b[^>]*?>)([\\s\\S]*?)<\\/script>(\\s*)/i'
104
+ ,array($this, '_removeScriptCB')
105
+ ,$this->_html);
106
+
107
+ // replace STYLEs (and minify) with placeholders
108
+ $this->_html = preg_replace_callback(
109
+ '/\\s*(<style\\b[^>]*?>)([\\s\\S]*?)<\\/style>\\s*/i'
110
+ ,array($this, '_removeStyleCB')
111
+ ,$this->_html);
112
+
113
+ // remove HTML comments (not containing IE conditional comments).
114
+ if ($this->_keepComments == false) {
115
+ $this->_html = preg_replace_callback(
116
+ '/<!--([\\s\\S]*?)-->/'
117
+ ,array($this, '_commentCB')
118
+ ,$this->_html);
119
+ }
120
+
121
+ // replace PREs with placeholders
122
+ $this->_html = preg_replace_callback('/\\s*(<pre\\b[^>]*?>[\\s\\S]*?<\\/pre>)\\s*/i'
123
+ ,array($this, '_removePreCB')
124
+ ,$this->_html);
125
+
126
+ // replace TEXTAREAs with placeholders
127
+ $this->_html = preg_replace_callback(
128
+ '/\\s*(<textarea\\b[^>]*?>[\\s\\S]*?<\\/textarea>)\\s*/i'
129
+ ,array($this, '_removeTextareaCB')
130
+ ,$this->_html);
131
+
132
+ // replace data: URIs with placeholders
133
+ $this->_html = preg_replace_callback(
134
+ '/(=("|\')data:.*\\2)/Ui'
135
+ ,array($this, '_removeDataURICB')
136
+ ,$this->_html);
137
+
138
+ // trim each line.
139
+ // replace by space instead of '' to avoid newline after opening tag getting zapped
140
+ $this->_html = preg_replace('/^\s+|\s+$/m', ' ', $this->_html);
141
+
142
+ // remove ws around block/undisplayed elements
143
+ $this->_html = preg_replace('/\\s+(<\\/?(?:area|article|aside|base(?:font)?|blockquote|body'
144
+ .'|canvas|caption|center|col(?:group)?|dd|dir|div|dl|dt|fieldset|figcaption|figure|footer|form'
145
+ .'|frame(?:set)?|h[1-6]|head|header|hgroup|hr|html|legend|li|link|main|map|menu|meta|nav'
146
+ .'|ol|opt(?:group|ion)|output|p|param|section|t(?:able|body|head|d|h||r|foot|itle)'
147
+ .'|ul|video)\\b[^>]*>)/i', '$1', $this->_html);
148
+
149
+ // remove ws outside of all elements
150
+ $this->_html = preg_replace_callback(
151
+ '/>([^<]+)</'
152
+ ,array($this, '_outsideTagCB')
153
+ ,$this->_html);
154
+
155
+ // use newlines before 1st attribute in open tags (to limit line lengths)
156
+ //$this->_html = preg_replace('/(<[a-z\\-]+)\\s+([^>]+>)/i', "$1\n$2", $this->_html);
157
+
158
+ // fill placeholders
159
+ $this->_html = str_replace(
160
+ array_keys($this->_placeholders)
161
+ ,array_values($this->_placeholders)
162
+ ,$this->_html
163
+ );
164
+ return $this->_html;
165
+ }
166
+
167
+ protected function _commentCB($m)
168
+ {
169
+ return (0 === strpos($m[1], '[') || false !== strpos($m[1], '<!['))
170
+ ? $m[0]
171
+ : '';
172
+ }
173
+
174
+ protected function _reservePlace($content)
175
+ {
176
+ $placeholder = '%' . $this->_replacementHash . count($this->_placeholders) . '%';
177
+ $this->_placeholders[$placeholder] = $content;
178
+ return $placeholder;
179
+ }
180
+
181
+ protected $_isXhtml = null;
182
+ protected $_replacementHash = null;
183
+ protected $_placeholders = array();
184
+ protected $_cssMinifier = null;
185
+ protected $_jsMinifier = null;
186
+ protected $_keepComments = false;
187
+
188
+ protected function _outsideTagCB($m)
189
+ {
190
+ return '>' . preg_replace('/^\\s+|\\s+$/', ' ', $m[1]) . '<';
191
+ }
192
+
193
+ protected function _removePreCB($m)
194
+ {
195
+ return $this->_reservePlace($m[1]);
196
+ }
197
+
198
+ protected function _removeTextareaCB($m)
199
+ {
200
+ return $this->_reservePlace($m[1]);
201
+ }
202
+
203
+ protected function _removeDataURICB($m)
204
+ {
205
+ return $this->_reservePlace($m[1]);
206
+ }
207
+
208
+ protected function _removeStyleCB($m)
209
+ {
210
+ $openStyle = $m[1];
211
+ $css = $m[2];
212
+ // remove HTML comments
213
+ $css = preg_replace('/(?:^\\s*<!--|-->\\s*$)/', '', $css);
214
+
215
+ // remove CDATA section markers
216
+ $css = $this->_removeCdata($css);
217
+
218
+ // minify
219
+ $minifier = $this->_cssMinifier
220
+ ? $this->_cssMinifier
221
+ : 'trim';
222
+ $css = call_user_func($minifier, $css);
223
+
224
+ return $this->_reservePlace($this->_needsCdata($css)
225
+ ? "{$openStyle}/*<![CDATA[*/{$css}/*]]>*/</style>"
226
+ : "{$openStyle}{$css}</style>"
227
+ );
228
+ }
229
+
230
+ protected function _removeScriptCB($m)
231
+ {
232
+ $openScript = $m[2];
233
+ $js = $m[3];
234
+
235
+ // whitespace surrounding? preserve at least one space
236
+ $ws1 = ($m[1] === '') ? '' : ' ';
237
+ $ws2 = ($m[4] === '') ? '' : ' ';
238
+
239
+ if ($this->_keepComments == false) {
240
+ // remove HTML comments (and ending "//" if present)
241
+ $js = preg_replace('/(?:^\\s*<!--\\s*|\\s*(?:\\/\\/)?\\s*-->\\s*$)/', '', $js);
242
+
243
+ // remove CDATA section markers
244
+ $js = $this->_removeCdata($js);
245
+ }
246
+
247
+ // minify
248
+ $minifier = $this->_jsMinifier
249
+ ? $this->_jsMinifier
250
+ : 'trim';
251
+ $js = call_user_func($minifier, $js);
252
+
253
+ return $this->_reservePlace($this->_needsCdata($js)
254
+ ? "{$ws1}{$openScript}/*<![CDATA[*/{$js}/*]]>*/</script>{$ws2}"
255
+ : "{$ws1}{$openScript}{$js}</script>{$ws2}"
256
+ );
257
+ }
258
+
259
+ protected function _removeCdata($str)
260
+ {
261
+ return (false !== strpos($str, '<![CDATA['))
262
+ ? str_replace(array('/* <![CDATA[ */','/* ]]> */','/*<![CDATA[*/','/*]]>*/','<![CDATA[', ']]>'), '', $str)
263
+ : $str;
264
+ }
265
+
266
+ protected function _needsCdata($str)
267
+ {
268
+ return ($this->_isXhtml && preg_match('/(?:[<&]|\\-\\-|\\]\\]>)/', $str));
269
+ }
270
+ }
components/html-minify/includes/classes/index.php ADDED
File without changes
components/html-minify/includes/index.php ADDED
File without changes
components/html-minify/index.php ADDED
File without changes
components/html-minify/languages/html-minify-ru_RU.mo ADDED
Binary file
components/html-minify/languages/html-minify-ru_RU.po ADDED
@@ -0,0 +1,417 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: clearfy\n"
4
+ "POT-Creation-Date: 2018-08-19 03:46+0300\n"
5
+ "PO-Revision-Date: 2018-08-19 03:48+0300\n"
6
+ "Last-Translator: alex.kovalevv@gmail.com <alex.kovalevv@gmail.com>\n"
7
+ "Language-Team: Alex Kovalev <alex.kovalevv@gmail.com>\n"
8
+ "Language: ru_RU\n"
9
+ "MIME-Version: 1.0\n"
10
+ "Content-Type: text/plain; charset=UTF-8\n"
11
+ "Content-Transfer-Encoding: 8bit\n"
12
+ "X-Generator: Poedit 2.1.1\n"
13
+ "X-Poedit-Basepath: ..\n"
14
+ "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
15
+ "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
16
+ "X-Poedit-SourceCharset: UTF-8\n"
17
+ "X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c\n"
18
+ "X-Poedit-SearchPath-0: .\n"
19
+ "X-Poedit-SearchPathExcluded-0: libs\n"
20
+
21
+ #: admin/boot.php:23
22
+ msgid ""
23
+ "Clearfy: Html minify component is not compatible with the Autoptimize "
24
+ "plugin, please do not use them together to avoid conflicts. Please disable "
25
+ "the Html minify component"
26
+ msgstr ""
27
+ "Clearfy: Компонент HTML сжатие не совместим с плагином Autoptimize, "
28
+ "пожалуйста, не используйте их вместе, чтобы избежать конфликтов. Отключите "
29
+ "компонент HTML сжатие"
30
+
31
+ #: admin/boot.php:46 admin/pages/settings.php:101
32
+ msgid "Optimize HTML Code?"
33
+ msgstr "Оптимизировать HTML код?"
34
+
35
+ #: admin/boot.php:52 admin/pages/settings.php:111
36
+ msgid "Keep HTML comments?"
37
+ msgstr "Оставлять HTML комментарии?"
38
+
39
+ #: admin/boot.php:69
40
+ msgid "One click optimize html code"
41
+ msgstr "Оптимизировать html код одним нажатием"
42
+
43
+ #: admin/boot.php:71
44
+ msgid "One click optimize html code and scripts"
45
+ msgstr "Оптимизировать html код и скрипты одним нажатием"
46
+
47
+ #: admin/pages/settings.php:35 admin/pages/settings.php:58
48
+ msgid "HTML Minify"
49
+ msgstr "HTML сжатие"
50
+
51
+ #: admin/pages/settings.php:59
52
+ msgid "General"
53
+ msgstr "Основные"
54
+
55
+ #: admin/pages/settings.php:93
56
+ msgid "HTML Options"
57
+ msgstr "Настройки HTML сжатия"
58
+
59
+ #: admin/pages/settings.php:93
60
+ msgid ""
61
+ "Ever look at the HTML markup of your website and notice how sloppy and "
62
+ "amateurish it looks? The Minify HTML options cleans up sloppy looking markup "
63
+ "and minifies, which also speeds up download."
64
+ msgstr ""
65
+ "Вы когда-нибудь видели HTML разметку на своем веб-сайте, замечали насколько "
66
+ "она неаккуратна и раздута? Настройки HTML сжатия позволят грамотно "
67
+ "установить правила формирования html разметки, а также регулировать вес "
68
+ "ваших страниц."
69
+
70
+ #: admin/pages/settings.php:113
71
+ msgid "Enable this if you want HTML comments to remain in the page."
72
+ msgstr ""
73
+ "Включите эту опцию, если хотите, чтобы при сжатии страницы, не удалялясь "
74
+ "Html комментарии."
75
+
76
+ #: html-minify.php:34
77
+ msgid ""
78
+ "The job of the component \"Html minify\" component has been suspended! You "
79
+ "are using the old version of PHP. Please update the PHP version to 5.4 or "
80
+ "later to continue to use this component!"
81
+ msgstr ""
82
+ "Работа компонента «Скрыть мой wp» была приостановлена! Вы используете старую "
83
+ "версию PHP. Обновите версию PHP до версии 5.4 или новее, чтобы продолжить "
84
+ "использование этого компонента!"
85
+
86
+ #: html-minify.php:52
87
+ msgid ""
88
+ "We found that you have the \"Clearfy - wordpress optimization plugin\" "
89
+ "plugin installed, this plugin already has Html minify functions, so you can "
90
+ "deactivate plugin \"Html minify\"!"
91
+ msgstr ""
92
+ "Мы обнаружили, что у вас установлен плагин «Clearfy - wordpress optimization "
93
+ "plugin», этот плагин уже имеет функции Html minify, поэтому вы можете "
94
+ "отключить плагин «Html minify»!"
95
+
96
+ #: html-minify.php:129
97
+ msgid "Webcraftic HTML Minify"
98
+ msgstr "Webcraftic HTML сжатие"
99
+
100
+ #~ msgid "Comments are closed."
101
+ #~ msgstr "Комментарии Закрыты."
102
+
103
+ #~ msgid ""
104
+ #~ "Note: The <em>%s</em> plugin is currently active, and comments are "
105
+ #~ "completely disabled on: %s. Many of the settings below will not be "
106
+ #~ "applicable for those post types."
107
+ #~ msgstr ""
108
+ #~ "Примечание. Плагин <em>%s</em> в настоящий момент активен, и комментарии "
109
+ #~ "полностью отключены: %s. Многие из приведенных ниже настроек не будут "
110
+ #~ "применяться для этих типов сообщений."
111
+
112
+ #~ msgid "Disable comments on the entire site"
113
+ #~ msgstr "Отключить комментарии на всем сайте"
114
+
115
+ #~ msgid "Select post types"
116
+ #~ msgstr "Выбрать тип записи"
117
+
118
+ #~ msgid "Replace external links in comments on the JavaScript code"
119
+ #~ msgstr "Заменить внешние ссылки в комментариях на JavaScript код"
120
+
121
+ #~ msgid "Replace external links from comment authors on the JavaScript code"
122
+ #~ msgstr "Заменить внешние ссылки от авторов комментариев на код JavaScript"
123
+
124
+ #~ msgid "Disable X-Pingback"
125
+ #~ msgstr "Убрать ссылку на X-Pingback и возможность спамить pingback-ами"
126
+
127
+ #~ msgid "Remove field \"site\" in comment form"
128
+ #~ msgstr "Удаляет поле \"Сайт\" в форме комментариев"
129
+
130
+ #~ msgid "One click disable all comments"
131
+ #~ msgstr "Отключить все комментарии в один клик"
132
+
133
+ #~ msgid "Get ultimate plugin free"
134
+ #~ msgstr "Получите полную версию плагина бесплатно"
135
+
136
+ #~ msgid "Disable comments"
137
+ #~ msgstr "Отключить комментарии"
138
+
139
+ #~ msgid "Comments"
140
+ #~ msgstr "Комментарии"
141
+
142
+ #~ msgid "Global disabling of comments"
143
+ #~ msgstr "Глобальное отключение комментариев"
144
+
145
+ #~ msgid ""
146
+ #~ "What is the difference between these and native WordPress functions? "
147
+ #~ "WordPress disables comments only for new posts! Using the functions "
148
+ #~ "below, you can disable comments globally, even for old posts, and you can "
149
+ #~ "choose which post types comments to disable. The plugin also disables the "
150
+ #~ "comment functionality itself, which creates a certain load on the site."
151
+ #~ msgstr ""
152
+ #~ "Чем отличается эти функции от нативных функций Wordpress? Wordpress "
153
+ #~ "отключает комментарии только для новых записей! С помощью функций ниже, "
154
+ #~ "вы можете отключить комментарии глобально, даже для старых записей, "
155
+ #~ "причем вы можете выбрать для каких типов записей нужно отключить "
156
+ #~ "комментарии. Плагин также отключает сам функционал комментариев, который "
157
+ #~ "создает определенную нагрузку на сайт."
158
+
159
+ #~ msgid "Not disable"
160
+ #~ msgstr "Не отключать"
161
+
162
+ #~ msgid "Everywhere"
163
+ #~ msgstr "Повсюду"
164
+
165
+ #~ msgid ""
166
+ #~ "You can delete all comments in the database by clicking on this link (<a "
167
+ #~ "href=\"%s\">cleaning comments in database</a>)."
168
+ #~ msgstr ""
169
+ #~ "Вы можете удалить все комментарии в базе данных, нажав на эту ссылку ( <a "
170
+ #~ "href=\"%s\">очистка комментариев в базе данных</a> )."
171
+
172
+ #~ msgid "On certain post types"
173
+ #~ msgstr "Только выбранные типы записей"
174
+
175
+ #~ msgid ""
176
+ #~ "You can delete all comments for the selected post types. Select the post "
177
+ #~ "types below and save the settings. After that, click the link (<a href="
178
+ #~ "\"%s\">delete all comments for the selected post types in database</a>)."
179
+ #~ msgstr ""
180
+ #~ "Вы можете удалить все комментарии для выбранных типов записей. Выберите "
181
+ #~ "типы записей ниже и сохраните настройки. После этого нажмите ссылку ( <a "
182
+ #~ "href=\"%s\">удалите все комментарии для выбранных типов записей в базе "
183
+ #~ "данных</a> )."
184
+
185
+ #~ msgid ""
186
+ #~ "Everywhere - Warning: This option is global and will affect your entire "
187
+ #~ "site. Use it only if you want to disable comments everywhere. A complete "
188
+ #~ "description of what this option does is available here"
189
+ #~ msgstr ""
190
+ #~ "Повсюду - предупреждение: этот параметр является глобальным и повлияет на "
191
+ #~ "весь ваш сайт. Используйте его только в том случае, если вы хотите "
192
+ #~ "отключить комментарии повсюду. "
193
+
194
+ #~ msgid ""
195
+ #~ "On certain post types - Disabling comments will also disable trackbacks "
196
+ #~ "and pingbacks. All comment-related fields will also be hidden from the "
197
+ #~ "edit/quick-edit screens of the affected posts. These settings cannot be "
198
+ #~ "overridden for individual posts."
199
+ #~ msgstr ""
200
+ #~ "В некоторых типах сообщений - отключение комментариев также отключает "
201
+ #~ "трекбэки и pingback. Все поля, связанные с комментариями, также будут "
202
+ #~ "скрыты от экранов редактирования / быстрого редактирования затронутых "
203
+ #~ "сообщений. Эти настройки нельзя переопределять для отдельных сообщений."
204
+
205
+ #~ msgid "Select the post types for which comments will be disabled"
206
+ #~ msgstr "Выберите типы записей, для которых комментарии будут отключены."
207
+
208
+ #~ msgid "General settings for comments"
209
+ #~ msgstr "Общие настройки комментариев"
210
+
211
+ #~ msgid ""
212
+ #~ "These settings will help you improve SEO and reduce the amount of spam."
213
+ #~ msgstr ""
214
+ #~ "Эти настройки помогут вам улучшить SEO и уменьшить количество спама."
215
+
216
+ #~ msgid ""
217
+ #~ "Tired of spam in the comments? Do visitors leave \"blank\" comments for "
218
+ #~ "the sake of a link to their site?"
219
+ #~ msgstr ""
220
+ #~ "Надоел спам в комментариях? Посетители оставляют «пустые» комментарии "
221
+ #~ "ради ссылки на свой сайт?"
222
+
223
+ #~ msgid "Removes the \"Site\" field from the comment form."
224
+ #~ msgstr "Убирает поле «Сайт» из формы комментирования."
225
+
226
+ #~ msgid ""
227
+ #~ "Works with the standard comment form, if the form is manually written in "
228
+ #~ "your theme-it probably will not work!"
229
+ #~ msgstr ""
230
+ #~ "Работает со стандартной формой комментирования, если в Вашей теме форма "
231
+ #~ "прописана вручную - скорей всего не сработает!"
232
+
233
+ #~ msgid ""
234
+ #~ "Superfluous external links from comments, which can be typed from a dozen "
235
+ #~ "and more for one article, do not bring anything good for promotion."
236
+ #~ msgstr ""
237
+ #~ "Внешние ссылки в комментариях, которых может быть десятки или больше на "
238
+ #~ "одной странице, могут ухудшить продвижение вашего сайта."
239
+
240
+ #~ msgid "Replaces the links of this kind of %s, on links of this kind %s"
241
+ #~ msgstr ""
242
+ #~ "Заменяет ссылки %s, на span тег и устанавливает переход с помощью "
243
+ #~ "JavaScript %s"
244
+
245
+ #~ msgid ""
246
+ #~ "Up to 90 percent of comments in the blog can be left for the sake of an "
247
+ #~ "external link. Even nofollow from page weight loss here does not help."
248
+ #~ msgstr ""
249
+ #~ "До 90 процентов комментариев в блоге оставляют ради внешней ссылки. Не "
250
+ #~ "поможет даже nofollow от потери веса страницы."
251
+
252
+ #~ msgid ""
253
+ #~ "Replaces the links of the authors of comments on the JavaScript code, it "
254
+ #~ "is impossible to distinguish it from usual links."
255
+ #~ msgstr ""
256
+ #~ "Заменяет ссылки авторов комментариев на JavaScript код, его невозможно "
257
+ #~ "отличить от обычной ссылки."
258
+
259
+ #~ msgid "In some Wordpress topics this may not work."
260
+ #~ msgstr "В некоторых темах Wordpress это может не сработать."
261
+
262
+ #~ msgid "Disable XML-RPC"
263
+ #~ msgstr "Отключить XML-RPC"
264
+
265
+ #~ msgid ""
266
+ #~ "A pingback is basically an automated comment that gets created when "
267
+ #~ "another blog links to you. A self-pingback is created when you link to an "
268
+ #~ "article within your own blog. Pingbacks are essentially nothing more than "
269
+ #~ "spam and simply waste resources."
270
+ #~ msgstr ""
271
+ #~ "Pingback по-существу автоматизированных комментарий, который создается, "
272
+ #~ "когда другой блог ссылается на вас. Self-pingback создается, когда вы "
273
+ #~ "оставили ссылку на статью в своем блоге. Pingbacks по существу являются "
274
+ #~ "не более чем спам и пустая трата ресурсов вашего сайта."
275
+
276
+ #~ msgid "Removes the server responses a reference to the xmlrpc file."
277
+ #~ msgstr "Удаляет ссылку на xmlrpc-файл и ответ сервера."
278
+
279
+ #~ msgid "Comments cleaner"
280
+ #~ msgstr "Очистка комментариев"
281
+
282
+ #~ msgid "All comments have been deleted."
283
+ #~ msgstr "Все комментарии были удалены."
284
+
285
+ #~ msgid ""
286
+ #~ "An error occurred while trying to delete comments. Internal error "
287
+ #~ "occured. Please try again later."
288
+ #~ msgstr ""
289
+ #~ "При попытке удалить комментарии произошла ошибка. Пожалуйста, повторите "
290
+ #~ "попытку позже."
291
+
292
+ #~ msgid ""
293
+ #~ "Are you sure you want to delete comments from the database without "
294
+ #~ "restoring?"
295
+ #~ msgstr ""
296
+ #~ "Вы уверены, что вы хотите удалить комментарии из базы данных без "
297
+ #~ "восстановления?"
298
+
299
+ #~ msgid "Comments clearing tools"
300
+ #~ msgstr "Комментарии очищающие инструменты"
301
+
302
+ #~ msgid ""
303
+ #~ "These functions can be useful for global disabling comments or bulk "
304
+ #~ "cleaning spam comments."
305
+ #~ msgstr ""
306
+ #~ "Эти функции могут быть полезны для глобальных отключений комментариев или "
307
+ #~ "массовой очистки спама комментариев."
308
+
309
+ #~ msgid "Remove all comments"
310
+ #~ msgstr "Удалить все комментарии"
311
+
312
+ #~ msgid "You can delete all comments in your database with one click."
313
+ #~ msgstr ""
314
+ #~ "Вы можете удалить все комментарии в базе данных с одним щелчком мыши."
315
+
316
+ #~ msgid "Choose post types"
317
+ #~ msgstr "Выберите типы записей"
318
+
319
+ #~ msgid "Select all"
320
+ #~ msgstr "Выбрать все"
321
+
322
+ #~ msgid "Delete Woocommerce order notices? (%d)"
323
+ #~ msgstr "Удалять заметки от заказов Woocommerce? (%d)"
324
+
325
+ #~ msgid "Delete (%d)"
326
+ #~ msgstr "Удалить (%d)"
327
+
328
+ #~ msgid "Remove spam comments"
329
+ #~ msgstr "Удалить спам комментарии"
330
+
331
+ #~ msgid "You can remove only spam comments from the database with one click."
332
+ #~ msgstr ""
333
+ #~ "Вы можете одним нажатием удалить только спам комментарии из базы данных."
334
+
335
+ #~ msgid "Remove unapproved comments"
336
+ #~ msgstr "Удалить неподтвержденные комментарии"
337
+
338
+ #~ msgid ""
339
+ #~ "You can remove only unapproved comments from the database with one click."
340
+ #~ msgstr ""
341
+ #~ "Вы можете одним нажатием удалить только не подтвержденные комментарии из "
342
+ #~ "базы данных."
343
+
344
+ #~ msgid "Remove trashed comments"
345
+ #~ msgstr "Удалить комментарии из корзины"
346
+
347
+ #~ msgid ""
348
+ #~ "You can remove only trashed comments from the database with one click."
349
+ #~ msgstr "Вы можете одним нажатием удалить только комментарии из корзины."
350
+
351
+ #~ msgid ""
352
+ #~ "We found that you have the \"Clearfy - disable unused features\" plugin "
353
+ #~ "installed, this plugin already has disable comments functions, so you can "
354
+ #~ "deactivate plugin \"Disable comments\"!"
355
+ #~ msgstr ""
356
+ #~ "Мы обнаружили, что у вас установлен плагин «Clearfy - отключить "
357
+ #~ "неиспользуемые функции», этот плагин уже имеет функции отключения "
358
+ #~ "комментариев, поэтому вы можете отключить плагин «Отключить комментарии»!"
359
+
360
+ #~ msgid "Webcraftic Disable comments"
361
+ #~ msgstr "Webcraftic отключить комментарии"
362
+
363
+ #~ msgid "Recommended"
364
+ #~ msgstr "Рекомендовано"
365
+
366
+ #~ msgid "You are not allowed to view this page."
367
+ #~ msgstr "Вам не разрешено просматривать эту страницу."
368
+
369
+ #~ msgid "You do not have the selected post types!"
370
+ #~ msgstr "Вы не выбрали еще ни одного типа записей!"
371
+
372
+ #~ msgid "No comments available for deletion."
373
+ #~ msgstr "Нет комментариев для удаления."
374
+
375
+ #~ msgid ""
376
+ #~ "Are you sure that you desire to delete all comments from the database?"
377
+ #~ msgstr "Вы уверены, что хотите удалить все комментарии из базы данных?"
378
+
379
+ #~ msgid ""
380
+ #~ "Deleting comments will remove existing comment entries in the database "
381
+ #~ "and cannot be reverted without a database backup."
382
+ #~ msgstr ""
383
+ #~ "При удалении комментариев удаляются существующие записи комментариев в "
384
+ #~ "базе данных, они не могут быть восстановлены без резервного копирования "
385
+ #~ "базы данных."
386
+
387
+ #~ msgid "You have %s comments"
388
+ #~ msgstr "У вас есть %s комментариев"
389
+
390
+ #~ msgid "Yes, I'm sure"
391
+ #~ msgstr "Да, я уверен"
392
+
393
+ #~ msgid "No, return back"
394
+ #~ msgstr "Нет, вернуться"
395
+
396
+ #~ msgid ""
397
+ #~ "Are you sure that you desire to delete all comments from the database for "
398
+ #~ "the selected post types (%s)?"
399
+ #~ msgstr ""
400
+ #~ "Вы уверены, что хотите удалить все комментарии из базы данных для "
401
+ #~ "выбранных типов записей (%s)?"
402
+
403
+ #~ msgid "Webcraftic comments tweaks"
404
+ #~ msgstr "Webcraftic инструменты комментариев"
405
+
406
+ #~ msgid ""
407
+ #~ "We found that you have the \"Clearfy - disable unused features\" plugin "
408
+ #~ "installed, this plugin already has disable comments functions, so you can "
409
+ #~ "deactivate plugin \"Comments tweaks\"!"
410
+ #~ msgstr ""
411
+ #~ "Мы обнаружили, что у вас установлен плагин «Clearfy - отключить "
412
+ #~ "неиспользуемые функции», этот плагин уже имеет функции отключения "
413
+ #~ "комментариев, поэтому вы можете отключить плагин «Инструменты "
414
+ #~ "комментариев»!"
415
+
416
+ #~ msgid "Disable all comments"
417
+ #~ msgstr "Отключить все комментарии"
components/html-minify/languages/index.php ADDED
File without changes
components/html-minify/readme.txt ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ === HTML optimization ===
2
+ Tags: html optimization
3
+ Contributors: webcraftic
4
+ Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=VDX7JNTQPNPFW
5
+ Requires at least: 4.2
6
+ Tested up to: 4.9
7
+ Requires PHP: 5.2
8
+ Stable tag: trunk
9
+ License: GPLv2
10
+
11
+ = 1.0.0 =
12
+ * Plugin release
13
+
14
+ = 0.0.1 =
15
+ * Plugin beta
components/html-minify/uninstall.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // if uninstall.php is not called by WordPress, die
4
+ if( !defined('WP_UNINSTALL_PLUGIN') ) {
5
+ die;
6
+ }
7
+
8
+ // remove plugin options
9
+ global $wpdb;
10
+
11
+ $wpdb->query("DELETE FROM {$wpdb->prefix}options WHERE option_name LIKE 'wbcr_htm_%';");
12
+
components/minify-and-combine/admin/boot.php ADDED
@@ -0,0 +1,146 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Admin boot
4
+ * @author Webcraftic <wordpress.webraftic@gmail.com>
5
+ * @copyright Webcraftic 25.05.2017
6
+ * @version 1.0
7
+ */
8
+
9
+ // Exit if accessed directly
10
+ if( !defined('ABSPATH') ) {
11
+ exit;
12
+ }
13
+
14
+ /**
15
+ * Печатает ошибки совместимости с похожими плагинами
16
+ */
17
+ add_action('wbcr_factory_notices_405_list', function ($notices, $plugin_name) {
18
+ if( $plugin_name != WMAC_Plugin::app()->getPluginName() ) {
19
+ return $notices;
20
+ }
21
+
22
+ if( is_plugin_active('autoptimize/autoptimize.php') ) {
23
+ $notice_text = __('Clearfy: Minify and Combine component is not compatible with the Autoptimize plugin, please do not use them together to avoid conflicts. Please disable the Minify and Combine component', 'minify-and-combine');
24
+
25
+ if( class_exists('WCL_Plugin') ) {
26
+ $component_button = WCL_Plugin::app()->getInstallComponentsButton('internal', 'minify_and_combine');
27
+ $notice_text .= ' ' . $component_button->getLink();
28
+ }
29
+
30
+ $notices[] = array(
31
+ 'id' => 'mac_plugin_compatibility',
32
+ 'type' => 'error',
33
+ 'classes' => array('wbcr-hide-after-action'),
34
+ 'dismissible' => false,
35
+ 'dismiss_expires' => 0,
36
+ 'text' => '<p>' . $notice_text . '</p>'
37
+ );
38
+ }
39
+
40
+ return $notices;
41
+ }, 10, 2);
42
+
43
+ add_filter("wbcr_clearfy_group_options", function ($options) {
44
+ /**
45
+ * Js optimize
46
+ */
47
+
48
+ $options[] = array(
49
+ 'name' => 'js_optimize',
50
+ 'title' => __('Optimize JavaScript Code?', 'minify-and-combine'),
51
+ 'tags' => array('optimize_code', 'hide_my_wp')
52
+ );
53
+ $options[] = array(
54
+ 'name' => 'js_aggregate',
55
+ 'title' => __('Aggregate JS-files?', 'minify-and-combine'),
56
+ 'tags' => array('optimize_code')
57
+ );
58
+ $options[] = array(
59
+ 'name' => 'js_include_inline',
60
+ 'title' => __('Also aggregate inline JS?', 'minify-and-combine'),
61
+ 'tags' => array()
62
+ );
63
+ $options[] = array(
64
+ 'name' => 'js_forcehead',
65
+ 'title' => __('Force JavaScript in &lt;head&gt;?', 'minify-and-combine'),
66
+ 'tags' => array()
67
+ );
68
+ $options[] = array(
69
+ 'name' => 'js_exclude',
70
+ 'title' => __('Exclude scripts from Мinify And Combine:', 'minify-and-combine'),
71
+ 'tags' => array()
72
+ );
73
+ $options[] = array(
74
+ 'name' => 'js_trycatch',
75
+ 'title' => __('Add try-catch wrapping?', 'minify-and-combine'),
76
+ 'tags' => array()
77
+ );
78
+ /**
79
+ * CSS optimize
80
+ */
81
+ $options[] = array(
82
+ 'name' => 'css_optimize',
83
+ 'title' => __('Optimize CSS Code?', 'minify-and-combine'),
84
+ 'tags' => array('optimize_code', 'hide_my_wp')
85
+ );
86
+
87
+ $options[] = array(
88
+ 'name' => 'css_aggregate',
89
+ 'title' => __('Aggregate CSS-files?', 'minify-and-combine'),
90
+ 'tags' => array()
91
+ );
92
+
93
+ $options[] = array(
94
+ 'name' => 'css_include_inline',
95
+ 'title' => __('Also aggregate inline CSS?', 'minify-and-combine'),
96
+ 'tags' => array()
97
+ );
98
+
99
+ $options[] = array(
100
+ 'name' => 'css_datauris',
101
+ 'title' => __('Generate data: URIs for images?', 'minify-and-combine'),
102
+ 'tags' => array()
103
+ );
104
+
105
+ $options[] = array(
106
+ 'name' => 'css_defer',
107
+ 'title' => __('Inline and Defer CSS?', 'minify-and-combine'),
108
+ 'tags' => array()
109
+ );
110
+
111
+ $options[] = array(
112
+ 'name' => 'css_inline',
113
+ 'title' => __('Inline all CSS?', 'minify-and-combine'),
114
+ 'tags' => array()
115
+ );
116
+
117
+ $options[] = array(
118
+ 'name' => 'css_exclude',
119
+ 'title' => __('Exclude CSS from Мinify And Combine', 'minify-and-combine'),
120
+ 'tags' => array()
121
+ );
122
+
123
+ return $options;
124
+ });
125
+
126
+ /**
127
+ * Adds a new mode to the Quick Setup page
128
+ *
129
+ * @param array $mods
130
+ * @return mixed
131
+ */
132
+
133
+ add_filter("wbcr_clearfy_allow_quick_mods", function ($mods) {
134
+ if( !defined('WHTM_PLUGIN_ACTIVE') ) {
135
+ $title = __('One click optimize scripts (js, css)', 'minify-and-combine');
136
+ } else {
137
+ $title = __('One click optimize html code and scripts', 'minify-and-combine');
138
+ }
139
+
140
+ $mod['optimize_code'] = array(
141
+ 'title' => $title,
142
+ 'icon' => 'dashicons-performance'
143
+ );
144
+
145
+ return $mod + $mods;
146
+ });
components/minify-and-combine/admin/index.php ADDED
File without changes
components/minify-and-combine/admin/pages/index.php ADDED
File without changes
components/minify-and-combine/admin/pages/settings.php ADDED
@@ -0,0 +1,376 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * The page Settings.
5
+ *
6
+ * @since 1.0.0
7
+ */
8
+
9
+ // Exit if accessed directly
10
+ if( !defined('ABSPATH') ) {
11
+ exit;
12
+ }
13
+
14
+ class WMAC_MinifyAndCombineSettingsPage extends Wbcr_FactoryPages407_ImpressiveThemplate {
15
+
16
+ /**
17
+ * The id of the page in the admin menu.
18
+ *
19
+ * Mainly used to navigate between pages.
20
+ * @see Wbcr_FactoryPages407_AdminPage
21
+ *
22
+ * @since 1.0.0
23
+ * @var string
24
+ */
25
+ public $id = "minify_and_combine"; // Уникальный идентификатор страницы
26
+ public $page_menu_dashicon = 'dashicons-testimonial'; // Иконка для закладки страницы, дашикон
27
+ public $page_parent_page = "performance"; // Уникальный идентификатор родительской страницы
28
+
29
+ /**
30
+ * @param Wbcr_Factory406_Plugin $plugin
31
+ */
32
+ public function __construct(Wbcr_Factory406_Plugin $plugin)
33
+ {
34
+ // Заголовок страницы
35
+ $this->menu_title = __('Minify And Combine (JS/CSS)', 'minify-and-combine');
36
+
37
+ // Если плагин загружен, как самостоятельный, то мы меняем настройки страницы и делаем ее внешней,
38
+ // а не внутренней страницей родительского плагина. Внешнии страницы добавляются в Wordpress меню "Общие"
39
+
40
+ if( !defined('LOADING_MINIFY_AND_COMBINE_AS_ADDON') ) {
41
+ // true - внутреняя, false- внешняя страница
42
+ $this->internal = false;
43
+ // меню к которому, нужно прикрепить ссылку на страницу
44
+ $this->menu_target = 'options-general.php';
45
+ // Если true, добавляет ссылку "Настройки", рядом с действиями активации, деактивации плагина, на странице плагинов.
46
+ $this->add_link_to_plugin_actions = true;
47
+
48
+ $this->page_parent_page = null;
49
+
50
+ $this->available_for_multisite = true;
51
+ }
52
+
53
+ parent::__construct($plugin);
54
+ }
55
+
56
+ // Метод позволяет менять заголовок меню, в зависимости от сборки плагина.
57
+ public function getMenuTitle()
58
+ {
59
+ return defined('LOADING_MINIFY_AND_COMBINE_AS_ADDON')
60
+ ? __('Scripts Minify And Combine', 'minify-and-combine')
61
+ : __('General', 'minify-and-combine');
62
+ }
63
+
64
+ /**
65
+ * Requests assets (js and css) for the page.
66
+ *
67
+ * @see Wbcr_FactoryPages407_AdminPage
68
+ *
69
+ * @since 1.0.0
70
+ * @return void
71
+ */
72
+ public function assets($scripts, $styles)
73
+ {
74
+ parent::assets($scripts, $styles);
75
+
76
+ // Add Clearfy styles for HMWP pages
77
+ if( defined('WBCR_CLEARFY_PLUGIN_ACTIVE') ) {
78
+ $this->styles->add(WCL_PLUGIN_URL . '/admin/assets/css/general.css');
79
+ }
80
+ }
81
+
82
+ /**
83
+ * Регистрируем уведомления для страницы
84
+ *
85
+ * @see libs\factory\pages\themplates\FactoryPages407_ImpressiveThemplate
86
+ * @param $notices
87
+ * @return array
88
+ */
89
+ public function getActionNotices($notices)
90
+ {
91
+ $notices[] = array(
92
+ 'conditions' => array(
93
+ 'wbcr_mac_clear_cache_success' => 1
94
+ ),
95
+ 'type' => 'success',
96
+ 'message' => __('The cache has been successfully cleaned.', 'minify-and-combine')
97
+ );
98
+
99
+ return $notices;
100
+ }
101
+
102
+ /**
103
+ * Метод должен передать массив опций для создания формы с полями.
104
+ * Созданием страницы и формы занимается фреймворк
105
+ *
106
+ * @since 1.0.0
107
+ * @return mixed[]
108
+ */
109
+ public function getOptions()
110
+ {
111
+ $options = array();
112
+
113
+ $options[] = array(
114
+ 'type' => 'html',
115
+ 'html' => '<div class="wbcr-factory-page-group-header"><strong>' . __('JavaScript Options', 'minify-and-combine') . '</strong><p></p></div>'
116
+ );
117
+
118
+ $options[] = array(
119
+ 'type' => 'checkbox',
120
+ 'way' => 'buttons',
121
+ 'name' => 'js_optimize',
122
+ 'title' => __('Optimize JavaScript Code?', 'minify-and-combine'),
123
+ 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
124
+ //'hint' => __('Optimize JavaScript Code.', 'minify-and-combine'),
125
+ 'default' => false,
126
+ 'eventsOn' => array(
127
+ 'show' => '#wbcr-mac-optimize-js-fields'
128
+ ),
129
+ 'eventsOff' => array(
130
+ 'hide' => '#wbcr-mac-optimize-js-fields'
131
+ )
132
+ );
133
+
134
+ $js_options[] = array(
135
+ 'type' => 'checkbox',
136
+ 'way' => 'buttons',
137
+ 'name' => 'js_aggregate',
138
+ 'title' => __('Aggregate JS-files?', 'minify-and-combine'),
139
+ 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
140
+ 'hint' => __('Aggregate all linked JS-files to have them loaded non-render blocking? If this option is off, the individual JS-files will remain in place but will be minified.', 'minify-and-combine'),
141
+ 'default' => false
142
+ );
143
+
144
+ $js_options[] = array(
145
+ 'type' => 'checkbox',
146
+ 'way' => 'buttons',
147
+ 'name' => 'js_include_inline',
148
+ 'title' => __('Also aggregate inline JS?', 'minify-and-combine'),
149
+ 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
150
+ 'hint' => __('Let Мinify And Combine also extract JS from the HTML. Warning: this can make Мinify And Combine\'s cache size grow quickly, so only enable this if you know what you\'re doing.', 'minify-and-combine'),
151
+ 'default' => false
152
+ );
153
+
154
+ $js_options[] = array(
155
+ 'type' => 'checkbox',
156
+ 'way' => 'buttons',
157
+ 'name' => 'js_forcehead',
158
+ 'title' => __('Force JavaScript in &lt;head&gt;?', 'minify-and-combine'),
159
+ 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
160
+ 'hint' => __('Load JavaScript early, this can potentially fix some JS-errors, but makes the JS render blocking.', 'minify-and-combine'),
161
+ 'default' => false
162
+ );
163
+
164
+ $js_options[] = array(
165
+ 'type' => 'textarea',
166
+ 'name' => 'js_exclude',
167
+ 'title' => __('Exclude scripts from Мinify And Combine:', 'minify-and-combine'),
168
+ //'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
169
+ 'hint' => __('A comma-separated list of scripts you want to exclude from being optimized, for example \'whatever.js, another.js\' (without the quotes) to exclude those scripts from being aggregated and minimized by Мinify And Combine.', 'minify-and-combine'),
170
+ 'default' => 'seal.js, js/jquery/jquery.js'
171
+ );
172
+
173
+ $js_options[] = array(
174
+ 'type' => 'checkbox',
175
+ 'way' => 'buttons',
176
+ 'name' => 'js_trycatch',
177
+ 'title' => __('Add try-catch wrapping?', 'minify-and-combine'),
178
+ 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
179
+ 'hint' => __('If your scripts break because of a JS-error, you might want to try this.', 'minify-and-combine'),
180
+ 'default' => false
181
+ );
182
+
183
+ $options[] = array(
184
+ 'type' => 'div',
185
+ 'id' => 'wbcr-mac-optimize-js-fields',
186
+ 'items' => $js_options
187
+ );
188
+
189
+ $options[] = array(
190
+ 'type' => 'html',
191
+ 'html' => '<div class="wbcr-factory-page-group-header"><strong>' . __('CSS Options', 'minify-and-combine') . '</strong><p></p></div>'
192
+ );
193
+
194
+ $options[] = array(
195
+ 'type' => 'checkbox',
196
+ 'way' => 'buttons',
197
+ 'name' => 'css_optimize',
198
+ 'title' => __('Optimize CSS Code?', 'minify-and-combine'),
199
+ 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
200
+ 'hint' => __('If your scripts break because of a JS-error, you might want to try this.', 'minify-and-combine'),
201
+ 'default' => false,
202
+ 'eventsOn' => array(
203
+ 'show' => '#wbcr-clr-optimize-css-fields'
204
+ ),
205
+ 'eventsOff' => array(
206
+ 'hide' => '#wbcr-clr-optimize-css-fields'
207
+ )
208
+ );
209
+
210
+ $css_options[] = array(
211
+ 'type' => 'checkbox',
212
+ 'way' => 'buttons',
213
+ 'name' => 'css_aggregate',
214
+ 'title' => __('Aggregate CSS-files?', 'minify-and-combine'),
215
+ 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
216
+ 'hint' => __('Aggregate all linked CSS-files? If this option is off, the individual CSS-files will remain in place but will be minified.', 'minify-and-combine'),
217
+ 'default' => false
218
+ );
219
+
220
+ $css_options[] = array(
221
+ 'type' => 'checkbox',
222
+ 'way' => 'buttons',
223
+ 'name' => 'css_include_inline',
224
+ 'title' => __('Also aggregate inline CSS?', 'minify-and-combine'),
225
+ 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
226
+ 'hint' => __('Check this option for Мinify And Combine to also aggregate CSS in the HTML.', 'minify-and-combine'),
227
+ 'default' => false
228
+ );
229
+
230
+ $css_options[] = array(
231
+ 'type' => 'checkbox',
232
+ 'way' => 'buttons',
233
+ 'name' => 'css_datauris',
234
+ 'title' => __('Generate data: URIs for images?', 'minify-and-combine'),
235
+ 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
236
+ 'hint' => __('Enable this to include small background-images in the CSS itself instead of as separate downloads.', 'minify-and-combine'),
237
+ 'default' => false
238
+ );
239
+
240
+ $css_options[] = array(
241
+ 'type' => 'checkbox',
242
+ 'way' => 'buttons',
243
+ 'name' => 'css_defer',
244
+ 'title' => __('Inline and Defer CSS?', 'minify-and-combine'),
245
+ 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
246
+ 'hint' => __('Inline "above the fold CSS" while loading the main auto optimized CSS only after page load. Check the FAQ for more info.
247
+ This can be fully automated for different types of pages with the Мinify And Combine CriticalCSS Power-Up.', 'minify-and-combine'),
248
+ 'default' => false
249
+ );
250
+
251
+ $css_options[] = array(
252
+ 'type' => 'checkbox',
253
+ 'way' => 'buttons',
254
+ 'name' => 'css_inline',
255
+ 'title' => __('Inline all CSS?', 'minify-and-combine'),
256
+ 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
257
+ 'hint' => __('Inlining all CSS can improve performance for sites with a low pageviews/ visitor-rate, but may slow down performance otherwise.', 'minify-and-combine'),
258
+ 'default' => false
259
+ );
260
+
261
+ $css_options[] = array(
262
+ 'type' => 'textarea',
263
+ 'name' => 'css_exclude',
264
+ 'title' => __('Exclude CSS from Мinify And Combine:', 'minify-and-combine'),
265
+ //'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'grey'),
266
+ 'hint' => __('A comma-separated list of CSS you want to exclude from being optimized.', 'minify-and-combine'),
267
+ 'default' => 'wp-content/cache/, wp-content/uploads/, admin-bar.min.css, dashicons.min.css'
268
+ );
269
+
270
+ $options[] = array(
271
+ 'type' => 'div',
272
+ 'id' => 'wbcr-clr-optimize-css-fields',
273
+ 'items' => $css_options
274
+ );
275
+
276
+ $options[] = array(
277
+ 'type' => 'html',
278
+ 'html' => '<div class="wbcr-factory-page-group-header"><strong>' . __('Cache Info', 'minify-and-combine') . '</strong><p>' . __('Описание раздела оптимизация', 'minify-and-combine') . '</p></div>'
279
+ );
280
+
281
+ // Произвольный html код
282
+ $options[] = array(
283
+ 'type' => 'html',
284
+ 'html' => array($this, 'cacheInfo')
285
+ );
286
+
287
+ $formOptions = array();
288
+
289
+ $formOptions[] = array(
290
+ 'type' => 'form-group',
291
+ 'items' => $options,
292
+ //'cssClass' => 'postbox'
293
+ );
294
+
295
+ return apply_filters('wbcr_mac_settings_form_options', $formOptions);
296
+ }
297
+
298
+ public function cacheInfo()
299
+ {
300
+ $is_network = is_network_admin();
301
+
302
+ $cache = $is_network
303
+ ? WMAC_PluginCache::getUsedCacheMultisite()
304
+ : WMAC_PluginCache::getUsedCache();
305
+ ?>
306
+ <div class="form-group">
307
+ <label for="wbcr_mac_css_optimize" class="col-sm-6 control-label">
308
+ Cache folder<?php echo $is_network
309
+ ? 's'
310
+ : '' ?>
311
+ </label>
312
+
313
+ <div class="control-group col-sm-6">
314
+ <?php echo $is_network
315
+ ? WP_CONTENT_DIR . WMAC_CACHE_CHILD_DIR . '[...]/'
316
+ : WMAC_PluginCache::getCacheDir() ?>
317
+ </div>
318
+ </div>
319
+ <div class="form-group">
320
+ <label for="wbcr_mac_css_optimize" class="col-sm-6 control-label">
321
+ Can we write?
322
+ </label>
323
+
324
+ <div class="control-group col-sm-6">
325
+ Yes
326
+ </div>
327
+ </div>
328
+ <div class="form-group">
329
+ <label for="wbcr_mac_css_optimize" class="col-sm-6 control-label">
330
+ Cached styles and scripts<?php echo $is_network
331
+ ? ' (all sites)'
332
+ : '' ?>
333
+ </label>
334
+
335
+ <div class="control-group col-sm-6">
336
+ <?php if( $is_network ) : ?>
337
+ <?php echo $cache['files'] ?> files, totalling <?php echo $cache['size'] ?> (calculated
338
+ at <?php echo gmdate('H:i') ?> UTC)
339
+ <?php else: ?>
340
+ <?php echo $cache['percent'] . '%, ' . $cache['files'] ?> files,
341
+ totalling <?php echo $cache['size'] ?> (calculated at <?php echo gmdate('H:i') ?> UTC)
342
+ <?php endif; ?>
343
+ </div>
344
+ </div>
345
+ <div class="form-group">
346
+ <label for="wbcr_mac_css_optimize" class="col-sm-6 control-label">
347
+ </label>
348
+
349
+ <div class="control-group col-sm-6">
350
+ <a class="btn btn-default" href="<?= wp_nonce_url($this->getActionUrl('clear-cache'), 'clear_cache_' . $this->getResultId()); ?>">
351
+ <?php _e('Clear cache', 'minify-and-combine') ?>
352
+ </a>
353
+ </div>
354
+ </div>
355
+ <?php
356
+ }
357
+
358
+ /**
359
+ * Действие rollback
360
+ * Если мы перейдем по ссылке, которую мы создали для кнопки "Восстановить" для метода rollbackButton,
361
+ * То выполнится это действие
362
+ */
363
+ public function clearCacheAction()
364
+ {
365
+ check_admin_referer('clear_cache_' . $this->getResultId());
366
+
367
+ if( is_network_admin() ) {
368
+ WMAC_PluginCache::clearAllMultisite();
369
+ } else {
370
+ WMAC_PluginCache::clearAll();
371
+ }
372
+
373
+ // редирект с выводом уведомления
374
+ $this->redirectToAction('index', array('wbcr_mac_clear_cache_success' => 1));
375
+ }
376
+ }
components/minify-and-combine/assets/css/index.php ADDED
File without changes
components/minify-and-combine/assets/index.php ADDED
File without changes
components/minify-and-combine/assets/js/index.php ADDED
File without changes
components/minify-and-combine/includes/boot.php ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Global boot
4
+ * @author Webcraftic <wordpress.webraftic@gmail.com>
5
+ * @copyright (c) 01.07.2018, Webcraftic
6
+ * @version 1.0
7
+ */
8
+
9
+ // Exit if accessed directly
10
+ if( !defined('ABSPATH') ) {
11
+ exit;
12
+ }
13
+
14
+ function wbcr_mac_clear_cache()
15
+ {
16
+ if( isset($_GET['wbcr_mac_clear_cache']) && isset($_GET['_wpnonce']) && wp_verify_nonce($_GET['_wpnonce'], 'clear_all_cache') ) {
17
+ $page = isset($_GET['page'])
18
+ ? $_GET['page']
19
+ : 'minify_and_combine-wbcr_minify_and_combine';
20
+ if( is_network_admin() ) {
21
+ WMAC_PluginCache::clearAllMultisite();
22
+ $base_url = network_admin_url('settings.php') . '?page=' . $page;
23
+ } else {
24
+ WMAC_PluginCache::clearAll();
25
+ $base_url = admin_url('options-general.php') . '?page=' . $page;
26
+ }
27
+
28
+ wp_safe_redirect(add_query_arg(array('wbcr_mac_clear_cache_success' => 1), $base_url));
29
+ }
30
+ }
31
+
32
+ add_action('init', 'wbcr_mac_clear_cache');
33
+
34
+ /**
35
+ * Добавляем кнопку сброса кеша в админ бар
36
+ *
37
+ * @param $wp_admin_bar
38
+ */
39
+ function wbcr_mac_admin_bar_menu($wp_admin_bar)
40
+ {
41
+ if( !current_user_can('manage_options') ) {
42
+ return;
43
+ }
44
+ $current_url = wp_nonce_url(add_query_arg(array('wbcr_mac_clear_cache' => 1)), 'clear_all_cache');
45
+
46
+ $args = array(
47
+ 'id' => 'clear-cache-btn',
48
+ 'title' => __('Clear cache', 'minify-and-combine') . (is_network_admin()
49
+ ? ''
50
+ : ' (' . WMAC_PluginCache::getUsedCache()['percent'] . '%)'),
51
+ 'href' => $current_url
52
+ );
53
+ $wp_admin_bar->add_menu($args);
54
+ }
55
+
56
+ /**
57
+ * Добавляем кнопку сброса кеша в Clearfy меню
58
+ */
59
+ function wbcr_mac_clearfy_admin_bar_menu($menu_items)
60
+ {
61
+ $current_url = wp_nonce_url(add_query_arg(array('wbcr_mac_clear_cache' => 1)), 'clear_all_cache');
62
+
63
+ $menu_items['mac-clear-cache'] = array(
64
+ 'title' => __('Clear cache', 'minify-and-combine') . (is_network_admin()
65
+ ? ''
66
+ : ' (' . WMAC_PluginCache::getUsedCache()['percent'] . '%)'),
67
+ 'href' => $current_url
68
+ );
69
+
70
+ return $menu_items;
71
+ }
72
+
73
+ if( defined('LOADING_MINIFY_AND_COMBINE_AS_ADDON') ) {
74
+ add_action('wbcr_clearfy_admin_bar_menu_items', 'wbcr_mac_clearfy_admin_bar_menu');
75
+ } else {
76
+ add_action('admin_bar_menu', 'wbcr_mac_admin_bar_menu');
77
+ }
components/minify-and-combine/includes/class.plugin.php ADDED
@@ -0,0 +1,183 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Основной класс плагина
4
+ * @author Webcraftic <wordpress.webraftic@gmail.com>
5
+ * @copyright (c) 19.02.2018, Webcraftic
6
+ * @version 1.0
7
+ */
8
+
9
+ // Exit if accessed directly
10
+ if( !defined('ABSPATH') ) {
11
+ exit;
12
+ }
13
+
14
+ if( !class_exists('WMAC_Plugin') ) {
15
+ if( !class_exists('WMAC_PluginFactory') ) {
16
+ // Этот плагин может быть аддоном плагина Clearfy, если он загружен, как аддон, то мы не подключаем фреймворк,
17
+ // а наследуем функции фреймворка от плагина Clearfy. Если плагин скомпилирован, как отдельный плагин, то он использует собственный фреймворк для работы.
18
+ // Константа LOADING_MINIFY_AND_COMBINE_AS_ADDON утсанавливается в классе libs/factory/core/includes/Wbcr_Factory406_Plugin
19
+
20
+ if( defined('LOADING_MINIFY_AND_COMBINE_AS_ADDON') ) {
21
+ class WMAC_PluginFactory {
22
+
23
+ }
24
+ } else {
25
+ class WMAC_PluginFactory extends Wbcr_Factory406_Plugin {
26
+
27
+ }
28
+ }
29
+ }
30
+
31
+ class WMAC_Plugin extends WMAC_PluginFactory {
32
+
33
+ /**
34
+ * @var Wbcr_Factory406_Plugin
35
+ */
36
+ private static $app;
37
+
38
+ /**
39
+ * @var bool
40
+ */
41
+ private $as_addon;
42
+
43
+ /**
44
+ * @param string $plugin_path
45
+ * @param array $data
46
+ * @throws Exception
47
+ */
48
+ public function __construct($plugin_path, $data)
49
+ {
50
+ $this->as_addon = isset($data['as_addon']);
51
+
52
+ if( $this->as_addon ) {
53
+ $plugin_parent = isset($data['plugin_parent'])
54
+ ? $data['plugin_parent']
55
+ : null;
56
+
57
+ if( !($plugin_parent instanceof Wbcr_Factory406_Plugin) ) {
58
+ throw new Exception('An invalid instance of the class was passed.');
59
+ }
60
+
61
+ // Если плагин загружен, как аддон, то мы передаем в app ссылку на класс родителя
62
+ self::$app = $plugin_parent;
63
+ } else {
64
+ // Если плагин самостоятельный, то записываем в app сслыку на текущий класс
65
+ self::$app = $this;
66
+
67
+ parent::__construct($plugin_path, $data);
68
+ }
69
+
70
+ $this->setTextDomain();
71
+ $this->setModules();
72
+ $this->globalScripts();
73
+
74
+ if( is_admin() ) {
75
+ $this->adminScripts();
76
+ }
77
+
78
+ add_action('plugins_loaded', array($this, 'pluginsLoaded'));
79
+ }
80
+
81
+ /**
82
+ * Статический метод для быстрого доступа к информации о плагине, а также часто использумых методах.
83
+ *
84
+ * Пример:
85
+ * WMAC_Plugin::app()->getOption()
86
+ * WMAC_Plugin::app()->updateOption()
87
+ * WMAC_Plugin::app()->deleteOption()
88
+ * WMAC_Plugin::app()->getPluginName()
89
+ *
90
+ * @return Wbcr_Factory406_Plugin
91
+ */
92
+ public static function app()
93
+ {
94
+ return self::$app;
95
+ }
96
+
97
+ /**
98
+ * Устанавливаем текстовый домен
99
+ */
100
+ protected function setTextDomain()
101
+ {
102
+ // Localization plugin
103
+ load_plugin_textdomain('minify-and-combine', false, dirname(WMAC_PLUGIN_BASE) . '/languages/');
104
+ }
105
+
106
+ /**
107
+ * Подключаем модули фреймворка
108
+ */
109
+ protected function setModules()
110
+ {
111
+ if( !$this->as_addon ) {
112
+ self::app()->load(array(
113
+ // Модуль отвечает за подключение скриптов и стилей для интерфейса
114
+ array('libs/factory/bootstrap', 'factory_bootstrap_406', 'admin'),
115
+ // Модуль отвечает за создание форм и полей
116
+ array('libs/factory/forms', 'factory_forms_407', 'admin'),
117
+ // Модуль отвечает за создание шаблонов страниц плагина
118
+ array('libs/factory/pages', 'factory_pages_407', 'admin'),
119
+ // Модуль в котором хранится общий функционал плагина Clearfy и его аддонов
120
+ array('libs/factory/clearfy', 'factory_clearfy_203', 'all')
121
+ ));
122
+ }
123
+ }
124
+
125
+ /**
126
+ * Регистрируем страницы плагина
127
+ */
128
+ private function registerPages()
129
+ {
130
+
131
+ $admin_path = WMAC_PLUGIN_DIR . '/admin/pages';
132
+
133
+ // Пример основной страницы настроек
134
+ self::app()->registerPage('WMAC_MinifyAndCombineSettingsPage', $admin_path . '/settings.php');
135
+
136
+ // Пример внутренней страницы настроек
137
+ //self::app()->registerPage('WMAC_StatisticPage', $admin_path . '/statistic.php');
138
+ }
139
+
140
+ /**
141
+ * Подключаем функции бекенда
142
+ */
143
+ private function adminScripts()
144
+ {
145
+ require_once(WMAC_PLUGIN_DIR . '/admin/boot.php');
146
+ $this->registerPages();
147
+ }
148
+
149
+ /**
150
+ * Подключаем глобальные функции
151
+ */
152
+ private function globalScripts()
153
+ {
154
+ //require(WMAC_PLUGIN_DIR . '/includes/classes/class.configurate-comments.php');
155
+ //new WMAC_ConfigComments(self::$app);
156
+ require_once(WMAC_PLUGIN_DIR . '/includes/boot.php');
157
+ }
158
+
159
+ /**
160
+ * Выполнение действий после загрузки плагина
161
+ * Подключаем все классы оптимизации и запускаем процесс
162
+ */
163
+ public function pluginsLoaded()
164
+ {
165
+ require_once(WMAC_PLUGIN_DIR . '/includes/classes/class.mac-base.php');
166
+ require_once(WMAC_PLUGIN_DIR . '/includes/classes/class.mac-cache.php');
167
+ require_once(WMAC_PLUGIN_DIR . '/includes/classes/class.mac-cache-checker.php');
168
+ require_once(WMAC_PLUGIN_DIR . '/includes/classes/class.mac-scripts.php');
169
+ require_once(WMAC_PLUGIN_DIR . '/includes/classes/class.mac-css-min.php');
170
+ require_once(WMAC_PLUGIN_DIR . '/includes/classes/class.mac-styles.php');
171
+ require_once(WMAC_PLUGIN_DIR . '/includes/classes/class.mac-main.php');
172
+ require_once(WMAC_PLUGIN_DIR . '/includes/classes/class.mac-helper.php');
173
+
174
+ require_once(WMAC_PLUGIN_DIR . '/includes/classes/ext/php/jsmin.php');
175
+ require_once(WMAC_PLUGIN_DIR . '/includes/classes/ext/php/yui-php-cssmin-bundled/Colors.php');
176
+ require_once(WMAC_PLUGIN_DIR . '/includes/classes/ext/php/yui-php-cssmin-bundled/Minifier.php');
177
+ require_once(WMAC_PLUGIN_DIR . '/includes/classes/ext/php/yui-php-cssmin-bundled/Utils.php');
178
+
179
+ $plugin = new WMAC_PluginMain();
180
+ $plugin->start();
181
+ }
182
+ }
183
+ }
components/minify-and-combine/includes/classes/class.mac-base.php ADDED
@@ -0,0 +1,666 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Base class
4
+ * @author Webcraftic <wordpress.webraftic@gmail.com>
5
+ * @copyright (c) 2018 Webraftic Ltd
6
+ * @version 1.0
7
+ */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit;
11
+ }
12
+
13
+ /**
14
+ * Class WMAC_PluginBase
15
+ */
16
+ abstract class WMAC_PluginBase
17
+ {
18
+ /**
19
+ * Holds content being processed (scripts, styles)
20
+ *
21
+ * @var string
22
+ */
23
+ protected $content = '';
24
+
25
+ /**
26
+ * Controls debug logging.
27
+ *
28
+ * @var bool
29
+ */
30
+ public $debug_log = false;
31
+
32
+ /**
33
+ * WMAC_PluginBase constructor.
34
+ *
35
+ * @param $content
36
+ */
37
+ public function __construct( $content )
38
+ {
39
+ $this->content = $content;
40
+ }
41
+
42
+ /**
43
+ * Reads the page and collects tags.
44
+ *
45
+ * @param array $options Options.
46
+ *
47
+ * @return bool
48
+ */
49
+ abstract public function read( $options );
50
+
51
+ /**
52
+ * Joins and optimizes collected things.
53
+ *
54
+ * @return bool
55
+ */
56
+ abstract public function minify();
57
+
58
+ /**
59
+ * Caches the things.
60
+ *
61
+ * @return void
62
+ */
63
+ abstract public function cache();
64
+
65
+ /**
66
+ * Returns the content
67
+ *
68
+ * @return string
69
+ */
70
+ abstract public function getContent();
71
+
72
+ /**
73
+ * Tranfsorms a given URL to a full local filepath if possible.
74
+ * Returns local filepath or false.
75
+ *
76
+ * @param string $url URL to transform.
77
+ *
78
+ * @return bool|string
79
+ */
80
+ public function getPath( $url )
81
+ {
82
+ $url = apply_filters( 'wmac_filter_cssjs_alter_url', $url );
83
+
84
+ if ( false !== strpos( $url, '%' ) ) {
85
+ $url = urldecode( $url );
86
+ }
87
+
88
+ $site_url = WMAC_PluginMain::getSiteUrl();
89
+ $site_host = parse_url( $site_url, PHP_URL_HOST );
90
+ $content_host = parse_url( WMAC_WP_ROOT_URL, PHP_URL_HOST );
91
+
92
+ // Normalizing attempts...
93
+ $double_slash_position = strpos( $url, '//' );
94
+ if ( 0 === $double_slash_position ) {
95
+ if ( is_ssl() ) {
96
+ $url = 'https:' . $url;
97
+ } else {
98
+ $url = 'http:' . $url;
99
+ }
100
+ } elseif ( ( false === $double_slash_position ) && ( false === strpos( $url, $site_host ) ) ) {
101
+ if ( $site_url === $site_host ) {
102
+ $url = $site_url . $url;
103
+ } else {
104
+ $url = $site_url . WMAC_PluginHelper::pathCanonicalize( $url );
105
+ }
106
+ }
107
+
108
+ if ( $site_host !== $content_host ) {
109
+ $url = str_replace( WMAC_PluginMain::getContentUrl(), $site_url . WMAC_WP_CONTENT_NAME, $url );
110
+ }
111
+
112
+ // First check; hostname wp site should be hostname of url!
113
+ $url_host = @parse_url( $url, PHP_URL_HOST ); // @codingStandardsIgnoreLine
114
+ if ( $url_host !== $site_host ) {
115
+ /**
116
+ * First try to get all domains from WPML (if available)
117
+ * then apply own filter wmac_filter_cssjs_multidomain takes an array of hostnames
118
+ * each item in that array will be considered part of the same WP multisite installation
119
+ */
120
+ $multidomains = array();
121
+
122
+ $multidomains_wpml = apply_filters( 'wpml_setting', array(), 'language_domains' );
123
+ if ( ! empty( $multidomains_wpml ) ) {
124
+ $multidomains = array_map( array( $this, 'getUrlHostname' ), $multidomains_wpml );
125
+ }
126
+
127
+ $multidomains = apply_filters( 'wmac_filter_cssjs_multidomain', $multidomains );
128
+
129
+ if ( ! empty( $multidomains ) ) {
130
+ if ( in_array( $url_host, $multidomains ) ) {
131
+ $url = str_replace( $url_host, $site_host, $url );
132
+ } else {
133
+ return false;
134
+ }
135
+ } else {
136
+ return false;
137
+ }
138
+ }
139
+
140
+ // Try to remove "wp root url" from url while not minding http<>https.
141
+ $tmp_ao_root = preg_replace( '/https?:/', '', WMAC_WP_ROOT_URL );
142
+
143
+ if ( $site_host !== $content_host ) {
144
+ // As we replaced the content-domain with the site-domain, we should match against that.
145
+ $tmp_ao_root = preg_replace( '/https?:/', '', $site_url );
146
+ }
147
+
148
+ $tmp_url = preg_replace( '/https?:/', '', $url );
149
+ $path = str_replace( $tmp_ao_root, '', $tmp_url );
150
+
151
+ // If path starts with :// or //, this is not a URL in the WP context and
152
+ // we have to assume we can't aggregate.
153
+ if ( preg_match( '#^:?//#', $path ) ) {
154
+ // External script/css (adsense, etc).
155
+ return false;
156
+ }
157
+
158
+ // Prepend with WMAC_ROOT_DIR to have full path to file.
159
+ $path = str_replace( '//', '/', WMAC_ROOT_DIR . $path );
160
+
161
+ // Final check: does file exist and is it readable?
162
+ if ( file_exists( $path ) && is_file( $path ) && is_readable( $path ) ) {
163
+ return $path;
164
+ } else {
165
+ return false;
166
+ }
167
+ }
168
+
169
+ /**
170
+ * Returns the hostname part of a given $url if we're able to parse it.
171
+ * If not, it returns the original url (prefixed with http:// scheme in case
172
+ * it was missing).
173
+ * Used as callback for WPML multidomains filter.
174
+ *
175
+ * @param string $url URL.
176
+ *
177
+ * @return string
178
+ */
179
+ protected function getUrlHostname( $url )
180
+ {
181
+ // Checking that the url starts with something vaguely resembling a protocol.
182
+ if ( ( 0 !== strpos( $url, 'http' ) ) && ( 0 !== strpos( $url, '//' ) ) ) {
183
+ $url = 'http://' . $url;
184
+ }
185
+
186
+ // Grab the hostname.
187
+ $hostname = parse_url( $url, PHP_URL_HOST );
188
+
189
+ // Fallback when parse_url() fails.
190
+ if ( empty( $hostname ) ) {
191
+ $hostname = $url;
192
+ }
193
+
194
+ return $hostname;
195
+ }
196
+
197
+ /**
198
+ * Hides everything between noptimize-comment tags.
199
+ *
200
+ * @param string $markup Markup to process.
201
+ *
202
+ * @return string
203
+ */
204
+ protected function hideNoptimize( $markup )
205
+ {
206
+ return $this->replaceContentsWithMarkerIfExists(
207
+ 'NOPTIMIZE',
208
+ '/<!--\s?noptimize\s?-->/',
209
+ '#<!--\s?noptimize\s?-->.*?<!--\s?/\s?noptimize\s?-->#is',
210
+ $markup
211
+ );
212
+ }
213
+
214
+ /**
215
+ * Unhide noptimize-tags.
216
+ *
217
+ * @param string $markup Markup to process.
218
+ *
219
+ * @return string
220
+ */
221
+ protected function restoreNoptimize( $markup )
222
+ {
223
+ return $this->restoreMarkedContent( 'NOPTIMIZE', $markup );
224
+ }
225
+
226
+ /**
227
+ * Hides "iehacks" content.
228
+ *
229
+ * @param string $markup Markup to process.
230
+ *
231
+ * @return string
232
+ */
233
+ protected function hideIEhacks( $markup )
234
+ {
235
+ return $this->replaceContentsWithMarkerIfExists(
236
+ 'IEHACK', // Marker name...
237
+ '<!--[if', // Invalid regex, will fallback to search using strpos()...
238
+ '#<!--\[if.*?\[endif\]-->#is', // Replacement regex...
239
+ $markup
240
+ );
241
+ }
242
+
243
+ /**
244
+ * Restores "hidden" iehacks content.
245
+ *
246
+ * @param string $markup Markup to process.
247
+ *
248
+ * @return string
249
+ */
250
+ protected function restoreIEhacks( $markup )
251
+ {
252
+ return $this->restoreMarkedContent( 'IEHACK', $markup );
253
+ }
254
+
255
+ /**
256
+ * "Hides" content within HTML comments using a regex-based replacement
257
+ * if HTML comment markers are found.
258
+ * `<!--example-->` becomes `%%COMMENTS%%ZXhhbXBsZQ==%%COMMENTS%%`
259
+ *
260
+ * @param string $markup Markup to process.
261
+ *
262
+ * @return string
263
+ */
264
+ protected function hideComments( $markup )
265
+ {
266
+ return $this->replaceContentsWithMarkerIfExists(
267
+ 'COMMENTS',
268
+ '<!--',
269
+ '#<!--.*?-->#is',
270
+ $markup
271
+ );
272
+ }
273
+
274
+ /**
275
+ * Restores original HTML comment markers inside a string whose HTML
276
+ * comments have been "hidden" by using `hideComments()`.
277
+ *
278
+ * @param string $markup Markup to process.
279
+ *
280
+ * @return string
281
+ */
282
+ protected function restoreComments( $markup )
283
+ {
284
+ return $this->restoreMarkedContent( 'COMMENTS', $markup );
285
+ }
286
+
287
+ /**
288
+ * Injects/replaces the given payload markup into `$this->content`
289
+ * at the specified location.
290
+ * If the specified tag cannot be found, the payload is appended into
291
+ * $this->content along with a warning wrapped inside <!--noptimize--> tags.
292
+ *
293
+ * @param string $payload Markup to inject.
294
+ * @param array $where Array specifying the tag name and method of injection.
295
+ * Index 0 is the tag name (i.e., `</body>`).
296
+ * Index 1 specifies ˛'before', 'after' or 'replace'. Defaults to 'before'.
297
+ *
298
+ * @return void
299
+ */
300
+ protected function injectInHtml( $payload, $where )
301
+ {
302
+ $warned = false;
303
+ $position = WMAC_PluginHelper::strpos( $this->content, $where[0] );
304
+ if ( false !== $position ) {
305
+ // Found the tag, setup content/injection as specified.
306
+ if ( 'after' === $where[1] ) {
307
+ $content = $where[0] . $payload;
308
+ } elseif ( 'replace' === $where[1] ) {
309
+ $content = $payload;
310
+ } else {
311
+ $content = $payload . $where[0];
312
+ }
313
+ // Place where specified.
314
+ $this->content = WMAC_PluginHelper::substrReplace(
315
+ $this->content,
316
+ $content,
317
+ $position,
318
+ // Using plain strlen() should be safe here for now, since
319
+ // we're not searching for multibyte chars here still...
320
+ strlen( $where[0] )
321
+ );
322
+ } else {
323
+ // Couldn't find what was specified, just append and add a warning.
324
+ $this->content .= $payload;
325
+ if ( ! $warned ) {
326
+ $tag_display = str_replace( array( '<', '>' ), '', $where[0] );
327
+ $this->content .= '<!--noptimize--><!-- Мinify And Combine found a problem with the HTML in your Theme, tag `' . $tag_display . '` missing --><!--/noptimize-->';
328
+ }
329
+ }
330
+ }
331
+
332
+ /**
333
+ * Returns true if given `$tag` is found in the list of `$removables`.
334
+ *
335
+ * @param string $tag Tag to search for.
336
+ * @param array $removables List of things considered completely removable.
337
+ *
338
+ * @return bool
339
+ */
340
+ protected function isremovable( $tag, $removables )
341
+ {
342
+ foreach ( $removables as $match ) {
343
+ if ( false !== strpos( $tag, $match ) ) {
344
+ return true;
345
+ }
346
+ }
347
+
348
+ return false;
349
+ }
350
+
351
+ /**
352
+ * Callback used in `self::injectMinified()`.
353
+ *
354
+ * @param array $matches Regex matches.
355
+ *
356
+ * @return string
357
+ */
358
+ public function injectMinifiedCallback( $matches )
359
+ {
360
+ /**
361
+ * $matches[1] holds the whole match caught by regex in self::injectMinified(),
362
+ * so we take that and split the string on `|`.
363
+ * First element is the filepath, second is the md5 hash of contents
364
+ * the filepath had when it was being processed.
365
+ * If we don't have those, we'll bail out early.
366
+ */
367
+ $filepath = null;
368
+ $filehash = null;
369
+
370
+ // Grab the parts we need.
371
+ $parts = explode( $matches[1], '|' );
372
+ if ( ! empty( $parts ) ) {
373
+ $filepath = isset( $parts[0] ) ? $parts[0] : null;
374
+ $filehash = isset( $parts[1] ) ? $parts[1] : null;
375
+ }
376
+
377
+ // Bail early if something's not right...
378
+ if ( ! $filepath || ! $filehash ) {
379
+ return "\n";
380
+ }
381
+
382
+ $filecontent = file_get_contents( $filepath );
383
+
384
+ // Some things are differently handled for css/js...
385
+ $is_js_file = ( '.js' === substr( $filepath, -3, 3 ) );
386
+
387
+ $is_css_file = false;
388
+ if ( ! $is_js_file ) {
389
+ $is_css_file = ( '.css' === substr( $filepath, -4, 4 ) );
390
+ }
391
+
392
+ // BOMs being nuked here unconditionally (regardless of where they are)!
393
+ $filecontent = preg_replace( "#\x{EF}\x{BB}\x{BF}#", '', $filecontent );
394
+
395
+ // Remove comments and blank lines.
396
+ if ( $is_js_file ) {
397
+ $filecontent = preg_replace( '#^\s*\/\/.*$#Um', '', $filecontent );
398
+ }
399
+
400
+ // Nuke un-important comments.
401
+ $filecontent = preg_replace( '#^\s*\/\*[^!].*\*\/\s?#Um', '', $filecontent );
402
+
403
+ // Normalize newlines.
404
+ $filecontent = preg_replace( '#(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+#', "\n", $filecontent );
405
+
406
+ // JS specifics.
407
+ if ( $is_js_file ) {
408
+ // Append a semicolon at the end of js files if it's missing.
409
+ $last_char = substr( $filecontent, -1, 1 );
410
+ if ( ';' !== $last_char && '}' !== $last_char ) {
411
+ $filecontent .= ';';
412
+ }
413
+ // Check if try/catch should be used.
414
+ $opt_js_try_catch = WMAC_Plugin::app()->getOption('js_trycatch');
415
+ if ( $opt_js_try_catch ) {
416
+ // It should, wrap in try/catch.
417
+ $filecontent = 'try{' . $filecontent . '}catch(e){}';
418
+ }
419
+ } elseif ( $is_css_file ) {
420
+ $filecontent = WMAC_PluginStyles::fixurls( $filepath, $filecontent );
421
+ } else {
422
+ $filecontent = '';
423
+ }
424
+
425
+ // Return modified (or empty!) code/content.
426
+ return "\n" . $filecontent;
427
+ }
428
+
429
+ /**
430
+ * Inject already minified code in optimized JS/CSS.
431
+ *
432
+ * @param string $in Markup.
433
+ *
434
+ * @return string
435
+ */
436
+ protected function injectMinified( $in )
437
+ {
438
+ $out = $in;
439
+
440
+ if ( false !== strpos( $in, '%%INJECTLATER%%' ) ) {
441
+ $out = preg_replace_callback(
442
+ '#\/\*\!%%INJECTLATER' . WMAC_HASH . '%%(.*?)%%INJECTLATER%%\*\/#is',
443
+ array( $this, 'injectMinifiedCallback' ),
444
+ $in
445
+ );
446
+ }
447
+
448
+ return $out;
449
+ }
450
+
451
+ /**
452
+ * Specialized method to create the INJECTLATER marker.
453
+ * These are somewhat "special", in the sense that they're additionally wrapped
454
+ * within an "exclamation mark style" comment, so that they're not stripped
455
+ * out by minifiers.
456
+ * They also currently contain the hash of the file's contents too (unlike other markers).
457
+ *
458
+ * @param string $filepath Filepath.
459
+ * @param string $hash Hash.
460
+ *
461
+ * @return string
462
+ */
463
+ public static function buildInjectlaterMarker( $filepath, $hash )
464
+ {
465
+ $contents = '/*!' . self::buildMarker( 'INJECTLATER', $filepath, $hash ) . '*/';
466
+
467
+ return $contents;
468
+ }
469
+
470
+ /**
471
+ * Creates and returns a `%%`-style named marker which holds
472
+ * the base64 encoded `$data`.
473
+ * If `$hash` is provided, it's appended to the base64 encoded string
474
+ * using `|` as the separator (in order to support building the
475
+ * somewhat special/different INJECTLATER marker).
476
+ *
477
+ * @param string $name Marker name.
478
+ * @param string $data Marker data which will be base64-encoded.
479
+ * @param string|null $hash Optional.
480
+ *
481
+ * @return string
482
+ */
483
+ public static function buildMarker( $name, $data, $hash = null )
484
+ {
485
+ // Start the marker, add the data.
486
+ $marker = '%%' . $name . WMAC_HASH . '%%' . base64_encode( $data );
487
+
488
+ // Add the hash if provided.
489
+ if ( null !== $hash ) {
490
+ $marker .= '|' . $hash;
491
+ }
492
+
493
+ // Close the marker.
494
+ $marker .= '%%' . $name . '%%';
495
+
496
+ return $marker;
497
+ }
498
+
499
+ /**
500
+ * Returns true if the string is a valid regex.
501
+ *
502
+ * @param string $string String, duh.
503
+ *
504
+ * @return bool
505
+ */
506
+ protected function strIsValidRegex( $string )
507
+ {
508
+ set_error_handler( function() {}, E_WARNING );
509
+ $is_regex = ( false !== preg_match( $string, '' ) );
510
+ restore_error_handler();
511
+
512
+ return $is_regex;
513
+ }
514
+
515
+ /**
516
+ * Searches for `$search` in `$content` (using either `preg_match()`
517
+ * or `strpos()`, depending on whether `$search` is a valid regex pattern or not).
518
+ * If something is found, it replaces `$content` using `$re_replace_pattern`,
519
+ * effectively creating our named markers (`%%{$marker}%%`.
520
+ * These are then at some point replaced back to their actual/original/modified
521
+ * contents using `WMAC_PluginBase::restoreMarkedContent()`.
522
+ *
523
+ * @param string $marker Marker name (without percent characters).
524
+ * @param string $search A string or full blown regex pattern to search for in $content. Uses `strpos()` or `preg_match()`.
525
+ * @param string $re_replace_pattern Regex pattern to use when replacing contents.
526
+ * @param string $content Content to work on.
527
+ *
528
+ * @return string
529
+ */
530
+ protected function replaceContentsWithMarkerIfExists( $marker, $search, $re_replace_pattern, $content )
531
+ {
532
+ $is_regex = $this->strIsValidRegex( $search );
533
+ if ( $is_regex ) {
534
+ $found = preg_match( $search, $content );
535
+ } else {
536
+ $found = ( false !== strpos( $content, $search ) );
537
+ }
538
+
539
+ if ( $found ) {
540
+ $content = preg_replace_callback(
541
+ $re_replace_pattern,
542
+ function( $matches ) use ( $marker ) {
543
+ return WMAC_PluginBase::buildMarker( $marker, $matches[0] );
544
+ },
545
+ $content
546
+ );
547
+ }
548
+
549
+ return $content;
550
+ }
551
+
552
+ /**
553
+ * Complements `WMAC_PluginBase::replaceContentsWithMarkerIfExists()`.
554
+ *
555
+ * @param string $marker Marker.
556
+ * @param string $content Markup.
557
+ *
558
+ * @return string
559
+ */
560
+ protected function restoreMarkedContent( $marker, $content )
561
+ {
562
+ if ( false !== strpos( $content, $marker ) ) {
563
+ $content = preg_replace_callback(
564
+ '#%%' . $marker . WMAC_HASH . '%%(.*?)%%' . $marker . '%%#is',
565
+ function ( $matches ) {
566
+ return base64_decode( $matches[1] );
567
+ },
568
+ $content
569
+ );
570
+ }
571
+
572
+ return $content;
573
+ }
574
+
575
+ /**
576
+ * Logs given `$data` for debugging purposes (when debug logging is on).
577
+ *
578
+ * @param mixed $data Data to log.
579
+ *
580
+ * @return void
581
+ */
582
+ protected function debugLog( $data )
583
+ {
584
+ if ( ! isset( $this->debug_log ) || ! $this->debug_log ) {
585
+ return;
586
+ }
587
+
588
+ if ( ! is_string( $data ) && ! is_resource( $data ) ) {
589
+ $data = var_export( $data, true );
590
+ }
591
+
592
+ error_log( $data );
593
+ }
594
+
595
+ /**
596
+ * Checks if a single local css/js file can be minified and returns source if so.
597
+ *
598
+ * @param string $filepath Filepath.
599
+ *
600
+ * @return bool|string to be minified code or false.
601
+ */
602
+ protected function prepareMinifySingle( $filepath )
603
+ {
604
+ // Decide what we're dealing with, return false if we don't know.
605
+ if ( $this->strEndsIn( $filepath, '.js' ) ) {
606
+ $type = 'js';
607
+ } elseif ( $this->strEndsIn( $filepath, '.css' ) ) {
608
+ $type = 'css';
609
+ } else {
610
+ return false;
611
+ }
612
+
613
+ // Bail if it looks like its already minifed (by having -min or .min
614
+ // in filename) or if it looks like WP jquery.js (which is minified).
615
+ $minified_variants = array(
616
+ '-min.' . $type,
617
+ '.min.' . $type,
618
+ 'js/jquery/jquery.js',
619
+ );
620
+ foreach ( $minified_variants as $ending ) {
621
+ if ( $this->strEndsIn( $filepath, $ending ) ) {
622
+ return false;
623
+ }
624
+ }
625
+
626
+ // Get file contents, bail if empty.
627
+ $contents = file_get_contents( $filepath );
628
+
629
+ return $contents;
630
+ }
631
+
632
+ /**
633
+ * Given an WMAC_PluginCache instance returns the url of
634
+ * the cached file.
635
+ *
636
+ * @param WMAC_PluginCache $cache WMAC_PluginCache instance.
637
+ *
638
+ * @return string
639
+ */
640
+ protected function buildMinifySingleUrl( WMAC_PluginCache $cache )
641
+ {
642
+ $url = WMAC_PluginCache::getCacheUrl() . $cache->getname();
643
+
644
+ return $url;
645
+ }
646
+
647
+ /**
648
+ * Returns true if given $str ends with given $test.
649
+ *
650
+ * @param string $str String to check.
651
+ * @param string $test Ending to match.
652
+ *
653
+ * @return bool
654
+ */
655
+ protected function strEndsIn( $str, $test )
656
+ {
657
+ // @codingStandardsIgnoreStart
658
+ // substr_compare() is bugged on 5.5.11: https://3v4l.org/qGYBH
659
+ // return ( 0 === substr_compare( $str, $test, -strlen( $test ) ) );
660
+ // @codingStandardsIgnoreEnd
661
+
662
+ $length = strlen( $test );
663
+
664
+ return ( substr( $str, -$length, $length ) === $test );
665
+ }
666
+ }
components/minify-and-combine/includes/classes/class.mac-cache-checker.php ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * CacheChecker - new in AO 2.0
4
+ *
5
+ * Daily cronned job (filter to change freq. + filter to disable).
6
+ * Checks if cachesize is > 0.5GB (size is filterable), if so, an option is set which controls showing an admin notice.
7
+ *
8
+ * @author Webcraftic <wordpress.webraftic@gmail.com>
9
+ * @copyright (c) 2018 Webraftic Ltd
10
+ * @version 1.0
11
+ */
12
+
13
+ if ( ! defined( 'ABSPATH' ) ) {
14
+ exit;
15
+ }
16
+
17
+ /**
18
+ * Class WMAC_PluginCacheChecker
19
+ */
20
+ class WMAC_PluginCacheChecker
21
+ {
22
+ const SCHEDULE_HOOK = 'wmac_cachechecker';
23
+
24
+ /**
25
+ * WMAC_PluginCacheChecker constructor.
26
+ */
27
+ public function __construct()
28
+ {
29
+ }
30
+
31
+ /**
32
+ * Run
33
+ */
34
+ public function run()
35
+ {
36
+ if ( is_admin() ) {
37
+ $this->setup();
38
+ }
39
+ $this->addHooks();
40
+ }
41
+
42
+ /**
43
+ * Add hooks
44
+ */
45
+ public function addHooks()
46
+ {
47
+ add_action( self::SCHEDULE_HOOK, array( $this, 'cronjob' ) );
48
+ add_action( 'admin_notices', array( $this, 'showAdminNotice' ) );
49
+ }
50
+
51
+ /**
52
+ * Setup
53
+ */
54
+ public function setup()
55
+ {
56
+ $do_cache_check = (bool) apply_filters( 'wmac_filter_cachecheck_do', true );
57
+ $schedule = wp_get_schedule( self::SCHEDULE_HOOK );
58
+ $frequency = apply_filters( 'wmac_filter_cachecheck_frequency', 'daily' );
59
+ if ( ! in_array( $frequency, array( 'hourly', 'daily', 'weekly', 'monthly' ) ) ) {
60
+ $frequency = 'daily';
61
+ }
62
+ if ( $do_cache_check && ( ! $schedule || $schedule !== $frequency ) ) {
63
+ wp_schedule_event( time(), $frequency, self::SCHEDULE_HOOK );
64
+ } elseif ( $schedule && ! $do_cache_check ) {
65
+ wp_clear_scheduled_hook( self::SCHEDULE_HOOK );
66
+ }
67
+ }
68
+
69
+ /**
70
+ * Cron job
71
+ */
72
+ public function cronjob()
73
+ {
74
+ $max_size = (int) apply_filters( 'wmac_filter_cachecheck_maxsize', 536870912 );
75
+ $do_cache_check = (bool) apply_filters( 'wmac_filter_cachecheck_do', true );
76
+ $stat_array = WMAC_PluginCache::stats();
77
+ $cache_size = round( $stat_array[1] );
78
+ if ( ( $cache_size > $max_size ) && ( $do_cache_check ) ) {
79
+ update_option( 'wmac_cachesize_notice', true );
80
+ if ( apply_filters( 'wmac_filter_cachecheck_sendmail', true ) ) {
81
+ $site_url = esc_url( site_url() );
82
+ $ao_mailto = apply_filters( 'wmac_filter_cachecheck_mailto', get_option( 'admin_email', '' ) );
83
+
84
+ $ao_mailsubject = __( 'Мinify And Combine cache size warning', 'minify-and-combine' ) . ' (' . $site_url . ')';
85
+ $ao_mailbody = __( 'Мinify And Combine\'s cache size is getting big, consider purging the cache. Have a look at https://wordpress.org/plugins/ to see how you can keep the cache size under control.', 'minify-and-combine' ) . ' (site: ' . $site_url . ')';
86
+
87
+ if ( ! empty( $ao_mailto ) ) {
88
+ $ao_mailresult = wp_mail( $ao_mailto, $ao_mailsubject, $ao_mailbody );
89
+ if ( ! $ao_mailresult ) {
90
+ error_log( 'Мinify And Combine could not send cache size warning mail.' );
91
+ }
92
+ }
93
+ }
94
+ }
95
+
96
+ // Nukes advanced cache clearing artifacts if they exists...
97
+ WMAC_PluginCache::deleteAdvancedCacheClearArtifacts();
98
+ }
99
+
100
+ /**
101
+ * Notice
102
+ */
103
+ public function showAdminNotice()
104
+ {
105
+ if ( (bool) get_option( 'wmac_cachesize_notice', false ) ) {
106
+ echo '<div class="notice notice-warning"><p>';
107
+ _e( '<strong>Мinify And Combine\'s cache size is getting big</strong>, consider purging the cache. Have a look at <a href="https://wordpress.org/plugins/" target="_blank" rel="noopener noreferrer">the Мinify And Combine FAQ</a> to see how you can keep the cache size under control.', 'minify-and-combine' );
108
+ echo '</p></div>';
109
+ update_option( 'wmac_cachesize_notice', false );
110
+ }
111
+ }
112
+ }
components/minify-and-combine/includes/classes/class.mac-cache.php ADDED
@@ -0,0 +1,769 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Operations with disc cache
4
+ * @author Webcraftic <wordpress.webraftic@gmail.com>
5
+ * @copyright (c) 2018 Webraftic Ltd
6
+ * @version 1.0
7
+ */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit;
11
+ }
12
+
13
+ /**
14
+ * Class WMAC_PluginCache
15
+ */
16
+ class WMAC_PluginCache
17
+ {
18
+ /**
19
+ * Cache filename.
20
+ *
21
+ * @var string
22
+ */
23
+ private $filename;
24
+
25
+ /**
26
+ * Whether gzipping is done by the web server or us.
27
+ * True => we don't gzip, the web server does it.
28
+ * False => we do it ourselves.
29
+ *
30
+ * @var bool
31
+ */
32
+ private $nogzip;
33
+
34
+ /**
35
+ * Ctor.
36
+ *
37
+ * @param string $md5 Hash.
38
+ * @param string $ext Extension.
39
+ */
40
+ public function __construct( $md5, $ext = 'php' )
41
+ {
42
+ $this->nogzip = WMAC_CACHE_NOGZIP;
43
+ if ( ! $this->nogzip ) {
44
+ $this->filename = WMAC_CACHEFILE_PREFIX . $md5 . '.php';
45
+ } else {
46
+ if ( in_array( $ext, array( 'js', 'css' ) ) ) {
47
+ $this->filename = $ext . '/' . WMAC_CACHEFILE_PREFIX . $md5 . '.' . $ext;
48
+ } else {
49
+ $this->filename = WMAC_CACHEFILE_PREFIX . $md5 . '.' . $ext;
50
+ }
51
+ }
52
+ }
53
+
54
+ /**
55
+ * Get cache dir
56
+ *
57
+ * @return string
58
+ */
59
+ public static function getCacheDir() {
60
+ return WMAC_PluginCache::getPathname();
61
+ }
62
+
63
+ /**
64
+ * Get cache url
65
+ *
66
+ * @return string
67
+ */
68
+ public static function getCacheUrl()
69
+ {
70
+ if ( is_multisite() && apply_filters( 'wmac_separate_blog_caches', true ) ) {
71
+ $blog_id = get_current_blog_id();
72
+ return WMAC_PluginMain::getContentUrl() . WMAC_CACHE_CHILD_DIR . $blog_id . '/';
73
+ } else {
74
+ return WMAC_PluginMain::getContentUrl() . WMAC_CACHE_CHILD_DIR;
75
+ }
76
+ }
77
+
78
+ /**
79
+ * Returns true if the cached file exists on disk.
80
+ *
81
+ * @return bool
82
+ */
83
+ public function check()
84
+ {
85
+ return file_exists( self::getCacheDir() . $this->filename );
86
+ }
87
+
88
+ /**
89
+ * Returns cache contents if they exist, false otherwise.
90
+ *
91
+ * @return string|false
92
+ */
93
+ public function retrieve()
94
+ {
95
+ if ( $this->check() ) {
96
+ if ( false == $this->nogzip ) {
97
+ return file_get_contents( self::getCacheDir() . $this->filename . '.none' );
98
+ } else {
99
+ return file_get_contents( self::getCacheDir() . $this->filename );
100
+ }
101
+ }
102
+ return false;
103
+ }
104
+
105
+ /**
106
+ * Stores given $data in cache.
107
+ *
108
+ * @param string $data Data to cache.
109
+ * @param string $mime Mimetype.
110
+ *
111
+ * @return void
112
+ */
113
+ public function cache( $data, $mime )
114
+ {
115
+ if ( false === $this->nogzip ) {
116
+ // We handle gzipping ourselves.
117
+ $file = 'default.php';
118
+ $phpcode = file_get_contents( WMAC_PLUGIN_DIR . '/config/' . $file );
119
+ $phpcode = str_replace( array( '%%CONTENT%%', 'exit;' ), array( $mime, '' ), $phpcode );
120
+
121
+ file_put_contents( self::getCacheDir() . $this->filename, $phpcode );
122
+ file_put_contents( self::getCacheDir() . $this->filename . '.none', $data );
123
+ } else {
124
+ // Write code to cache without doing anything else.
125
+ file_put_contents( self::getCacheDir() . $this->filename, $data );
126
+ if ( apply_filters( 'wmac_filter_cache_create_static_gzip', false ) ) {
127
+ // Create an additional cached gzip file.
128
+ file_put_contents( self::getCacheDir() . $this->filename . '.gz', gzencode( $data, 9, FORCE_GZIP ) );
129
+ }
130
+ }
131
+ }
132
+
133
+ /**
134
+ * Get cache filename.
135
+ *
136
+ * @return string
137
+ */
138
+ public function getname()
139
+ {
140
+ // NOTE: This could've maybe been a do_action() instead, however,
141
+ // that ship has sailed.
142
+ // The original idea here was to provide 3rd party code a hook so that
143
+ // it can "listen" to all the complete auto optimized-urls that the page
144
+ // will emit... Or something to that effect I think?
145
+ apply_filters( 'wmac_filter_cache_getname', WMAC_PluginCache::getCacheUrl() . $this->filename );
146
+
147
+ return $this->filename;
148
+ }
149
+
150
+ /**
151
+ * Returns true if given `$file` is considered a valid Мinify And Combine cache file,
152
+ * false otherwise.
153
+ *
154
+ * @param string $dir Directory name (with a trailing slash).
155
+ * @param string $file Filename.
156
+ *
157
+ * @return bool
158
+ */
159
+ protected static function isValidCacheFile( $dir, $file )
160
+ {
161
+ if ( '.' !== $file && '..' !== $file &&
162
+ false !== strpos( $file, WMAC_CACHEFILE_PREFIX ) &&
163
+ is_file( $dir . $file ) ) {
164
+
165
+ // It's a valid file!
166
+ return true;
167
+ }
168
+
169
+ // Everything else is considered invalid!
170
+ return false;
171
+ }
172
+
173
+ /**
174
+ * Clears contents of cache dir.
175
+ *
176
+ * @return void
177
+ */
178
+ protected static function clearCacheClassic()
179
+ {
180
+ $contents = self::getCacheContents();
181
+ foreach ( $contents as $name => $files ) {
182
+ $dir = rtrim( self::getCacheDir() . $name, '/' ) . '/';
183
+ foreach ( $files as $file ) {
184
+ if ( self::isValidCacheFile( $dir, $file ) ) {
185
+ @unlink( $dir . $file ); // @codingStandardsIgnoreLine
186
+ }
187
+ }
188
+ }
189
+
190
+ @unlink( self::getCacheDir() . '/.htaccess' ); // @codingStandardsIgnoreLine
191
+ }
192
+
193
+ /**
194
+ * Recursively deletes the specified pathname (file/directory) if possible.
195
+ * Returns true on success, false otherwise.
196
+ *
197
+ * @param string $pathname Pathname to remove.
198
+ *
199
+ * @return bool
200
+ */
201
+ protected static function rmdir( $pathname )
202
+ {
203
+ $files = self::getDirContents( $pathname );
204
+ foreach ( $files as $file ) {
205
+ $path = $pathname . '/' . $file;
206
+ if ( is_dir( $path ) ) {
207
+ self::rmdir( $path );
208
+ } else {
209
+ unlink( $path );
210
+ }
211
+ }
212
+
213
+ return rmdir( $pathname );
214
+ }
215
+
216
+ /**
217
+ * Clears contents of cache dir by renaming the current
218
+ * cache directory into a new one with a unique name and then
219
+ * re-creating the default (empty) cache directory.
220
+ *
221
+ * @return bool Returns true when everything is done successfully, false otherwise.
222
+ */
223
+ protected static function clearCacheViaRename()
224
+ {
225
+ $ok = false;
226
+ $dir = self::getPathnameBase();
227
+ $new_name = self::getUniqueName();
228
+
229
+ // Makes sure the new pathname is on the same level...
230
+ $new_pathname = dirname( $dir ) . '/' . $new_name;
231
+ $renamed = @rename( $dir, $new_pathname ); // @codingStandardsIgnoreLine
232
+
233
+ // When renamed, re-create the default cache directory back so it's
234
+ // available again...
235
+ if ( $renamed ) {
236
+ $ok = self::cacheAvail();
237
+ }
238
+
239
+ return $ok;
240
+ }
241
+
242
+ /**
243
+ * Returns true when advanced cache clearing is enabled.
244
+ *
245
+ * @return bool
246
+ */
247
+ public static function advancedCacheClearEnabled()
248
+ {
249
+ return apply_filters( 'wmac_filter_cache_clear_advanced', false );
250
+ }
251
+
252
+ /**
253
+ * Returns a (hopefully) unique new cache folder name for renaming purposes.
254
+ *
255
+ * @return string
256
+ */
257
+ protected static function getUniqueName()
258
+ {
259
+ $prefix = self::getAdvancedCacheClearPrefix();
260
+ $new_name = uniqid( $prefix, true );
261
+
262
+ return $new_name;
263
+ }
264
+
265
+ /**
266
+ * Get cache prefix name used in advanced cache clearing mode.
267
+ *
268
+ * @return string
269
+ */
270
+ protected static function getAdvancedCacheClearPrefix()
271
+ {
272
+ $pathname = self::getPathnameBase();
273
+ $basename = basename( $pathname );
274
+ $prefix = $basename . '-';
275
+
276
+ return $prefix;
277
+ }
278
+
279
+ /**
280
+ * Returns an array of file and directory names found within
281
+ * the given $pathname without '.' and '..' elements.
282
+ *
283
+ * @param string $pathname Pathname.
284
+ *
285
+ * @return array
286
+ */
287
+ protected static function getDirContents( $pathname )
288
+ {
289
+ return array_slice( scandir( $pathname ), 2 );
290
+ }
291
+
292
+ /**
293
+ * Wipes directories which were created as part of the fast cache clearing
294
+ * routine (which renames the current cache directory into a new one with
295
+ * a custom-prefixed unique name).
296
+ *
297
+ * @return bool
298
+ */
299
+ public static function deleteAdvancedCacheClearArtifacts()
300
+ {
301
+ $dir = self::getPathnameBase();
302
+ $prefix = self::getAdvancedCacheClearPrefix();
303
+ $parent = dirname( $dir );
304
+ $ok = false;
305
+
306
+ // Returns the list of files without '.' and '..' elements.
307
+ $files = self::getDirContents( $parent );
308
+ foreach ( $files as $file ) {
309
+ $path = $parent . '/' . $file;
310
+ $prefixed = ( false !== strpos( $path, $prefix ) );
311
+ // Removing only our own (prefixed) directories...
312
+ if ( is_dir( $path ) && $prefixed ) {
313
+ $ok = self::rmdir( $path );
314
+ }
315
+ }
316
+
317
+ return $ok;
318
+ }
319
+
320
+ /**
321
+ * Returns the cache directory pathname used.
322
+ * Done as a function so we canSlightly different
323
+ * if multisite is used and `wmac_separate_blog_caches` filter
324
+ * is used.
325
+ *
326
+ * @return string
327
+ */
328
+ public static function getPathname()
329
+ {
330
+ $pathname = self::getPathnameBase();
331
+
332
+ if ( is_multisite() && apply_filters( 'wmac_separate_blog_caches', true ) ) {
333
+ $blog_id = get_current_blog_id();
334
+ $pathname .= $blog_id . '/';
335
+ }
336
+
337
+ return $pathname;
338
+ }
339
+
340
+ /**
341
+ * Returns the base path of our cache directory.
342
+ *
343
+ * @return string
344
+ */
345
+ protected static function getPathnameBase()
346
+ {
347
+ $pathname = WP_CONTENT_DIR . WMAC_CACHE_CHILD_DIR;
348
+
349
+ return $pathname;
350
+ }
351
+
352
+ /**
353
+ * Deletes everything from the cache directories for all sites.
354
+ *
355
+ * @param bool $propagate Whether to trigger additional actions when cache is purged.
356
+ */
357
+ public static function clearAllMultisite( $propagate = true ) {
358
+ $sites = get_sites( array(
359
+ 'archived' => 0,
360
+ 'mature' => 0,
361
+ 'spam' => 0,
362
+ 'deleted' => 0,
363
+ ) );
364
+
365
+ foreach ( $sites as $site ) {
366
+ switch_to_blog( $site->blog_id );
367
+
368
+ self::clearAll( $propagate );
369
+
370
+ restore_current_blog();
371
+ }
372
+ }
373
+
374
+ /**
375
+ * Deletes everything from the cache directories.
376
+ *
377
+ * @param bool $propagate Whether to trigger additional actions when cache is purged.
378
+ *
379
+ * @return bool
380
+ */
381
+ public static function clearAll( $propagate = true )
382
+ {
383
+ if ( ! self::cacheAvail() ) {
384
+ return false;
385
+ }
386
+
387
+ // TODO/FIXME: If cache is big, switch to advanced/new cache clearing automatically?
388
+ if ( self::advancedCacheClearEnabled() ) {
389
+ self::clearCacheViaRename();
390
+ } else {
391
+ self::clearCacheClassic();
392
+ }
393
+
394
+ // Remove the transient so it gets regenerated...
395
+ delete_transient( 'wmac_stats' );
396
+
397
+ // Cache was just purged, clear page cache and allow others to hook into our purging...
398
+ if ( true === $propagate ) {
399
+ if ( ! function_exists( 'wmac_do_cachepurged_action' ) ) {
400
+ function wmac_do_cachepurged_action() {
401
+ do_action( 'wmac_action_cachepurged' );
402
+ }
403
+ }
404
+ add_action( 'shutdown', 'wmac_do_cachepurged_action', 11 );
405
+ add_action( 'wmac_action_cachepurged', array( 'WMAC_PluginCache', 'flushPageCache' ), 10, 0 );
406
+ }
407
+
408
+ // Warm cache (part of speedupper)!
409
+ if ( apply_filters( 'wmac_filter_speedupper', true ) ) {
410
+ $url = site_url() . '/?ao_speedup_cachebuster=' . rand( 1, 100000 );
411
+ $cache = @wp_remote_get( $url ); // @codingStandardsIgnoreLine
412
+ unset( $cache );
413
+ }
414
+
415
+ return true;
416
+ }
417
+
418
+ /**
419
+ * Wrapper for clearAll but with false param
420
+ * to ensure the event is not propagated to others
421
+ * through our own hooks (to avoid infinite loops).
422
+ *
423
+ * @return bool
424
+ */
425
+ public static function clearAllActionless()
426
+ {
427
+ return self::clearAll( false );
428
+ }
429
+
430
+ /**
431
+ * Returns the contents of our cache dirs.
432
+ *
433
+ * @return array
434
+ */
435
+ protected static function getCacheContents()
436
+ {
437
+ $contents = array();
438
+
439
+ foreach ( array( '', 'js', 'css' ) as $dir ) {
440
+ $contents[ $dir ] = scandir( self::getCacheDir() . $dir );
441
+ }
442
+
443
+ return $contents;
444
+ }
445
+
446
+ /**
447
+ * Returns stats about cached contents.
448
+ *
449
+ * @return array|int|mixed
450
+ */
451
+ public static function stats()
452
+ {
453
+ $stats = get_transient( 'wmac_stats' );
454
+
455
+ // If no transient, do the actual scan!
456
+ if ( ! is_array( $stats ) ) {
457
+ if ( ! self::cacheAvail() ) {
458
+ return 0;
459
+ }
460
+ $stats = self::statsScan();
461
+ $count = $stats[0];
462
+ if ( $count > 100 ) {
463
+ // Store results in transient.
464
+ set_transient(
465
+ 'wmac_stats',
466
+ $stats,
467
+ apply_filters( 'wmac_filter_cache_statsexpiry', HOUR_IN_SECONDS )
468
+ );
469
+ }
470
+ }
471
+
472
+ return $stats;
473
+ }
474
+
475
+ /**
476
+ * Return cache used data
477
+ *
478
+ * @return array
479
+ */
480
+ public static function getUsedCache( ) {
481
+ // Retrieve the Autoptimize Cache Stats information.
482
+ $stats = WMAC_PluginCache::stats();
483
+
484
+ // Set the Max Size recommended for cache files.
485
+ $max_size = apply_filters( 'wmac_filter_cachecheck_maxsize', 512 * 1024 * 1024 );
486
+
487
+ // Retrieve the current Total Files in cache.
488
+ $files = $stats[0];
489
+ // Retrieve the current Total Size of the cache.
490
+ $bytes = $stats[1];
491
+ $size = WMAC_PluginHelper::format_filesize( $bytes );
492
+
493
+ // Calculate the percentage of cache used.
494
+ $percent = ceil( $bytes / $max_size * 100 );
495
+ if ( $percent > 100 ) {
496
+ $percent = 100;
497
+ }
498
+
499
+ return array(
500
+ 'files' => $files,
501
+ 'size' => $size,
502
+ 'percent' => $percent,
503
+ );
504
+ }
505
+
506
+ /**
507
+ * Return cache used data
508
+ *
509
+ * @return array
510
+ */
511
+ public static function getUsedCacheMultisite() {
512
+ $files = $bytes = 0;
513
+
514
+ $sites = get_sites( array(
515
+ 'archived' => 0,
516
+ 'mature' => 0,
517
+ 'spam' => 0,
518
+ 'deleted' => 0,
519
+ ) );
520
+
521
+ foreach ( $sites as $site ) {
522
+ switch_to_blog( $site->blog_id );
523
+
524
+ // Retrieve the Autoptimize Cache Stats information.
525
+ $stats = WMAC_PluginCache::stats();
526
+
527
+ // Retrieve the current Total Files in cache.
528
+ $files += $stats[0];
529
+ // Retrieve the current Total Size of the cache.
530
+ $bytes += $stats[1];
531
+
532
+ restore_current_blog();
533
+ }
534
+
535
+ $size = WMAC_PluginHelper::format_filesize( $bytes );
536
+
537
+ return array(
538
+ 'files' => $files,
539
+ 'size' => $size,
540
+ );
541
+ }
542
+
543
+ /**
544
+ * Performs a scan of cache directory contents and returns an array
545
+ * with 3 values: count, size, timestamp.
546
+ * count = total number of found files
547
+ * size = total filesize (in bytes) of found files
548
+ * timestamp = unix timestamp when the scan was last performed/finished.
549
+ *
550
+ * @return array
551
+ */
552
+ protected static function statsScan()
553
+ {
554
+ $count = 0;
555
+ $size = 0;
556
+
557
+ // Scan everything in our cache directories.
558
+ foreach ( self::getCacheContents() as $name => $files ) {
559
+ $dir = rtrim( self::getCacheDir() . $name, '/' ) . '/';
560
+ foreach ( $files as $file ) {
561
+ if ( self::isValidCacheFile( $dir, $file ) ) {
562
+ if ( WMAC_CACHE_NOGZIP &&
563
+ (
564
+ false !== strpos( $file, '.js' ) ||
565
+ false !== strpos( $file, '.css' ) ||
566
+ false !== strpos( $file, '.img' ) ||
567
+ false !== strpos( $file, '.txt' )
568
+ )
569
+ ) {
570
+ // Web server is gzipping, we count .js|.css|.img|.txt files.
571
+ $count++;
572
+ } elseif ( ! WMAC_CACHE_NOGZIP && false !== strpos( $file, '.none' ) ) {
573
+ // We are gzipping ourselves via php, counting only .none files.
574
+ $count++;
575
+ }
576
+ $size += filesize( $dir . $file );
577
+ }
578
+ }
579
+ }
580
+
581
+ $stats = array( $count, $size, time() );
582
+
583
+ return $stats;
584
+ }
585
+
586
+ /**
587
+ * Ensures the cache directory exists, is writeable and contains the
588
+ * required .htaccess files.
589
+ * Returns false in case it fails to ensure any of those things.
590
+ *
591
+ * @return bool
592
+ */
593
+ public static function cacheAvail()
594
+ {
595
+ foreach ( array( '', 'js', 'css' ) as $dir ) {
596
+ if ( ! self::checkCacheDir( self::getCacheDir() . $dir ) ) {
597
+ return false;
598
+ }
599
+ }
600
+
601
+ // Using .htaccess inside our cache folder to overrule wp-super-cache.
602
+ $htaccess = self::getCacheDir() . '/.htaccess';
603
+ if ( ! is_file( $htaccess ) ) {
604
+ /**
605
+ * Create `wp-content/AO_htaccess_tmpl` file with
606
+ * whatever htaccess rules you might need
607
+ * if you want to override default AO htaccess
608
+ */
609
+ $htaccess_tmpl = WP_CONTENT_DIR . '/AO_htaccess_tmpl';
610
+ if ( is_file( $htaccess_tmpl ) ) {
611
+ $content = file_get_contents( $htaccess_tmpl );
612
+ } elseif ( is_multisite() || ! WMAC_CACHE_NOGZIP ) {
613
+ $content = '<IfModule mod_expires.c>
614
+ ExpiresActive On
615
+ ExpiresByType text/css A30672000
616
+ ExpiresByType text/javascript A30672000
617
+ ExpiresByType application/javascript A30672000
618
+ </IfModule>
619
+ <IfModule mod_headers.c>
620
+ Header append Cache-Control "public, immutable"
621
+ </IfModule>
622
+ <IfModule mod_deflate.c>
623
+ <FilesMatch "\.(js|css)$">
624
+ SetOutputFilter DEFLATE
625
+ </FilesMatch>
626
+ </IfModule>
627
+ <IfModule mod_authz_core.c>
628
+ <Files *.php>
629
+ Require all granted
630
+ </Files>
631
+ </IfModule>
632
+ <IfModule !mod_authz_core.c>
633
+ <Files *.php>
634
+ Order allow,deny
635
+ Allow from all
636
+ </Files>
637
+ </IfModule>';
638
+ } else {
639
+ $content = '<IfModule mod_expires.c>
640
+ ExpiresActive On
641
+ ExpiresByType text/css A30672000
642
+ ExpiresByType text/javascript A30672000
643
+ ExpiresByType application/javascript A30672000
644
+ </IfModule>
645
+ <IfModule mod_headers.c>
646
+ Header append Cache-Control "public, immutable"
647
+ </IfModule>
648
+ <IfModule mod_deflate.c>
649
+ <FilesMatch "\.(js|css)$">
650
+ SetOutputFilter DEFLATE
651
+ </FilesMatch>
652
+ </IfModule>
653
+ <IfModule mod_authz_core.c>
654
+ <Files *.php>
655
+ Require all denied
656
+ </Files>
657
+ </IfModule>
658
+ <IfModule !mod_authz_core.c>
659
+ <Files *.php>
660
+ Order deny,allow
661
+ Deny from all
662
+ </Files>
663
+ </IfModule>';
664
+ }
665
+ @file_put_contents( $htaccess, $content ); // @codingStandardsIgnoreLine
666
+ }
667
+
668
+ // All OK!
669
+ return true;
670
+ }
671
+
672
+ /**
673
+ * Ensures the specified `$dir` exists and is writeable.
674
+ * Returns false if that's not the case.
675
+ *
676
+ * @param string $dir Directory to check/create.
677
+ *
678
+ * @return bool
679
+ */
680
+ protected static function checkCacheDir( $dir )
681
+ {
682
+ // Try creating the dir if it doesn't exist.
683
+ if ( ! file_exists( $dir ) ) {
684
+ @mkdir( $dir, 0775, true ); // @codingStandardsIgnoreLine
685
+ if ( ! file_exists( $dir ) ) {
686
+ return false;
687
+ }
688
+ }
689
+
690
+ // If we still cannot write, bail.
691
+ if ( ! is_writable( $dir ) ) {
692
+ return false;
693
+ }
694
+
695
+ // Create an index.html in there to avoid prying eyes!
696
+ $idx_file = rtrim( $dir, '/\\' ) . '/index.html';
697
+ if ( ! is_file( $idx_file ) ) {
698
+ @file_put_contents( $idx_file, '<html><head><meta name="robots" content="noindex, nofollow"></head><body>Generated by <a href="http://wordpress.org/extend/plugins/" rel="nofollow">Мinify And Combine</a></body></html>' ); // @codingStandardsIgnoreLine
699
+ }
700
+
701
+ return true;
702
+ }
703
+
704
+ /**
705
+ * Flushes as many page cache plugin's caches as possible.
706
+ *
707
+ * @return void
708
+ */
709
+ // @codingStandardsIgnoreStart
710
+ public static function flushPageCache()
711
+ {
712
+ if ( function_exists( 'wp_cache_clear_cache' ) ) {
713
+ if ( is_multisite() ) {
714
+ $blog_id = get_current_blog_id();
715
+ wp_cache_clear_cache( $blog_id );
716
+ } else {
717
+ wp_cache_clear_cache();
718
+ }
719
+ } elseif ( has_action( 'cachify_flush_cache' ) ) {
720
+ do_action( 'cachify_flush_cache' );
721
+ } elseif ( function_exists( 'w3tc_pgcache_flush' ) ) {
722
+ w3tc_pgcache_flush();
723
+ } elseif ( function_exists( 'wp_fast_cache_bulk_delete_all' ) ) {
724
+ wp_fast_cache_bulk_delete_all();
725
+ } elseif ( class_exists( 'WpFastestCache' ) ) {
726
+ $wpfc = new WpFastestCache();
727
+ $wpfc->deleteCache();
728
+ } elseif ( class_exists( 'c_ws_plugin__qcache_purging_routines' ) ) {
729
+ c_ws_plugin__qcache_purging_routines::purge_cache_dir(); // quick cache
730
+ } elseif ( class_exists( 'zencache' ) ) {
731
+ zencache::clear();
732
+ } elseif ( class_exists( 'comet_cache' ) ) {
733
+ comet_cache::clear();
734
+ } elseif ( class_exists( 'WpeCommon' ) ) {
735
+ // WPEngine cache purge/flush methods to call by default
736
+ $wpe_methods = array(
737
+ 'purge_varnish_cache',
738
+ );
739
+
740
+ // More agressive clear/flush/purge behind a filter
741
+ if ( apply_filters( 'wmac_flush_wpengine_aggressive', false ) ) {
742
+ $wpe_methods = array_merge( $wpe_methods, array( 'purge_memcached', 'clear_maxcdn_cache' ) );
743
+ }
744
+
745
+ // Filtering the entire list of WpeCommon methods to be called (for advanced usage + easier testing)
746
+ $wpe_methods = apply_filters( 'wmac_flush_wpengine_methods', $wpe_methods );
747
+
748
+ foreach ( $wpe_methods as $wpe_method ) {
749
+ if ( method_exists( 'WpeCommon', $wpe_method ) ) {
750
+ WpeCommon::$wpe_method();
751
+ }
752
+ }
753
+ } elseif ( function_exists( 'sg_cachepress_purge_cache' ) ) {
754
+ sg_cachepress_purge_cache();
755
+ } elseif ( file_exists( WP_CONTENT_DIR . '/wp-cache-config.php' ) && function_exists( 'prune_super_cache' ) ) {
756
+ // fallback for WP-Super-Cache
757
+ global $cache_path;
758
+ if ( is_multisite() ) {
759
+ $blog_id = get_current_blog_id();
760
+ prune_super_cache( get_supercache_dir( $blog_id ), true );
761
+ prune_super_cache( $cache_path . 'blogs/', true );
762
+ } else {
763
+ prune_super_cache( $cache_path . 'supercache/', true );
764
+ prune_super_cache( $cache_path, true );
765
+ }
766
+ }
767
+ }
768
+ // @codingStandardsIgnoreEnd
769
+ }
components/minify-and-combine/includes/classes/class.mac-css-min.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Thin wrapper around css minifiers to avoid rewriting a bunch of existing code.
4
+ * @author Webcraftic <wordpress.webraftic@gmail.com>
5
+ * @copyright (c) 2018 Webraftic Ltd
6
+ * @version 1.0
7
+ */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit;
11
+ }
12
+
13
+ /**
14
+ * Class WMAC_PluginCSSmin
15
+ */
16
+ class WMAC_PluginCSSmin
17
+ {
18
+ /**
19
+ * Minifier instance.
20
+ *
21
+ * @var WMAC\tubalmartin\CssMin\Minifier|null
22
+ */
23
+ protected $minifier = null;
24
+
25
+ /**
26
+ * Construtor.
27
+ *
28
+ * @param bool $raise_limits Whether to raise memory limits or not. Default true.
29
+ */
30
+ public function __construct( $raise_limits = true )
31
+ {
32
+ $this->minifier = new WMAC\tubalmartin\CssMin\Minifier( $raise_limits );
33
+ }
34
+
35
+ /**
36
+ * Runs the minifier on given string of $css.
37
+ * Returns the minified css.
38
+ *
39
+ * @param string $css CSS to minify.
40
+ *
41
+ * @return string
42
+ */
43
+ public function run( $css )
44
+ {
45
+ $result = $this->minifier->run( $css );
46
+
47
+ return $result;
48
+ }
49
+
50
+ /**
51
+ * Static helper.
52
+ *
53
+ * @param string $css CSS to minify.
54
+ *
55
+ * @return string
56
+ */
57
+ public static function minify( $css )
58
+ {
59
+ $minifier = new self();
60
+
61
+ return $minifier->run( $css );
62
+ }
63
+ }
components/minify-and-combine/includes/classes/class.mac-helper.php ADDED
@@ -0,0 +1,340 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Helper
4
+ *
5
+ * @author Webcraftic <wordpress.webraftic@gmail.com>
6
+ * @copyright (c) 2018 Webraftic Ltd
7
+ * @version 1.0
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) {
11
+ exit;
12
+ }
13
+
14
+ /**
15
+ * Class WMAC_PluginHelper
16
+ */
17
+ class WMAC_PluginHelper
18
+ {
19
+ /**
20
+ * Returns true when mbstring is available.
21
+ *
22
+ * @param bool|null $override Allows overriding the decision.
23
+ *
24
+ * @return bool
25
+ */
26
+ public static function mbstringAvailable( $override = null )
27
+ {
28
+ static $available = null;
29
+
30
+ if ( null === $available ) {
31
+ $available = \extension_loaded( 'mbstring' );
32
+ }
33
+
34
+ if ( null !== $override ) {
35
+ $available = $override;
36
+ }
37
+
38
+ return $available;
39
+ }
40
+
41
+ /**
42
+ * Returns true when iconv is available.
43
+ *
44
+ * @param bool|null $override Allows overriding the decision.
45
+ *
46
+ * @return bool
47
+ */
48
+ public static function iconvAvailable( $override = null )
49
+ {
50
+ static $available = null;
51
+
52
+ if ( null === $available ) {
53
+ $available = \extension_loaded( 'iconv' );
54
+ }
55
+
56
+ if ( null !== $override ) {
57
+ $available = $override;
58
+ }
59
+
60
+ return $available;
61
+ }
62
+
63
+ /**
64
+ * Multibyte-capable strpos() if support is available on the server.
65
+ * If not, it falls back to using \strpos().
66
+ *
67
+ * @param string $haystack Haystack.
68
+ * @param string $needle Needle.
69
+ * @param int $offset Offset.
70
+ * @param string|null $encoding Encoding. Default null.
71
+ *
72
+ * @return int|false
73
+ */
74
+ public static function strpos( $haystack, $needle, $offset = 0, $encoding = null )
75
+ {
76
+ if ( self::mbstringAvailable() ) {
77
+ return ( null === $encoding ) ? \mb_strpos( $haystack, $needle, $offset ) : \mb_strlen( $haystack, $needle, $offset, $encoding );
78
+ } elseif ( self::iconvAvailable() ) {
79
+ return ( null === $encoding ) ? \iconv_strpos( $haystack, $needle, $offset ) : \iconv_strpos( $haystack, $needle, $offset, $encoding );
80
+ } else {
81
+ return \strpos( $haystack, $needle, $offset );
82
+ }
83
+ }
84
+
85
+ /**
86
+ * Attempts to return the number of characters in the given $string if
87
+ * mbstring or iconv is available. Returns the number of bytes
88
+ * (instead of characters) as fallback.
89
+ *
90
+ * @param string $string String.
91
+ * @param string|null $encoding Encoding.
92
+ *
93
+ * @return int Number of charcters or bytes in given $string
94
+ * (characters if/when supported, bytes otherwise).
95
+ */
96
+ public static function strlen( $string, $encoding = null )
97
+ {
98
+ if ( self::mbstringAvailable() ) {
99
+ return ( null === $encoding ) ? \mb_strlen( $string ) : \mb_strlen( $string, $encoding );
100
+ } elseif ( self::iconvAvailable() ) {
101
+ return ( null === $encoding ) ? @iconv_strlen( $string ) : @iconv_strlen( $string, $encoding );
102
+ } else {
103
+ return \strlen( $string );
104
+ }
105
+ }
106
+
107
+ /**
108
+ * Our wrapper around implementations of \substr_replace()
109
+ * that attempts to not break things horribly if at all possible.
110
+ * Uses mbstring and/or iconv if available, before falling back to regular
111
+ * substr_replace() (which works just fine in the majority of cases).
112
+ *
113
+ * @param string $string String.
114
+ * @param string $replacement Replacement.
115
+ * @param int $start Start offset.
116
+ * @param int|null $length Length.
117
+ * @param string|null $encoding Encoding.
118
+ *
119
+ * @return string
120
+ */
121
+ public static function substrReplace( $string, $replacement, $start, $length = null, $encoding = null )
122
+ {
123
+ if ( self::mbstringAvailable() ) {
124
+ $strlen = self::strlen( $string, $encoding );
125
+
126
+ if ( $start < 0 ) {
127
+ if ( -$start < $strlen ) {
128
+ $start = $strlen + $start;
129
+ } else {
130
+ $start = 0;
131
+ }
132
+ } elseif ( $start > $strlen ) {
133
+ $start = $strlen;
134
+ }
135
+
136
+ if ( null === $length || '' === $length ) {
137
+ $start2 = $strlen;
138
+ } elseif ( $length < 0 ) {
139
+ $start2 = $strlen + $length;
140
+ if ( $start2 < $start ) {
141
+ $start2 = $start;
142
+ }
143
+ } else {
144
+ $start2 = $start + $length;
145
+ }
146
+
147
+ if ( null === $encoding ) {
148
+ $leader = $start ? \mb_substr( $string, 0, $start ) : '';
149
+ $trailer = ( $start2 < $strlen ) ? \mb_substr( $string, $start2, null ) : '';
150
+ } else {
151
+ $leader = $start ? \mb_substr( $string, 0, $start, $encoding ) : '';
152
+ $trailer = ( $start2 < $strlen ) ? \mb_substr( $string, $start2, null, $encoding ) : '';
153
+ }
154
+
155
+ return "{$leader}{$replacement}{$trailer}";
156
+ } elseif ( self::iconvAvailable() ) {
157
+ $strlen = self::strlen( $string, $encoding );
158
+
159
+ if ( $start < 0 ) {
160
+ $start = \max( 0, $strlen + $start );
161
+ $start = $strlen + $start;
162
+ if ( $start < 0 ) {
163
+ $start = 0;
164
+ }
165
+ } elseif ( $start > $strlen ) {
166
+ $start = $strlen;
167
+ }
168
+
169
+ if ( $length < 0 ) {
170
+ $length = \max( 0, $strlen - $start + $length );
171
+ } elseif ( null === $length || ( $length > $strlen ) ) {
172
+ $length = $strlen;
173
+ }
174
+
175
+ if ( ( $start + $length ) > $strlen ) {
176
+ $length = $strlen - $start;
177
+ }
178
+
179
+ if ( null === $encoding ) {
180
+ return self::iconvSubstr( $string, 0, $start ) . $replacement . self::iconvSubstr( $string, $start + $length, $strlen - $start - $length );
181
+ }
182
+
183
+ return self::iconvSubstr( $string, 0, $start, $encoding ) . $replacement . self::iconvSubstr( $string, $start + $length, $strlen - $start - $length, $encoding );
184
+ }
185
+
186
+ return ( null === $length ) ? \substr_replace( $string, $replacement, $start ) : \substr_replace( $string, $replacement, $start, $length );
187
+ }
188
+
189
+ /**
190
+ * Wrapper around iconv_substr().
191
+ *
192
+ * @param string $s String.
193
+ * @param int $start Start offset.
194
+ * @param int|null $length Length.
195
+ * @param string|null $encoding Encoding.
196
+ *
197
+ * @return string
198
+ */
199
+ protected static function iconvSubstr( $s, $start, $length = null, $encoding = null )
200
+ {
201
+ if ( $start < 0 ) {
202
+ $start = self::strlen( $s, $encoding ) + $start;
203
+ if ( $start < 0 ) {
204
+ $start = 0;
205
+ }
206
+ }
207
+
208
+ if ( null === $length ) {
209
+ $length = 2147483647;
210
+ } elseif ( $length < 0 ) {
211
+ $length = self::strlen( $s, $encoding ) + ( $length - $start );
212
+ if ( $length < 0 ) {
213
+ return '';
214
+ }
215
+ }
216
+
217
+ return (string) ( null === $encoding ) ? \iconv_substr( $s, $start, $length ) : \iconv_substr( $s, $start, $length, $encoding );
218
+ }
219
+
220
+ /**
221
+ * Decides whether this is a "subdirectory site" or not.
222
+ *
223
+ * @param bool $override Allows overriding the decision when needed.
224
+ *
225
+ * @return bool
226
+ */
227
+ public static function siteurlNotRoot( $override = null )
228
+ {
229
+ static $subdir = null;
230
+
231
+ if ( null === $subdir ) {
232
+ $parts = self::getMacWpSiteUrlParts();
233
+ $subdir = ( isset( $parts['path'] ) && ( '/' !== $parts['path'] ) );
234
+ }
235
+
236
+ if ( null !== $override ) {
237
+ $subdir = $override;
238
+ }
239
+
240
+ return $subdir;
241
+ }
242
+
243
+ /**
244
+ * Parse site URL into components using \parse_url(), but do
245
+ * so only once per request/lifecycle.
246
+ *
247
+ * @return array
248
+ */
249
+ public static function getMacWpSiteUrlParts()
250
+ {
251
+ static $parts = array();
252
+
253
+ if ( empty( $parts ) ) {
254
+ $parts = \parse_url( WMAC_PluginMain::getSiteUrl() );
255
+ }
256
+
257
+ return $parts;
258
+ }
259
+
260
+ /**
261
+ * Given an array or components returned from \parse_url(), assembles back
262
+ * the complete URL.
263
+ * If optional
264
+ *
265
+ * @param array $parsed_url URL components array.
266
+ * @param bool $schemeless Whether the assembled URL should be
267
+ * protocol-relative (schemeless) or not.
268
+ *
269
+ * @return string
270
+ */
271
+ public static function assembleParsedUrl( array $parsed_url, $schemeless = false )
272
+ {
273
+ $scheme = isset( $parsed_url['scheme'] ) ? $parsed_url['scheme'] . '://' : '';
274
+ if ( $schemeless ) {
275
+ $scheme = '//';
276
+ }
277
+ $host = isset( $parsed_url['host'] ) ? $parsed_url['host'] : '';
278
+ $port = isset( $parsed_url['port'] ) ? ':' . $parsed_url['port'] : '';
279
+ $user = isset( $parsed_url['user'] ) ? $parsed_url['user'] : '';
280
+ $pass = isset( $parsed_url['pass'] ) ? ':' . $parsed_url['pass'] : '';
281
+ $pass = ( $user || $pass ) ? "$pass@" : '';
282
+ $path = isset( $parsed_url['path'] ) ? $parsed_url['path'] : '';
283
+ $query = isset( $parsed_url['query'] ) ? '?' . $parsed_url['query'] : '';
284
+ $fragment = isset( $parsed_url['fragment'] ) ? '#' . $parsed_url['fragment'] : '';
285
+
286
+ return "$scheme$user$pass$host$port$path$query$fragment";
287
+ }
288
+
289
+ /**
290
+ * Returns true if given $url is protocol-relative.
291
+ *
292
+ * @param string $url URL to check.
293
+ *
294
+ * @return bool
295
+ */
296
+ public static function isProtocolRelative( $url )
297
+ {
298
+ return ( '/' === $url{1} ); // second char is `/`.
299
+ }
300
+
301
+ /**
302
+ * Canonicalizes the given path regardless of it existing or not.
303
+ *
304
+ * @param string $path Path to normalize.
305
+ *
306
+ * @return string
307
+ */
308
+ public static function pathCanonicalize( $path )
309
+ {
310
+ $patterns = array(
311
+ '~/{2,}~',
312
+ '~/(\./)+~',
313
+ '~([^/\.]+/(?R)*\.{2,}/)~',
314
+ '~\.\./~',
315
+ );
316
+ $replacements = array(
317
+ '/',
318
+ '/',
319
+ '',
320
+ '',
321
+ );
322
+
323
+ return preg_replace( $patterns, $replacements, $path );
324
+ }
325
+
326
+ /**
327
+ * @param $bytes
328
+ * @param int $decimals
329
+ *
330
+ * @return string
331
+ */
332
+ public static function format_filesize( $bytes, $decimals = 2 )
333
+ {
334
+ $units = array( 'B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB' );
335
+
336
+ for ( $i = 0; ( $bytes / 1024) > 0.9; $i++, $bytes /= 1024 ) {} // @codingStandardsIgnoreLine
337
+
338
+ return sprintf( "%1.{$decimals}f %s", round( $bytes, $decimals ), $units[ $i ] );
339
+ }
340
+ }
components/minify-and-combine/includes/classes/class.mac-main.php ADDED
@@ -0,0 +1,450 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Main class
4
+ * @author Webcraftic <wordpress.webraftic@gmail.com>
5
+ * @copyright (c) 2018 Webraftic Ltd
6
+ * @version 1.0
7
+ */
8
+
9
+ if( !defined('ABSPATH') ) {
10
+ exit;
11
+ }
12
+
13
+ /**
14
+ * Class WMAC_PluginMain
15
+ */
16
+ class WMAC_PluginMain {
17
+
18
+ const INIT_EARLIER_PRIORITY = -1;
19
+ const DEFAULT_HOOK_PRIORITY = 2;
20
+
21
+ /**
22
+ * Constructor.
23
+ */
24
+ public function __construct()
25
+ {
26
+ }
27
+
28
+ /**
29
+ * Start processing
30
+ */
31
+ public function start()
32
+ {
33
+ $this->setup();
34
+ $this->run();
35
+ $this->check();
36
+ $this->clear();
37
+ }
38
+
39
+ /**
40
+ * Runs cache size checker
41
+ */
42
+ public function check()
43
+ {
44
+ $checker = new WMAC_PluginCacheChecker();
45
+ $checker->run();
46
+ }
47
+
48
+ /**
49
+ * Setting the parameters
50
+ */
51
+ public function setup()
52
+ {
53
+ // Do we gzip in php when caching or is the webserver doing it?
54
+ if( !defined('WMAC_CACHE_NOGZIP') ) {
55
+ define('WMAC_CACHE_NOGZIP', true /*(bool) get_option( 'wmac_cache_nogzip' )*/);
56
+ }
57
+
58
+ // These can be overridden by specifying them in wp-config.php or such.
59
+ if( !defined('WMAC_WP_CONTENT_NAME') ) {
60
+ define('WMAC_WP_CONTENT_NAME', '/' . wp_basename(WP_CONTENT_DIR));
61
+ }
62
+
63
+ if( !defined('WMAC_CACHE_CHILD_DIR') ) {
64
+ define('WMAC_CACHE_CHILD_DIR', '/cache/wmac/');
65
+ }
66
+
67
+ if( !defined('WMAC_CACHEFILE_PREFIX') ) {
68
+ define('WMAC_CACHEFILE_PREFIX', 'wmac_');
69
+ }
70
+
71
+ if( !defined('WMAC_ROOT_DIR') ) {
72
+ define('WMAC_ROOT_DIR', substr(WP_CONTENT_DIR, 0, strlen(WP_CONTENT_DIR) - strlen(WMAC_WP_CONTENT_NAME)));
73
+ }
74
+
75
+ if( !defined('WMAC_WP_ROOT_URL') ) {
76
+ define('WMAC_WP_ROOT_URL', str_replace(WMAC_WP_CONTENT_NAME, '', self::getContentUrl()));
77
+ }
78
+
79
+ if( !defined('WMAC_HASH') ) {
80
+ define('WMAC_HASH', wp_hash(WMAC_PluginCache::getCacheUrl()));
81
+ }
82
+ }
83
+
84
+ /**
85
+ * Run
86
+ */
87
+ public function run()
88
+ {
89
+ if( WMAC_PluginCache::cacheAvail() ) {
90
+
91
+ if( WMAC_Plugin::app()->getOption('js_optimize') || WMAC_Plugin::app()->getOption('css_optimize')
92
+ ) {
93
+ // Hook into WordPress frontend.
94
+ if( defined('WMAC_INIT_EARLIER') ) {
95
+ add_action('init', array($this, 'startBuffering'), self::INIT_EARLIER_PRIORITY);
96
+ } else {
97
+ if( !defined('WMAC_HOOK_INTO') ) {
98
+ define('WMAC_HOOK_INTO', 'template_redirect');
99
+ }
100
+ add_action(constant('WMAC_HOOK_INTO'), array(
101
+ $this,
102
+ 'startBuffering'
103
+ ), self::DEFAULT_HOOK_PRIORITY);
104
+ }
105
+ }
106
+ } else {
107
+ add_action('admin_notices', 'WMAC_PluginMain::noticeCacheUnavailable');
108
+ }
109
+ }
110
+
111
+ /**
112
+ * Clear cache
113
+ */
114
+ public function clear()
115
+ {
116
+ // hook into a collection of page cache purge actions if filter allows.
117
+ if( apply_filters('wmac_filter_main_hookpagecachepurge', true) ) {
118
+ $page_cache_purge_actions = array(
119
+ 'after_rocket_clean_domain', // exists.
120
+ 'hyper_cache_purged', // Stefano confirmed this will be added.
121
+ 'w3tc_flush_posts', // exits.
122
+ 'w3tc_flush_all', // exists.
123
+ 'ce_action_cache_cleared', // Sven confirmed this will be added.
124
+ 'comet_cache_wipe_cache', // still to be confirmed by Raam.
125
+ 'wp_cache_cleared', // cfr. https://github.com/Automattic/wp-super-cache/pull/537.
126
+ 'wpfc_delete_cache', // Emre confirmed this will be added this.
127
+ 'swift_performance_after_clear_all_cache', // swift perf. yeah!
128
+ );
129
+ $page_cache_purge_actions = apply_filters('wmac_filter_main_pagecachepurgeactions', $page_cache_purge_actions);
130
+ foreach($page_cache_purge_actions as $purge_action) {
131
+ add_action($purge_action, 'WMAC_PluginCache::clearAllActionless');
132
+ }
133
+ }
134
+ }
135
+
136
+ /**
137
+ * Setup output buffering if needed.
138
+ *
139
+ * @return void
140
+ */
141
+ public function startBuffering()
142
+ {
143
+ if( $this->shouldBuffer() ) {
144
+
145
+ // Load speedupper conditionally (true by default).
146
+ if( apply_filters('wmac_filter_extend', true) ) {
147
+ $this->extend();
148
+ }
149
+
150
+ if( WMAC_Plugin::app()->getOption('js_optimize') ) {
151
+ if( !defined('CONCATENATE_SCRIPTS') ) {
152
+ define('CONCATENATE_SCRIPTS', false);
153
+ }
154
+ if( !defined('COMPRESS_SCRIPTS') ) {
155
+ define('COMPRESS_SCRIPTS', false);
156
+ }
157
+ }
158
+
159
+ if( WMAC_Plugin::app()->getOption('css_optimize') ) {
160
+ if( !defined('COMPRESS_CSS') ) {
161
+ define('COMPRESS_CSS', false);
162
+ }
163
+ }
164
+
165
+ if( apply_filters('wmac_filter_obkiller', false) ) {
166
+ while( ob_get_level() > 0 ) {
167
+ ob_end_clean();
168
+ }
169
+ }
170
+
171
+ // Now, start the real thing!
172
+ ob_start(array($this, 'endBuffering'));
173
+ }
174
+ }
175
+
176
+ /**
177
+ * Returns true if all the conditions to start output buffering are satisfied.
178
+ *
179
+ * @param bool $doing_tests Allows overriding the optimization of only
180
+ * deciding once per request (for use in tests).
181
+ * @return bool
182
+ */
183
+ public function shouldBuffer($doing_tests = false)
184
+ {
185
+ static $do_buffering = null;
186
+
187
+ // Only check once in case we're called multiple times by others but
188
+ // still allows multiple calls when doing tests.
189
+ if( null === $do_buffering || $doing_tests ) {
190
+ $wmac_noptimize = false;
191
+
192
+ // Checking for DONOTMINIFY constant as used by e.g. WooCommerce POS.
193
+ if( defined('DONOTMINIFY') && (constant('DONOTMINIFY') === true || constant('DONOTMINIFY') === 'true')
194
+ ) {
195
+ $wmac_noptimize = true;
196
+ }
197
+
198
+ // Skip checking query strings if they're disabled.
199
+ if( apply_filters('wmac_filter_honor_qs_noptimize', true) ) {
200
+ // Check for `wmac_noptimize` (and other) keys in the query string
201
+ // to get non-optimized page for debugging.
202
+ $keys = array(
203
+ 'wmac_noptimize',
204
+ 'wmac_noptirocket',
205
+ );
206
+ foreach($keys as $key) {
207
+ if( array_key_exists($key, $_GET) && '1' === $_GET[$key] ) {
208
+ $wmac_noptimize = true;
209
+ break;
210
+ }
211
+ }
212
+ }
213
+
214
+ // Allows blocking of auto optimization on your own terms regardless of above decisions.
215
+ $wmac_noptimize = (bool)apply_filters('wmac_filter_noptimize', $wmac_noptimize);
216
+
217
+ // Check for site being previewed in the Customizer (available since WP 4.0).
218
+ $is_customize_preview = false;
219
+ if( function_exists('is_customize_preview') && is_customize_preview() ) {
220
+ $is_customize_preview = is_customize_preview();
221
+ }
222
+
223
+ /**
224
+ * We only buffer the frontend requests (and then only if not a feed
225
+ * and not turned off explicitly and not when being previewed in Customizer)!
226
+ * NOTE: Tests throw a notice here due to is_feed() being called
227
+ * while the main query hasn't been ran yet. Thats why we use
228
+ * WMAC_INIT_EARLIER in tests.
229
+ */
230
+ $do_buffering = (!is_admin() && !is_feed() && !$wmac_noptimize && !$is_customize_preview);
231
+ }
232
+
233
+ return $do_buffering;
234
+ }
235
+
236
+ /**
237
+ * Returns true if given markup is considered valid/processable/optimizable.
238
+ *
239
+ * @param string $content Markup.
240
+ *
241
+ * @return bool
242
+ */
243
+ public function isValidBuffer($content)
244
+ {
245
+ // Defaults to true.
246
+ $valid = true;
247
+
248
+ $has_no_html_tag = (false === stripos($content, '<html'));
249
+ $has_xsl_stylesheet = (false !== stripos($content, '<xsl:stylesheet'));
250
+ $has_html5_doctype = (preg_match('/^<!DOCTYPE.+html>/i', $content) > 0);
251
+
252
+ if( $has_no_html_tag ) {
253
+ // Can't be valid amp markup without an html tag preceding it.
254
+ $is_amp_markup = false;
255
+ } else {
256
+ $is_amp_markup = self::isAmpMarkup($content);
257
+ }
258
+
259
+ // If it's not html, or if it's amp or contains xsl stylesheets we don't touch it.
260
+ if( $has_no_html_tag && !$has_html5_doctype || $is_amp_markup || $has_xsl_stylesheet ) {
261
+ $valid = false;
262
+ }
263
+
264
+ return $valid;
265
+ }
266
+
267
+ /**
268
+ * Returns true if given $content is considered to be AMP markup.
269
+ * This is far from actual validation against AMP spec, but it'll do for now.
270
+ *
271
+ * @param string $content Markup to check.
272
+ *
273
+ * @return bool
274
+ */
275
+ public static function isAmpMarkup($content)
276
+ {
277
+ $is_amp_markup = preg_match('/<html[^>]*(?:amp|⚡)/i', $content);
278
+
279
+ return (bool)$is_amp_markup;
280
+ }
281
+
282
+ /**
283
+ * Processes/optimizes the output-buffered content and returns it.
284
+ * If the content is not processable, it is returned unmodified.
285
+ *
286
+ * @param string $content Buffered content.
287
+ *
288
+ * @return string
289
+ */
290
+ public function endBuffering($content)
291
+ {
292
+ // Bail early without modifying anything if we can't handle the content.
293
+ if( !$this->isValidBuffer($content) ) {
294
+ return $content;
295
+ }
296
+
297
+ // Determine what needs to be ran.
298
+ $classes = array();
299
+ if( WMAC_Plugin::app()->getOption('js_optimize') ) {
300
+ $classes[] = 'WMAC_PluginScripts';
301
+ }
302
+ if( WMAC_Plugin::app()->getOption('css_optimize') ) {
303
+ $classes[] = 'WMAC_PluginStyles';
304
+ }
305
+
306
+ $classoptions = array(
307
+ 'WMAC_PluginScripts' => array(
308
+ 'aggregate' => WMAC_Plugin::app()->getOption('js_aggregate'),
309
+ 'forcehead' => WMAC_Plugin::app()->getOption('js_forcehead'),
310
+ 'trycatch' => WMAC_Plugin::app()->getOption('js_trycatch'),
311
+ 'js_exclude' => WMAC_Plugin::app()->getOption('js_exclude'),
312
+ 'include_inline' => WMAC_Plugin::app()->getOption('js_include_inline'),
313
+ ),
314
+ 'WMAC_PluginStyles' => array(
315
+ 'aggregate' => WMAC_Plugin::app()->getOption('css_aggregate'),
316
+ 'datauris' => WMAC_Plugin::app()->getOption('css_datauris'),
317
+ 'defer' => WMAC_Plugin::app()->getOption('css_defer'),
318
+ 'inline' => WMAC_Plugin::app()->getOption('css_inline'),
319
+ 'css_exclude' => WMAC_Plugin::app()->getOption('css_exclude'),
320
+ 'include_inline' => WMAC_Plugin::app()->getOption('css_include_inline'),
321
+ ),
322
+ );
323
+
324
+ $content = apply_filters('wmac_filter_html_before_minify', $content);
325
+
326
+ // Run the classes!
327
+ foreach($classes as $name) {
328
+ $instance = new $name($content);
329
+ if( $instance->read($classoptions[$name]) ) {
330
+ $instance->minify();
331
+ $instance->cache();
332
+ $content = $instance->getContent();
333
+ }
334
+ unset($instance);
335
+ }
336
+
337
+ $content = apply_filters('wmac_html_after_minify', $content);
338
+
339
+ return $content;
340
+ }
341
+
342
+ /**
343
+ * Extended functional
344
+ */
345
+ public function extend()
346
+ {
347
+ if( apply_filters('wmac_js_do_minify', true) ) {
348
+ add_filter('wmac_js_individual_script', array($this, 'jsSnippetcacher'), 10, 2);
349
+ add_filter('wmac_js_after_minify', array($this, 'jsCleanup'), 10, 1);
350
+ }
351
+ }
352
+
353
+ /**
354
+ * @param $jsin
355
+ * @param $jsfilename
356
+ *
357
+ * @return false|mixed|string
358
+ */
359
+ public function jsSnippetcacher($jsin, $jsfilename)
360
+ {
361
+ $md5hash = 'snippet_' . md5($jsin);
362
+ $ccheck = new WMAC_PluginCache($md5hash, 'js');
363
+ if( $ccheck->check() ) {
364
+ $scriptsrc = $ccheck->retrieve();
365
+ } else {
366
+ if( false === (strpos($jsfilename, 'min.js')) && (false === strpos($jsfilename, 'js/jquery/jquery.js')) && (str_replace(apply_filters('wmac_filter_js_consider_minified', false), '', $jsfilename) === $jsfilename)
367
+ ) {
368
+ $tmp_jscode = trim(WMAC\JSMin::minify($jsin));
369
+ if( !empty($tmp_jscode) ) {
370
+ $scriptsrc = $tmp_jscode;
371
+ unset($tmp_jscode);
372
+ } else {
373
+ $scriptsrc = $jsin;
374
+ }
375
+ } else {
376
+ // Removing comments, linebreaks and stuff!
377
+ $scriptsrc = preg_replace('#^\s*\/\/.*$#Um', '', $jsin);
378
+ $scriptsrc = preg_replace('#^\s*\/\*[^!].*\*\/\s?#Us', '', $scriptsrc);
379
+ $scriptsrc = preg_replace("#(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+#", "\n", $scriptsrc);
380
+ }
381
+
382
+ $last_char = substr($scriptsrc, -1, 1);
383
+ if( ';' !== $last_char && '}' !== $last_char ) {
384
+ $scriptsrc .= ';';
385
+ }
386
+
387
+ if( !empty($jsfilename) && str_replace(apply_filters('wmac_filter_js_speedup_cache', false), '', $jsfilename) === $jsfilename
388
+ ) {
389
+ // Don't cache inline CSS or if filter says no!
390
+ $ccheck->cache($scriptsrc, 'text/javascript');
391
+ }
392
+ }
393
+ unset($ccheck);
394
+
395
+ return $scriptsrc;
396
+ }
397
+
398
+ /**
399
+ * JS cleanup
400
+ *
401
+ * @param $jsin
402
+ *
403
+ * @return string
404
+ */
405
+ public function jsCleanup($jsin)
406
+ {
407
+ return trim($jsin);
408
+ }
409
+
410
+ /**
411
+ * Notice
412
+ */
413
+ public static function noticeCacheUnavailable()
414
+ {
415
+ echo '<div class="error"><p>';
416
+ // Translators: %s is the cache directory location.
417
+ printf(__('Мinify And Combine cannot write to the cache directory (%s), please fix to enable CSS/ JS optimization!', 'minify-and-combine'), WMAC_PluginCache::getCacheDir());
418
+ echo '</p></div>';
419
+ }
420
+
421
+ /**
422
+ * Get site url
423
+ *
424
+ * @return string
425
+ */
426
+ public static function getSiteUrl()
427
+ {
428
+ if( function_exists('domain_mapping_siteurl') ) {
429
+ return domain_mapping_siteurl(get_current_blog_id());
430
+ } else {
431
+ return site_url();
432
+ }
433
+ }
434
+
435
+ /**
436
+ * Get content url
437
+ *
438
+ * @return string
439
+ */
440
+ public static function getContentUrl()
441
+ {
442
+ if( function_exists('get_original_url') ) {
443
+ $site_url = self::getSiteUrl();
444
+
445
+ return str_replace(get_original_url($site_url), $site_url, content_url());
446
+ } else {
447
+ return content_url();
448
+ }
449
+ }
450
+ }
components/minify-and-combine/includes/classes/class.mac-scripts.php ADDED
@@ -0,0 +1,635 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Operations with scripts
4
+ * @author Webcraftic <wordpress.webraftic@gmail.com>
5
+ * @copyright (c) 2018 Webraftic Ltd
6
+ * @version 1.0
7
+ */
8
+
9
+ if( !defined('ABSPATH') ) {
10
+ exit;
11
+ }
12
+
13
+ /**
14
+ * Class WMAC_PluginScripts
15
+ */
16
+ class WMAC_PluginScripts extends WMAC_PluginBase {
17
+
18
+ private $scripts = array();
19
+ private $move = array(
20
+ 'first' => array(),
21
+ 'last' => array()
22
+ );
23
+
24
+ private $dontmove = array(
25
+ 'document.write',
26
+ 'html5.js',
27
+ 'show_ads.js',
28
+ 'google_ad',
29
+ 'histats.com/js',
30
+ 'statcounter.com/counter/counter.js',
31
+ 'ws.amazon.com/widgets',
32
+ 'media.fastclick.net',
33
+ '/ads/',
34
+ 'comment-form-quicktags/quicktags.php',
35
+ 'edToolbar',
36
+ 'intensedebate.com',
37
+ 'scripts.chitika.net/',
38
+ '_gaq.push',
39
+ 'jotform.com/',
40
+ 'admin-bar.min.js',
41
+ 'GoogleAnalyticsObject',
42
+ 'plupload.full.min.js',
43
+ 'syntaxhighlighter',
44
+ 'adsbygoogle',
45
+ 'gist.github.com',
46
+ '_stq',
47
+ 'nonce',
48
+ 'post_id',
49
+ 'data-noptimize',
50
+ 'logHuman'
51
+ );
52
+ private $domove = array(
53
+ 'gaJsHost',
54
+ 'load_cmc',
55
+ 'jd.gallery.transitions.js',
56
+ 'swfobject.embedSWF(',
57
+ 'tiny_mce.js',
58
+ 'tinyMCEPreInit.go'
59
+ );
60
+ private $domovelast = array(
61
+ 'addthis.com',
62
+ '/afsonline/show_afs_search.js',
63
+ 'disqus.js',
64
+ 'networkedblogs.com/getnetworkwidget',
65
+ 'infolinks.com/js/',
66
+ 'jd.gallery.js.php',
67
+ 'jd.gallery.transitions.js',
68
+ 'swfobject.embedSWF(',
69
+ 'linkwithin.com/widget.js',
70
+ 'tiny_mce.js',
71
+ 'tinyMCEPreInit.go'
72
+ );
73
+
74
+ private $aggregate = true;
75
+ private $trycatch = false;
76
+ private $alreadyminified = false;
77
+ private $forcehead = true;
78
+ private $include_inline = false;
79
+ private $jscode = '';
80
+ private $url = '';
81
+ private $md5hash = '';
82
+ private $whitelist = array();
83
+ private $jsremovables = array();
84
+ private $inject_min_late = '';
85
+
86
+ /**
87
+ * Reads the page and collects script tags
88
+ *
89
+ * @param array $options
90
+ *
91
+ * @return bool
92
+ */
93
+ public function read($options)
94
+ {
95
+ $noptimizeJS = apply_filters('wmac_filter_js_noptimize', false, $this->content);
96
+ if( $noptimizeJS ) {
97
+ return false;
98
+ }
99
+
100
+ // only optimize known good JS?
101
+ $whitelistJS = apply_filters('wmac_filter_js_whitelist', '', $this->content);
102
+ if( !empty($whitelistJS) ) {
103
+ $this->whitelist = array_filter(array_map('trim', explode(',', $whitelistJS)));
104
+ }
105
+
106
+ // is there JS we should simply remove
107
+ $removableJS = apply_filters('wmac_filter_js_removables', '', $this->content);
108
+ if( !empty($removableJS) ) {
109
+ $this->jsremovables = array_filter(array_map('trim', explode(',', $removableJS)));
110
+ }
111
+
112
+ // Determine whether we're doing JS-files aggregation or not.
113
+ if( !$options['aggregate'] ) {
114
+ $this->aggregate = false;
115
+ }
116
+ // Returning true for "dontaggregate" turns off aggregation.
117
+ if( $this->aggregate && apply_filters('wmac_filter_js_dontaggregate', false) ) {
118
+ $this->aggregate = false;
119
+ }
120
+
121
+ // include inline?
122
+ if( apply_filters('wmac_js_include_inline', $options['include_inline']) ) {
123
+ $this->include_inline = true;
124
+ }
125
+
126
+ // filter to "late inject minified JS", default to true for now (it is faster)
127
+ $this->inject_min_late = apply_filters('wmac_filter_js_inject_min_late', true);
128
+
129
+ // filters to override hardcoded do(nt)move(last) array contents (array in, array out!)
130
+ $this->dontmove = apply_filters('wmac_filter_js_dontmove', $this->dontmove);
131
+ $this->domovelast = apply_filters('wmac_filter_js_movelast', $this->domovelast);
132
+ $this->domove = apply_filters('wmac_filter_js_domove', $this->domove);
133
+
134
+ // get extra exclusions settings or filter
135
+ $excludeJS = $options['js_exclude'];
136
+ $excludeJS = apply_filters('wmac_filter_js_exclude', $excludeJS, $this->content);
137
+
138
+ if( '' !== $excludeJS ) {
139
+ if( is_array($excludeJS) ) {
140
+ if( ($removeKeys = array_keys($excludeJS, 'remove')) !== false ) {
141
+ foreach($removeKeys as $removeKey) {
142
+ unset($excludeJS[$removeKey]);
143
+ $this->jsremovables[] = $removeKey;
144
+ }
145
+ }
146
+ $exclJSArr = array_keys($excludeJS);
147
+ } else {
148
+ $exclJSArr = array_filter(array_map('trim', explode(',', $excludeJS)));
149
+ }
150
+ $this->dontmove = array_merge($exclJSArr, $this->dontmove);
151
+ }
152
+
153
+ // Should we add try-catch?
154
+ if( $options['trycatch'] ) {
155
+ $this->trycatch = true;
156
+ }
157
+
158
+ // force js in head?
159
+ if( $options['forcehead'] ) {
160
+ $this->forcehead = true;
161
+ } else {
162
+ $this->forcehead = false;
163
+ }
164
+
165
+ $this->forcehead = apply_filters('wmac_filter_js_forcehead', $this->forcehead);
166
+
167
+ // noptimize me
168
+ $this->content = $this->hideNoptimize($this->content);
169
+
170
+ // Save IE hacks
171
+ $this->content = $this->hideIEhacks($this->content);
172
+
173
+ // comments
174
+ $this->content = $this->hideComments($this->content);
175
+
176
+ // Get script files
177
+ if( preg_match_all('#<script.*</script>#Usmi', $this->content, $matches) ) {
178
+ foreach($matches[0] as $tag) {
179
+ // only consider script aggregation for types whitelisted in should_aggregate-function
180
+ $should_aggregate = $this->shouldAggregate($tag);
181
+ if( !$should_aggregate ) {
182
+ $tag = '';
183
+ continue;
184
+ }
185
+
186
+ if( preg_match('#<script[^>]*src=("|\')([^>]*)("|\')#Usmi', $tag, $source) ) {
187
+ // non-inline script
188
+ if( $this->isremovable($tag, $this->jsremovables) ) {
189
+ $this->content = str_replace($tag, '', $this->content);
190
+ continue;
191
+ }
192
+
193
+ $origTag = null;
194
+ $url = current(explode('?', $source[2], 2));
195
+ $path = $this->getPath($url);
196
+ if( false !== $path && preg_match('#\.js$#', $path) && $this->isMergeable($tag) ) {
197
+ // ok to optimize, add to array
198
+ $this->scripts[] = $path;
199
+ } else {
200
+ $origTag = $tag;
201
+ $newTag = $tag;
202
+
203
+ // non-mergeable script (excluded or dynamic or external)
204
+ if( is_array($excludeJS) ) {
205
+ // should we add flags?
206
+ foreach($excludeJS as $exclTag => $exclFlags) {
207
+ if( false !== strpos($origTag, $exclTag) && in_array($exclFlags, array(
208
+ 'async',
209
+ 'defer'
210
+ ))
211
+ ) {
212
+ $newTag = str_replace('<script ', '<script ' . $exclFlags . ' ', $newTag);
213
+ }
214
+ }
215
+ }
216
+
217
+ // Should we minify the non-aggregated script?
218
+ if( $path && apply_filters('wmac_filter_js_minify_excluded', true, $url) ) {
219
+ $minified_url = $this->minifySingle($path);
220
+ // replace orig URL with minified URL from cache if so
221
+ if( !empty($minified_url) ) {
222
+ $newTag = str_replace($url, $minified_url, $newTag);
223
+ }
224
+
225
+ // remove querystring from URL in newTag
226
+ if( !empty($explUrl[1]) ) {
227
+ $newTag = str_replace('?' . $explUrl[1], '', $newTag);
228
+ }
229
+ }
230
+
231
+ if( $this->isMovable($newTag) ) {
232
+ // can be moved, flags and all
233
+ if( $this->moveToLast($newTag) ) {
234
+ $this->move['last'][] = $newTag;
235
+ } else {
236
+ $this->move['first'][] = $newTag;
237
+ }
238
+ } else {
239
+ // cannot be moved, so if flag was added re-inject altered tag immediately
240
+ if( $origTag !== $newTag ) {
241
+ $this->content = str_replace($origTag, $newTag, $this->content);
242
+ }
243
+ // and forget about the $tag (not to be touched any more)
244
+ $tag = '';
245
+ }
246
+ }
247
+ } else {
248
+ // Inline script
249
+ if( $this->isremovable($tag, $this->jsremovables) ) {
250
+ $this->content = str_replace($tag, '', $this->content);
251
+ continue;
252
+ }
253
+
254
+ // unhide comments, as javascript may be wrapped in comment-tags for old times' sake
255
+ $tag = $this->restoreComments($tag);
256
+ if( $this->isMergeable($tag) && $this->include_inline ) {
257
+ preg_match('#<script.*>(.*)</script>#Usmi', $tag, $code);
258
+ $code = preg_replace('#.*<!\[CDATA\[(?:\s*\*/)?(.*)(?://|/\*)\s*?\]\]>.*#sm', '$1', $code[1]);
259
+ $code = preg_replace('/(?:^\\s*<!--\\s*|\\s*(?:\\/\\/)?\\s*-->\\s*$)/', '', $code);
260
+ $this->scripts[] = 'INLINE;' . $code;
261
+ } else {
262
+ // Can we move this?
263
+ $wmac_js_moveable = apply_filters('wmac_js_moveable', '', $tag);
264
+ if( $this->isMovable($tag) || '' !== $wmac_js_moveable ) {
265
+ if( $this->moveToLast($tag) || 'last' === $wmac_js_moveable ) {
266
+ $this->move['last'][] = $tag;
267
+ } else {
268
+ $this->move['first'][] = $tag;
269
+ }
270
+ } else {
271
+ // We shouldn't touch this
272
+ $tag = '';
273
+ }
274
+ }
275
+ // Re-hide comments to be able to do the removal based on tag from $this->content
276
+ $tag = $this->hideComments($tag);
277
+ }
278
+
279
+ //Remove the original script tag
280
+ $this->content = str_replace($tag, '', $this->content);
281
+ }
282
+
283
+ return true;
284
+ }
285
+
286
+ return false;
287
+ }
288
+
289
+ /**
290
+ * Determines wheter a certain `<script>` $tag should be aggregated or not.
291
+ *
292
+ * We consider these as "aggregation-safe" currently:
293
+ * - script tags without a `type` attribute
294
+ * - script tags with these `type` attribute values: `text/javascript`, `text/ecmascript`, `application/javascript`,
295
+ * and `application/ecmascript`
296
+ *
297
+ * Everything else should return false.
298
+ *
299
+ * @link https://developer.mozilla.org/en/docs/Web/HTML/Element/script#attr-type
300
+ *
301
+ * @param string $tag
302
+ *
303
+ * @return bool
304
+ */
305
+ public function shouldAggregate($tag)
306
+ {
307
+ // We're only interested in the type attribute of the <script> tag itself, not any possible
308
+ // inline code that might just contain the 'type=' string...
309
+ $tag_parts = array();
310
+ preg_match('#<(script[^>]*)>#i', $tag, $tag_parts);
311
+ $tag_without_contents = null;
312
+ if( !empty($tag_parts[1]) ) {
313
+ $tag_without_contents = $tag_parts[1];
314
+ }
315
+
316
+ $has_type = (strpos($tag_without_contents, 'type') !== false);
317
+
318
+ $type_valid = false;
319
+ if( $has_type ) {
320
+ $type_valid = (bool)preg_match('/type\s*=\s*[\'"]?(?:text|application)\/(?:javascript|ecmascript)[\'"]?/i', $tag_without_contents);
321
+ }
322
+
323
+ $should_aggregate = false;
324
+ if( !$has_type || $type_valid ) {
325
+ $should_aggregate = true;
326
+ }
327
+
328
+ return $should_aggregate;
329
+ }
330
+
331
+ /**
332
+ * Joins and optimizes JS
333
+ *
334
+ * @return bool
335
+ */
336
+ public function minify()
337
+ {
338
+ foreach($this->scripts as $script) {
339
+ // TODO/FIXME: some duplicate code here, can be reduced/simplified
340
+ if( preg_match('#^INLINE;#', $script) ) {
341
+ // Inline script
342
+ $script = preg_replace('#^INLINE;#', '', $script);
343
+ $script = rtrim($script, ";\n\t\r") . ';';
344
+ // Add try-catch?
345
+ if( $this->trycatch ) {
346
+ $script = 'try{' . $script . '}catch(e){}';
347
+ }
348
+ $tmpscript = apply_filters('wmac_js_individual_script', $script, '');
349
+ if( has_filter('wmac_js_individual_script') && !empty($tmpscript) ) {
350
+ $script = $tmpscript;
351
+ $this->alreadyminified = true;
352
+ }
353
+ $this->jscode .= "\n" . $script;
354
+ } else {
355
+ // External script
356
+ if( false !== $script && file_exists($script) && is_readable($script) ) {
357
+ $scriptsrc = file_get_contents($script);
358
+ $scriptsrc = preg_replace('/\x{EF}\x{BB}\x{BF}/', '', $scriptsrc);
359
+ $scriptsrc = rtrim($scriptsrc, ";\n\t\r") . ';';
360
+ // Add try-catch?
361
+ if( $this->trycatch ) {
362
+ $scriptsrc = 'try{' . $scriptsrc . '}catch(e){}';
363
+ }
364
+ $tmpscriptsrc = apply_filters('wmac_js_individual_script', $scriptsrc, $script);
365
+ if( has_filter('wmac_js_individual_script') && !empty($tmpscriptsrc) ) {
366
+ $scriptsrc = $tmpscriptsrc;
367
+ $this->alreadyminified = true;
368
+ } else if( $this->canInjectLate($script) ) {
369
+ $scriptsrc = self::buildInjectlaterMarker($script, md5($scriptsrc));
370
+ }
371
+ $this->jscode .= "\n" . $scriptsrc;
372
+ }/*else{
373
+ //Couldn't read JS. Maybe getPath isn't working?
374
+ }*/
375
+ }
376
+ }
377
+
378
+ // Check for already-minified code
379
+ $this->md5hash = md5($this->jscode);
380
+ $ccheck = new WMAC_PluginCache($this->md5hash, 'js');
381
+ if( $ccheck->check() ) {
382
+ $this->jscode = $ccheck->retrieve();
383
+
384
+ return true;
385
+ }
386
+ unset($ccheck);
387
+
388
+ // $this->jscode has all the uncompressed code now.
389
+ if( true !== $this->alreadyminified ) {
390
+ if( apply_filters('wmac_js_do_minify', true) ) {
391
+ $tmp_jscode = trim(WMAC\JSMin::minify($this->jscode));
392
+ if( !empty($tmp_jscode) ) {
393
+ $this->jscode = $tmp_jscode;
394
+ unset($tmp_jscode);
395
+ }
396
+ $this->jscode = $this->injectMinified($this->jscode);
397
+ $this->jscode = apply_filters('wmac_js_after_minify', $this->jscode);
398
+
399
+ return true;
400
+ } else {
401
+ $this->jscode = $this->injectMinified($this->jscode);
402
+
403
+ return false;
404
+ }
405
+ }
406
+
407
+ $this->jscode = apply_filters('wmac_js_after_minify', $this->jscode);
408
+
409
+ return true;
410
+ }
411
+
412
+ /**
413
+ * Caches the JS in uncompressed, deflated and gzipped form.
414
+ */
415
+ public function cache()
416
+ {
417
+ $cache = new WMAC_PluginCache($this->md5hash, 'js');
418
+ if( !$cache->check() ) {
419
+ // Cache our code
420
+ $cache->cache($this->jscode, 'text/javascript');
421
+ }
422
+ $this->url = WMAC_PluginCache::getCacheUrl() . $cache->getname();
423
+ }
424
+
425
+ /**
426
+ * Returns the content
427
+ *
428
+ * @return string
429
+ */
430
+ public function getContent()
431
+ {
432
+ // Add the scripts taking forcehead/ deferred (default) into account
433
+ if( $this->forcehead ) {
434
+ $replaceTag = array('</head>', 'before');
435
+ $defer = '';
436
+ } else {
437
+ $replaceTag = array('</body>', 'before');
438
+ $defer = 'defer ';
439
+ }
440
+
441
+ $defer = apply_filters('wmac_filter_js_defer', $defer);
442
+
443
+ $bodyreplacementpayload = '<script type="text/javascript" ' . $defer . 'src="' . $this->url . '"></script>';
444
+ $bodyreplacementpayload = apply_filters('wmac_filter_js_bodyreplacementpayload', $bodyreplacementpayload);
445
+
446
+ $bodyreplacement = implode('', $this->move['first']);
447
+ $bodyreplacement .= $bodyreplacementpayload;
448
+ $bodyreplacement .= implode('', $this->move['last']);
449
+
450
+ $replaceTag = apply_filters('wmac_filter_js_replacetag', $replaceTag);
451
+
452
+ if( strlen($this->jscode) > 0 ) {
453
+ $this->injectInHtml($bodyreplacement, $replaceTag);
454
+ }
455
+
456
+ // Restore comments.
457
+ $this->content = $this->restoreComments($this->content);
458
+
459
+ // Restore IE hacks.
460
+ $this->content = $this->restoreIEhacks($this->content);
461
+
462
+ // Restore noptimize.
463
+ $this->content = $this->restoreNoptimize($this->content);
464
+
465
+ // Return the modified HTML.
466
+ return $this->content;
467
+ }
468
+
469
+ /**
470
+ * Checks against the white- and blacklists
471
+ *
472
+ * @param $tag
473
+ *
474
+ * @return bool
475
+ */
476
+ private function isMergeable($tag)
477
+ {
478
+ if( !$this->aggregate ) {
479
+ return false;
480
+ }
481
+
482
+ if( !empty($this->whitelist) ) {
483
+ foreach($this->whitelist as $match) {
484
+ if( false !== strpos($tag, $match) ) {
485
+ return true;
486
+ }
487
+ }
488
+
489
+ // no match with whitelist
490
+ return false;
491
+ } else {
492
+ foreach($this->domove as $match) {
493
+ if( false !== strpos($tag, $match) ) {
494
+ // Matched something
495
+ return false;
496
+ }
497
+ }
498
+
499
+ if( $this->moveToLast($tag) ) {
500
+ return false;
501
+ }
502
+
503
+ foreach($this->dontmove as $match) {
504
+ if( false !== strpos($tag, $match) ) {
505
+ // Matched something
506
+ return false;
507
+ }
508
+ }
509
+
510
+ // If we're here it's safe to merge
511
+ return true;
512
+ }
513
+ }
514
+
515
+ /**
516
+ * Checks agains the blacklist
517
+ *
518
+ * @param $tag
519
+ *
520
+ * @return bool
521
+ */
522
+ private function isMovable($tag)
523
+ {
524
+ if( true !== $this->include_inline || apply_filters('wmac_filter_js_unmovable', true) ) {
525
+ return false;
526
+ }
527
+
528
+ foreach($this->domove as $match) {
529
+ if( false !== strpos($tag, $match) ) {
530
+ // Matched something
531
+ return true;
532
+ }
533
+ }
534
+
535
+ if( $this->moveToLast($tag) ) {
536
+ return true;
537
+ }
538
+
539
+ foreach($this->dontmove as $match) {
540
+ if( false !== strpos($tag, $match) ) {
541
+ // Matched something
542
+ return false;
543
+ }
544
+ }
545
+
546
+ // If we're here it's safe to move
547
+ return true;
548
+ }
549
+
550
+ /**
551
+ * @param $tag
552
+ *
553
+ * @return bool
554
+ */
555
+ private function moveToLast($tag)
556
+ {
557
+ foreach($this->domovelast as $match) {
558
+ if( false !== strpos($tag, $match) ) {
559
+ // Matched, return true
560
+ return true;
561
+ }
562
+ }
563
+
564
+ // Should be in 'first'
565
+ return false;
566
+ }
567
+
568
+ /**
569
+ * Determines wheter a <script> $tag can be excluded from minification (as already minified) based on:
570
+ * - inject_min_late being active
571
+ * - filename ending in `min.js`
572
+ * - filename matching `js/jquery/jquery.js` (wordpress core jquery, is minified)
573
+ * - filename matching one passed in the consider minified filter
574
+ *
575
+ * @param string $jsPath
576
+ *
577
+ * @return bool
578
+ */
579
+ private function canInjectLate($jsPath)
580
+ {
581
+ $consider_minified_array = apply_filters('wmac_filter_js_consider_minified', false);
582
+ if( true !== $this->inject_min_late ) {
583
+ // late-inject turned off
584
+ return false;
585
+ } else if( (false === strpos($jsPath, 'min.js')) && (false === strpos($jsPath, 'wp-includes/js/jquery/jquery.js')) && (str_replace($consider_minified_array, '', $jsPath) === $jsPath) ) {
586
+ // file not minified based on filename & filter
587
+ return false;
588
+ } else {
589
+ // phew, all is safe, we can late-inject
590
+ return true;
591
+ }
592
+ }
593
+
594
+ /**
595
+ * Returns whether we're doing aggregation or not.
596
+ *
597
+ * @return bool
598
+ */
599
+ public function aggregating()
600
+ {
601
+ return $this->aggregate;
602
+ }
603
+
604
+ /**
605
+ * Minifies a single local js file and returns its (cached) url.
606
+ *
607
+ * @param string $filepath Filepath.
608
+ * @param bool $cache_miss Optional. Force a cache miss. Default false.
609
+ *
610
+ * @return bool|string Url pointing to the minified js file or false.
611
+ */
612
+ public function minifySingle($filepath, $cache_miss = false)
613
+ {
614
+ $contents = $this->prepareMinifySingle($filepath);
615
+
616
+ if( empty($contents) ) {
617
+ return false;
618
+ }
619
+
620
+ // Check cache.
621
+ $hash = 'single_' . md5($contents);
622
+ $cache = new WMAC_PluginCache($hash, 'js');
623
+
624
+ // If not in cache already, minify...
625
+ if( !$cache->check() || $cache_miss ) {
626
+ $contents = trim(WMAC\JSMin::minify($contents));
627
+ // Store in cache.
628
+ $cache->cache($contents, 'text/javascript');
629
+ }
630
+
631
+ $url = $this->buildMinifySingleUrl($cache);
632
+
633
+ return $url;
634
+ }
635
+ }
components/minify-and-combine/includes/classes/class.mac-styles.php ADDED
@@ -0,0 +1,1127 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Operations with styles
4
+ * @author Webcraftic <wordpress.webraftic@gmail.com>
5
+ * @copyright (c) 2018 Webraftic Ltd
6
+ * @version 1.0
7
+ */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit;
11
+ }
12
+
13
+ /**
14
+ * Class WMAC_PluginStyles
15
+ */
16
+ class WMAC_PluginStyles extends WMAC_PluginBase
17
+ {
18
+ const ASSETS_REGEX = '/url\s*\(\s*(?!["\']?data:)(?![\'|\"]?[\#|\%|])([^)]+)\s*\)([^;},\s]*)/i';
19
+
20
+ /**
21
+ * Font-face regex-fu from HamZa at: https://stackoverflow.com/a/21395083
22
+ * ~
23
+ * @font-face\s* # Match @font-face and some spaces
24
+ * ( # Start group 1
25
+ * \{ # Match {
26
+ * (?: # A non-capturing group
27
+ * [^{}]+ # Match anything except {} one or more times
28
+ * | # Or
29
+ * (?1) # Recurse/rerun the expression of group 1
30
+ * )* # Repeat 0 or more times
31
+ * \} # Match }
32
+ * ) # End group 1
33
+ * ~xs';
34
+ */
35
+ const FONT_FACE_REGEX = '~@font-face\s*(\{(?:[^{}]+|(?1))*\})~xsi'; // added `i` flag for case-insensitivity.
36
+
37
+ private $options = array();
38
+ private $dontmove = array();
39
+ private $css = array();
40
+ private $csscode = array();
41
+ private $url = array();
42
+ private $restofcontent = '';
43
+ private $datauris = false;
44
+ private $hashmap = array();
45
+ private $alreadyminified = false;
46
+ private $aggregate = true;
47
+ private $inline = false;
48
+ private $defer = false;
49
+ //private $defer_inline = false;
50
+ private $whitelist = array();
51
+ private $cssinlinesize = '';
52
+ private $cssremovables = array();
53
+ private $include_inline = false;
54
+ private $inject_min_late = '';
55
+
56
+ /**
57
+ * Reads the page and collects style tags.
58
+ *
59
+ * @param array $options
60
+ *
61
+ * @return bool
62
+ */
63
+ public function read( $options )
64
+ {
65
+ $noptimizeCSS = apply_filters( 'wmac_filter_css_noptimize', false, $this->content );
66
+ if ( $noptimizeCSS ) {
67
+ return false;
68
+ }
69
+
70
+ $whitelistCSS = apply_filters( 'wmac_filter_css_whitelist', '', $this->content );
71
+ if ( ! empty( $whitelistCSS ) ) {
72
+ $this->whitelist = array_filter( array_map( 'trim', explode( ',', $whitelistCSS ) ) );
73
+ }
74
+
75
+ $removableCSS = apply_filters( 'wmac_filter_css_removables', '' );
76
+ if ( ! empty( $removableCSS ) ) {
77
+ $this->cssremovables = array_filter( array_map( 'trim', explode( ',', $removableCSS ) ) );
78
+ }
79
+
80
+ $this->cssinlinesize = apply_filters( 'wmac_filter_css_inlinesize', 256 );
81
+
82
+ // filter to "late inject minified CSS", default to true for now (it is faster).
83
+ $this->inject_min_late = apply_filters( 'wmac_filter_css_inject_min_late', true );
84
+
85
+ // Remove everything that's not the header.
86
+ /*if ( apply_filters( 'wmac_filter_css_justhead', $options['justhead'] ) ) {
87
+ $content = explode( '</head>', $this->content, 2 );
88
+ $this->content = $content[0] . '</head>';
89
+ $this->restofcontent = $content[1];
90
+ }*/
91
+
92
+ // Determine whether we're doing CSS-files aggregation or not.
93
+ if ( isset( $options['aggregate'] ) && ! $options['aggregate'] ) {
94
+ $this->aggregate = false;
95
+ }
96
+ // Returning true for "dontaggregate" turns off aggregation.
97
+ if ( $this->aggregate && apply_filters( 'wmac_filter_css_dontaggregate', false ) ) {
98
+ $this->aggregate = false;
99
+ }
100
+
101
+ // include inline?
102
+ if ( apply_filters( 'wmac_css_include_inline', $options['include_inline'] ) ) {
103
+ $this->include_inline = true;
104
+ }
105
+
106
+ // List of CSS strings which are excluded from autoptimization.
107
+ $excludeCSS = apply_filters( 'wmac_filter_css_exclude', $options['css_exclude'], $this->content );
108
+ if ( '' !== $excludeCSS ) {
109
+ $this->dontmove = array_filter( array_map( 'trim', explode( ',', $excludeCSS ) ) );
110
+ } else {
111
+ $this->dontmove = array();
112
+ }
113
+
114
+ // forcefully exclude CSS with data-noptimize attrib.
115
+ $this->dontmove[] = 'data-noptimize';
116
+
117
+ // Should we defer css?
118
+ // value: true / false.
119
+ $this->defer = $options['defer'];
120
+ $this->defer = apply_filters( 'wmac_filter_css_defer', $this->defer, $this->content );
121
+
122
+ // Should we inline while deferring?
123
+ // value: inlined CSS.
124
+ //$this->defer_inline = apply_filters( 'wmac_filter_css_defer_inline', $options['defer_inline'], $this->content );
125
+
126
+ // Should we inline?
127
+ // value: true / false.
128
+ $this->inline = $options['inline'];
129
+ $this->inline = apply_filters( 'wmac_filter_css_inline', $this->inline, $this->content );
130
+
131
+ // Store data: URIs setting for later use.
132
+ $this->datauris = $options['datauris'];
133
+
134
+ // noptimize me.
135
+ $this->content = $this->hideNoptimize( $this->content );
136
+
137
+ // Exclude (no)script, as those may contain CSS which should be left as is.
138
+ $this->content = $this->replaceContentsWithMarkerIfExists(
139
+ 'SCRIPT',
140
+ '<script',
141
+ '#<(?:no)?script.*?<\/(?:no)?script>#is',
142
+ $this->content
143
+ );
144
+
145
+ // Save IE hacks.
146
+ $this->content = $this->hideIehacks( $this->content );
147
+
148
+ // Hide HTML comments.
149
+ $this->content = $this->hideComments( $this->content );
150
+
151
+ // Get <style> and <link>.
152
+ if ( preg_match_all( '#(<style[^>]*>.*</style>)|(<link[^>]*stylesheet[^>]*>)#Usmi', $this->content, $matches ) ) {
153
+
154
+ foreach ( $matches[0] as $tag ) {
155
+ if ( $this->isremovable( $tag, $this->cssremovables ) ) {
156
+ $this->content = str_replace( $tag, '', $this->content );
157
+ } elseif ( $this->isMovable( $tag ) ) {
158
+ // Get the media.
159
+ if ( false !== strpos( $tag, 'media=' ) ) {
160
+ preg_match( '#media=(?:"|\')([^>]*)(?:"|\')#Ui', $tag, $medias );
161
+ $medias = explode( ',', $medias[1] );
162
+ $media = array();
163
+ foreach ( $medias as $elem ) {
164
+ /* $media[] = current(explode(' ',trim($elem),2)); */
165
+ if ( empty( $elem ) ) {
166
+ $elem = 'all';
167
+ }
168
+
169
+ $media[] = $elem;
170
+ }
171
+ } else {
172
+ // No media specified - applies to all.
173
+ $media = array( 'all' );
174
+ }
175
+
176
+ $media = apply_filters( 'wmac_filter_css_tagmedia', $media, $tag );
177
+
178
+ if ( preg_match( '#<link.*href=("|\')(.*)("|\')#Usmi', $tag, $source ) ) {
179
+ // <link>.
180
+ $url = current( explode( '?', $source[2], 2 ) );
181
+ $path = $this->getpath( $url );
182
+
183
+ if ( false !== $path && preg_match( '#\.css$#', $path ) ) {
184
+ // Good link.
185
+ $this->css[] = array( $media, $path );
186
+ } else {
187
+ // Link is dynamic (.php etc).
188
+ $tag = '';
189
+ }
190
+ } else {
191
+ // Inline css in style tags can be wrapped in comment tags, so restore comments.
192
+ $tag = $this->restoreComments( $tag );
193
+ preg_match( '#<style.*>(.*)</style>#Usmi', $tag, $code );
194
+
195
+ // And re-hide them to be able to to the removal based on tag.
196
+ $tag = $this->hideComments( $tag );
197
+
198
+ if ( $this->include_inline ) {
199
+ $code = preg_replace( '#^.*<!\[CDATA\[(?:\s*\*/)?(.*)(?://|/\*)\s*?\]\]>.*$#sm', '$1', $code[1] );
200
+ $this->css[] = array( $media, 'INLINE;' . $code );
201
+ } else {
202
+ $tag = '';
203
+ }
204
+ }
205
+
206
+ // Remove the original style tag.
207
+ $this->content = str_replace( $tag, '', $this->content );
208
+ } else {
209
+ // Excluded CSS, minify if getpath and filter says so...
210
+ if ( preg_match( '#<link.*href=("|\')(.*)("|\')#Usmi', $tag, $source ) ) {
211
+ $exploded_url = explode( '?', $source[2], 2 );
212
+ $url = $exploded_url[0];
213
+ $path = $this->getpath( $url );
214
+
215
+ if ( $path && apply_filters( 'wmac_filter_css_minify_excluded', true, $url ) ) {
216
+ $minified_url = $this->minifySingle( $path );
217
+ if ( ! empty( $minified_url ) ) {
218
+ // Replace orig URL with cached minified URL.
219
+ $new_tag = str_replace( $url, $minified_url, $tag );
220
+ } else {
221
+ $new_tag = $tag;
222
+ }
223
+
224
+ // Removes querystring from URL.
225
+ if ( ! empty( $exploded_url[1] ) ) {
226
+ $new_tag = str_replace( '?' . $exploded_url[1], '', $new_tag );
227
+ }
228
+
229
+ // Defer single CSS if "inline & defer" is on.
230
+ if ( $this->defer ) {
231
+ // Get/ set (via filter) the JS to be triggers onload of the preloaded CSS.
232
+ $_preload_onload = apply_filters(
233
+ 'wmac_filter_css_preload_onload',
234
+ "this.onload=null;this.rel='stylesheet'",
235
+ $url
236
+ );
237
+ // Adapt original <link> element for CSS to be preloaded.
238
+ $new_tag = str_replace(
239
+ array(
240
+ "rel='stylesheet'",
241
+ 'rel="stylesheet"',
242
+ ),
243
+ "rel='preload' as='style' onload=\"" . $_preload_onload . "\"",
244
+ $new_tag
245
+ );
246
+ }
247
+
248
+ // And replace!
249
+ $this->content = str_replace( $tag, $new_tag, $this->content );
250
+ }
251
+ }
252
+ }
253
+ }
254
+ return true;
255
+ }
256
+
257
+ // Really, no styles?
258
+ return false;
259
+ }
260
+
261
+ /**
262
+ * Checks if the local file referenced by $path is a valid
263
+ * candidate for being inlined into a data: URI
264
+ *
265
+ * @param string $path
266
+ * @return boolean
267
+ */
268
+ private function isDatauriCandidate( $path )
269
+ {
270
+ // Call only once since it's called from a loop.
271
+ static $max_size = null;
272
+ if ( null === $max_size ) {
273
+ $max_size = $this->getDatauriMaxsize();
274
+ }
275
+
276
+ if ( $path && preg_match( '#\.(jpe?g|png|gif|webp|bmp)$#i', $path ) &&
277
+ file_exists( $path ) && is_readable( $path ) && filesize( $path ) <= $max_size ) {
278
+
279
+ // Seems we have a candidate.
280
+ $is_candidate = true;
281
+ } else {
282
+ // Filter allows overriding default decision (which checks for local file existence).
283
+ $is_candidate = apply_filters( 'wmac_filter_css_is_datauri_candidate', false, $path );
284
+ }
285
+
286
+ return $is_candidate;
287
+ }
288
+
289
+ /**
290
+ * Returns the amount of bytes that shouldn't be exceeded if a file is to
291
+ * be inlined into a data: URI. Defaults to 4096, passed through
292
+ * `wmac_filter_css_datauri_maxsize` filter.
293
+ *
294
+ * @return mixed
295
+ */
296
+ private function getDatauriMaxsize()
297
+ {
298
+ static $max_size = null;
299
+
300
+ /**
301
+ * No need to apply the filter multiple times in case the
302
+ * method itself is invoked multiple times during a single request.
303
+ * This prevents some wild stuff like having different maxsizes
304
+ * for different files/site-sections etc. But if you're into that sort
305
+ * of thing you're probably better of building assets completely
306
+ * outside of WordPress anyway.
307
+ */
308
+ if ( null === $max_size ) {
309
+ $max_size = (int) apply_filters( 'wmac_filter_css_datauri_maxsize', 4096 );
310
+ }
311
+
312
+ return $max_size;
313
+ }
314
+
315
+ /**
316
+ * @param $url
317
+ *
318
+ * @return bool
319
+ */
320
+ private function checkDatauriExcludeList( $url )
321
+ {
322
+ static $exclude_list = null;
323
+ $no_datauris = array();
324
+
325
+ // Again, skip doing certain stuff repeatedly when loop-called.
326
+ if ( null === $exclude_list ) {
327
+ $exclude_list = apply_filters( 'wmac_filter_css_datauri_exclude', '' );
328
+ $no_datauris = array_filter( array_map( 'trim', explode( ',', $exclude_list ) ) );
329
+ }
330
+
331
+ $matched = false;
332
+
333
+ if ( ! empty( $exclude_list ) ) {
334
+ foreach ( $no_datauris as $no_datauri ) {
335
+ if ( false !== strpos( $url, $no_datauri ) ) {
336
+ $matched = true;
337
+ break;
338
+ }
339
+ }
340
+ }
341
+
342
+ return $matched;
343
+ }
344
+
345
+ /**
346
+ * @param $path
347
+ *
348
+ * @return array
349
+ */
350
+ private function buildOrGetDatauriImage( $path )
351
+ {
352
+ /**
353
+ * TODO/FIXME: document the required return array format, or better yet,
354
+ * use a string, since we don't really need an array for this. That would, however,
355
+ * require changing even more code, which is not happening right now...
356
+ */
357
+
358
+ // Allows short-circuiting datauri generation for an image.
359
+ $result = apply_filters( 'wmac_filter_css_datauri_image', array(), $path );
360
+ if ( ! empty( $result ) ) {
361
+ if ( is_array( $result ) && isset( $result['full'] ) && isset( $result['base64data'] ) ) {
362
+ return $result;
363
+ }
364
+ }
365
+
366
+ $hash = md5( $path );
367
+ $check = new WMAC_PluginCache( $hash, 'img' );
368
+ if ( $check->check() ) {
369
+ // we have the base64 image in cache.
370
+ $headAndData = $check->retrieve();
371
+ $_base64data = explode( ';base64,', $headAndData );
372
+ $base64data = $_base64data[1];
373
+ unset( $_base64data );
374
+ } else {
375
+ // It's an image and we don't have it in cache, get the type by extension.
376
+ $exploded_path = explode( '.', $path );
377
+ $type = end( $exploded_path );
378
+
379
+ switch ( $type ) {
380
+ case 'jpg':
381
+ case 'jpeg':
382
+ $dataurihead = 'data:image/jpeg;base64,';
383
+ break;
384
+ case 'gif':
385
+ $dataurihead = 'data:image/gif;base64,';
386
+ break;
387
+ case 'png':
388
+ $dataurihead = 'data:image/png;base64,';
389
+ break;
390
+ case 'bmp':
391
+ $dataurihead = 'data:image/bmp;base64,';
392
+ break;
393
+ case 'webp':
394
+ $dataurihead = 'data:image/webp;base64,';
395
+ break;
396
+ default:
397
+ $dataurihead = 'data:application/octet-stream;base64,';
398
+ }
399
+
400
+ // Encode the data.
401
+ $base64data = base64_encode( file_get_contents( $path ) );
402
+ $headAndData = $dataurihead . $base64data;
403
+
404
+ // Save in cache.
405
+ $check->cache( $headAndData, 'text/plain' );
406
+ }
407
+ unset( $check );
408
+
409
+ return array( 'full' => $headAndData, 'base64data' => $base64data );
410
+ }
411
+
412
+ /**
413
+ * Given an array of key/value pairs to replace in $string,
414
+ * it does so by replacing the longest-matching strings first.
415
+ *
416
+ * @param string $string
417
+ * @param array $replacements
418
+ *
419
+ * @return string
420
+ */
421
+ protected static function replaceLongestMatchesFirst( $string, $replacements = array() )
422
+ {
423
+ if ( ! empty( $replacements ) ) {
424
+ // Sort the replacements array by key length in desc order (so that the longest strings are replaced first).
425
+ $keys = array_map( 'strlen', array_keys( $replacements ) );
426
+ array_multisort( $keys, SORT_DESC, $replacements );
427
+ $string = str_replace( array_keys( $replacements ), array_values( $replacements ), $string );
428
+ }
429
+
430
+ return $string;
431
+ }
432
+
433
+ /**
434
+ * Rewrites/Replaces any ASSETS_REGEX-matching urls in a string.
435
+ * Replacements are performed in a `longest-match-replaced-first` way.
436
+ *
437
+ * @param string $code CSS code.
438
+ *
439
+ * @return string
440
+ */
441
+ public function replaceUrls( $code = '' )
442
+ {
443
+ $replacements = array();
444
+
445
+ preg_match_all( self::ASSETS_REGEX, $code, $url_src_matches );
446
+ if ( is_array( $url_src_matches ) && ! empty( $url_src_matches ) ) {
447
+ foreach ( $url_src_matches[1] as $count => $original_url ) {
448
+ // Removes quotes and other cruft.
449
+ $url = trim( $original_url, " \t\n\r\0\x0B\"'" );
450
+
451
+ // Prepare replacements array.
452
+ $replacements[ $url_src_matches[1][ $count ] ] = str_replace(
453
+ $original_url, $url, $url_src_matches[1][$count]
454
+ );
455
+ }
456
+ }
457
+
458
+ $code = self::replaceLongestMatchesFirst( $code, $replacements );
459
+
460
+ return $code;
461
+ }
462
+
463
+ /**
464
+ * "Hides" @font-face declarations by replacing them with `%%FONTFACE%%` markers.
465
+ *
466
+ * @param string $code
467
+ * @return string
468
+ */
469
+ public function hideFontface( $code )
470
+ {
471
+ // Proceed only if @font-face declarations exist within $code.
472
+ preg_match_all( self::FONT_FACE_REGEX, $code, $fontfaces );
473
+ if ( isset( $fontfaces[0] ) ) {
474
+
475
+ foreach ( $fontfaces[0] as $full_match ) {
476
+ // Keep original match so we can search/replace it.
477
+ $match_search = $full_match;
478
+
479
+ // Replace declaration with its base64 encoded string.
480
+ $replacement = self::buildMarker( 'FONTFACE', $full_match );
481
+ $code = str_replace( $match_search, $replacement, $code );
482
+ }
483
+ }
484
+
485
+ return $code;
486
+ }
487
+
488
+ /**
489
+ * Restores original @font-face declarations that have been "hidden"
490
+ * using `hideFontface()`.
491
+ *
492
+ * @param string $code
493
+ *
494
+ * @return string
495
+ */
496
+ public function restoreFontface( $code )
497
+ {
498
+ return $this->restoreMarkedContent( 'FONTFACE', $code );
499
+ }
500
+
501
+ /**
502
+ * Re-write (and/or inline) referenced assets.
503
+ *
504
+ * @param $code
505
+ *
506
+ * @return string
507
+ */
508
+ public function rewriteAssets( $code )
509
+ {
510
+ // Handle @font-face rules by hiding and processing them separately.
511
+ $code = $this->hideFontface( $code );
512
+
513
+ /**
514
+ * TODO/FIXME:
515
+ * Certain code parts below are kind-of repeated now in `replaceUrls()`, which is not ideal.
516
+ * There is maybe a way to separate/refactor things and then be able to keep
517
+ * the ASSETS_REGEX rewriting/handling logic in a single place (along with removing quotes/cruft from matched urls).
518
+ * See comments in `replaceUrls()` regarding this. The idea is to extract the inlining
519
+ * logic out (which is the only real difference between replaceUrls() and the code below), but still
520
+ * achieve identical results as before.
521
+ */
522
+
523
+ // Re-write (and/or inline) URLs
524
+ $url_src_matches = array();
525
+ $imgreplace = array();
526
+ // Matches and captures anything specified within the literal `url()` and excludes those containing data: URIs.
527
+ preg_match_all( self::ASSETS_REGEX, $code, $url_src_matches );
528
+ if ( is_array( $url_src_matches ) && ! empty( $url_src_matches ) ) {
529
+ foreach ( $url_src_matches[1] as $count => $original_url ) {
530
+ // Removes quotes and other cruft.
531
+ $url = trim( $original_url, " \t\n\r\0\x0B\"'" );
532
+
533
+ // If datauri inlining is turned on, do it.
534
+ if ( $this->datauris ) {
535
+ $iurl = $url;
536
+ if ( false !== strpos( $iurl, '?' ) ) {
537
+ $iurl = strtok( $iurl, '?' );
538
+ }
539
+
540
+ $ipath = $this->getpath( $iurl );
541
+
542
+ $excluded = $this->checkDatauriExcludeList( $ipath );
543
+ if ( ! $excluded ) {
544
+ $is_datauri_candidate = $this->isDatauriCandidate( $ipath );
545
+ if ( $is_datauri_candidate ) {
546
+ $datauri = $this->buildOrGetDatauriImage( $ipath );
547
+ //$base64data = $datauri['base64data'];
548
+ // Add it to the list for replacement.
549
+ $imgreplace[ $url_src_matches[1][ $count ] ] = str_replace(
550
+ $original_url,
551
+ $datauri['full'],
552
+ $url_src_matches[1][$count]
553
+ );
554
+ }
555
+ }
556
+ }
557
+
558
+ $imgreplace[ $url_src_matches[1][ $count ] ] = str_replace(
559
+ $original_url, $url, $url_src_matches[1][$count]
560
+ );
561
+ }
562
+ }
563
+
564
+ $code = self::replaceLongestMatchesFirst( $code, $imgreplace );
565
+
566
+ // Replace back font-face markers with actual font-face declarations.
567
+ $code = $this->restoreFontface( $code );
568
+
569
+ return $code;
570
+ }
571
+
572
+ /**
573
+ * Joins and optimizes CSS.
574
+ *
575
+ * @return bool
576
+ */
577
+ public function minify()
578
+ {
579
+ foreach ( $this->css as $group ) {
580
+ list( $media, $css ) = $group;
581
+ if ( preg_match( '#^INLINE;#', $css ) ) {
582
+ // <style>.
583
+ $css = preg_replace( '#^INLINE;#', '', $css );
584
+ $css = self::fixUrls( ABSPATH . 'index.php', $css ); // ABSPATH already contains a trailing slash.
585
+ $tmpstyle = apply_filters( 'wmac_css_individual_style', $css, '' );
586
+ if ( has_filter( 'wmac_css_individual_style' ) && ! empty( $tmpstyle ) ) {
587
+ $css = $tmpstyle;
588
+ $this->alreadyminified = true;
589
+ }
590
+ } else {
591
+ // <link>
592
+ if ( false !== $css && file_exists( $css ) && is_readable( $css ) ) {
593
+ $cssPath = $css;
594
+ $css = self::fixUrls( $cssPath, file_get_contents( $cssPath ) );
595
+ $css = preg_replace( '/\x{EF}\x{BB}\x{BF}/', '', $css );
596
+ $tmpstyle = apply_filters( 'wmac_css_individual_style', $css, $cssPath );
597
+ if ( has_filter( 'wmac_css_individual_style' ) && ! empty( $tmpstyle ) ) {
598
+ $css = $tmpstyle;
599
+ $this->alreadyminified = true;
600
+ } elseif ( $this->canInjectLate( $cssPath, $css ) ) {
601
+ $css = self::buildInjectlaterMarker( $cssPath, md5( $css ) );
602
+ }
603
+ } else {
604
+ // Couldn't read CSS. Maybe getpath isn't working?
605
+ $css = '';
606
+ }
607
+ }
608
+
609
+ foreach ( $media as $elem ) {
610
+ if ( ! empty( $css ) ) {
611
+ if ( ! isset( $this->csscode[$elem] ) ) {
612
+ $this->csscode[$elem] = '';
613
+ }
614
+ $this->csscode[$elem] .= "\n/*FILESTART*/" . $css;
615
+ }
616
+ }
617
+ }
618
+
619
+ // Check for duplicate code.
620
+ $md5list = array();
621
+ $tmpcss = $this->csscode;
622
+ foreach ( $tmpcss as $media => $code ) {
623
+ $md5sum = md5( $code );
624
+ $medianame = $media;
625
+ foreach ( $md5list as $med => $sum ) {
626
+ // If same code.
627
+ if ( $sum === $md5sum ) {
628
+ // Add the merged code.
629
+ $medianame = $med . ', ' . $media;
630
+ $this->csscode[$medianame] = $code;
631
+ $md5list[$medianame] = $md5list[$med];
632
+ unset( $this->csscode[$med], $this->csscode[$media], $md5list[$med] );
633
+ }
634
+ }
635
+ $md5list[$medianame] = $md5sum;
636
+ }
637
+ unset( $tmpcss );
638
+
639
+ // Manage @imports, while is for recursive import management.
640
+ foreach ( $this->csscode as &$thiscss ) {
641
+ // Flag to trigger import reconstitution and var to hold external imports.
642
+ $fiximports = false;
643
+ $external_imports = '';
644
+
645
+ // remove comments to avoid importing commented-out imports.
646
+ $thiscss_nocomments = preg_replace( '#/\*.*\*/#Us', '', $thiscss );
647
+ while ( preg_match_all( '#@import +(?:url)?(?:(?:\((["\']?)(?:[^"\')]+)\1\)|(["\'])(?:[^"\']+)\2)(?:[^,;"\']+(?:,[^,;"\']+)*)?)(?:;)#mi', $thiscss_nocomments, $matches ) ) {
648
+ foreach ( $matches[0] as $import ) {
649
+ if ( $this->isremovable( $import, $this->cssremovables ) ) {
650
+ $thiscss = str_replace( $import, '', $thiscss );
651
+ $import_ok = true;
652
+ } else {
653
+ $url = trim( preg_replace( '#^.*((?:https?:|ftp:)?//.*\.css).*$#', '$1', trim( $import ) ), " \t\n\r\0\x0B\"'" );
654
+ $path = $this->getpath( $url );
655
+ $import_ok = false;
656
+ if ( file_exists( $path ) && is_readable( $path ) ) {
657
+ $code = addcslashes( self::fixUrls( $path, file_get_contents( $path ) ), "\\" );
658
+ $code = preg_replace( '/\x{EF}\x{BB}\x{BF}/', '', $code );
659
+ $tmpstyle = apply_filters( 'wmac_css_individual_style', $code, '' );
660
+ if ( has_filter( 'wmac_css_individual_style' ) && ! empty( $tmpstyle ) ) {
661
+ $code = $tmpstyle;
662
+ $this->alreadyminified = true;
663
+ } elseif ( $this->canInjectLate( $path, $code ) ) {
664
+ $code = self::buildInjectlaterMarker( $path, md5( $code ) );
665
+ }
666
+
667
+ if ( ! empty( $code ) ) {
668
+ $tmp_thiscss = preg_replace( '#(/\*FILESTART\*/.*)' . preg_quote( $import, '#' ) . '#Us', '/*FILESTART2*/' . $code . '$1', $thiscss );
669
+ if ( ! empty( $tmp_thiscss ) ) {
670
+ $thiscss = $tmp_thiscss;
671
+ $import_ok = true;
672
+ unset( $tmp_thiscss );
673
+ }
674
+ }
675
+ unset( $code );
676
+ }
677
+ }
678
+ if ( ! $import_ok ) {
679
+ // External imports and general fall-back.
680
+ $external_imports .= $import;
681
+
682
+ $thiscss = str_replace( $import, '', $thiscss );
683
+ $fiximports = true;
684
+ }
685
+ }
686
+ $thiscss = preg_replace( '#/\*FILESTART\*/#', '', $thiscss );
687
+ $thiscss = preg_replace( '#/\*FILESTART2\*/#', '/*FILESTART*/', $thiscss );
688
+
689
+ // and update $thiscss_nocomments before going into next iteration in while loop.
690
+ $thiscss_nocomments = preg_replace( '#/\*.*\*/#Us', '', $thiscss );
691
+ }
692
+ unset( $thiscss_nocomments );
693
+
694
+ // Add external imports to top of aggregated CSS.
695
+ if ( $fiximports ) {
696
+ $thiscss = $external_imports . $thiscss;
697
+ }
698
+ }
699
+ unset( $thiscss );
700
+
701
+ // $this->csscode has all the uncompressed code now.
702
+ foreach ( $this->csscode as &$code ) {
703
+ // Check for already-minified code.
704
+ $hash = md5( $code );
705
+ do_action( 'wmac_action_css_hash', $hash );
706
+ $ccheck = new WMAC_PluginCache( $hash, 'css' );
707
+ if ( $ccheck->check() ) {
708
+ $code = $ccheck->retrieve();
709
+ $this->hashmap[md5( $code )] = $hash;
710
+ continue;
711
+ }
712
+ unset( $ccheck );
713
+
714
+ // Rewrite and/or inline referenced assets.
715
+ $code = $this->rewriteAssets( $code );
716
+
717
+ // Minify.
718
+ $code = $this->runMinifierOn( $code );
719
+
720
+ // Bring back INJECTLATER stuff.
721
+ $code = $this->injectMinified( $code );
722
+
723
+ // Filter results.
724
+ $tmp_code = apply_filters( 'wmac_css_after_minify', $code );
725
+ if ( ! empty( $tmp_code ) ) {
726
+ $code = $tmp_code;
727
+ unset( $tmp_code );
728
+ }
729
+
730
+ $this->hashmap[md5( $code )] = $hash;
731
+ }
732
+
733
+ unset( $code );
734
+
735
+ return true;
736
+ }
737
+
738
+ /**
739
+ * @param $code
740
+ *
741
+ * @return string
742
+ */
743
+ public function runMinifierOn( $code )
744
+ {
745
+ if ( ! $this->alreadyminified ) {
746
+ $do_minify = apply_filters( 'wmac_css_do_minify', true );
747
+
748
+ if ( $do_minify ) {
749
+ $cssmin = new WMAC_PluginCSSmin();
750
+ $tmp_code = trim( $cssmin->run( $code ) );
751
+
752
+ if ( ! empty( $tmp_code ) ) {
753
+ $code = $tmp_code;
754
+ unset( $tmp_code );
755
+ }
756
+ }
757
+ }
758
+
759
+ return $code;
760
+ }
761
+
762
+ /**
763
+ * Caches the CSS in uncompressed, deflated and gzipped form.
764
+ */
765
+ public function cache()
766
+ {
767
+ // CSS cache.
768
+ foreach ( $this->csscode as $media => $code ) {
769
+ $md5 = $this->hashmap[md5( $code )];
770
+ $cache = new WMAC_PluginCache( $md5, 'css' );
771
+ if ( ! $cache->check() ) {
772
+ // Cache our code.
773
+ $cache->cache( $code, 'text/css' );
774
+ }
775
+ $this->url[$media] = WMAC_PluginCache::getCacheUrl() . $cache->getname();
776
+ }
777
+ }
778
+
779
+ /**
780
+ * Returns the content.
781
+ *
782
+ * @return string
783
+ */
784
+ public function getContent()
785
+ {
786
+ // restore IE hacks.
787
+ $this->content = $this->restoreIehacks( $this->content );
788
+
789
+ // restore comments.
790
+ $this->content = $this->restoreComments( $this->content );
791
+
792
+ // restore (no)script.
793
+ $this->content = $this->restoreMarkedContent( 'SCRIPT', $this->content );
794
+
795
+ // Restore noptimize.
796
+ $this->content = $this->restoreNoptimize( $this->content );
797
+
798
+ $preloadCssBlock = '';
799
+ $noScriptCssBlock = '';
800
+
801
+ // Restore the full content.
802
+ if ( ! empty( $this->restofcontent ) ) {
803
+ $this->content .= $this->restofcontent;
804
+ $this->restofcontent = '';
805
+ }
806
+
807
+ // Inject the new stylesheets.
808
+ $replaceTag = array( '<title', 'before' );
809
+ $replaceTag = apply_filters( 'wmac_filter_css_replacetag', $replaceTag, $this->content );
810
+
811
+ if ( $this->inline ) {
812
+ foreach ( $this->csscode as $media => $code ) {
813
+ $this->injectInHtml( '<style type="text/css" media="' . $media . '">' . $code . '</style>', $replaceTag );
814
+ }
815
+ } else {
816
+ if ( $this->defer ) {
817
+ $preloadCssBlock = '';
818
+ $noScriptCssBlock = "<noscript id=\"aonoscrcss\">";
819
+
820
+ /*$defer_inline_code = $this->defer_inline;
821
+ if ( ! empty( $defer_inline_code ) ) {
822
+ if ( apply_filters( 'wmac_filter_css_critcss_minify', true ) ) {
823
+ $iCssHash = md5( $defer_inline_code );
824
+ $iCssCache = new WMAC_PluginCache( $iCssHash, 'css' );
825
+ if ( $iCssCache->check() ) {
826
+ // we have the optimized inline CSS in cache.
827
+ $defer_inline_code = $iCssCache->retrieve();
828
+ } else {
829
+ $cssmin = new WMAC_PluginCSSmin();
830
+ $tmp_code = trim( $cssmin->run( $defer_inline_code ) );
831
+
832
+ if ( ! empty( $tmp_code ) ) {
833
+ $defer_inline_code = $tmp_code;
834
+ $iCssCache->cache( $defer_inline_code, 'text/css' );
835
+ unset( $tmp_code );
836
+ }
837
+ }
838
+ }
839
+ $code_out = '<style type="text/css" id="aoatfcss" media="all">' . $defer_inline_code . '</style>';
840
+ $this->injectInHtml( $code_out, $replaceTag );
841
+ }*/
842
+ }
843
+
844
+ foreach ( $this->url as $media => $url ) {
845
+ // Add the stylesheet either deferred (import at bottom) or normal links in head.
846
+ if ( $this->defer ) {
847
+ $preloadOnLoad = $this->getAoCssPreloadOnload();
848
+
849
+ $preloadCssBlock .= '<link rel="preload" as="style" media="' . $media . '" href="' . $url . '" onload="' . $preloadOnLoad . '" />';
850
+ $noScriptCssBlock .= '<link type="text/css" media="' . $media . '" href="' . $url . '" rel="stylesheet" />';
851
+ } else {
852
+ // $this->inject_in_html('<link type="text/css" media="' . $media . '" href="' . $url . '" rel="stylesheet" />', $replaceTag);
853
+ if ( strlen( $this->csscode[$media] ) > $this->cssinlinesize ) {
854
+ $this->injectInHtml( '<link type="text/css" media="' . $media . '" href="' . $url . '" rel="stylesheet" />', $replaceTag );
855
+ } elseif ( strlen( $this->csscode[$media] ) > 0 ) {
856
+ $this->injectInHtml( '<style type="text/css" media="' . $media . '">' . $this->csscode[$media] . '</style>', $replaceTag );
857
+ }
858
+ }
859
+ }
860
+
861
+ if ( $this->defer ) {
862
+ $preload_polyfill = $this->getAoCssPreloadPolyfill();
863
+ $noScriptCssBlock .= '</noscript>';
864
+ $this->injectInHtml( $preloadCssBlock . $noScriptCssBlock, $replaceTag );
865
+
866
+ // Adds preload polyfill at end of body tag.
867
+ $this->injectInHtml(
868
+ apply_filters( 'wmac_css_preload_polyfill', $preload_polyfill ),
869
+ array( '</body>', 'before' )
870
+ );
871
+ }
872
+ }
873
+
874
+ // Return the modified stylesheet.
875
+ return $this->content;
876
+ }
877
+
878
+ /**
879
+ * @param $file
880
+ * @param $code
881
+ *
882
+ * @return mixed|string
883
+ */
884
+ static function fixUrls( $file, $code )
885
+ {
886
+ // Switch all imports to the url() syntax.
887
+ $code = preg_replace( '#@import ("|\')(.+?)\.css.*?("|\')#', '@import url("${2}.css")', $code );
888
+
889
+ if ( preg_match_all( self::ASSETS_REGEX, $code, $matches ) ) {
890
+ $file = str_replace( WMAC_ROOT_DIR, '/', $file );
891
+ /**
892
+ * rollback as per https://github.com/futtta/autoptimize/issues/94
893
+ * $file = str_replace( WMAC_WP_CONTENT_NAME, '', $file );
894
+ */
895
+ $dir = dirname( $file ); // Like /themes/expound/css.
896
+
897
+ /**
898
+ * $dir should not contain backslashes, since it's used to replace
899
+ * urls, but it can contain them when running on Windows because
900
+ * fixUrls() is sometimes called with `ABSPATH . 'index.php'`
901
+ */
902
+ $dir = str_replace( '\\', '/', $dir );
903
+ unset( $file ); // not used below at all.
904
+
905
+ $replace = array();
906
+ foreach ( $matches[1] as $k => $url ) {
907
+ // Remove quotes.
908
+ $url = trim( $url, " \t\n\r\0\x0B\"'" );
909
+ $noQurl = trim( $url, "\"'" );
910
+ if ( $url !== $noQurl ) {
911
+ $removedQuotes = true;
912
+ } else {
913
+ $removedQuotes = false;
914
+ }
915
+
916
+ if ( '' === $noQurl ) {
917
+ continue;
918
+ }
919
+
920
+ $url = $noQurl;
921
+ if ( '/' === $url{0} || preg_match( '#^(https?://|ftp://|data:)#i', $url ) ) {
922
+ // URL is protocol-relative, host-relative or something we don't touch.
923
+ continue;
924
+ } else {
925
+ // Relative URL.
926
+ /**
927
+ * rollback as per https://github.com/futtta/autoptimize/issues/94
928
+ * $newurl = preg_replace( '/https?:/', '', str_replace( ' ', '%20', WMAC_PluginMain::getContentUrl() . str_replace( '//', '/', $dir . '/' . $url ) ) );
929
+ */
930
+ $newurl = preg_replace( '/https?:/', '', str_replace( ' ', '%20', WMAC_WP_ROOT_URL . str_replace( '//', '/', $dir . '/' . $url ) ) );
931
+
932
+ /**
933
+ * Hash the url + whatever was behind potentially for replacement
934
+ * We must do this, or different css classes referencing the same bg image (but
935
+ * different parts of it, say, in sprites and such) loose their stuff...
936
+ */
937
+ $hash = md5( $url . $matches[2][$k] );
938
+ $code = str_replace( $matches[0][$k], $hash, $code );
939
+
940
+ if ( $removedQuotes ) {
941
+ $replace[$hash] = "url('" . $newurl . "')" . $matches[2][$k];
942
+ } else {
943
+ $replace[$hash] = 'url(' . $newurl . ')' . $matches[2][$k];
944
+ }
945
+ }
946
+ }
947
+
948
+ $code = self::replaceLongestMatchesFirst( $code, $replace );
949
+ }
950
+
951
+ return $code;
952
+ }
953
+
954
+ /**
955
+ * @param $tag
956
+ *
957
+ * @return bool
958
+ */
959
+ private function isMovable( $tag )
960
+ {
961
+ if ( ! $this->aggregate ) {
962
+ return false;
963
+ }
964
+
965
+ if ( ! empty( $this->whitelist ) ) {
966
+ foreach ( $this->whitelist as $match ) {
967
+ if ( false !== strpos( $tag, $match ) ) {
968
+ return true;
969
+ }
970
+ }
971
+ // no match with whitelist.
972
+ return false;
973
+ } else {
974
+ if ( is_array( $this->dontmove ) && ! empty( $this->dontmove ) ) {
975
+ foreach ( $this->dontmove as $match ) {
976
+ if ( false !== strpos( $tag, $match ) ) {
977
+ // Matched something.
978
+ return false;
979
+ }
980
+ }
981
+ }
982
+
983
+ // If we're here it's safe to move.
984
+ return true;
985
+ }
986
+ }
987
+
988
+ /**
989
+ * @param $cssPath
990
+ * @param $css
991
+ *
992
+ * @return bool
993
+ */
994
+ private function canInjectLate( $cssPath, $css )
995
+ {
996
+ $consider_minified_array = apply_filters( 'wmac_filter_css_consider_minified', false, $cssPath );
997
+ if ( true !== $this->inject_min_late ) {
998
+ // late-inject turned off.
999
+ return false;
1000
+ } elseif (
1001
+ ( false === strpos( $cssPath, 'min.css' ) )
1002
+ && ( str_replace( $consider_minified_array, '', $cssPath ) === $cssPath )
1003
+ ) {
1004
+ // file not minified based on filename & filter.
1005
+ return false;
1006
+ } elseif ( false !== strpos( $css, '@import' ) ) {
1007
+ // can't late-inject files with imports as those need to be aggregated.
1008
+ return false;
1009
+ } elseif (
1010
+ ( $this->datauris == true )
1011
+ && preg_match( '#background[^;}]*url\(#Ui', $css )
1012
+ ) {
1013
+ // don't late-inject CSS with images if image inlining is on.
1014
+ return false;
1015
+ } else {
1016
+ // phew, all is safe, we can late-inject.
1017
+ return true;
1018
+ }
1019
+ }
1020
+
1021
+ /**
1022
+ * Minifies a single local css file
1023
+ * and returns its (cached) url.
1024
+ *
1025
+ * @param string $filepath Filepath.
1026
+ * @param bool $cache_miss Optional. Force a cache miss. Default false.
1027
+ *
1028
+ * @return bool|string Url pointing to the minified css file or false.
1029
+ */
1030
+ public function minifySingle( $filepath, $cache_miss = false )
1031
+ {
1032
+ $contents = $this->prepareMinifySingle( $filepath );
1033
+
1034
+ if ( empty( $contents ) ) {
1035
+ return false;
1036
+ }
1037
+
1038
+ // Check cache.
1039
+ $hash = 'single_' . md5( $contents );
1040
+ $cache = new WMAC_PluginCache( $hash, 'css' );
1041
+
1042
+ // If not in cache already, minify...
1043
+ if ( ! $cache->check() || $cache_miss ) {
1044
+ // Fixurls...
1045
+ $contents = self::fixUrls( $filepath, $contents );
1046
+ // replace any referenced assets if needed...
1047
+ $contents = $this->replaceUrls( $contents );
1048
+ // Now minify...
1049
+ $cssmin = new WMAC_PluginCSSmin();
1050
+ $contents = trim( $cssmin->run( $contents ) );
1051
+ // Store in cache.
1052
+ $cache->cache( $contents, 'text/css' );
1053
+ }
1054
+
1055
+ $url = $this->buildMinifySingleUrl( $cache );
1056
+
1057
+ return $url;
1058
+ }
1059
+
1060
+ /**
1061
+ * Returns preload JS onload handler.
1062
+ *
1063
+ * @return string
1064
+ */
1065
+ public function getAoCssPreloadOnload()
1066
+ {
1067
+ $preload_onload = apply_filters('wmac_filter_css_preload_onload',"this.onload=null;this.rel='stylesheet'");
1068
+ return $preload_onload;
1069
+ }
1070
+
1071
+ /**
1072
+ * Returns preload polyfill JS.
1073
+ *
1074
+ * @return string
1075
+ */
1076
+ public function getAoCssPreloadPolyfill()
1077
+ {
1078
+ $preload_poly = apply_filters('autoptimize_css_preload_polyfill','<script data-cfasync=\'false\'>!function(t){"use strict";t.loadCSS||(t.loadCSS=function(){});var e=loadCSS.relpreload={};if(e.support=function(){var e;try{e=t.document.createElement("link").relList.supports("preload")}catch(t){e=!1}return function(){return e}}(),e.bindMediaToggle=function(t){function e(){t.media=a}var a=t.media||"all";t.addEventListener?t.addEventListener("load",e):t.attachEvent&&t.attachEvent("onload",e),setTimeout(function(){t.rel="stylesheet",t.media="only x"}),setTimeout(e,3e3)},e.poly=function(){if(!e.support())for(var a=t.document.getElementsByTagName("link"),n=0;n<a.length;n++){var o=a[n];"preload"!==o.rel||"style"!==o.getAttribute("as")||o.getAttribute("data-loadcss")||(o.setAttribute("data-loadcss",!0),e.bindMediaToggle(o))}},!e.support()){e.poly();var a=t.setInterval(e.poly,500);t.addEventListener?t.addEventListener("load",function(){e.poly(),t.clearInterval(a)}):t.attachEvent&&t.attachEvent("onload",function(){e.poly(),t.clearInterval(a)})}"undefined"!=typeof exports?exports.loadCSS=loadCSS:t.loadCSS=loadCSS}("undefined"!=typeof global?global:this);</script>');
1079
+ return $preload_poly;
1080
+ }
1081
+
1082
+ /**
1083
+ * Returns whether we're doing aggregation or not.
1084
+ *
1085
+ * @return bool
1086
+ */
1087
+ public function aggregating()
1088
+ {
1089
+ return $this->aggregate;
1090
+ }
1091
+
1092
+ /**
1093
+ * @return array
1094
+ */
1095
+ public function getOptions()
1096
+ {
1097
+ return $this->options;
1098
+ }
1099
+
1100
+ /**
1101
+ * @param $options
1102
+ */
1103
+ public function replaceOptions( $options )
1104
+ {
1105
+ $this->options = $options;
1106
+ }
1107
+
1108
+ /**
1109
+ * @param $name
1110
+ * @param $value
1111
+ */
1112
+ public function setOption( $name, $value )
1113
+ {
1114
+ $this->options[$name] = $value;
1115
+ $this->$name = $value;
1116
+ }
1117
+
1118
+ /**
1119
+ * @param $name
1120
+ *
1121
+ * @return mixed
1122
+ */
1123
+ public function getOption( $name )
1124
+ {
1125
+ return $this->options[$name];
1126
+ }
1127
+ }
components/minify-and-combine/includes/classes/ext/php/jsmin.php ADDED
@@ -0,0 +1,472 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * JSMin.php - modified PHP implementation of Douglas Crockford's JSMin.
4
+ *
5
+ * <code>
6
+ * $minifiedJs = WMAC\JSMin::minify($js);
7
+ * </code>
8
+ *
9
+ * This is a modified port of jsmin.c. Improvements:
10
+ *
11
+ * Does not choke on some regexp literals containing quote characters. E.g. /'/
12
+ *
13
+ * Spaces are preserved after some add/sub operators, so they are not mistakenly
14
+ * converted to post-inc/dec. E.g. a + ++b -> a+ ++b
15
+ *
16
+ * Preserves multi-line comments that begin with /*!
17
+ *
18
+ * PHP 5 or higher is required.
19
+ *
20
+ * Permission is hereby granted to use this version of the library under the
21
+ * same terms as jsmin.c, which has the following license:
22
+ *
23
+ * --
24
+ * Copyright (c) 2002 Douglas Crockford (www.crockford.com)
25
+ *
26
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
27
+ * this software and associated documentation files (the "Software"), to deal in
28
+ * the Software without restriction, including without limitation the rights to
29
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
30
+ * of the Software, and to permit persons to whom the Software is furnished to do
31
+ * so, subject to the following conditions:
32
+ *
33
+ * The above copyright notice and this permission notice shall be included in all
34
+ * copies or substantial portions of the Software.
35
+ *
36
+ * The Software shall be used for Good, not Evil.
37
+ *
38
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
39
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
40
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
41
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
42
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
43
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
44
+ * SOFTWARE.
45
+ * --
46
+ *
47
+ * @package JSMin
48
+ * @author Ryan Grove <ryan@wonko.com> (PHP port)
49
+ * @author Steve Clay <steve@mrclay.org> (modifications + cleanup)
50
+ * @author Andrea Giammarchi <http://www.3site.eu> (spaceBeforeRegExp)
51
+ * @copyright 2002 Douglas Crockford <douglas@crockford.com> (jsmin.c)
52
+ * @copyright 2008 Ryan Grove <ryan@wonko.com> (PHP port)
53
+ * @license http://opensource.org/licenses/mit-license.php MIT License
54
+ * @link http://code.google.com/p/jsmin-php/
55
+ */
56
+
57
+ // This is from https://github.com/mrclay/jsmin-php 2.3.2
58
+
59
+ namespace WMAC;
60
+
61
+ if( !defined('ABSPATH') ) {
62
+ exit;
63
+ }
64
+
65
+
66
+ class JSMin {
67
+
68
+ const ORD_LF = 10;
69
+ const ORD_SPACE = 32;
70
+ const ACTION_KEEP_A = 1;
71
+ const ACTION_DELETE_A = 2;
72
+ const ACTION_DELETE_A_B = 3;
73
+
74
+ protected $a = "\n";
75
+ protected $b = '';
76
+ protected $input = '';
77
+ protected $inputIndex = 0;
78
+ protected $inputLength = 0;
79
+ protected $lookAhead = null;
80
+ protected $output = '';
81
+ protected $lastByteOut = '';
82
+ protected $keptComment = '';
83
+
84
+ /**
85
+ * Minify Javascript.
86
+ *
87
+ * @param string $js Javascript to be minified
88
+ *
89
+ * @return string
90
+ */
91
+ public static function minify($js)
92
+ {
93
+ $jsmin = new JSMin($js);
94
+
95
+ return $jsmin->min();
96
+ }
97
+
98
+ /**
99
+ * @param string $input
100
+ */
101
+ public function __construct($input)
102
+ {
103
+ $this->input = $input;
104
+ }
105
+
106
+ /**
107
+ * Perform minification, return result
108
+ *
109
+ * @return string
110
+ */
111
+ public function min()
112
+ {
113
+ if( $this->output !== '' ) { // min already run
114
+ return $this->output;
115
+ }
116
+
117
+ $mbIntEnc = null;
118
+ if( function_exists('mb_strlen') && ((int)ini_get('mbstring.func_overload') & 2) ) {
119
+ $mbIntEnc = mb_internal_encoding();
120
+ mb_internal_encoding('8bit');
121
+ }
122
+
123
+ if( isset($this->input[0]) && $this->input[0] === "\xef" ) {
124
+ $this->input = substr($this->input, 3);
125
+ }
126
+
127
+ $this->input = str_replace("\r\n", "\n", $this->input);
128
+ $this->inputLength = strlen($this->input);
129
+
130
+ $this->action(self::ACTION_DELETE_A_B);
131
+
132
+ while( $this->a !== null ) {
133
+ // determine next command
134
+ $command = self::ACTION_KEEP_A; // default
135
+ if( $this->a === ' ' ) {
136
+ if( ($this->lastByteOut === '+' || $this->lastByteOut === '-') && ($this->b === $this->lastByteOut) ) {
137
+ // Don't delete this space. If we do, the addition/subtraction
138
+ // could be parsed as a post-increment
139
+ } elseif( !$this->isAlphaNum($this->b) ) {
140
+ $command = self::ACTION_DELETE_A;
141
+ }
142
+ } elseif( $this->a === "\n" ) {
143
+ if( $this->b === ' ' ) {
144
+ $command = self::ACTION_DELETE_A_B;
145
+
146
+ // in case of mbstring.func_overload & 2, must check for null b,
147
+ // otherwise mb_strpos will give WARNING
148
+ } elseif( $this->b === null || (false === strpos('{[(+-!~', $this->b) && !$this->isAlphaNum($this->b)) ) {
149
+ $command = self::ACTION_DELETE_A;
150
+ }
151
+ } elseif( !$this->isAlphaNum($this->a) ) {
152
+ if( $this->b === ' ' || ($this->b === "\n" && (false === strpos('}])+-"\'', $this->a))) ) {
153
+ $command = self::ACTION_DELETE_A_B;
154
+ }
155
+ }
156
+ $this->action($command);
157
+ }
158
+ $this->output = trim($this->output);
159
+
160
+ if( $mbIntEnc !== null ) {
161
+ mb_internal_encoding($mbIntEnc);
162
+ }
163
+
164
+ return $this->output;
165
+ }
166
+
167
+ /**
168
+ * ACTION_KEEP_A = Output A. Copy B to A. Get the next B.
169
+ * ACTION_DELETE_A = Copy B to A. Get the next B.
170
+ * ACTION_DELETE_A_B = Get the next B.
171
+ *
172
+ * @param int $command
173
+ * @throws JSMin_UnterminatedRegExpException|JSMin_UnterminatedStringException
174
+ */
175
+ protected function action($command)
176
+ {
177
+ // make sure we don't compress "a + ++b" to "a+++b", etc.
178
+ if( $command === self::ACTION_DELETE_A_B && $this->b === ' ' && ($this->a === '+' || $this->a === '-') ) {
179
+ // Note: we're at an addition/substraction operator; the inputIndex
180
+ // will certainly be a valid index
181
+ if( $this->input[$this->inputIndex] === $this->a ) {
182
+ // This is "+ +" or "- -". Don't delete the space.
183
+ $command = self::ACTION_KEEP_A;
184
+ }
185
+ }
186
+
187
+ switch( $command ) {
188
+ case self::ACTION_KEEP_A: // 1
189
+ $this->output .= $this->a;
190
+
191
+ if( $this->keptComment ) {
192
+ $this->output = rtrim($this->output, "\n");
193
+ $this->output .= $this->keptComment;
194
+ $this->keptComment = '';
195
+ }
196
+
197
+ $this->lastByteOut = $this->a;
198
+
199
+ // fallthrough intentional
200
+ case self::ACTION_DELETE_A: // 2
201
+ $this->a = $this->b;
202
+ if( $this->a === "'" || $this->a === '"' ) { // string literal
203
+ $str = $this->a; // in case needed for exception
204
+ for(; ;) {
205
+ $this->output .= $this->a;
206
+ $this->lastByteOut = $this->a;
207
+
208
+ $this->a = $this->get();
209
+ if( $this->a === $this->b ) { // end quote
210
+ break;
211
+ }
212
+ if( $this->isEOF($this->a) ) {
213
+ $byte = $this->inputIndex - 1;
214
+ throw new JSMin_UnterminatedStringException("WMAC\JSMin: Unterminated String at byte {$byte}: {$str}");
215
+ }
216
+ $str .= $this->a;
217
+ if( $this->a === '\\' ) {
218
+ $this->output .= $this->a;
219
+ $this->lastByteOut = $this->a;
220
+
221
+ $this->a = $this->get();
222
+ $str .= $this->a;
223
+ }
224
+ }
225
+ }
226
+
227
+ // fallthrough intentional
228
+ case self::ACTION_DELETE_A_B: // 3
229
+ $this->b = $this->next();
230
+ if( $this->b === '/' && $this->isRegexpLiteral() ) {
231
+ $this->output .= $this->a . $this->b;
232
+ $pattern = '/'; // keep entire pattern in case we need to report it in the exception
233
+ for(; ;) {
234
+ $this->a = $this->get();
235
+ $pattern .= $this->a;
236
+ if( $this->a === '[' ) {
237
+ for(; ;) {
238
+ $this->output .= $this->a;
239
+ $this->a = $this->get();
240
+ $pattern .= $this->a;
241
+ if( $this->a === ']' ) {
242
+ break;
243
+ }
244
+ if( $this->a === '\\' ) {
245
+ $this->output .= $this->a;
246
+ $this->a = $this->get();
247
+ $pattern .= $this->a;
248
+ }
249
+ if( $this->isEOF($this->a) ) {
250
+ throw new JSMin_UnterminatedRegExpException("WMAC\JSMin: Unterminated set in RegExp at byte " . $this->inputIndex . ": {$pattern}");
251
+ }
252
+ }
253
+ }
254
+
255
+ if( $this->a === '/' ) { // end pattern
256
+ break; // while (true)
257
+ } elseif( $this->a === '\\' ) {
258
+ $this->output .= $this->a;
259
+ $this->a = $this->get();
260
+ $pattern .= $this->a;
261
+ } elseif( $this->isEOF($this->a) ) {
262
+ $byte = $this->inputIndex - 1;
263
+ throw new JSMin_UnterminatedRegExpException("WMAC\JSMin: Unterminated RegExp at byte {$byte}: {$pattern}");
264
+ }
265
+ $this->output .= $this->a;
266
+ $this->lastByteOut = $this->a;
267
+ }
268
+ $this->b = $this->next();
269
+ }
270
+ // end case ACTION_DELETE_A_B
271
+ }
272
+ }
273
+
274
+ /**
275
+ * @return bool
276
+ */
277
+ protected function isRegexpLiteral()
278
+ {
279
+ if( false !== strpos("(,=:[!&|?+-~*{;", $this->a) ) {
280
+ // we can't divide after these tokens
281
+ return true;
282
+ }
283
+
284
+ // check if first non-ws token is "/" (see starts-regex.js)
285
+ $length = strlen($this->output);
286
+ if( $this->a === ' ' || $this->a === "\n" ) {
287
+ if( $length < 2 ) { // weird edge case
288
+ return true;
289
+ }
290
+ }
291
+
292
+ // if the "/" follows a keyword, it must be a regexp, otherwise it's best to assume division
293
+
294
+ $subject = $this->output . trim($this->a);
295
+ if( !preg_match('/(?:case|else|in|return|typeof)$/', $subject, $m) ) {
296
+ // not a keyword
297
+ return false;
298
+ }
299
+
300
+ // can't be sure it's a keyword yet (see not-regexp.js)
301
+ $charBeforeKeyword = substr($subject, 0 - strlen($m[0]) - 1, 1);
302
+ if( $this->isAlphaNum($charBeforeKeyword) ) {
303
+ // this is really an identifier ending in a keyword, e.g. "xreturn"
304
+ return false;
305
+ }
306
+
307
+ // it's a regexp. Remove unneeded whitespace after keyword
308
+ if( $this->a === ' ' || $this->a === "\n" ) {
309
+ $this->a = '';
310
+ }
311
+
312
+ return true;
313
+ }
314
+
315
+ /**
316
+ * Return the next character from stdin. Watch out for lookahead. If the character is a control character,
317
+ * translate it to a space or linefeed.
318
+ *
319
+ * @return string
320
+ */
321
+ protected function get()
322
+ {
323
+ $c = $this->lookAhead;
324
+ $this->lookAhead = null;
325
+ if( $c === null ) {
326
+ // getc(stdin)
327
+ if( $this->inputIndex < $this->inputLength ) {
328
+ $c = $this->input[$this->inputIndex];
329
+ $this->inputIndex += 1;
330
+ } else {
331
+ $c = null;
332
+ }
333
+ }
334
+ if( ord($c) >= self::ORD_SPACE || $c === "\n" || $c === null ) {
335
+ return $c;
336
+ }
337
+ if( $c === "\r" ) {
338
+ return "\n";
339
+ }
340
+
341
+ return ' ';
342
+ }
343
+
344
+ /**
345
+ * Does $a indicate end of input?
346
+ *
347
+ * @param string $a
348
+ * @return bool
349
+ */
350
+ protected function isEOF($a)
351
+ {
352
+ return ord($a) <= self::ORD_LF;
353
+ }
354
+
355
+ /**
356
+ * Get next char (without getting it). If is ctrl character, translate to a space or newline.
357
+ *
358
+ * @return string
359
+ */
360
+ protected function peek()
361
+ {
362
+ $this->lookAhead = $this->get();
363
+
364
+ return $this->lookAhead;
365
+ }
366
+
367
+ /**
368
+ * Return true if the character is a letter, digit, underscore, dollar sign, or non-ASCII character.
369
+ *
370
+ * @param string $c
371
+ *
372
+ * @return bool
373
+ */
374
+ protected function isAlphaNum($c)
375
+ {
376
+ return (preg_match('/^[a-z0-9A-Z_\\$\\\\]$/', $c) || ord($c) > 126);
377
+ }
378
+
379
+ /**
380
+ * Consume a single line comment from input (possibly retaining it)
381
+ */
382
+ protected function consumeSingleLineComment()
383
+ {
384
+ $comment = '';
385
+ while( true ) {
386
+ $get = $this->get();
387
+ $comment .= $get;
388
+ if( ord($get) <= self::ORD_LF ) { // end of line reached
389
+ // if IE conditional comment
390
+ if( preg_match('/^\\/@(?:cc_on|if|elif|else|end)\\b/', $comment) ) {
391
+ $this->keptComment .= "/{$comment}";
392
+ }
393
+
394
+ return;
395
+ }
396
+ }
397
+ }
398
+
399
+ /**
400
+ * Consume a multiple line comment from input (possibly retaining it)
401
+ *
402
+ * @throws JSMin_UnterminatedCommentException
403
+ */
404
+ protected function consumeMultipleLineComment()
405
+ {
406
+ $this->get();
407
+ $comment = '';
408
+ for(; ;) {
409
+ $get = $this->get();
410
+ if( $get === '*' ) {
411
+ if( $this->peek() === '/' ) { // end of comment reached
412
+ $this->get();
413
+ if( 0 === strpos($comment, '!') ) {
414
+ // preserved by YUI Compressor
415
+ if( !$this->keptComment ) {
416
+ // don't prepend a newline if two comments right after one another
417
+ $this->keptComment = "\n";
418
+ }
419
+ $this->keptComment .= "/*!" . substr($comment, 1) . "*/\n";
420
+ } else if( preg_match('/^@(?:cc_on|if|elif|else|end)\\b/', $comment) ) {
421
+ // IE conditional
422
+ $this->keptComment .= "/*{$comment}*/";
423
+ }
424
+
425
+ return;
426
+ }
427
+ } elseif( $get === null ) {
428
+ throw new JSMin_UnterminatedCommentException("WMAC\\JSMin: Unterminated comment at byte {$this->inputIndex}: /*{$comment}");
429
+ }
430
+ $comment .= $get;
431
+ }
432
+ }
433
+
434
+ /**
435
+ * Get the next character, skipping over comments. Some comments may be preserved.
436
+ *
437
+ * @return string
438
+ */
439
+ protected function next()
440
+ {
441
+ $get = $this->get();
442
+ if( $get === '/' ) {
443
+ switch( $this->peek() ) {
444
+ case '/':
445
+ $this->consumeSingleLineComment();
446
+ $get = "\n";
447
+ break;
448
+ case '*':
449
+ $this->consumeMultipleLineComment();
450
+ $get = ' ';
451
+ break;
452
+ }
453
+ }
454
+
455
+ return $get;
456
+ }
457
+ }
458
+
459
+ class JSMin_UnterminatedStringException extends \Exception {
460
+
461
+ }
462
+
463
+
464
+ class JSMin_UnterminatedCommentException extends \Exception {
465
+
466
+ }
467
+
468
+
469
+ class JSMin_UnterminatedRegExpException extends \Exception {
470
+
471
+ }
472
+
components/minify-and-combine/includes/classes/ext/php/yui-php-cssmin-bundled/Colors.php ADDED
@@ -0,0 +1,159 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WMAC\tubalmartin\CssMin;
4
+
5
+ if( !defined('ABSPATH') ) {
6
+ exit;
7
+ }
8
+
9
+ class Colors {
10
+
11
+ public static function getHexToNamedMap()
12
+ {
13
+ // Hex colors longer than named counterpart
14
+ return array(
15
+ '#f0ffff' => 'azure',
16
+ '#f5f5dc' => 'beige',
17
+ '#ffe4c4' => 'bisque',
18
+ '#a52a2a' => 'brown',
19
+ '#ff7f50' => 'coral',
20
+ '#ffd700' => 'gold',
21
+ '#808080' => 'gray',
22
+ '#008000' => 'green',
23
+ '#4b0082' => 'indigo',
24
+ '#fffff0' => 'ivory',
25
+ '#f0e68c' => 'khaki',
26
+ '#faf0e6' => 'linen',
27
+ '#800000' => 'maroon',
28
+ '#000080' => 'navy',
29
+ '#fdf5e6' => 'oldlace',
30
+ '#808000' => 'olive',
31
+ '#ffa500' => 'orange',
32
+ '#da70d6' => 'orchid',
33
+ '#cd853f' => 'peru',
34
+ '#ffc0cb' => 'pink',
35
+ '#dda0dd' => 'plum',
36
+ '#800080' => 'purple',
37
+ '#f00' => 'red',
38
+ '#fa8072' => 'salmon',
39
+ '#a0522d' => 'sienna',
40
+ '#c0c0c0' => 'silver',
41
+ '#fffafa' => 'snow',
42
+ '#d2b48c' => 'tan',
43
+ '#008080' => 'teal',
44
+ '#ff6347' => 'tomato',
45
+ '#ee82ee' => 'violet',
46
+ '#f5deb3' => 'wheat'
47
+ );
48
+ }
49
+
50
+ public static function getNamedToHexMap()
51
+ {
52
+ // Named colors longer than hex counterpart
53
+ return array(
54
+ 'aliceblue' => '#f0f8ff',
55
+ 'antiquewhite' => '#faebd7',
56
+ 'aquamarine' => '#7fffd4',
57
+ 'black' => '#000',
58
+ 'blanchedalmond' => '#ffebcd',
59
+ 'blueviolet' => '#8a2be2',
60
+ 'burlywood' => '#deb887',
61
+ 'cadetblue' => '#5f9ea0',
62
+ 'chartreuse' => '#7fff00',
63
+ 'chocolate' => '#d2691e',
64
+ 'cornflowerblue' => '#6495ed',
65
+ 'cornsilk' => '#fff8dc',
66
+ 'darkblue' => '#00008b',
67
+ 'darkcyan' => '#008b8b',
68
+ 'darkgoldenrod' => '#b8860b',
69
+ 'darkgray' => '#a9a9a9',
70
+ 'darkgreen' => '#006400',
71
+ 'darkgrey' => '#a9a9a9',
72
+ 'darkkhaki' => '#bdb76b',
73
+ 'darkmagenta' => '#8b008b',
74
+ 'darkolivegreen' => '#556b2f',
75
+ 'darkorange' => '#ff8c00',
76
+ 'darkorchid' => '#9932cc',
77
+ 'darksalmon' => '#e9967a',
78
+ 'darkseagreen' => '#8fbc8f',
79
+ 'darkslateblue' => '#483d8b',
80
+ 'darkslategray' => '#2f4f4f',
81
+ 'darkslategrey' => '#2f4f4f',
82
+ 'darkturquoise' => '#00ced1',
83
+ 'darkviolet' => '#9400d3',
84
+ 'deeppink' => '#ff1493',
85
+ 'deepskyblue' => '#00bfff',
86
+ 'dodgerblue' => '#1e90ff',
87
+ 'firebrick' => '#b22222',
88
+ 'floralwhite' => '#fffaf0',
89
+ 'forestgreen' => '#228b22',
90
+ 'fuchsia' => '#f0f',
91
+ 'gainsboro' => '#dcdcdc',
92
+ 'ghostwhite' => '#f8f8ff',
93
+ 'goldenrod' => '#daa520',
94
+ 'greenyellow' => '#adff2f',
95
+ 'honeydew' => '#f0fff0',
96
+ 'indianred' => '#cd5c5c',
97
+ 'lavender' => '#e6e6fa',
98
+ 'lavenderblush' => '#fff0f5',
99
+ 'lawngreen' => '#7cfc00',
100
+ 'lemonchiffon' => '#fffacd',
101
+ 'lightblue' => '#add8e6',
102
+ 'lightcoral' => '#f08080',
103
+ 'lightcyan' => '#e0ffff',
104
+ 'lightgoldenrodyellow' => '#fafad2',
105
+ 'lightgray' => '#d3d3d3',
106
+ 'lightgreen' => '#90ee90',
107
+ 'lightgrey' => '#d3d3d3',
108
+ 'lightpink' => '#ffb6c1',
109
+ 'lightsalmon' => '#ffa07a',
110
+ 'lightseagreen' => '#20b2aa',
111
+ 'lightskyblue' => '#87cefa',
112
+ 'lightslategray' => '#778899',
113
+ 'lightslategrey' => '#778899',
114
+ 'lightsteelblue' => '#b0c4de',
115
+ 'lightyellow' => '#ffffe0',
116
+ 'limegreen' => '#32cd32',
117
+ 'mediumaquamarine' => '#66cdaa',
118
+ 'mediumblue' => '#0000cd',
119
+ 'mediumorchid' => '#ba55d3',
120
+ 'mediumpurple' => '#9370db',
121
+ 'mediumseagreen' => '#3cb371',
122
+ 'mediumslateblue' => '#7b68ee',
123
+ 'mediumspringgreen' => '#00fa9a',
124
+ 'mediumturquoise' => '#48d1cc',
125
+ 'mediumvioletred' => '#c71585',
126
+ 'midnightblue' => '#191970',
127
+ 'mintcream' => '#f5fffa',
128
+ 'mistyrose' => '#ffe4e1',
129
+ 'moccasin' => '#ffe4b5',
130
+ 'navajowhite' => '#ffdead',
131
+ 'olivedrab' => '#6b8e23',
132
+ 'orangered' => '#ff4500',
133
+ 'palegoldenrod' => '#eee8aa',
134
+ 'palegreen' => '#98fb98',
135
+ 'paleturquoise' => '#afeeee',
136
+ 'palevioletred' => '#db7093',
137
+ 'papayawhip' => '#ffefd5',
138
+ 'peachpuff' => '#ffdab9',
139
+ 'powderblue' => '#b0e0e6',
140
+ 'rebeccapurple' => '#663399',
141
+ 'rosybrown' => '#bc8f8f',
142
+ 'royalblue' => '#4169e1',
143
+ 'saddlebrown' => '#8b4513',
144
+ 'sandybrown' => '#f4a460',
145
+ 'seagreen' => '#2e8b57',
146
+ 'seashell' => '#fff5ee',
147
+ 'slateblue' => '#6a5acd',
148
+ 'slategray' => '#708090',
149
+ 'slategrey' => '#708090',
150
+ 'springgreen' => '#00ff7f',
151
+ 'steelblue' => '#4682b4',
152
+ 'turquoise' => '#40e0d0',
153
+ 'white' => '#fff',
154
+ 'whitesmoke' => '#f5f5f5',
155
+ 'yellow' => '#ff0',
156
+ 'yellowgreen' => '#9acd32'
157
+ );
158
+ }
159
+ }
components/minify-and-combine/includes/classes/ext/php/yui-php-cssmin-bundled/Minifier.php ADDED
@@ -0,0 +1,864 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*!
4
+ * CssMin
5
+ * Author: Tubal Martin - http://tubalmartin.me/
6
+ * Repo: https://github.com/tubalmartin/YUI-CSS-compressor-PHP-port
7
+ *
8
+ * This is a PHP port of the CSS minification tool distributed with YUICompressor,
9
+ * itself a port of the cssmin utility by Isaac Schlueter - http://foohack.com/
10
+ * Permission is hereby granted to use the PHP version under the same
11
+ * conditions as the YUICompressor.
12
+ */
13
+
14
+ /*!
15
+ * YUI Compressor
16
+ * http://developer.yahoo.com/yui/compressor/
17
+ * Author: Julien Lecomte - http://www.julienlecomte.net/
18
+ * Copyright (c) 2013 Yahoo! Inc. All rights reserved.
19
+ * The copyrights embodied in the content of this file are licensed
20
+ * by Yahoo! Inc. under the BSD (revised) open source license.
21
+ */
22
+
23
+ namespace WMAC\tubalmartin\CssMin;
24
+
25
+ if( !defined('ABSPATH') ) {
26
+ exit;
27
+ }
28
+
29
+ class Minifier {
30
+
31
+ const QUERY_FRACTION = '_CSSMIN_QF_';
32
+ const COMMENT_TOKEN = '_CSSMIN_CMT_%d_';
33
+ const COMMENT_TOKEN_START = '_CSSMIN_CMT_';
34
+ const RULE_BODY_TOKEN = '_CSSMIN_RBT_%d_';
35
+ const PRESERVED_TOKEN = '_CSSMIN_PTK_%d_';
36
+
37
+ // Token lists
38
+ private $comments = array();
39
+ private $ruleBodies = array();
40
+ private $preservedTokens = array();
41
+
42
+ // Output options
43
+ private $keepImportantComments = true;
44
+ private $keepSourceMapComment = false;
45
+ private $linebreakPosition = 0;
46
+
47
+ // PHP ini limits
48
+ private $raisePhpLimits;
49
+ private $memoryLimit;
50
+ private $maxExecutionTime = 60; // 1 min
51
+ private $pcreBacktrackLimit;
52
+ private $pcreRecursionLimit;
53
+
54
+ // Color maps
55
+ private $hexToNamedColorsMap;
56
+ private $namedToHexColorsMap;
57
+
58
+ // Regexes
59
+ private $numRegex;
60
+ private $charsetRegex = '/@charset [^;]+;/Si';
61
+ private $importRegex = '/@import [^;]+;/Si';
62
+ private $namespaceRegex = '/@namespace [^;]+;/Si';
63
+ private $namedToHexColorsRegex;
64
+ private $shortenOneZeroesRegex;
65
+ private $shortenTwoZeroesRegex;
66
+ private $shortenThreeZeroesRegex;
67
+ private $shortenFourZeroesRegex;
68
+ private $unitsGroupRegex = '(?:ch|cm|em|ex|gd|in|mm|px|pt|pc|q|rem|vh|vmax|vmin|vw|%)';
69
+
70
+ /**
71
+ * @param bool|int $raisePhpLimits If true, PHP settings will be raised if needed
72
+ */
73
+ public function __construct($raisePhpLimits = true)
74
+ {
75
+ $this->raisePhpLimits = (bool)$raisePhpLimits;
76
+ $this->memoryLimit = 128 * 1048576; // 128MB in bytes
77
+ $this->pcreBacktrackLimit = 1000 * 1000;
78
+ $this->pcreRecursionLimit = 500 * 1000;
79
+ $this->hexToNamedColorsMap = Colors::getHexToNamedMap();
80
+ $this->namedToHexColorsMap = Colors::getNamedToHexMap();
81
+ $this->namedToHexColorsRegex = sprintf('/([:,( ])(%s)( |,|\)|;|$)/Si', implode('|', array_keys($this->namedToHexColorsMap)));
82
+ $this->numRegex = sprintf('-?\d*\.?\d+%s?', $this->unitsGroupRegex);
83
+ $this->setShortenZeroValuesRegexes();
84
+ }
85
+
86
+ /**
87
+ * Parses & minifies the given input CSS string
88
+ * @param string $css
89
+ * @return string
90
+ */
91
+ public function run($css = '')
92
+ {
93
+ if( empty($css) || !is_string($css) ) {
94
+ return '';
95
+ }
96
+
97
+ $this->resetRunProperties();
98
+
99
+ if( $this->raisePhpLimits ) {
100
+ $this->doRaisePhpLimits();
101
+ }
102
+
103
+ return $this->minify($css);
104
+ }
105
+
106
+ /**
107
+ * Sets whether to keep or remove sourcemap special comment.
108
+ * Sourcemap comments are removed by default.
109
+ * @param bool $keepSourceMapComment
110
+ */
111
+ public function keepSourceMapComment($keepSourceMapComment = true)
112
+ {
113
+ $this->keepSourceMapComment = (bool)$keepSourceMapComment;
114
+ }
115
+
116
+ /**
117
+ * Sets whether to keep or remove important comments.
118
+ * Important comments outside of a declaration block are kept by default.
119
+ * @param bool $removeImportantComments
120
+ */
121
+ public function removeImportantComments($removeImportantComments = true)
122
+ {
123
+ $this->keepImportantComments = !(bool)$removeImportantComments;
124
+ }
125
+
126
+ /**
127
+ * Sets the approximate column after which long lines will be splitted in the output
128
+ * with a linebreak.
129
+ * @param int $position
130
+ */
131
+ public function setLineBreakPosition($position)
132
+ {
133
+ $this->linebreakPosition = (int)$position;
134
+ }
135
+
136
+ /**
137
+ * Sets the memory limit for this script
138
+ * @param int|string $limit
139
+ */
140
+ public function setMemoryLimit($limit)
141
+ {
142
+ $this->memoryLimit = Utils::normalizeInt($limit);
143
+ }
144
+
145
+ /**
146
+ * Sets the maximum execution time for this script
147
+ * @param int|string $seconds
148
+ */
149
+ public function setMaxExecutionTime($seconds)
150
+ {
151
+ $this->maxExecutionTime = (int)$seconds;
152
+ }
153
+
154
+ /**
155
+ * Sets the PCRE backtrack limit for this script
156
+ * @param int $limit
157
+ */
158
+ public function setPcreBacktrackLimit($limit)
159
+ {
160
+ $this->pcreBacktrackLimit = (int)$limit;
161
+ }
162
+
163
+ /**
164
+ * Sets the PCRE recursion limit for this script
165
+ * @param int $limit
166
+ */
167
+ public function setPcreRecursionLimit($limit)
168
+ {
169
+ $this->pcreRecursionLimit = (int)$limit;
170
+ }
171
+
172
+ /**
173
+ * Builds regular expressions needed for shortening zero values
174
+ */
175
+ private function setShortenZeroValuesRegexes()
176
+ {
177
+ $zeroRegex = '0' . $this->unitsGroupRegex;
178
+ $numOrPosRegex = '(' . $this->numRegex . '|top|left|bottom|right|center) ';
179
+ $oneZeroSafeProperties = array(
180
+ '(?:line-)?height',
181
+ '(?:(?:min|max)-)?width',
182
+ 'top',
183
+ 'left',
184
+ 'background-position',
185
+ 'bottom',
186
+ 'right',
187
+ 'border(?:-(?:top|left|bottom|right))?(?:-width)?',
188
+ 'border-(?:(?:top|bottom)-(?:left|right)-)?radius',
189
+ 'column-(?:gap|width)',
190
+ 'margin(?:-(?:top|left|bottom|right))?',
191
+ 'outline-width',
192
+ 'padding(?:-(?:top|left|bottom|right))?'
193
+ );
194
+
195
+ // First zero regex
196
+ $regex = '/(^|;)(' . implode('|', $oneZeroSafeProperties) . '):%s/Si';
197
+ $this->shortenOneZeroesRegex = sprintf($regex, $zeroRegex);
198
+
199
+ // Multiple zeroes regexes
200
+ $regex = '/(^|;)(margin|padding|border-(?:width|radius)|background-position):%s/Si';
201
+ $this->shortenTwoZeroesRegex = sprintf($regex, $numOrPosRegex . $zeroRegex);
202
+ $this->shortenThreeZeroesRegex = sprintf($regex, $numOrPosRegex . $numOrPosRegex . $zeroRegex);
203
+ $this->shortenFourZeroesRegex = sprintf($regex, $numOrPosRegex . $numOrPosRegex . $numOrPosRegex . $zeroRegex);
204
+ }
205
+
206
+ /**
207
+ * Resets properties whose value may change between runs
208
+ */
209
+ private function resetRunProperties()
210
+ {
211
+ $this->comments = array();
212
+ $this->ruleBodies = array();
213
+ $this->preservedTokens = array();
214
+ }
215
+
216
+ /**
217
+ * Tries to configure PHP to use at least the suggested minimum settings
218
+ * @return void
219
+ */
220
+ private function doRaisePhpLimits()
221
+ {
222
+ $phpLimits = array(
223
+ 'memory_limit' => $this->memoryLimit,
224
+ 'max_execution_time' => $this->maxExecutionTime,
225
+ 'pcre.backtrack_limit' => $this->pcreBacktrackLimit,
226
+ 'pcre.recursion_limit' => $this->pcreRecursionLimit
227
+ );
228
+
229
+ // If current settings are higher respect them.
230
+ foreach($phpLimits as $name => $suggested) {
231
+ $current = Utils::normalizeInt(ini_get($name));
232
+
233
+ if( $current >= $suggested ) {
234
+ continue;
235
+ }
236
+
237
+ // memoryLimit exception: allow -1 for "no memory limit".
238
+ if( $name === 'memory_limit' && $current === -1 ) {
239
+ continue;
240
+ }
241
+
242
+ // maxExecutionTime exception: allow 0 for "no memory limit".
243
+ if( $name === 'max_execution_time' && $current === 0 ) {
244
+ continue;
245
+ }
246
+
247
+ ini_set($name, $suggested);
248
+ }
249
+ }
250
+
251
+ /**
252
+ * Registers a preserved token
253
+ * @param string $token
254
+ * @return string The token ID string
255
+ */
256
+ private function registerPreservedToken($token)
257
+ {
258
+ $tokenId = sprintf(self::PRESERVED_TOKEN, count($this->preservedTokens));
259
+ $this->preservedTokens[$tokenId] = $token;
260
+
261
+ return $tokenId;
262
+ }
263
+
264
+ /**
265
+ * Registers a candidate comment token
266
+ * @param string $comment
267
+ * @return string The comment token ID string
268
+ */
269
+ private function registerCommentToken($comment)
270
+ {
271
+ $tokenId = sprintf(self::COMMENT_TOKEN, count($this->comments));
272
+ $this->comments[$tokenId] = $comment;
273
+
274
+ return $tokenId;
275
+ }
276
+
277
+ /**
278
+ * Registers a rule body token
279
+ * @param string $body the minified rule body
280
+ * @return string The rule body token ID string
281
+ */
282
+ private function registerRuleBodyToken($body)
283
+ {
284
+ if( empty($body) ) {
285
+ return '';
286
+ }
287
+
288
+ $tokenId = sprintf(self::RULE_BODY_TOKEN, count($this->ruleBodies));
289
+ $this->ruleBodies[$tokenId] = $body;
290
+
291
+ return $tokenId;
292
+ }
293
+
294
+ /**
295
+ * Parses & minifies the given input CSS string
296
+ * @param string $css
297
+ * @return string
298
+ */
299
+ private function minify($css)
300
+ {
301
+ // Process data urls
302
+ $css = $this->processDataUrls($css);
303
+
304
+ // Process comments
305
+ $css = preg_replace_callback('/(?<!\\\\)\/\*(.*?)\*(?<!\\\\)\//Ss', array(
306
+ $this,
307
+ 'processCommentsCallback'
308
+ ), $css);
309
+
310
+ // IE7: Process Microsoft matrix filters (whitespaces between Matrix parameters). Can contain strings inside.
311
+ $css = preg_replace_callback('/filter:\s*progid:DXImageTransform\.Microsoft\.Matrix\(([^)]+)\)/Ss', array(
312
+ $this,
313
+ 'processOldIeSpecificMatrixDefinitionCallback'
314
+ ), $css);
315
+
316
+ // Process quoted unquotable attribute selectors to unquote them. Covers most common cases.
317
+ // Likelyhood of a quoted attribute selector being a substring in a string: Very very low.
318
+ $css = preg_replace('/\[\s*([a-z][a-z-]+)\s*([\*\|\^\$~]?=)\s*[\'"](-?[a-z_][a-z0-9-_]+)[\'"]\s*\]/Ssi', '[$1$2$3]', $css);
319
+
320
+ // Process strings so their content doesn't get accidentally minified
321
+ $css = preg_replace_callback('/(?:"(?:[^\\\\"]|\\\\.|\\\\)*")|' . "(?:'(?:[^\\\\']|\\\\.|\\\\)*')/S", array(
322
+ $this,
323
+ 'processStringsCallback'
324
+ ), $css);
325
+
326
+ // Normalize all whitespace strings to single spaces. Easier to work with that way.
327
+ $css = preg_replace('/\s+/S', ' ', $css);
328
+
329
+ // Process import At-rules with unquoted URLs so URI reserved characters such as a semicolon may be used safely.
330
+ $css = preg_replace_callback('/@import url\(([^\'"]+?)\)( |;)/Si', array(
331
+ $this,
332
+ 'processImportUnquotedUrlAtRulesCallback'
333
+ ), $css);
334
+
335
+ // Process comments
336
+ $css = $this->processComments($css);
337
+
338
+ // Process rule bodies
339
+ $css = $this->processRuleBodies($css);
340
+
341
+ // Process at-rules and selectors
342
+ $css = $this->processAtRulesAndSelectors($css);
343
+
344
+ // Restore preserved rule bodies before splitting
345
+ $css = strtr($css, $this->ruleBodies);
346
+
347
+ // Split long lines in output if required
348
+ $css = $this->processLongLineSplitting($css);
349
+
350
+ // Restore preserved comments and strings
351
+ $css = strtr($css, $this->preservedTokens);
352
+
353
+ return trim($css);
354
+ }
355
+
356
+ /**
357
+ * Searches & replaces all data urls with tokens before we start compressing,
358
+ * to avoid performance issues running some of the subsequent regexes against large string chunks.
359
+ * @param string $css
360
+ * @return string
361
+ */
362
+ private function processDataUrls($css)
363
+ {
364
+ $ret = '';
365
+ $searchOffset = $substrOffset = 0;
366
+
367
+ // Since we need to account for non-base64 data urls, we need to handle
368
+ // ' and ) being part of the data string.
369
+ while( preg_match('/url\(\s*(["\']?)data:/Si', $css, $m, PREG_OFFSET_CAPTURE, $searchOffset) ) {
370
+ $matchStartIndex = $m[0][1];
371
+ $dataStartIndex = $matchStartIndex + 4; // url( length
372
+ $searchOffset = $matchStartIndex + strlen($m[0][0]);
373
+ $terminator = $m[1][0]; // ', " or empty (not quoted)
374
+ $terminatorRegex = '/(?<!\\\\)' . (strlen($terminator) === 0
375
+ ? ''
376
+ : $terminator . '\s*') . '(\))/S';
377
+
378
+ $ret .= substr($css, $substrOffset, $matchStartIndex - $substrOffset);
379
+
380
+ // Terminator found
381
+ if( preg_match($terminatorRegex, $css, $matches, PREG_OFFSET_CAPTURE, $searchOffset) ) {
382
+ $matchEndIndex = $matches[1][1];
383
+ $searchOffset = $matchEndIndex + 1;
384
+ $token = substr($css, $dataStartIndex, $matchEndIndex - $dataStartIndex);
385
+
386
+ // Remove all spaces only for base64 encoded URLs.
387
+ if( stripos($token, 'base64,') !== false ) {
388
+ $token = preg_replace('/\s+/S', '', $token);
389
+ }
390
+
391
+ $ret .= 'url(' . $this->registerPreservedToken(trim($token)) . ')';
392
+ // No end terminator found, re-add the whole match. Should we throw/warn here?
393
+ } else {
394
+ $ret .= substr($css, $matchStartIndex, $searchOffset - $matchStartIndex);
395
+ }
396
+
397
+ $substrOffset = $searchOffset;
398
+ }
399
+
400
+ $ret .= substr($css, $substrOffset);
401
+
402
+ return $ret;
403
+ }
404
+
405
+ /**
406
+ * Registers all comments found as candidates to be preserved.
407
+ * @param array $matches
408
+ * @return string
409
+ */
410
+ private function processCommentsCallback($matches)
411
+ {
412
+ return '/*' . $this->registerCommentToken($matches[1]) . '*/';
413
+ }
414
+
415
+ /**
416
+ * Preserves old IE Matrix string definition
417
+ * @param array $matches
418
+ * @return string
419
+ */
420
+ private function processOldIeSpecificMatrixDefinitionCallback($matches)
421
+ {
422
+ return 'filter:progid:DXImageTransform.Microsoft.Matrix(' . $this->registerPreservedToken($matches[1]) . ')';
423
+ }
424
+
425
+ /**
426
+ * Preserves strings found
427
+ * @param array $matches
428
+ * @return string
429
+ */
430
+ private function processStringsCallback($matches)
431
+ {
432
+ $match = $matches[0];
433
+ $quote = substr($match, 0, 1);
434
+ $match = substr($match, 1, -1);
435
+
436
+ // maybe the string contains a comment-like substring?
437
+ // one, maybe more? put'em back then
438
+ if( strpos($match, self::COMMENT_TOKEN_START) !== false ) {
439
+ $match = strtr($match, $this->comments);
440
+ }
441
+
442
+ // minify alpha opacity in filter strings
443
+ $match = str_ireplace('progid:DXImageTransform.Microsoft.Alpha(Opacity=', 'alpha(opacity=', $match);
444
+
445
+ return $quote . $this->registerPreservedToken($match) . $quote;
446
+ }
447
+
448
+ /**
449
+ * Searches & replaces all import at-rule unquoted urls with tokens so URI reserved characters such as a semicolon
450
+ * may be used safely in a URL.
451
+ * @param array $matches
452
+ * @return string
453
+ */
454
+ private function processImportUnquotedUrlAtRulesCallback($matches)
455
+ {
456
+ return '@import url(' . $this->registerPreservedToken($matches[1]) . ')' . $matches[2];
457
+ }
458
+
459
+ /**
460
+ * Preserves or removes comments found.
461
+ * @param string $css
462
+ * @return string
463
+ */
464
+ private function processComments($css)
465
+ {
466
+ foreach($this->comments as $commentId => $comment) {
467
+ $commentIdString = '/*' . $commentId . '*/';
468
+
469
+ // ! in the first position of the comment means preserve
470
+ // so push to the preserved tokens keeping the !
471
+ if( $this->keepImportantComments && strpos($comment, '!') === 0 ) {
472
+ $preservedTokenId = $this->registerPreservedToken($comment);
473
+ // Put new lines before and after /*! important comments
474
+ $css = str_replace($commentIdString, "\n/*$preservedTokenId*/\n", $css);
475
+ continue;
476
+ }
477
+
478
+ // # sourceMappingURL= in the first position of the comment means sourcemap
479
+ // so push to the preserved tokens if {$this->keepSourceMapComment} is truthy.
480
+ if( $this->keepSourceMapComment && strpos($comment, '# sourceMappingURL=') === 0 ) {
481
+ $preservedTokenId = $this->registerPreservedToken($comment);
482
+ // Add new line before the sourcemap comment
483
+ $css = str_replace($commentIdString, "\n/*$preservedTokenId*/", $css);
484
+ continue;
485
+ }
486
+
487
+ // Keep empty comments after child selectors (IE7 hack)
488
+ // e.g. html >/**/ body
489
+ if( strlen($comment) === 0 && strpos($css, '>/*' . $commentId) !== false ) {
490
+ $css = str_replace($commentId, $this->registerPreservedToken(''), $css);
491
+ continue;
492
+ }
493
+
494
+ // in all other cases kill the comment
495
+ $css = str_replace($commentIdString, '', $css);
496
+ }
497
+
498
+ // Normalize whitespace again
499
+ $css = preg_replace('/ +/S', ' ', $css);
500
+
501
+ return $css;
502
+ }
503
+
504
+ /**
505
+ * Finds, minifies & preserves all rule bodies.
506
+ * @param string $css the whole stylesheet.
507
+ * @return string
508
+ */
509
+ private function processRuleBodies($css)
510
+ {
511
+ $ret = '';
512
+ $searchOffset = $substrOffset = 0;
513
+
514
+ while( ($blockStartPos = strpos($css, '{', $searchOffset)) !== false ) {
515
+ $blockEndPos = strpos($css, '}', $blockStartPos);
516
+ $nextBlockStartPos = strpos($css, '{', $blockStartPos + 1);
517
+ $ret .= substr($css, $substrOffset, $blockStartPos - $substrOffset);
518
+
519
+ if( $nextBlockStartPos !== false && $nextBlockStartPos < $blockEndPos ) {
520
+ $ret .= substr($css, $blockStartPos, $nextBlockStartPos - $blockStartPos);
521
+ $searchOffset = $nextBlockStartPos;
522
+ } else {
523
+ $ruleBody = substr($css, $blockStartPos + 1, $blockEndPos - $blockStartPos - 1);
524
+ $ruleBodyToken = $this->registerRuleBodyToken($this->processRuleBody($ruleBody));
525
+ $ret .= '{' . $ruleBodyToken . '}';
526
+ $searchOffset = $blockEndPos + 1;
527
+ }
528
+
529
+ $substrOffset = $searchOffset;
530
+ }
531
+
532
+ $ret .= substr($css, $substrOffset);
533
+
534
+ return $ret;
535
+ }
536
+
537
+ /**
538
+ * Compresses non-group rule bodies.
539
+ * @param string $body The rule body without curly braces
540
+ * @return string
541
+ */
542
+ private function processRuleBody($body)
543
+ {
544
+ $body = trim($body);
545
+
546
+ // Remove spaces before the things that should not have spaces before them.
547
+ $body = preg_replace('/ ([:=,)*\/;\n])/S', '$1', $body);
548
+
549
+ // Remove the spaces after the things that should not have spaces after them.
550
+ $body = preg_replace('/([:=,(*\/!;\n]) /S', '$1', $body);
551
+
552
+ // Replace multiple semi-colons in a row by a single one
553
+ $body = preg_replace('/;;+/S', ';', $body);
554
+
555
+ // Remove semicolon before closing brace except when:
556
+ // - The last property is prefixed with a `*` (lte IE7 hack) to avoid issues on Symbian S60 3.x browsers.
557
+ if( !preg_match('/\*[a-z0-9-]+:[^;]+;$/Si', $body) ) {
558
+ $body = rtrim($body, ';');
559
+ }
560
+
561
+ // Remove important comments inside a rule body (because they make no sense here).
562
+ if( strpos($body, '/*') !== false ) {
563
+ $body = preg_replace('/\n?\/\*[A-Z0-9_]+\*\/\n?/S', '', $body);
564
+ }
565
+
566
+ // Empty rule body? Exit :)
567
+ if( empty($body) ) {
568
+ return '';
569
+ }
570
+
571
+ // Shorten font-weight values
572
+ $body = preg_replace(array('/(font-weight:)bold\b/Si', '/(font-weight:)normal\b/Si'), array(
573
+ '${1}700',
574
+ '${1}400'
575
+ ), $body);
576
+
577
+ // Shorten background property
578
+ $body = preg_replace('/(background:)(?:none|transparent)( !|;|$)/Si', '${1}0 0$2', $body);
579
+
580
+ // Shorten opacity IE filter
581
+ $body = str_ireplace('progid:DXImageTransform.Microsoft.Alpha(Opacity=', 'alpha(opacity=', $body);
582
+
583
+ // Shorten colors from rgb(51,102,153) to #336699, rgb(100%,0%,0%) to #ff0000 (sRGB color space)
584
+ // Shorten colors from hsl(0, 100%, 50%) to #ff0000 (sRGB color space)
585
+ // This makes it more likely that it'll get further compressed in the next step.
586
+ $body = preg_replace_callback('/(rgb|hsl)\(([0-9,.% -]+)\)(.|$)/Si', array(
587
+ $this,
588
+ 'shortenHslAndRgbToHexCallback'
589
+ ), $body);
590
+
591
+ // Shorten colors from #AABBCC to #ABC or shorter color name:
592
+ // - Look for hex colors which don't have a "=" in front of them (to avoid MSIE filters)
593
+ $body = preg_replace_callback('/(?<!=)#([0-9a-f]{3,6})( |,|\)|;|$)/Si', array(
594
+ $this,
595
+ 'shortenHexColorsCallback'
596
+ ), $body);
597
+
598
+ // Shorten long named colors with a shorter HEX counterpart: white -> #fff.
599
+ // Run at least 2 times to cover most cases
600
+ $body = preg_replace_callback(array(
601
+ $this->namedToHexColorsRegex,
602
+ $this->namedToHexColorsRegex
603
+ ), array($this, 'shortenNamedColorsCallback'), $body);
604
+
605
+ // Replace positive sign from numbers before the leading space is removed.
606
+ // +1.2em to 1.2em, +.8px to .8px, +2% to 2%
607
+ $body = preg_replace('/([ :,(])\+(\.?\d+)/S', '$1$2', $body);
608
+
609
+ // shorten ms to s
610
+ $body = preg_replace_callback('/([ :,(])(-?)(\d{3,})ms/Si', function ($matches) {
611
+ return $matches[1] . $matches[2] . ((int)$matches[3] / 1000) . 's';
612
+ }, $body);
613
+
614
+ // Remove leading zeros from integer and float numbers.
615
+ // 000.6 to .6, -0.8 to -.8, 0050 to 50, -01.05 to -1.05
616
+ $body = preg_replace('/([ :,(])(-?)0+([1-9]?\.?\d+)/S', '$1$2$3', $body);
617
+
618
+ // Remove trailing zeros from float numbers.
619
+ // -6.0100em to -6.01em, .0100 to .01, 1.200px to 1.2px
620
+ $body = preg_replace('/([ :,(])(-?\d?\.\d+?)0+([^\d])/S', '$1$2$3', $body);
621
+
622
+ // Remove trailing .0 -> -9.0 to -9
623
+ $body = preg_replace('/([ :,(])(-?\d+)\.0([^\d])/S', '$1$2$3', $body);
624
+
625
+ // Replace 0 length numbers with 0
626
+ $body = preg_replace('/([ :,(])-?\.?0+([^\d])/S', '${1}0$2', $body);
627
+
628
+ // Shorten zero values for safe properties only
629
+ $body = preg_replace(array(
630
+ $this->shortenOneZeroesRegex,
631
+ $this->shortenTwoZeroesRegex,
632
+ $this->shortenThreeZeroesRegex,
633
+ $this->shortenFourZeroesRegex
634
+ ), array(
635
+ '$1$2:0',
636
+ '$1$2:$3 0',
637
+ '$1$2:$3 $4 0',
638
+ '$1$2:$3 $4 $5 0'
639
+ ), $body);
640
+
641
+ // Replace 0 0 0; or 0 0 0 0; with 0 0 for background-position property.
642
+ $body = preg_replace('/(background-position):0(?: 0){2,3}( !|;|$)/Si', '$1:0 0$2', $body);
643
+
644
+ // Shorten suitable shorthand properties with repeated values
645
+ $body = preg_replace(array(
646
+ '/(margin|padding|border-(?:width|radius)):(' . $this->numRegex . ')(?: \2)+( !|;|$)/Si',
647
+ '/(border-(?:style|color)):([#a-z0-9]+)(?: \2)+( !|;|$)/Si'
648
+ ), '$1:$2$3', $body);
649
+ $body = preg_replace(array(
650
+ '/(margin|padding|border-(?:width|radius)):' . '(' . $this->numRegex . ') (' . $this->numRegex . ') \2 \3( !|;|$)/Si',
651
+ '/(border-(?:style|color)):([#a-z0-9]+) ([#a-z0-9]+) \2 \3( !|;|$)/Si'
652
+ ), '$1:$2 $3$4', $body);
653
+ $body = preg_replace(array(
654
+ '/(margin|padding|border-(?:width|radius)):' . '(' . $this->numRegex . ') (' . $this->numRegex . ') (' . $this->numRegex . ') \3( !|;|$)/Si',
655
+ '/(border-(?:style|color)):([#a-z0-9]+) ([#a-z0-9]+) ([#a-z0-9]+) \3( !|;|$)/Si'
656
+ ), '$1:$2 $3 $4$5', $body);
657
+
658
+ // Lowercase some common functions that can be values
659
+ $body = preg_replace_callback('/(?:attr|blur|brightness|circle|contrast|cubic-bezier|drop-shadow|ellipse|from|grayscale|' . 'hsla?|hue-rotate|inset|invert|local|minmax|opacity|perspective|polygon|rgba?|rect|repeat|saturate|sepia|' . 'steps|to|url|var|-webkit-gradient|' . '(?:-(?:atsc|khtml|moz|ms|o|wap|webkit)-)?(?:calc|(?:repeating-)?(?:linear|radial)-gradient))\(/Si', array(
660
+ $this,
661
+ 'strtolowerCallback'
662
+ ), $body);
663
+
664
+ // Lowercase all uppercase properties
665
+ $body = preg_replace_callback('/(?:^|;)[A-Z-]+:/S', array($this, 'strtolowerCallback'), $body);
666
+
667
+ return $body;
668
+ }
669
+
670
+ /**
671
+ * Compresses At-rules and selectors.
672
+ * @param string $css the whole stylesheet with rule bodies tokenized.
673
+ * @return string
674
+ */
675
+ private function processAtRulesAndSelectors($css)
676
+ {
677
+ $charset = '';
678
+ $imports = '';
679
+ $namespaces = '';
680
+
681
+ // Remove spaces before the things that should not have spaces before them.
682
+ $css = preg_replace('/ ([@{};>+)\]~=,\/\n])/S', '$1', $css);
683
+
684
+ // Remove the spaces after the things that should not have spaces after them.
685
+ $css = preg_replace('/([{}:;>+(\[~=,\/\n]) /S', '$1', $css);
686
+
687
+ // Shorten shortable double colon (CSS3) pseudo-elements to single colon (CSS2)
688
+ $css = preg_replace('/::(before|after|first-(?:line|letter))(\{|,)/Si', ':$1$2', $css);
689
+
690
+ // Retain space for special IE6 cases
691
+ $css = preg_replace_callback('/:first-(line|letter)(\{|,)/Si', function ($matches) {
692
+ return ':first-' . strtolower($matches[1]) . ' ' . $matches[2];
693
+ }, $css);
694
+
695
+ // Find a fraction that may used in some @media queries such as: (min-aspect-ratio: 1/1)
696
+ // Add token to add the "/" back in later
697
+ $css = preg_replace('/\(([a-z-]+):([0-9]+)\/([0-9]+)\)/Si', '($1:$2' . self::QUERY_FRACTION . '$3)', $css);
698
+
699
+ // Remove empty rule blocks up to 2 levels deep.
700
+ $css = preg_replace(array_fill(0, 2, '/(\{)[^{};\/\n]+\{\}/S'), '$1', $css);
701
+ $css = preg_replace('/[^{};\/\n]+\{\}/S', '', $css);
702
+
703
+ // Two important comments next to each other? Remove extra newline.
704
+ if( $this->keepImportantComments ) {
705
+ $css = str_replace("\n\n", "\n", $css);
706
+ }
707
+
708
+ // Restore fraction
709
+ $css = str_replace(self::QUERY_FRACTION, '/', $css);
710
+
711
+ // Lowercase some popular @directives
712
+ $css = preg_replace_callback('/(?<!\\\\)@(?:charset|document|font-face|import|(?:-(?:atsc|khtml|moz|ms|o|wap|webkit)-)?keyframes|media|' . 'namespace|page|supports|viewport)/Si', array(
713
+ $this,
714
+ 'strtolowerCallback'
715
+ ), $css);
716
+
717
+ // Lowercase some popular media types
718
+ $css = preg_replace_callback('/[ ,](?:all|aural|braille|handheld|print|projection|screen|tty|tv|embossed|speech)[ ,;{]/Si', array(
719
+ $this,
720
+ 'strtolowerCallback'
721
+ ), $css);
722
+
723
+ // Lowercase some common pseudo-classes & pseudo-elements
724
+ $css = preg_replace_callback('/(?<!\\\\):(?:active|after|before|checked|default|disabled|empty|enabled|first-(?:child|of-type)|' . 'focus(?:-within)?|hover|indeterminate|in-range|invalid|lang\(|last-(?:child|of-type)|left|link|not\(|' . 'nth-(?:child|of-type)\(|nth-last-(?:child|of-type)\(|only-(?:child|of-type)|optional|out-of-range|' . 'read-(?:only|write)|required|right|root|:selection|target|valid|visited)/Si', array(
725
+ $this,
726
+ 'strtolowerCallback'
727
+ ), $css);
728
+
729
+ // @charset handling
730
+ if( preg_match($this->charsetRegex, $css, $matches) ) {
731
+ // Keep the first @charset at-rule found
732
+ $charset = $matches[0];
733
+ // Delete all @charset at-rules
734
+ $css = preg_replace($this->charsetRegex, '', $css);
735
+ }
736
+
737
+ // @import handling
738
+ $css = preg_replace_callback($this->importRegex, function ($matches) use (&$imports) {
739
+ // Keep all @import at-rules found for later
740
+ $imports .= $matches[0];
741
+
742
+ // Delete all @import at-rules
743
+ return '';
744
+ }, $css);
745
+
746
+ // @namespace handling
747
+ $css = preg_replace_callback($this->namespaceRegex, function ($matches) use (&$namespaces) {
748
+ // Keep all @namespace at-rules found for later
749
+ $namespaces .= $matches[0];
750
+
751
+ // Delete all @namespace at-rules
752
+ return '';
753
+ }, $css);
754
+
755
+ // Order critical at-rules:
756
+ // 1. @charset first
757
+ // 2. @imports below @charset
758
+ // 3. @namespaces below @imports
759
+ $css = $charset . $imports . $namespaces . $css;
760
+
761
+ return $css;
762
+ }
763
+
764
+ /**
765
+ * Splits long lines after a specific column.
766
+ *
767
+ * Some source control tools don't like it when files containing lines longer
768
+ * than, say 8000 characters, are checked in. The linebreak option is used in
769
+ * that case to split long lines after a specific column.
770
+ *
771
+ * @param string $css the whole stylesheet.
772
+ * @return string
773
+ */
774
+ private function processLongLineSplitting($css)
775
+ {
776
+ if( $this->linebreakPosition > 0 ) {
777
+ $l = strlen($css);
778
+ $offset = $this->linebreakPosition;
779
+ while( preg_match('/(?<!\\\\)\}(?!\n)/S', $css, $matches, PREG_OFFSET_CAPTURE, $offset) ) {
780
+ $matchIndex = $matches[0][1];
781
+ $css = substr_replace($css, "\n", $matchIndex + 1, 0);
782
+ $offset = $matchIndex + 2 + $this->linebreakPosition;
783
+ $l += 1;
784
+ if( $offset > $l ) {
785
+ break;
786
+ }
787
+ }
788
+ }
789
+
790
+ return $css;
791
+ }
792
+
793
+ /**
794
+ * Converts hsl() & rgb() colors to HEX format.
795
+ * @param $matches
796
+ * @return string
797
+ */
798
+ private function shortenHslAndRgbToHexCallback($matches)
799
+ {
800
+ $type = $matches[1];
801
+ $values = explode(',', $matches[2]);
802
+ $terminator = $matches[3];
803
+
804
+ if( $type === 'hsl' ) {
805
+ $values = Utils::hslToRgb($values);
806
+ }
807
+
808
+ $hexColors = Utils::rgbToHex($values);
809
+
810
+ // Restore space after rgb() or hsl() function in some cases such as:
811
+ // background-image: linear-gradient(to bottom, rgb(210,180,140) 10%, rgb(255,0,0) 90%);
812
+ if( !empty($terminator) && !preg_match('/[ ,);]/S', $terminator) ) {
813
+ $terminator = ' ' . $terminator;
814
+ }
815
+
816
+ return '#' . implode('', $hexColors) . $terminator;
817
+ }
818
+
819
+ /**
820
+ * Compresses HEX color values of the form #AABBCC to #ABC or short color name.
821
+ * @param $matches
822
+ * @return string
823
+ */
824
+ private function shortenHexColorsCallback($matches)
825
+ {
826
+ $hex = $matches[1];
827
+
828
+ // Shorten suitable 6 chars HEX colors
829
+ if( strlen($hex) === 6 && preg_match('/^([0-9a-f])\1([0-9a-f])\2([0-9a-f])\3$/Si', $hex, $m) ) {
830
+ $hex = $m[1] . $m[2] . $m[3];
831
+ }
832
+
833
+ // Lowercase
834
+ $hex = '#' . strtolower($hex);
835
+
836
+ // Replace Hex colors with shorter color names
837
+ $color = array_key_exists($hex, $this->hexToNamedColorsMap)
838
+ ? $this->hexToNamedColorsMap[$hex]
839
+ : $hex;
840
+
841
+ return $color . $matches[2];
842
+ }
843
+
844
+ /**
845
+ * Shortens all named colors with a shorter HEX counterpart for a set of safe properties
846
+ * e.g. white -> #fff
847
+ * @param array $matches
848
+ * @return string
849
+ */
850
+ private function shortenNamedColorsCallback($matches)
851
+ {
852
+ return $matches[1] . $this->namedToHexColorsMap[strtolower($matches[2])] . $matches[3];
853
+ }
854
+
855
+ /**
856
+ * Makes a string lowercase
857
+ * @param array $matches
858
+ * @return string
859
+ */
860
+ private function strtolowerCallback($matches)
861
+ {
862
+ return strtolower($matches[0]);
863
+ }
864
+ }
components/minify-and-combine/includes/classes/ext/php/yui-php-cssmin-bundled/Utils.php ADDED
@@ -0,0 +1,159 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace WMAC\tubalmartin\CssMin;
3
+
4
+ if( !defined('ABSPATH') ) {
5
+ exit;
6
+ }
7
+
8
+ class Utils {
9
+
10
+ /**
11
+ * Clamps a number between a minimum and a maximum value.
12
+ * @param int|float $n the number to clamp
13
+ * @param int|float $min the lower end number allowed
14
+ * @param int|float $max the higher end number allowed
15
+ * @return int|float
16
+ */
17
+ public static function clampNumber($n, $min, $max)
18
+ {
19
+ return min(max($n, $min), $max);
20
+ }
21
+
22
+ /**
23
+ * Clamps a RGB color number outside the sRGB color space
24
+ * @param int|float $n the number to clamp
25
+ * @return int|float
26
+ */
27
+ public static function clampNumberSrgb($n)
28
+ {
29
+ return self::clampNumber($n, 0, 255);
30
+ }
31
+
32
+ /**
33
+ * Converts a HSL color into a RGB color
34
+ * @param array $hslValues
35
+ * @return array
36
+ */
37
+ public static function hslToRgb($hslValues)
38
+ {
39
+ $h = floatval($hslValues[0]);
40
+ $s = floatval(str_replace('%', '', $hslValues[1]));
41
+ $l = floatval(str_replace('%', '', $hslValues[2]));
42
+
43
+ // Wrap and clamp, then fraction!
44
+ $h = ((($h % 360) + 360) % 360) / 360;
45
+ $s = self::clampNumber($s, 0, 100) / 100;
46
+ $l = self::clampNumber($l, 0, 100) / 100;
47
+
48
+ if( $s == 0 ) {
49
+ $r = $g = $b = self::roundNumber(255 * $l);
50
+ } else {
51
+ $v2 = $l < 0.5
52
+ ? $l * (1 + $s)
53
+ : ($l + $s) - ($s * $l);
54
+ $v1 = (2 * $l) - $v2;
55
+ $r = self::roundNumber(255 * self::hueToRgb($v1, $v2, $h + (1 / 3)));
56
+ $g = self::roundNumber(255 * self::hueToRgb($v1, $v2, $h));
57
+ $b = self::roundNumber(255 * self::hueToRgb($v1, $v2, $h - (1 / 3)));
58
+ }
59
+
60
+ return array($r, $g, $b);
61
+ }
62
+
63
+ /**
64
+ * Tests and selects the correct formula for each RGB color channel
65
+ * @param $v1
66
+ * @param $v2
67
+ * @param $vh
68
+ * @return mixed
69
+ */
70
+ public static function hueToRgb($v1, $v2, $vh)
71
+ {
72
+ $vh = $vh < 0
73
+ ? $vh + 1
74
+ : ($vh > 1
75
+ ? $vh - 1
76
+ : $vh);
77
+
78
+ if( $vh * 6 < 1 ) {
79
+ return $v1 + ($v2 - $v1) * 6 * $vh;
80
+ }
81
+
82
+ if( $vh * 2 < 1 ) {
83
+ return $v2;
84
+ }
85
+
86
+ if( $vh * 3 < 2 ) {
87
+ return $v1 + ($v2 - $v1) * ((2 / 3) - $vh) * 6;
88
+ }
89
+
90
+ return $v1;
91
+ }
92
+
93
+ /**
94
+ * Convert strings like "64M" or "30" to int values
95
+ * @param mixed $size
96
+ * @return int
97
+ */
98
+ public static function normalizeInt($size)
99
+ {
100
+ if( is_string($size) ) {
101
+ $letter = substr($size, -1);
102
+ $size = intval($size);
103
+ switch( $letter ) {
104
+ case 'M':
105
+ case 'm':
106
+ return (int)$size * 1048576;
107
+ case 'K':
108
+ case 'k':
109
+ return (int)$size * 1024;
110
+ case 'G':
111
+ case 'g':
112
+ return (int)$size * 1073741824;
113
+ }
114
+ }
115
+
116
+ return (int)$size;
117
+ }
118
+
119
+ /**
120
+ * Converts a string containing and RGB percentage value into a RGB integer value i.e. '90%' -> 229.5
121
+ * @param $rgbPercentage
122
+ * @return int
123
+ */
124
+ public static function rgbPercentageToRgbInteger($rgbPercentage)
125
+ {
126
+ if( strpos($rgbPercentage, '%') !== false ) {
127
+ $rgbPercentage = self::roundNumber(floatval(str_replace('%', '', $rgbPercentage)) * 2.55);
128
+ }
129
+
130
+ return intval($rgbPercentage, 10);
131
+ }
132
+
133
+ /**
134
+ * Converts a RGB color into a HEX color
135
+ * @param array $rgbColors
136
+ * @return array
137
+ */
138
+ public static function rgbToHex($rgbColors)
139
+ {
140
+ $hexColors = array();
141
+
142
+ // Values outside the sRGB color space should be clipped (0-255)
143
+ for($i = 0, $l = count($rgbColors); $i < $l; $i++) {
144
+ $hexColors[$i] = sprintf("%02x", self::clampNumberSrgb(self::rgbPercentageToRgbInteger($rgbColors[$i])));
145
+ }
146
+
147
+ return $hexColors;
148
+ }
149
+
150
+ /**
151
+ * Rounds a number to its closest integer
152
+ * @param $n
153
+ * @return int
154
+ */
155
+ public static function roundNumber($n)
156
+ {
157
+ return intval(round(floatval($n)), 10);
158
+ }
159
+ }
components/minify-and-combine/includes/classes/ext/php/yui-php-cssmin-bundled/index.html ADDED
@@ -0,0 +1 @@
 
1
+ <html><head><meta name="robots" content="noindex, nofollow"></head><body>Generated by <a href="http://wordpress.org/extend/plugins/" rel="nofollow">Мinify And Combine</a></body></html>
components/minify-and-combine/includes/classes/index.php ADDED
File without changes
components/minify-and-combine/includes/index.php ADDED
File without changes
components/minify-and-combine/index.php ADDED
File without changes
components/minify-and-combine/languages/index.php ADDED
File without changes
components/minify-and-combine/languages/minify-and-combine-ru_RU.mo ADDED
Binary file
components/minify-and-combine/languages/minify-and-combine-ru_RU.po ADDED
@@ -0,0 +1,573 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: clearfy\n"
4
+ "POT-Creation-Date: 2018-08-19 03:48+0300\n"
5
+ "PO-Revision-Date: 2018-08-19 03:54+0300\n"
6
+ "Last-Translator: alex.kovalevv@gmail.com <alex.kovalevv@gmail.com>\n"
7
+ "Language-Team: Alex Kovalev <alex.kovalevv@gmail.com>\n"
8
+ "Language: ru_RU\n"
9
+ "MIME-Version: 1.0\n"
10
+ "Content-Type: text/plain; charset=UTF-8\n"
11
+ "Content-Transfer-Encoding: 8bit\n"
12
+ "X-Generator: Poedit 2.1.1\n"
13
+ "X-Poedit-Basepath: ..\n"
14
+ "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
15
+ "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
16
+ "X-Poedit-SourceCharset: UTF-8\n"
17
+ "X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c\n"
18
+ "X-Poedit-SearchPath-0: .\n"
19
+ "X-Poedit-SearchPathExcluded-0: libs\n"
20
+
21
+ #: admin/boot.php:23
22
+ msgid ""
23
+ "Clearfy: Minify and Combine component is not compatible with the Autoptimize "
24
+ "plugin, please do not use them together to avoid conflicts. Please disable "
25
+ "the Minify and Combine component"
26
+ msgstr ""
27
+ "Clearfy: Компонент Сжатие и Объединение (JS,CSS) не совместим с плагином "
28
+ "Autoptimize, пожалуйста, не используйте их вместе, чтобы избежать "
29
+ "конфликтов. Отключите компонент Сжатие и Объединение (JS,CSS)"
30
+
31
+ #: admin/boot.php:50 admin/pages/settings.php:122
32
+ msgid "Optimize JavaScript Code?"
33
+ msgstr "Оптимизировать код JavaScript?"
34
+
35
+ #: admin/boot.php:55 admin/pages/settings.php:138
36
+ msgid "Aggregate JS-files?"
37
+ msgstr "Объединять JS-файлы"
38
+
39
+ #: admin/boot.php:60 admin/pages/settings.php:148
40
+ msgid "Also aggregate inline JS?"
41
+ msgstr "Также объединять встроенный JS?"
42
+
43
+ #: admin/boot.php:65 admin/pages/settings.php:158
44
+ msgid "Force JavaScript in &lt;head&gt;?"
45
+ msgstr "Принудительно переместить JS в &lt;head&gt;?"
46
+
47
+ #: admin/boot.php:70 admin/pages/settings.php:167
48
+ msgid "Exclude scripts from Мinify And Combine:"
49
+ msgstr "Исключить скрипты:"
50
+
51
+ #: admin/boot.php:75 admin/pages/settings.php:177
52
+ msgid "Add try-catch wrapping?"
53
+ msgstr "Добавить обертку try-catch?"
54
+
55
+ #: admin/boot.php:83 admin/pages/settings.php:198
56
+ msgid "Optimize CSS Code?"
57
+ msgstr "Оптимизировать CSS код?"
58
+
59
+ #: admin/boot.php:89 admin/pages/settings.php:214
60
+ msgid "Aggregate CSS-files?"
61
+ msgstr "Объединять CSS файлы?"
62
+
63
+ #: admin/boot.php:95 admin/pages/settings.php:224
64
+ msgid "Also aggregate inline CSS?"
65
+ msgstr "Извлекать встроенный CSS код для объединения?"
66
+
67
+ #: admin/boot.php:101 admin/pages/settings.php:234
68
+ msgid "Generate data: URIs for images?"
69
+ msgstr "Преобразовать изображения в CSS код?"
70
+
71
+ #: admin/boot.php:107 admin/pages/settings.php:244
72
+ msgid "Inline and Defer CSS?"
73
+ msgstr "Встроить и отложить выполнение CSS?"
74
+
75
+ #: admin/boot.php:113 admin/pages/settings.php:255
76
+ msgid "Inline all CSS?"
77
+ msgstr "Поместить весь CSS код в теле страницы?"
78
+
79
+ #: admin/boot.php:119
80
+ msgid "Exclude CSS from Мinify And Combine"
81
+ msgstr "Исключить CSS файлы"
82
+
83
+ #: admin/boot.php:135
84
+ msgid "One click optimize scripts (js, css)"
85
+ msgstr "Оптимизировать скрипты (js, css) одним нажатием"
86
+
87
+ #: admin/boot.php:137
88
+ msgid "One click optimize html code and scripts"
89
+ msgstr "Оптимизировать Html код и скрипты одним нажатием"
90
+
91
+ #: admin/pages/settings.php:35
92
+ msgid "Minify And Combine (JS/CSS)"
93
+ msgstr "Сжатие и Объединение (JS/CSS)"
94
+
95
+ #: admin/pages/settings.php:60
96
+ msgid "Scripts Minify And Combine"
97
+ msgstr "Сжатие и объединение скриптов"
98
+
99
+ #: admin/pages/settings.php:61
100
+ msgid "General"
101
+ msgstr "Основные"
102
+
103
+ #: admin/pages/settings.php:96
104
+ msgid "The cache has been successfully cleaned."
105
+ msgstr "Кэш был успешно очищен."
106
+
107
+ #: admin/pages/settings.php:115
108
+ msgid "JavaScript Options"
109
+ msgstr "Настройки JavaScript"
110
+
111
+ #: admin/pages/settings.php:140
112
+ msgid ""
113
+ "Aggregate all linked JS-files to have them loaded non-render blocking? If "
114
+ "this option is off, the individual JS-files will remain in place but will be "
115
+ "minified."
116
+ msgstr ""
117
+
118
+ #: admin/pages/settings.php:150
119
+ msgid ""
120
+ "Let Мinify And Combine also extract JS from the HTML. Warning: this can make "
121
+ "Мinify And Combine's cache size grow quickly, so only enable this if you "
122
+ "know what you're doing."
123
+ msgstr ""
124
+ "Пусть Minify And Combine также извлекает JS из HTML. Предупреждение: это "
125
+ "может привести к быстрому увеличению размера кеша Minify и Combine, поэтому "
126
+ "включите его, только если вы знаете, что делаете."
127
+
128
+ #: admin/pages/settings.php:160
129
+ msgid ""
130
+ "Load JavaScript early, this can potentially fix some JS-errors, but makes "
131
+ "the JS render blocking."
132
+ msgstr ""
133
+
134
+ #: admin/pages/settings.php:169
135
+ msgid ""
136
+ "A comma-separated list of scripts you want to exclude from being optimized, "
137
+ "for example 'whatever.js, another.js' (without the quotes) to exclude those "
138
+ "scripts from being aggregated and minimized by Мinify And Combine."
139
+ msgstr ""
140
+ "Список сценариев, которые вы хотите исключить из оптимизации, например, "
141
+ "«whatever.js, another.js» (без кавычек), чтобы исключить агрегирование и "
142
+ "минимизацию этих сценариев с помощью Мinify And Combine."
143
+
144
+ #: admin/pages/settings.php:179 admin/pages/settings.php:200
145
+ msgid ""
146
+ "If your scripts break because of a JS-error, you might want to try this."
147
+ msgstr ""
148
+ "Если ваши сценарии прерываются из-за ошибки JS, вы можете попробовать это."
149
+
150
+ #: admin/pages/settings.php:191
151
+ msgid "CSS Options"
152
+ msgstr ""
153
+
154
+ #: admin/pages/settings.php:216
155
+ msgid ""
156
+ "Aggregate all linked CSS-files? If this option is off, the individual CSS-"
157
+ "files will remain in place but will be minified."
158
+ msgstr ""
159
+
160
+ #: admin/pages/settings.php:226
161
+ msgid ""
162
+ "Check this option for Мinify And Combine to also aggregate CSS in the HTML."
163
+ msgstr ""
164
+ "Установите этот параметр для Minify And Combine, чтобы агрегировать CSS в "
165
+ "HTML."
166
+
167
+ #: admin/pages/settings.php:236
168
+ msgid ""
169
+ "Enable this to include small background-images in the CSS itself instead of "
170
+ "as separate downloads."
171
+ msgstr ""
172
+
173
+ #: admin/pages/settings.php:246
174
+ msgid ""
175
+ "Inline \"above the fold CSS\" while loading the main auto optimized CSS only "
176
+ "after page load. Check the FAQ for more info.\n"
177
+ "This can be fully automated for different types of pages with the Мinify And "
178
+ "Combine CriticalCSS Power-Up."
179
+ msgstr ""
180
+ "Inline «над слоем CSS» при загрузке основного автоматически "
181
+ "оптимизированного CSS только после загрузки страницы. Проверьте часто "
182
+ "задаваемые вопросы для получения дополнительной информации. Это может быть "
183
+ "полностью автоматизировано для разных типов страниц с помощью Powerin Up и "
184
+ "Mineify и Combine CriticalCSS."
185
+
186
+ #: admin/pages/settings.php:257
187
+ msgid ""
188
+ "Inlining all CSS can improve performance for sites with a low pageviews/ "
189
+ "visitor-rate, but may slow down performance otherwise."
190
+ msgstr ""
191
+
192
+ #: admin/pages/settings.php:264
193
+ msgid "Exclude CSS from Мinify And Combine:"
194
+ msgstr ""
195
+
196
+ #: admin/pages/settings.php:266
197
+ msgid "A comma-separated list of CSS you want to exclude from being optimized."
198
+ msgstr ""
199
+
200
+ #: admin/pages/settings.php:278
201
+ msgid "Cache Info"
202
+ msgstr ""
203
+
204
+ #: admin/pages/settings.php:278
205
+ msgid "Описание раздела оптимизация"
206
+ msgstr ""
207
+
208
+ #: admin/pages/settings.php:351 includes/boot.php:48 includes/boot.php:64
209
+ msgid "Clear cache"
210
+ msgstr ""
211
+
212
+ #: includes/classes/class.mac-cache-checker.php:84
213
+ msgid "Мinify And Combine cache size warning"
214
+ msgstr ""
215
+
216
+ #: includes/classes/class.mac-cache-checker.php:85
217
+ msgid ""
218
+ "Мinify And Combine's cache size is getting big, consider purging the cache. "
219
+ "Have a look at https://wordpress.org/plugins/ to see how you can keep the "
220
+ "cache size under control."
221
+ msgstr ""
222
+
223
+ #: includes/classes/class.mac-cache-checker.php:107
224
+ msgid ""
225
+ "<strong>Мinify And Combine's cache size is getting big</strong>, consider "
226
+ "purging the cache. Have a look at <a href=\"https://wordpress.org/plugins/\" "
227
+ "target=\"_blank\" rel=\"noopener noreferrer\">the Мinify And Combine FAQ</a> "
228
+ "to see how you can keep the cache size under control."
229
+ msgstr ""
230
+
231
+ #: includes/classes/class.mac-main.php:417
232
+ #, php-format
233
+ msgid ""
234
+ "Мinify And Combine cannot write to the cache directory (%s), please fix to "
235
+ "enable CSS/ JS optimization!"
236
+ msgstr ""
237
+
238
+ #: minify-and-combine.php:34
239
+ msgid ""
240
+ "The job of the component \"Minify and Combine\" component has been "
241
+ "suspended! You are using the old version of PHP. Please update the PHP "
242
+ "version to 5.4 or later to continue to use this component!"
243
+ msgstr ""
244
+
245
+ #: minify-and-combine.php:53
246
+ msgid ""
247
+ "We found that you have the \"Clearfy - wordpress optimization plugin\" "
248
+ "plugin installed, this plugin already has \"Minify and combine\" functions, "
249
+ "so you can deactivate plugin \"Minify and combine\"!"
250
+ msgstr ""
251
+
252
+ #: minify-and-combine.php:130
253
+ msgid "Webcraftic minify and combine"
254
+ msgstr ""
255
+
256
+ #~ msgid "Disable comments on the entire site"
257
+ #~ msgstr "Отключить комментарии на всем сайте"
258
+
259
+ #~ msgid "Select post types"
260
+ #~ msgstr "Выбрать тип записи"
261
+
262
+ #~ msgid "Replace external links in comments on the JavaScript code"
263
+ #~ msgstr "Заменить внешние ссылки в комментариях на JavaScript код"
264
+
265
+ #~ msgid "Replace external links from comment authors on the JavaScript code"
266
+ #~ msgstr "Заменить внешние ссылки от авторов комментариев на код JavaScript"
267
+
268
+ #~ msgid "Disable X-Pingback"
269
+ #~ msgstr "Убрать ссылку на X-Pingback и возможность спамить pingback-ами"
270
+
271
+ #~ msgid "Remove field \"site\" in comment form"
272
+ #~ msgstr "Удаляет поле \"Сайт\" в форме комментариев"
273
+
274
+ #~ msgid "One click disable all comments"
275
+ #~ msgstr "Отключить все комментарии в один клик"
276
+
277
+ #~ msgid "Get ultimate plugin free"
278
+ #~ msgstr "Получите полную версию плагина бесплатно"
279
+
280
+ #~ msgid "Disable comments"
281
+ #~ msgstr "Отключить комментарии"
282
+
283
+ #~ msgid "Comments"
284
+ #~ msgstr "Комментарии"
285
+
286
+ #~ msgid "Global disabling of comments"
287
+ #~ msgstr "Глобальное отключение комментариев"
288
+
289
+ #~ msgid ""
290
+ #~ "What is the difference between these and native WordPress functions? "
291
+ #~ "WordPress disables comments only for new posts! Using the functions "
292
+ #~ "below, you can disable comments globally, even for old posts, and you can "
293
+ #~ "choose which post types comments to disable. The plugin also disables the "
294
+ #~ "comment functionality itself, which creates a certain load on the site."
295
+ #~ msgstr ""
296
+ #~ "Чем отличается эти функции от нативных функций Wordpress? Wordpress "
297
+ #~ "отключает комментарии только для новых записей! С помощью функций ниже, "
298
+ #~ "вы можете отключить комментарии глобально, даже для старых записей, "
299
+ #~ "причем вы можете выбрать для каких типов записей нужно отключить "
300
+ #~ "комментарии. Плагин также отключает сам функционал комментариев, который "
301
+ #~ "создает определенную нагрузку на сайт."
302
+
303
+ #~ msgid "Not disable"
304
+ #~ msgstr "Не отключать"
305
+
306
+ #~ msgid "Everywhere"
307
+ #~ msgstr "Повсюду"
308
+
309
+ #~ msgid ""
310
+ #~ "You can delete all comments in the database by clicking on this link (<a "
311
+ #~ "href=\"%s\">cleaning comments in database</a>)."
312
+ #~ msgstr ""
313
+ #~ "Вы можете удалить все комментарии в базе данных, нажав на эту ссылку ( <a "
314
+ #~ "href=\"%s\">очистка комментариев в базе данных</a> )."
315
+
316
+ #~ msgid "On certain post types"
317
+ #~ msgstr "Только выбранные типы записей"
318
+
319
+ #~ msgid ""
320
+ #~ "You can delete all comments for the selected post types. Select the post "
321
+ #~ "types below and save the settings. After that, click the link (<a href="
322
+ #~ "\"%s\">delete all comments for the selected post types in database</a>)."
323
+ #~ msgstr ""
324
+ #~ "Вы можете удалить все комментарии для выбранных типов записей. Выберите "
325
+ #~ "типы записей ниже и сохраните настройки. После этого нажмите ссылку ( <a "
326
+ #~ "href=\"%s\">удалите все комментарии для выбранных типов записей в базе "
327
+ #~ "данных</a> )."
328
+
329
+ #~ msgid ""
330
+ #~ "Everywhere - Warning: This option is global and will affect your entire "
331
+ #~ "site. Use it only if you want to disable comments everywhere. A complete "
332
+ #~ "description of what this option does is available here"
333
+ #~ msgstr ""
334
+ #~ "Повсюду - предупреждение: этот параметр является глобальным и повлияет на "
335
+ #~ "весь ваш сайт. Используйте его только в том случае, если вы хотите "
336
+ #~ "отключить комментарии повсюду. "
337
+
338
+ #~ msgid ""
339
+ #~ "On certain post types - Disabling comments will also disable trackbacks "
340
+ #~ "and pingbacks. All comment-related fields will also be hidden from the "
341
+ #~ "edit/quick-edit screens of the affected posts. These settings cannot be "
342
+ #~ "overridden for individual posts."
343
+ #~ msgstr ""
344
+ #~ "В некоторых типах сообщений - отключение комментариев также отключает "
345
+ #~ "трекбэки и pingback. Все поля, связанные с комментариями, также будут "
346
+ #~ "скрыты от экранов редактирования / быстрого редактирования затронутых "
347
+ #~ "сообщений. Эти настройки нельзя переопределять для отдельных сообщений."
348
+
349
+ #~ msgid "Select the post types for which comments will be disabled"
350
+ #~ msgstr "Выберите типы записей, для которых комментарии будут отключены."
351
+
352
+ #~ msgid "General settings for comments"
353
+ #~ msgstr "Общие настройки комментариев"
354
+
355
+ #~ msgid ""
356
+ #~ "These settings will help you improve SEO and reduce the amount of spam."
357
+ #~ msgstr ""
358
+ #~ "Эти настройки помогут вам улучшить SEO и уменьшить количество спама."
359
+
360
+ #~ msgid ""
361
+ #~ "Tired of spam in the comments? Do visitors leave \"blank\" comments for "
362
+ #~ "the sake of a link to their site?"
363
+ #~ msgstr ""
364
+ #~ "Надоел спам в комментариях? Посетители оставляют «пустые» комментарии "
365
+ #~ "ради ссылки на свой сайт?"
366
+
367
+ #~ msgid "Removes the \"Site\" field from the comment form."
368
+ #~ msgstr "Убирает поле «Сайт» из формы комментирования."
369
+
370
+ #~ msgid ""
371
+ #~ "Works with the standard comment form, if the form is manually written in "
372
+ #~ "your theme-it probably will not work!"
373
+ #~ msgstr ""
374
+ #~ "Работает со стандартной формой комментирования, если в Вашей теме форма "
375
+ #~ "прописана вручную - скорей всего не сработает!"
376
+
377
+ #~ msgid ""
378
+ #~ "Superfluous external links from comments, which can be typed from a dozen "
379
+ #~ "and more for one article, do not bring anything good for promotion."
380
+ #~ msgstr ""
381
+ #~ "Внешние ссылки в комментариях, которых может быть десятки или больше на "
382
+ #~ "одной странице, могут ухудшить продвижение вашего сайта."
383
+
384
+ #~ msgid "Replaces the links of this kind of %s, on links of this kind %s"
385
+ #~ msgstr ""
386
+ #~ "Заменяет ссылки %s, на span тег и устанавливает переход с помощью "
387
+ #~ "JavaScript %s"
388
+
389
+ #~ msgid ""
390
+ #~ "Up to 90 percent of comments in the blog can be left for the sake of an "
391
+ #~ "external link. Even nofollow from page weight loss here does not help."
392
+ #~ msgstr ""
393
+ #~ "До 90 процентов комментариев в блоге оставляют ради внешней ссылки. Не "
394
+ #~ "поможет даже nofollow от потери веса страницы."
395
+
396
+ #~ msgid ""
397
+ #~ "Replaces the links of the authors of comments on the JavaScript code, it "
398
+ #~ "is impossible to distinguish it from usual links."
399
+ #~ msgstr ""
400
+ #~ "Заменяет ссылки авторов комментариев на JavaScript код, его невозможно "
401
+ #~ "отличить от обычной ссылки."
402
+
403
+ #~ msgid "In some Wordpress topics this may not work."
404
+ #~ msgstr "В некоторых темах Wordpress это может не сработать."
405
+
406
+ #~ msgid "Disable XML-RPC"
407
+ #~ msgstr "Отключить XML-RPC"
408
+
409
+ #~ msgid ""
410
+ #~ "A pingback is basically an automated comment that gets created when "
411
+ #~ "another blog links to you. A self-pingback is created when you link to an "
412
+ #~ "article within your own blog. Pingbacks are essentially nothing more than "
413
+ #~ "spam and simply waste resources."
414
+ #~ msgstr ""
415
+ #~ "Pingback по-существу автоматизированных комментарий, который создается, "
416
+ #~ "когда другой блог ссылается на вас. Self-pingback создается, когда вы "
417
+ #~ "оставили ссылку на статью в своем блоге. Pingbacks по существу являются "
418
+ #~ "не более чем спам и пустая трата ресурсов вашего сайта."
419
+
420
+ #~ msgid "Removes the server responses a reference to the xmlrpc file."
421
+ #~ msgstr "Удаляет ссылку на xmlrpc-файл и ответ сервера."
422
+
423
+ #~ msgid "Comments cleaner"
424
+ #~ msgstr "Очистка комментариев"
425
+
426
+ #~ msgid "All comments have been deleted."
427
+ #~ msgstr "Все комментарии были удалены."
428
+
429
+ #~ msgid ""
430
+ #~ "An error occurred while trying to delete comments. Internal error "
431
+ #~ "occured. Please try again later."
432
+ #~ msgstr ""
433
+ #~ "При попытке удалить комментарии произошла ошибка. Пожалуйста, повторите "
434
+ #~ "попытку позже."
435
+
436
+ #~ msgid ""
437
+ #~ "Are you sure you want to delete comments from the database without "
438
+ #~ "restoring?"
439
+ #~ msgstr ""
440
+ #~ "Вы уверены, что вы хотите удалить комментарии из базы данных без "
441
+ #~ "восстановления?"
442
+
443
+ #~ msgid "Comments clearing tools"
444
+ #~ msgstr "Комментарии очищающие инструменты"
445
+
446
+ #~ msgid ""
447
+ #~ "These functions can be useful for global disabling comments or bulk "
448
+ #~ "cleaning spam comments."
449
+ #~ msgstr ""
450
+ #~ "Эти функции могут быть полезны для глобальных отключений комментариев или "
451
+ #~ "массовой очистки спама комментариев."
452
+
453
+ #~ msgid "Remove all comments"
454
+ #~ msgstr "Удалить все комментарии"
455
+
456
+ #~ msgid "You can delete all comments in your database with one click."
457
+ #~ msgstr ""
458
+ #~ "Вы можете удалить все комментарии в базе данных с одним щелчком мыши."
459
+
460
+ #~ msgid "Choose post types"
461
+ #~ msgstr "Выберите типы записей"
462
+
463
+ #~ msgid "Select all"
464
+ #~ msgstr "Выбрать все"
465
+
466
+ #~ msgid "Delete Woocommerce order notices? (%d)"
467
+ #~ msgstr "Удалять заметки от заказов Woocommerce? (%d)"
468
+
469
+ #~ msgid "Delete (%d)"
470
+ #~ msgstr "Удалить (%d)"
471
+
472
+ #~ msgid "Remove spam comments"
473
+ #~ msgstr "Удалить спам комментарии"
474
+
475
+ #~ msgid "You can remove only spam comments from the database with one click."
476
+ #~ msgstr ""
477
+ #~ "Вы можете одним нажатием удалить только спам комментарии из базы данных."
478
+
479
+ #~ msgid "Remove unapproved comments"
480
+ #~ msgstr "Удалить неподтвержденные комментарии"
481
+
482
+ #~ msgid ""
483
+ #~ "You can remove only unapproved comments from the database with one click."
484
+ #~ msgstr ""
485
+ #~ "Вы можете одним нажатием удалить только не подтвержденные комментарии из "
486
+ #~ "базы данных."
487
+
488
+ #~ msgid "Remove trashed comments"
489
+ #~ msgstr "Удалить комментарии из корзины"
490
+
491
+ #~ msgid ""
492
+ #~ "You can remove only trashed comments from the database with one click."
493
+ #~ msgstr "Вы можете одним нажатием удалить только комментарии из корзины."
494
+
495
+ #~ msgid ""
496
+ #~ "We found that you have the \"Clearfy - disable unused features\" plugin "
497
+ #~ "installed, this plugin already has disable comments functions, so you can "
498
+ #~ "deactivate plugin \"Disable comments\"!"
499
+ #~ msgstr ""
500
+ #~ "Мы обнаружили, что у вас установлен плагин «Clearfy - отключить "
501
+ #~ "неиспользуемые функции», этот плагин уже имеет функции отключения "
502
+ #~ "комментариев, поэтому вы можете отключить плагин «Отключить комментарии»!"
503
+
504
+ #~ msgid "Webcraftic Disable comments"
505
+ #~ msgstr "Webcraftic отключить комментарии"
506
+
507
+ #~ msgid "Comments are closed."
508
+ #~ msgstr "Комментарии Закрыты."
509
+
510
+ #~ msgid ""
511
+ #~ "Note: The <em>%s</em> plugin is currently active, and comments are "
512
+ #~ "completely disabled on: %s. Many of the settings below will not be "
513
+ #~ "applicable for those post types."
514
+ #~ msgstr ""
515
+ #~ "Примечание. Плагин <em>%s</em> в настоящий момент активен, и комментарии "
516
+ #~ "полностью отключены: %s. Многие из приведенных ниже настроек не будут "
517
+ #~ "применяться для этих типов сообщений."
518
+
519
+ #~ msgid "Recommended"
520
+ #~ msgstr "Рекомендовано"
521
+
522
+ #~ msgid "You are not allowed to view this page."
523
+ #~ msgstr "Вам не разрешено просматривать эту страницу."
524
+
525
+ #~ msgid "You do not have the selected post types!"
526
+ #~ msgstr "Вы не выбрали еще ни одного типа записей!"
527
+
528
+ #~ msgid "No comments available for deletion."
529
+ #~ msgstr "Нет комментариев для удаления."
530
+
531
+ #~ msgid ""
532
+ #~ "Are you sure that you desire to delete all comments from the database?"
533
+ #~ msgstr "Вы уверены, что хотите удалить все комментарии из базы данных?"
534
+
535
+ #~ msgid ""
536
+ #~ "Deleting comments will remove existing comment entries in the database "
537
+ #~ "and cannot be reverted without a database backup."
538
+ #~ msgstr ""
539
+ #~ "При удалении комментариев удаляются существующие записи комментариев в "
540
+ #~ "базе данных, они не могут быть восстановлены без резервного копирования "
541
+ #~ "базы данных."
542
+
543
+ #~ msgid "You have %s comments"
544
+ #~ msgstr "У вас есть %s комментариев"
545
+
546
+ #~ msgid "Yes, I'm sure"
547
+ #~ msgstr "Да, я уверен"
548
+
549
+ #~ msgid "No, return back"
550
+ #~ msgstr "Нет, вернуться"
551
+
552
+ #~ msgid ""
553
+ #~ "Are you sure that you desire to delete all comments from the database for "
554
+ #~ "the selected post types (%s)?"
555
+ #~ msgstr ""
556
+ #~ "Вы уверены, что хотите удалить все комментарии из базы данных для "
557
+ #~ "выбранных типов записей (%s)?"
558
+
559
+ #~ msgid "Webcraftic comments tweaks"
560
+ #~ msgstr "Webcraftic инструменты комментариев"
561
+
562
+ #~ msgid ""
563
+ #~ "We found that you have the \"Clearfy - disable unused features\" plugin "
564
+ #~ "installed, this plugin already has disable comments functions, so you can "
565
+ #~ "deactivate plugin \"Comments tweaks\"!"
566
+ #~ msgstr ""
567
+ #~ "Мы обнаружили, что у вас установлен плагин «Clearfy - отключить "
568
+ #~ "неиспользуемые функции», этот плагин уже имеет функции отключения "
569
+ #~ "комментариев, поэтому вы можете отключить плагин «Инструменты "
570
+ #~ "комментариев»!"
571
+
572
+ #~ msgid "Disable all comments"
573
+ #~ msgstr "Отключить все комментарии"
components/minify-and-combine/minify-and-combine.php ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Plugin Name: Мinify And Combine
4
+ * Plugin URI: https://clearfy.pro/minify-and-combine/
5
+ * Description: Optimizes your website, concatenating the CSS and JavaScript code, and compressing it.
6
+ * Author: Webcraftic <wordpress.webraftic@gmail.com>
7
+ * Version: 1.0.1
8
+ * Text Domain: minify-and-combine
9
+ * Domain Path: /languages/
10
+ * Author URI: https://clearfy.pro
11
+ */
12
+
13
+ /*
14
+ * #### CREDITS ####
15
+ * This plugin is based on the plugin Autoptimize by the author Frank Goossens, we have finalized this code for our project and our goals.
16
+ * Many thanks to Frank Goossens for the quality solution for optimizing scripts in Wordpress.
17
+ *
18
+ * Public License is a GPLv2 compatible license allowing you to change and use this version of the plugin for free.
19
+ */
20
+
21
+ // Exit if accessed directly
22
+ if( !defined('ABSPATH') ) {
23
+ exit;
24
+ }
25
+
26
+ /**
27
+ * Troubleshoot old versions of PHP on the client server
28
+ */
29
+ if( version_compare(PHP_VERSION, '5.4.0', '<') ) {
30
+ function wbcr_mac_admin_notice_php_error()
31
+ {
32
+ ?>
33
+ <div class="notice notice-error">
34
+ <p><?php _e('The job of the component "Minify and Combine" component has been suspended! You are using the old version of PHP. Please update the PHP version to 5.4 or later to continue to use this component!', 'minify-and-combine'); ?></p>
35
+ </div>
36
+ <?php
37
+ }
38
+
39
+ add_action('admin_notices', 'wbcr_mac_admin_notice_php_error');
40
+ return;
41
+ }
42
+
43
+
44
+ /**
45
+ * Notification that this plugin is already used as part of the Clearfy plugin as its component.
46
+ * We block the work of this plugin, so as not to cause conflict.
47
+ */
48
+ if( defined('WMAC_PLUGIN_ACTIVE') || (defined('WMAC_PLUGIN_ACTIVE') && !defined('LOADING_MINIFY_AND_COMBINE_AS_ADDON')) ) {
49
+ function wbcr_mac_admin_notice_error()
50
+ {
51
+ ?>
52
+ <div class="notice notice-error">
53
+ <p><?php _e('We found that you have the "Clearfy - wordpress optimization plugin" plugin installed, this plugin already has "Minify and combine" functions, so you can deactivate plugin "Minify and combine"!'); ?></p>
54
+ </div>
55
+ <?php
56
+ }
57
+
58
+ add_action('admin_notices', 'wbcr_mac_admin_notice_error');
59
+
60
+ return;
61
+ } else {
62
+
63
+ // Устанавливаем контстанту, что плагин уже используется
64
+ define('WMAC_PLUGIN_ACTIVE', true);
65
+
66
+ // Директория плагина
67
+ define('WMAC_PLUGIN_DIR', dirname(__FILE__));
68
+
69
+ // Относительный путь к плагину
70
+ define('WMAC_PLUGIN_BASE', plugin_basename(__FILE__));
71
+
72
+ // Ссылка к директории плагина
73
+ define('WMAC_PLUGIN_URL', plugins_url(null, __FILE__));
74
+
75
+
76
+
77
+ // Этот плагин может быть аддоном плагина Clearfy, если он загружен, как аддон, то мы не подключаем фреймворк,
78
+ // а наследуем функции фреймворка от плагина Clearfy. Если плагин скомпилирован, как отдельный плагин, то он использует собственный фреймворк для работы.
79
+ // Константа LOADING_MINIFY_AND_COMBINE_AS_ADDON утсанавливается в классе libs/factory/core/includes/Wbcr_Factory406_Plugin
80
+
81
+ if( !defined('LOADING_MINIFY_AND_COMBINE_AS_ADDON') ) {
82
+ // Фреймворк - отвечает за интерфейс, содержит общие функции для серии плагинов и готовые шаблоны для быстрого развертывания плагина.
83
+ require_once(WMAC_PLUGIN_DIR . '/libs/factory/core/boot.php');
84
+ }
85
+
86
+ // Основной класс плагина
87
+ require_once(WMAC_PLUGIN_DIR . '/includes/class.plugin.php');
88
+
89
+ // Класс WMAC_Plugin создается только, если этот плагин работает, как самостоятельный плагин.
90
+ // Если плагин работает, как аддон, то класс создается родительским плагином.
91
+
92
+ if( !defined('LOADING_MINIFY_AND_COMBINE_AS_ADDON') ) {
93
+ new WMAC_Plugin(__FILE__, array(
94
+ 'prefix' => 'wbcr_mac_', // префикс для базы данных и полей формы
95
+ 'plugin_name' => 'wbcr_minify_and_combine', // имя плагина, как уникальный идентификатор
96
+ 'plugin_title' => __('Webcraftic minify and combine', 'minify-and-combine'), // заголовок плагина
97
+ 'plugin_version' => '1.0.1', // текущая версия плагина
98
+ 'required_php_version' => '5.2', // минимальная версия php для работы плагина
99
+ 'required_wp_version' => '4.2', // минимальная версия wp для работы плагина
100
+ 'plugin_build' => 'free', // сборка плагина
101
+ //'updates' => WMAC_PLUGIN_DIR . '/updates/' в этой папке хранятся миграции для разных версий плагина
102
+ ));
103
+ }
104
+ }
components/minify-and-combine/readme.txt ADDED
@@ -0,0 +1,155 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ === Disable Comments for Any Post Types (Remove comments) ===
2
+ Tags: disable comments, disable XML-RPC, remove comments, delete comments, no self pings, wp disable, disable pingback comments, comments manager, webcraftic update manager, clearfy, replace external links, remove comment form, comment form, remove comment form fields, bulk comments management, spam comments cleaner, delete comments by status, no page comment, wp disable comments
3
+ Contributors: webcraftic
4
+ Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=VDX7JNTQPNPFW
5
+ Requires at least: 4.2
6
+ Tested up to: 4.9
7
+ Requires PHP: 5.2
8
+ Stable tag: trunk
9
+ License: GPLv2
10
+
11
+ Allows administrators to disable comments on their website. Comments can be disabled according to Post, Page, Media type.
12
+
13
+ == Description ==
14
+
15
+ <strong>Disable comments</strong> plugin is a useful tool for blog or site administrators that allows fully disabling or hiding comments for any post types, pages or attachments.
16
+
17
+ It removes the all comments related features and options:
18
+
19
+ * <strong>disable comments</strong> on frontend at all;
20
+ * <strong>remove comments</strong> option from WordPress dashboard menu;
21
+ * <strong>hide comments</strong> option from the admin bar;
22
+ * <strong>Turn off comments widgets.</strong>
23
+
24
+ In addition, this plugin can <strong>disable XML-RPC</strong> related functions in WordPress including disable pingbacks and disable trackbacks, and helps to prevent the attacks on the xmlrpc.php file. Lastly, it attempts to generate a “403 Denied” error for requests to the /xmlrpc.php URL, but does not affect that file or your server in any way.
25
+
26
+ If you want <strong>completely remove comments</strong>, you can do this individually for selected post types. You can easily bulk delete all WordPress comments in some clicks. No any other “Delete All Comments” plugins or phpMyAdmin needed.
27
+
28
+ You can disable comments but if you decide to leave them, you need to close comments external links from the search engines. By default when users places comments, the WordPress adds rel=”nofollow” attribute to the comment author URL and for all links in the comments text. However, already for a long time, search engines ignores this and follows links. It makes dozens of superfluous external links from comments that are do not bring anything good for your SEO. <strong>Disable Comments</strong> plugin makes all external links in WordPress comments invisible for search engines with Javascript and improves your blog or website SEO.
29
+
30
+ In addition, if you do not want to disable comments you may need to remove website field from the WordPress comment form. Note: you can remove comment author URL but this feature can be not work with some themes.
31
+
32
+ Generally, the <strong>Disable Comments</strong> plugin uses the intelligent algorithm to <strong>hide comments</strong> and <strong>remove comments</strong>. You just need to turn some toggles on.
33
+
34
+ If you come across any bugs or have suggestions with <strong>Disable Comments</strong>, please use the plugin support forum. I cannot fix them if I do not know about! Please check the FAQ for common issues.
35
+
36
+
37
+ == Frequently Asked Questions ==
38
+
39
+ = Nothing happens after I disable comments on all posts – comment forms are still appears inside my posts. =
40
+
41
+ That is because your theme is not checking the comment status of posts in the correct way.
42
+
43
+ You may like to point your theme’s author to this explanation of what they are doing wrong, and how to fix it.
44
+
45
+ = How can I remove the text “comments are closed” at the bottom of articles when comments are disabled? =
46
+
47
+ The plugin tries to hide it (and any other comment-related elements) as well as possible.
48
+
49
+ If you still see this message, it means that your theme is overrides this behavior and you will have to edit its files manually for fix it. Two common approaches are to either delete or comment out the relevant lines in wp-content/your-theme/comments.php, or to add a declaration to wp-content/your-theme/style.css that hides the message from your visitors. In either case, make know what you are doing!
50
+
51
+ = I only want to disable comments on certain posts, not globally. What do I need to do? =
52
+
53
+ Do not install this plugin!
54
+
55
+ Go to the edit page for the post you want to disable comments. Scroll down to the “Discussion” box, where you will find the comment options for that post. If you do not see a “Discussion” box, then click on “Screen Options” at the top of your screen, and make sure the “Discussion” checkbox is checked.
56
+
57
+ You can also bulk-edit the comment status of multiple posts from the posts screen.
58
+
59
+ = I want to delete comments from my database. What do I need to do? =
60
+
61
+ When you will change the plugin settings, you will be prompt to delete comments from the database.
62
+
63
+ == Details ==
64
+
65
+ The Disable Comments plugin allows you <strong>completely disable the commenting feature in WordPress</strong>. When this option is on you will get the following changes:
66
+
67
+ <strong>* Easy Enable or disable Comments;</strong>
68
+ <strong>* Disable comments globally;</strong>
69
+ <strong>* Disable comments on certain Pages;</strong>
70
+ <strong>* Disable comments on posts Only;</strong>
71
+ <strong>* Disable comments on pages Only;</strong>
72
+ <strong>* Disable comments for any post types;</strong>
73
+ <strong>* Disable comments links in the Admin Menu and Admin Bar;</strong>
74
+ <strong>* Disable comments related sections (“Recent Comments”, “Discussion” etc.) and hide from the WordPress Dashboard;</strong>
75
+ <strong>* Disable comments related widgets (so your theme cannot to use them);</strong>
76
+ <strong>* Disable comments “Discussion” settings page;</strong>
77
+ <strong>* Disable comments in RSS/Atom feeds (and requests for comments RSS will be redirect to the parent post);</strong>
78
+ <strong>* Disable X-Pingback HTTP header and remove from all pages;</strong>
79
+ <strong>* Disable outgoing pingbacks;</strong>
80
+ <strong>* Making comments external links “nofollow” and invisible for search engines;</strong>
81
+ <strong>* Remove website/URL field from the comment form;</strong>
82
+ <strong>* Remove comments, Delete comments in one click.</strong>
83
+
84
+ We recently added brand new features into the <strong>Disable Comments plugin</strong>. These are <strong>Disable X-Pingback</strong> function, <strong>Replace external links</strong> and <strong>Remove website/url comment field</strong>.
85
+
86
+ Some functions was taken from the following popular plugins: <strong>Clearfy – disable unused features</strong>, <strong>Bulk Comments Management</strong>, <strong>Spam Comments Cleaner</strong>, <strong>Delete Comments By Status</strong>, <strong>No Page Comment</strong>, <strong>WP Disable Comments</strong>, <strong>Hide “Comments are closed”</strong>, <strong>Hide Show Comment</strong>.
87
+
88
+ == Advanced Configuration ==
89
+
90
+ Site administrators and plugin/theme developers can modify some of the plugin’s behavior through the code:
91
+
92
+ Define DISABLE_COMMENTS_REMOVE_COMMENTS_TEMPLATE and set it to false to prevent the plugin from replacing theme’s comment template with an empty one.
93
+
94
+ These definitions can be make either in your main wp-config.php or in your theme’s functions.php file.
95
+
96
+ #### RECOMMENDED SEPARATE MODULES ####
97
+ We invite you to check out a few other related free plugins that our team has also produced that you may find especially useful:
98
+
99
+ * [Clearfy – WordPress optimization plugin and disable ultimate tweaker](https://wordpress.org/plugins/clearfy/)
100
+ * [Disable updates, Disable automatic updates, Updates manager](https://wordpress.org/plugins/webcraftic-updates-manager/)
101
+ * [Cyrlitera – transliteration of links and file names](https://wordpress.org/plugins/cyrlitera/)
102
+ * [Cyr-to-lat reloaded – transliteration of links and file names](https://wordpress.org/plugins/cyr-and-lat/ "Cyr-to-lat reloaded")
103
+ * [Disable admin notices individually](https://wordpress.org/plugins/disable-admin-notices/ "Disable admin notices individually")
104
+ * [WordPress Assets manager, dequeue scripts, dequeue styles](https://wordpress.org/plugins/gonzales/ "WordPress Assets manager, dequeue scripts, dequeue styles")
105
+ * [Hide login page](https://wordpress.org/plugins/hide-login-page/ "Hide login page")
106
+
107
+ == Translations ==
108
+
109
+ * English - default, always included
110
+ * Russian
111
+
112
+ If you want to help with the translation, please contact me through this site or through the contacts inside the plugin.
113
+
114
+ == Installation ==
115
+
116
+ 1. Upload the plugin folder to the `/wp-content/plugins/` directory
117
+ 2. Activate the plugin through the 'Plugins' menu in WordPress
118
+ 3. The plugin settings can be accessed via the 'Settings' menu in the administration area (either your site administration for single-site installs).
119
+
120
+ == Screenshots ==
121
+ 1. Control panel (General)
122
+ 2. Control panel (Remove comments)
123
+
124
+ == Changelog ==
125
+ = 1.0.9 =
126
+ * Fixed: Update core
127
+
128
+ = 1.0.8 =
129
+ * Fixed: Update core
130
+ * Fixed: Small bugs
131
+ * Fixed: Translations
132
+
133
+ = 1.0.7 =
134
+ * Fixed: Update core
135
+ * ADDED: Plugin options caching to reduce database queries for 90%. Clearfy became lighter and faster.
136
+ * ADDED: Compress and cache the plugin core files, to reduce the load on the admin panel
137
+
138
+ = 1.0.5 =
139
+ * Added a new feature: Added page for cleaning comments
140
+ * Fixed: Bugs with Woocommerce
141
+
142
+ = 1.0.4 =
143
+ * Update plugin core
144
+ * Fixed bug reduced plugin weight.
145
+ * Fixed JS error with external links option.
146
+ * Add french translation
147
+
148
+ = 1.0.3 =
149
+ * Update plugin core
150
+
151
+ = 1.0.2 =
152
+ * Fixed a bug where you selected the recommended mode, on some pages you see a white screen. Now you will not encounter this error.
153
+
154
+ = 1.0.1 =
155
+ * Plugin release
components/minify-and-combine/uninstall.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // if uninstall.php is not called by WordPress, die
4
+ if( !defined('WP_UNINSTALL_PLUGIN') ) {
5
+ die;
6
+ }
7
+
8
+ if ( ! defined( 'WMAC_PLUGIN_DIR' ) ) {
9
+ define( 'WMAC_PLUGIN_DIR', dirname( __FILE__ ) );
10
+ }
11
+
12
+ require_once( WMAC_PLUGIN_DIR . '/includes/classes/class.mac-cache.php' );
13
+ require_once( WMAC_PLUGIN_DIR . '/includes/classes/class.mac-main.php' );
14
+
15
+ /**
16
+ * Удаление кеша и опций
17
+ */
18
+ function uninstal() {
19
+ $plugin = new WMAC_PluginMain();
20
+ $plugin->setup();
21
+
22
+ WMAC_PluginCache::clearAll();
23
+
24
+ // remove plugin options
25
+ global $wpdb;
26
+
27
+ $wpdb->query("DELETE FROM {$wpdb->prefix}options WHERE option_name LIKE 'wbcr_mac_%';");
28
+ }
29
+
30
+ if ( is_multisite() ) {
31
+ $sites = get_sites( array(
32
+ 'archived' => 0,
33
+ 'mature' => 0,
34
+ 'spam' => 0,
35
+ 'deleted' => 0,
36
+ ) );
37
+
38
+ foreach ( $sites as $site ) {
39
+ switch_to_blog( $site->blog_id );
40
+
41
+ uninstal();
42
+
43
+ restore_current_blog();
44
+ }
45
+ } else {
46
+ uninstal();
47
+ }
components/updates-manager/admin/boot.php CHANGED
@@ -9,61 +9,59 @@
9
  /**
10
  * Ошибки совместимости с похожими плагинами
11
  */
12
- function wbcr_upm_admin_conflict_notices_error()
13
  {
14
- $notices = array();
 
 
 
 
15
 
16
  $default_notice = WUP_Plugin::app()
17
  ->getPluginTitle() . ': ' . __('We found that you have the plugin %s installed. The functions of this plugin already exist in %s. Please deactivate plugin %s to avoid conflicts between plugins\' functions.', 'webcraftic-updates-manager');
18
  $default_notice .= ' ' . __('If you do not want to deactivate the plugin %s for some reason, we strongly recommend do not use the same plugins\' functions at the same time!', 'webcraftic-updates-manager');
19
 
20
  if( is_plugin_active('companion-auto-update/companion-auto-update.php') ) {
21
- $notices[] = sprintf($default_notice, 'Companion Auto Update', WUP_Plugin::app()
22
  ->getPluginTitle(), 'Companion Auto Update', 'Companion Auto Update');
23
  }
24
 
25
  if( is_plugin_active('disable-updates/disable-updates.php') ) {
26
- $notices[] = sprintf($default_notice, 'Disable Updates', WUP_Plugin::app()
27
  ->getPluginTitle(), 'Disable Updates', 'Disable Updates');
28
  }
29
 
30
  if( is_plugin_active('disable-wordpress-updates/disable-updates.php') ) {
31
- $notices[] = sprintf($default_notice, 'Disable All WordPress Updates', WUP_Plugin::app()
32
  ->getPluginTitle(), 'Disable All WordPress Updates', 'Disable All WordPress Updates');
33
  }
34
 
35
  if( is_plugin_active('stops-core-theme-and-plugin-updates/main.php') ) {
36
- $notices[] = sprintf($default_notice, 'Easy Updates Manager', WUP_Plugin::app()
37
  ->getPluginTitle(), 'Easy Updates Manager', 'Easy Updates Manager');
38
  }
39
 
40
- if( empty($notices) ) {
41
- return;
42
  }
43
-
44
- ?>
45
- <div id="wbcr-update-manager-conflict-error" class="notice notice-error is-dismissible">
46
- <?php foreach((array)$notices as $notice): ?>
47
- <p>
48
- <?= $notice ?>
49
- </p>
50
- <?php endforeach; ?>
51
- </div>
52
- <?php
53
- }
54
-
55
- add_action('admin_notices', 'wbcr_upm_admin_conflict_notices_error');
56
-
57
- function wbcr_upm_rating_widget_url($page_url, $plugin_name)
58
- {
59
- if( $plugin_name == WUP_Plugin::app()->getPluginName() ) {
60
- return 'https://goo.gl/Be2hQU';
61
  }
62
 
63
- return $page_url;
 
 
 
 
 
 
 
 
64
  }
65
 
66
- add_filter('wbcr_factory_pages_401_imppage_rating_widget_url', 'wbcr_upm_rating_widget_url', 10, 2);
 
67
 
68
  function wbcr_upm_group_options($options)
69
  {
@@ -126,7 +124,16 @@
126
  function wbcr_ump_set_plugin_meta($links, $file)
127
  {
128
  if( $file == WUP_PLUGIN_BASE ) {
129
- $links[] = '<a href="https://goo.gl/TcMcS4" style="color: #FF5722;font-weight: bold;" target="_blank">' . __('Get ultimate plugin free', 'webcraftic-updates-manager') . '</a>';
 
 
 
 
 
 
 
 
 
130
  }
131
 
132
  return $links;
@@ -136,6 +143,24 @@
136
  add_filter('plugin_row_meta', 'wbcr_ump_set_plugin_meta', 10, 2);
137
  }
138
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
 
140
 
141
 
9
  /**
10
  * Ошибки совместимости с похожими плагинами
11
  */
12
+ function wbcr_upm_admin_conflict_notices_error($notices, $plugin_name)
13
  {
14
+ if( $plugin_name != WUP_Plugin::app()->getPluginName() ) {
15
+ return $notices;
16
+ }
17
+
18
+ $warnings = array();
19
 
20
  $default_notice = WUP_Plugin::app()
21
  ->getPluginTitle() . ': ' . __('We found that you have the plugin %s installed. The functions of this plugin already exist in %s. Please deactivate plugin %s to avoid conflicts between plugins\' functions.', 'webcraftic-updates-manager');
22
  $default_notice .= ' ' . __('If you do not want to deactivate the plugin %s for some reason, we strongly recommend do not use the same plugins\' functions at the same time!', 'webcraftic-updates-manager');
23
 
24
  if( is_plugin_active('companion-auto-update/companion-auto-update.php') ) {
25
+ $warnings[] = sprintf($default_notice, 'Companion Auto Update', WUP_Plugin::app()
26
  ->getPluginTitle(), 'Companion Auto Update', 'Companion Auto Update');
27
  }
28
 
29
  if( is_plugin_active('disable-updates/disable-updates.php') ) {
30
+ $warnings[] = sprintf($default_notice, 'Disable Updates', WUP_Plugin::app()
31
  ->getPluginTitle(), 'Disable Updates', 'Disable Updates');
32
  }
33
 
34
  if( is_plugin_active('disable-wordpress-updates/disable-updates.php') ) {
35
+ $warnings[] = sprintf($default_notice, 'Disable All WordPress Updates', WUP_Plugin::app()
36
  ->getPluginTitle(), 'Disable All WordPress Updates', 'Disable All WordPress Updates');
37
  }
38
 
39
  if( is_plugin_active('stops-core-theme-and-plugin-updates/main.php') ) {
40
+ $warnings[] = sprintf($default_notice, 'Easy Updates Manager', WUP_Plugin::app()
41
  ->getPluginTitle(), 'Easy Updates Manager', 'Easy Updates Manager');
42
  }
43
 
44
+ if( empty($warnings) ) {
45
+ return $notices;
46
  }
47
+ $notice_text = '';
48
+ foreach((array)$warnings as $warning) {
49
+ $notice_text .= '<p>' . $warning . '</p>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  }
51
 
52
+ $notices[] = array(
53
+ 'id' => 'ump_plugin_compatibility',
54
+ 'type' => 'error',
55
+ 'dismissible' => true,
56
+ 'dismiss_expires' => 0,
57
+ 'text' => $notice_text
58
+ );
59
+
60
+ return $notices;
61
  }
62
 
63
+ //add_action('admin_notices', 'wbcr_upm_admin_conflict_notices_error');
64
+ add_filter('wbcr_factory_notices_405_list', 'wbcr_upm_admin_conflict_notices_error', 10, 2);
65
 
66
  function wbcr_upm_group_options($options)
67
  {
124
  function wbcr_ump_set_plugin_meta($links, $file)
125
  {
126
  if( $file == WUP_PLUGIN_BASE ) {
127
+
128
+ $url = 'https://clearfy.pro';
129
+
130
+ if( get_locale() == 'ru_RU' ) {
131
+ $url = 'https://ru.clearfy.pro';
132
+ }
133
+
134
+ $url .= '?utm_source=wordpress.org&utm_campaign=' . WUP_Plugin::app()->getPluginName();
135
+
136
+ $links[] = '<a href="' . $url . '" style="color: #FF5722;font-weight: bold;" target="_blank">' . __('Get ultimate plugin free', 'webcraftic-updates-manager') . '</a>';
137
  }
138
 
139
  return $links;
143
  add_filter('plugin_row_meta', 'wbcr_ump_set_plugin_meta', 10, 2);
144
  }
145
 
146
+ /**
147
+ * Rating widget url
148
+ *
149
+ * @param string $page_url
150
+ * @param string $plugin_name
151
+ * @return string
152
+ */
153
+ function wbcr_upm_rating_widget_url($page_url, $plugin_name)
154
+ {
155
+ if( !defined('LOADING_UPDATES_MANAGER_AS_ADDON') && ($plugin_name == WUP_Plugin::app()->getPluginName()) ) {
156
+ return 'https://goo.gl/Be2hQU';
157
+ }
158
+
159
+ return $page_url;
160
+ }
161
+
162
+ add_filter('wbcr_factory_pages_407_imppage_rating_widget_url', 'wbcr_upm_rating_widget_url', 10, 2);
163
+
164
 
165
 
166
 
components/updates-manager/admin/pages/advanced.php CHANGED
@@ -10,13 +10,13 @@
10
  exit;
11
  }
12
 
13
- class WbcrUpm_AdvancedPage extends Wbcr_FactoryPages401_ImpressiveThemplate {
14
 
15
  /**
16
  * The id of the page in the admin menu.
17
  *
18
  * Mainly used to navigate between pages.
19
- * @see FactoryPages401_AdminPage
20
  *
21
  * @since 1.0.0
22
  * @var string
@@ -30,14 +30,32 @@
30
  public $page_menu_dashicon = 'dashicons-cloud';
31
 
32
  /**
33
- * @param Wbcr_Factory400_Plugin $plugin
34
  */
35
- public function __construct(Wbcr_Factory400_Plugin $plugin)
36
  {
37
  $this->menu_title = __('Advanced', 'webcraftic-updates-manager');
38
 
39
  parent::__construct($plugin);
40
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
 
42
  public function warningNotice()
43
  {
10
  exit;
11
  }
12
 
13
+ class WbcrUpm_AdvancedPage extends Wbcr_FactoryPages407_ImpressiveThemplate {
14
 
15
  /**
16
  * The id of the page in the admin menu.
17
  *
18
  * Mainly used to navigate between pages.
19
+ * @see FactoryPages407_AdminPage
20
  *
21
  * @since 1.0.0
22
  * @var string
30
  public $page_menu_dashicon = 'dashicons-cloud';
31
 
32
  /**
33
+ * @param Wbcr_Factory406_Plugin $plugin
34
  */
35
+ public function __construct(Wbcr_Factory406_Plugin $plugin)
36
  {
37
  $this->menu_title = __('Advanced', 'webcraftic-updates-manager');
38
 
39
  parent::__construct($plugin);
40
  }
41
+
42
+ /**
43
+ * Requests assets (js and css) for the page.
44
+ *
45
+ * @see Wbcr_FactoryPages407_AdminPage
46
+ *
47
+ * @since 1.0.0
48
+ * @return void
49
+ */
50
+ public function assets($scripts, $styles)
51
+ {
52
+ parent::assets($scripts, $styles);
53
+
54
+ // Add Clearfy styles for HMWP pages
55
+ if( defined('WBCR_CLEARFY_PLUGIN_ACTIVE') ) {
56
+ $this->styles->add(WCL_PLUGIN_URL . '/admin/assets/css/general.css');
57
+ }
58
+ }
59
 
60
  public function warningNotice()
61
  {
components/updates-manager/admin/pages/more-features.php CHANGED
@@ -11,6 +11,6 @@
11
  exit;
12
  }
13
 
14
- class WbcrUpm_MoreFeaturesPage extends Wbcr_FactoryClearfy200_MoreFeaturesPage {
15
 
16
  }
11
  exit;
12
  }
13
 
14
+ class WbcrUpm_MoreFeaturesPage extends Wbcr_FactoryClearfy203_MoreFeaturesPage {
15
 
16
  }
components/updates-manager/admin/pages/plugins.php CHANGED
@@ -12,13 +12,13 @@
12
  }
13
 
14
 
15
- class WbcrUpm_PluginsPage extends Wbcr_FactoryPages401_ImpressiveThemplate {
16
 
17
  /**
18
  * The id of the page in the admin menu.
19
  *
20
  * Mainly used to navigate between pages.
21
- * @see FactoryPages401_AdminPage
22
  *
23
  * @since 1.0.0
24
  * @var string
@@ -56,9 +56,9 @@
56
  private $plugins_update_filters = array();
57
 
58
  /**
59
- * @param Wbcr_Factory400_Plugin $plugin
60
  */
61
- public function __construct(Wbcr_Factory400_Plugin $plugin)
62
  {
63
  $this->menu_title = __('Plugins', 'webcraftic-updates-manager');
64
 
@@ -93,7 +93,7 @@
93
  /**
94
  * Requests assets (js and css) for the page.
95
  *
96
- * @see FactoryPages401_AdminPage
97
  *
98
  * @since 1.0.0
99
  * @return void
@@ -102,6 +102,11 @@
102
  {
103
  parent::assets($scripts, $styles);
104
  $this->styles->add(WUP_PLUGIN_URL . '/admin/assets/css/general.css');
 
 
 
 
 
105
  }
106
 
107
  public function savePluginsUpdateFilters()
12
  }
13
 
14
 
15
+ class WbcrUpm_PluginsPage extends Wbcr_FactoryPages407_ImpressiveThemplate {
16
 
17
  /**
18
  * The id of the page in the admin menu.
19
  *
20
  * Mainly used to navigate between pages.
21
+ * @see FactoryPages407_AdminPage
22
  *
23
  * @since 1.0.0
24
  * @var string
56
  private $plugins_update_filters = array();
57
 
58
  /**
59
+ * @param Wbcr_Factory406_Plugin $plugin
60
  */
61
+ public function __construct(Wbcr_Factory406_Plugin $plugin)
62
  {
63
  $this->menu_title = __('Plugins', 'webcraftic-updates-manager');
64
 
93
  /**
94
  * Requests assets (js and css) for the page.
95
  *
96
+ * @see FactoryPages407_AdminPage
97
  *
98
  * @since 1.0.0
99
  * @return void
102
  {
103
  parent::assets($scripts, $styles);
104
  $this->styles->add(WUP_PLUGIN_URL . '/admin/assets/css/general.css');
105
+
106
+ // Add Clearfy styles for HMWP pages
107
+ if( defined('WBCR_CLEARFY_PLUGIN_ACTIVE') ) {
108
+ $this->styles->add(WCL_PLUGIN_URL . '/admin/assets/css/general.css');
109
+ }
110
  }
111
 
112
  public function savePluginsUpdateFilters()
components/updates-manager/admin/pages/updates.php CHANGED
@@ -11,13 +11,13 @@
11
  exit;
12
  }
13
 
14
- class WbcrUpm_UpdatesPage extends Wbcr_FactoryPages401_ImpressiveThemplate {
15
 
16
  /**
17
  * The id of the page in the admin menu.
18
  *
19
  * Mainly used to navigate between pages.
20
- * @see FactoryPages401_AdminPage
21
  *
22
  * @since 1.0.0
23
  * @var string
@@ -30,9 +30,9 @@
30
  public $page_menu_dashicon = 'dashicons-cloud';
31
 
32
  /**
33
- * @param Wbcr_Factory400_Plugin $plugin
34
  */
35
- public function __construct(Wbcr_Factory400_Plugin $plugin)
36
  {
37
  $this->menu_title = __('Updates manager', 'webcraftic-updates-manager');
38
 
@@ -52,6 +52,24 @@
52
  : __('General', 'webcraftic-updates-manager');
53
  }
54
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
  /**
56
  * Permalinks options.
57
  *
11
  exit;
12
  }
13
 
14
+ class WbcrUpm_UpdatesPage extends Wbcr_FactoryPages407_ImpressiveThemplate {
15
 
16
  /**
17
  * The id of the page in the admin menu.
18
  *
19
  * Mainly used to navigate between pages.
20
+ * @see FactoryPages407_AdminPage
21
  *
22
  * @since 1.0.0
23
  * @var string
30
  public $page_menu_dashicon = 'dashicons-cloud';
31
 
32
  /**
33
+ * @param Wbcr_Factory406_Plugin $plugin
34
  */
35
+ public function __construct(Wbcr_Factory406_Plugin $plugin)
36
  {
37
  $this->menu_title = __('Updates manager', 'webcraftic-updates-manager');
38
 
52
  : __('General', 'webcraftic-updates-manager');
53
  }
54
 
55
+ /**
56
+ * Requests assets (js and css) for the page.
57
+ *
58
+ * @see Wbcr_FactoryPages407_AdminPage
59
+ *
60
+ * @since 1.0.0
61
+ * @return void
62
+ */
63
+ public function assets($scripts, $styles)
64
+ {
65
+ parent::assets($scripts, $styles);
66
+
67
+ // Add Clearfy styles for HMWP pages
68
+ if( defined('WBCR_CLEARFY_PLUGIN_ACTIVE') ) {
69
+ $this->styles->add(WCL_PLUGIN_URL . '/admin/assets/css/general.css');
70
+ }
71
+ }
72
+
73
  /**
74
  * Permalinks options.
75
  *
components/updates-manager/includes/class.plugin.php CHANGED
@@ -19,7 +19,7 @@
19
 
20
  }
21
  } else {
22
- class WUP_PluginFactory extends Wbcr_Factory400_Plugin {
23
 
24
  }
25
  }
@@ -28,7 +28,7 @@
28
  class WUP_Plugin extends WUP_PluginFactory {
29
 
30
  /**
31
- * @var Wbcr_Factory400_Plugin
32
  */
33
  private static $app;
34
 
@@ -51,7 +51,7 @@
51
  ? $data['plugin_parent']
52
  : null;
53
 
54
- if( !($plugin_parent instanceof Wbcr_Factory400_Plugin) ) {
55
  throw new Exception('An invalid instance of the class was passed.');
56
  }
57
 
@@ -77,7 +77,7 @@
77
  }
78
 
79
  /**
80
- * @return Wbcr_Factory400_Plugin
81
  */
82
  public static function app()
83
  {
@@ -94,10 +94,11 @@
94
  {
95
  if( !$this->as_addon ) {
96
  self::app()->load(array(
97
- array('libs/factory/bootstrap', 'factory_bootstrap_400', 'admin'),
98
- array('libs/factory/forms', 'factory_forms_400', 'admin'),
99
- array('libs/factory/pages', 'factory_pages_401', 'admin'),
100
- array('libs/factory/clearfy', 'factory_clearfy_200', 'all')
 
101
  ));
102
  }
103
  }
19
 
20
  }
21
  } else {
22
+ class WUP_PluginFactory extends Wbcr_Factory406_Plugin {
23
 
24
  }
25
  }
28
  class WUP_Plugin extends WUP_PluginFactory {
29
 
30
  /**
31
+ * @var Wbcr_Factory406_Plugin
32
  */
33
  private static $app;
34
 
51
  ? $data['plugin_parent']
52
  : null;
53
 
54
+ if( !($plugin_parent instanceof Wbcr_Factory406_Plugin) ) {
55
  throw new Exception('An invalid instance of the class was passed.');
56
  }
57
 
77
  }
78
 
79
  /**
80
+ * @return Wbcr_Factory406_Plugin
81
  */
82
  public static function app()
83
  {
94
  {
95
  if( !$this->as_addon ) {
96
  self::app()->load(array(
97
+ array('libs/factory/bootstrap', 'factory_bootstrap_406', 'admin'),
98
+ array('libs/factory/forms', 'factory_forms_407', 'admin'),
99
+ array('libs/factory/pages', 'factory_pages_407', 'admin'),
100
+ array('libs/factory/clearfy', 'factory_clearfy_203', 'all'),
101
+ array('libs/factory/notices', 'factory_notices_405', 'admin')
102
  ));
103
  }
104
  }
components/updates-manager/includes/classes/class.configurate-updates.php CHANGED
@@ -12,7 +12,7 @@
12
  exit;
13
  }
14
 
15
- class WbcrUpm_ConfigUpdates extends Wbcr_FactoryClearfy200_Configurate {
16
 
17
  public function registerActionsAndFilters()
18
  {
@@ -111,6 +111,10 @@
111
  $plugins_updates = $this->getOption('plugin_updates') == 'disable_plugin_updates';
112
  $themes_updates = $this->getOption('theme_updates') == 'disable_theme_updates';
113
 
 
 
 
 
114
  switch( $event->hook ) {
115
  case 'wp_version_check':
116
  $event = $core_updates
12
  exit;
13
  }
14
 
15
+ class WbcrUpm_ConfigUpdates extends Wbcr_FactoryClearfy203_Configurate {
16
 
17
  public function registerActionsAndFilters()
18
  {
111
  $plugins_updates = $this->getOption('plugin_updates') == 'disable_plugin_updates';
112
  $themes_updates = $this->getOption('theme_updates') == 'disable_theme_updates';
113
 
114
+ if( !is_object($event) || empty($event->hook) ) {
115
+ return $event;
116
+ }
117
+
118
  switch( $event->hook ) {
119
  case 'wp_version_check':
120
  $event = $core_updates
components/updates-manager/languages/webcraftic-updates-manager-ru_RU.mo CHANGED
Binary file
components/updates-manager/languages/webcraftic-updates-manager-ru_RU.po CHANGED
@@ -1,8 +1,8 @@
1
  msgid ""
2
  msgstr ""
3
  "Project-Id-Version: clearfy\n"
4
- "POT-Creation-Date: 2018-03-14 17:40+0300\n"
5
- "PO-Revision-Date: 2018-03-14 17:44+0300\n"
6
  "Last-Translator: alex.kovalevv@gmail.com <alex.kovalevv@gmail.com>\n"
7
  "Language-Team: Alex Kovalev <alex.kovalevv@gmail.com>\n"
8
  "Language: ru_RU\n"
@@ -85,11 +85,11 @@ msgstr ""
85
  "Пожалуйста, подождите 90 сек., чтобы увидеть результат принудительного "
86
  "автоматического обновления."
87
 
88
- #: admin/pages/advanced.php:58
89
  msgid "Force Automatic Updates"
90
  msgstr "Принудительное автоматическое обновление"
91
 
92
- #: admin/pages/advanced.php:60
93
  msgid ""
94
  "This will attempt to force automatic updates. This is useful for debugging."
95
  msgstr ""
@@ -97,7 +97,7 @@ msgstr ""
97
  "Настройте автоматические обновления и нажмите на эту кнопку, чтобы проверить "
98
  "работают они или нет."
99
 
100
- #: admin/pages/advanced.php:61
101
  msgid "Force update"
102
  msgstr "Запустить обновление"
103
 
@@ -123,53 +123,53 @@ msgstr ""
123
  "опцию “Автоматические обновления”, сохраните настройки и вернитесь на эту "
124
  "страницу."
125
 
126
- #: admin/pages/plugins.php:234
127
  msgid "Plugins list"
128
  msgstr "Ваш список плагинов"
129
 
130
- #: admin/pages/plugins.php:237
131
  msgid "This page you can individually disable plugin updates and auto updates."
132
  msgstr ""
133
  "На этой странице вы можете индивидуально отключить обновления и "
134
  "автообновления плагинов."
135
 
136
- #: admin/pages/plugins.php:253
137
  msgid "Bulk actions"
138
  msgstr "Массовые действия"
139
 
140
- #: admin/pages/plugins.php:254 admin/pages/plugins.php:329
141
- #: admin/pages/plugins.php:334 admin/pages/updates.php:78
142
  #: admin/pages/updates.php:93 admin/pages/updates.php:114
143
  msgid "Disable updates"
144
  msgstr "Отключить все обновления"
145
 
146
- #: admin/pages/plugins.php:255 admin/pages/plugins.php:331
147
  msgid "Enable updates"
148
  msgstr "Включить обновления"
149
 
150
- #: admin/pages/plugins.php:256 admin/pages/plugins.php:341
151
- #: admin/pages/plugins.php:347
152
  msgid "Enable auto-updates"
153
  msgstr "Включить авто-обновления"
154
 
155
- #: admin/pages/plugins.php:257 admin/pages/plugins.php:339
156
- #: admin/pages/plugins.php:345
157
  msgid "Disable auto-updates"
158
  msgstr "Отключить авто-обновления"
159
 
160
- #: admin/pages/plugins.php:259
161
  msgid "Apply"
162
  msgstr "Применить"
163
 
164
- #: admin/pages/plugins.php:266
165
  msgid "Plugin"
166
  msgstr "Плагин"
167
 
168
- #: admin/pages/plugins.php:268
169
  msgid "Description"
170
  msgstr "Описание"
171
 
172
- #: admin/pages/plugins.php:315
173
  msgid "Select"
174
  msgstr "Выбор"
175
 
@@ -297,7 +297,7 @@ msgstr ""
297
  "Если у вас несколько пользователей, это означает, что те, кто не являются "
298
  "админами, не должны видеть уведомления об обновлениях."
299
 
300
- #: webcraftic-updates-manager.php:17
301
  msgid ""
302
  "We found that you have the \"Clearfy - disable unused features\" plugin "
303
  "installed, this plugin already has update manager functions, so you can "
@@ -307,6 +307,6 @@ msgstr ""
307
  "неиспользуемые функции», этот плагин уже имеет функции менеджера обновлений, "
308
  "поэтому вы можете отключить плагин «Менеджер обновлений»!"
309
 
310
- #: webcraftic-updates-manager.php:74
311
  msgid "Webcraftic Updates Manager"
312
  msgstr "Webcraftic менеджер обновлений"
1
  msgid ""
2
  msgstr ""
3
  "Project-Id-Version: clearfy\n"
4
+ "POT-Creation-Date: 2018-03-25 03:09+0300\n"
5
+ "PO-Revision-Date: 2018-03-25 03:09+0300\n"
6
  "Last-Translator: alex.kovalevv@gmail.com <alex.kovalevv@gmail.com>\n"
7
  "Language-Team: Alex Kovalev <alex.kovalevv@gmail.com>\n"
8
  "Language: ru_RU\n"
85
  "Пожалуйста, подождите 90 сек., чтобы увидеть результат принудительного "
86
  "автоматического обновления."
87
 
88
+ #: admin/pages/advanced.php:57
89
  msgid "Force Automatic Updates"
90
  msgstr "Принудительное автоматическое обновление"
91
 
92
+ #: admin/pages/advanced.php:59
93
  msgid ""
94
  "This will attempt to force automatic updates. This is useful for debugging."
95
  msgstr ""
97
  "Настройте автоматические обновления и нажмите на эту кнопку, чтобы проверить "
98
  "работают они или нет."
99
 
100
+ #: admin/pages/advanced.php:60
101
  msgid "Force update"
102
  msgstr "Запустить обновление"
103
 
123
  "опцию “Автоматические обновления”, сохраните настройки и вернитесь на эту "
124
  "страницу."
125
 
126
+ #: admin/pages/plugins.php:233
127
  msgid "Plugins list"
128
  msgstr "Ваш список плагинов"
129
 
130
+ #: admin/pages/plugins.php:236
131
  msgid "This page you can individually disable plugin updates and auto updates."
132
  msgstr ""
133
  "На этой странице вы можете индивидуально отключить обновления и "
134
  "автообновления плагинов."
135
 
136
+ #: admin/pages/plugins.php:252
137
  msgid "Bulk actions"
138
  msgstr "Массовые действия"
139
 
140
+ #: admin/pages/plugins.php:253 admin/pages/plugins.php:328
141
+ #: admin/pages/plugins.php:333 admin/pages/updates.php:78
142
  #: admin/pages/updates.php:93 admin/pages/updates.php:114
143
  msgid "Disable updates"
144
  msgstr "Отключить все обновления"
145
 
146
+ #: admin/pages/plugins.php:254 admin/pages/plugins.php:330
147
  msgid "Enable updates"
148
  msgstr "Включить обновления"
149
 
150
+ #: admin/pages/plugins.php:255 admin/pages/plugins.php:340
151
+ #: admin/pages/plugins.php:346
152
  msgid "Enable auto-updates"
153
  msgstr "Включить авто-обновления"
154
 
155
+ #: admin/pages/plugins.php:256 admin/pages/plugins.php:338
156
+ #: admin/pages/plugins.php:344
157
  msgid "Disable auto-updates"
158
  msgstr "Отключить авто-обновления"
159
 
160
+ #: admin/pages/plugins.php:258
161
  msgid "Apply"
162
  msgstr "Применить"
163
 
164
+ #: admin/pages/plugins.php:265
165
  msgid "Plugin"
166
  msgstr "Плагин"
167
 
168
+ #: admin/pages/plugins.php:267
169
  msgid "Description"
170
  msgstr "Описание"
171
 
172
+ #: admin/pages/plugins.php:314
173
  msgid "Select"
174
  msgstr "Выбор"
175
 
297
  "Если у вас несколько пользователей, это означает, что те, кто не являются "
298
  "админами, не должны видеть уведомления об обновлениях."
299
 
300
+ #: webcraftic-updates-manager.php:18
301
  msgid ""
302
  "We found that you have the \"Clearfy - disable unused features\" plugin "
303
  "installed, this plugin already has update manager functions, so you can "
307
  "неиспользуемые функции», этот плагин уже имеет функции менеджера обновлений, "
308
  "поэтому вы можете отключить плагин «Менеджер обновлений»!"
309
 
310
+ #: webcraftic-updates-manager.php:75
311
  msgid "Webcraftic Updates Manager"
312
  msgstr "Webcraftic менеджер обновлений"
components/updates-manager/readme.txt CHANGED
@@ -17,35 +17,47 @@ With loads of settings making endless possibilities for configuration, Webcrafti
17
  FEATURES INCLUDE
18
 
19
  <strong>Disable all updates</strong> – This setting quite easily just overrides all other settings and disables everything.
 
20
  <strong>Disable updates of the WordPress Core</strong> - This setting is used to toggle on and off the WordPress core updates.
 
21
  <strong>Disable plugins updates</strong> – This setting is used to disable all plugins updates on your website.
 
22
  <strong>Disable themes updates</strong> – This setting is used to disable all theme updates on your website.
 
23
  <strong>Enable Major Releases</strong> – This setting toggles whether or not you want the major WordPress core versions to automatically update themselves.
 
24
  <strong>Enable Minor Releases</strong> – This setting toggles whether or not you want the minor WordPress core versions to automatically update themselves.
 
25
  <strong>Enable Development Updates</strong> – This setting toggles whether or not you want the bleeding edge version of WordPress to automatically update itself.
 
26
  <strong>Enable automatic plugins updates</strong> – This setting can either automatically update all your plugins, or automatically update any select plugins you want.
 
27
  <strong>Enable automatic themes updates</strong> – This setting can either automatically update all your themes, or automatically update any select themes you want.
 
28
  <strong>Disable translation updates</strong> – This setting can unable automatic updating for translation updates.
 
29
  <strong>Disable automatic updates for plugins.</strong>
 
30
  <strong>Disable automatic updates for themes.</strong>
 
31
  <strong>Disable automatic updates for core.</strong>
32
 
33
  Some functions are taken from the following popular plugins <strong>Easy Updates Manager</strong>, <strong>Clearfy – disable unused features</strong>, <strong>WP Disables Updates</strong>, <strong>Companion Auto Update</strong>, <strong>Disable All WordPress Updates</strong>, <strong>WP Updates Settings</strong>, <strong>WP Disable Automatic Updates</strong>
34
 
35
  == Translations ==
36
  * English - default, always included
37
- * French - Thank you very much to user (kingteamdunet)
38
  * Russian
39
 
40
- #### Recommended separate modules ####
41
-
42
  We invite you to check out a few other related free plugins that our team has also produced that you may find especially useful:
43
 
44
  * [Clearfy – WordPress optimization plugin and disable ultimate tweaker](https://wordpress.org/plugins/clearfy/)
45
  * [Disable Comments for Any Post Types (Remove Comments)](https://wordpress.org/plugins/comments-plus/)
46
  * [Cyrlitera – transliteration of links and file names](https://wordpress.org/plugins/cyrlitera/)
 
47
  * [Disable admin notices individually](https://wordpress.org/plugins/disable-admin-notices/ "Disable admin notices individually")
48
- * [WordPress Assets manager, dequeue scripts, dequeue styles](https://wordpress.org/plugins/gonzales/)
 
49
 
50
  If you want to help with the translation, please contact me through this site or through the contacts inside the plugin.
51
 
@@ -61,6 +73,15 @@ This section describes how to install the plugin and get it working.
61
  2. Control panel (Individualy updates)
62
 
63
  == Changelog ==
 
 
 
 
 
 
 
 
 
64
  = 1.0.5 =
65
  * Fixed: Compatibility with Clearfy plugin
66
  * Fixed: Slowing down the plugins page when updates were disabled
17
  FEATURES INCLUDE
18
 
19
  <strong>Disable all updates</strong> – This setting quite easily just overrides all other settings and disables everything.
20
+
21
  <strong>Disable updates of the WordPress Core</strong> - This setting is used to toggle on and off the WordPress core updates.
22
+
23
  <strong>Disable plugins updates</strong> – This setting is used to disable all plugins updates on your website.
24
+
25
  <strong>Disable themes updates</strong> – This setting is used to disable all theme updates on your website.
26
+
27
  <strong>Enable Major Releases</strong> – This setting toggles whether or not you want the major WordPress core versions to automatically update themselves.
28
+
29
  <strong>Enable Minor Releases</strong> – This setting toggles whether or not you want the minor WordPress core versions to automatically update themselves.
30
+
31
  <strong>Enable Development Updates</strong> – This setting toggles whether or not you want the bleeding edge version of WordPress to automatically update itself.
32
+
33
  <strong>Enable automatic plugins updates</strong> – This setting can either automatically update all your plugins, or automatically update any select plugins you want.
34
+
35
  <strong>Enable automatic themes updates</strong> – This setting can either automatically update all your themes, or automatically update any select themes you want.
36
+
37
  <strong>Disable translation updates</strong> – This setting can unable automatic updating for translation updates.
38
+
39
  <strong>Disable automatic updates for plugins.</strong>
40
+
41
  <strong>Disable automatic updates for themes.</strong>
42
+
43
  <strong>Disable automatic updates for core.</strong>
44
 
45
  Some functions are taken from the following popular plugins <strong>Easy Updates Manager</strong>, <strong>Clearfy – disable unused features</strong>, <strong>WP Disables Updates</strong>, <strong>Companion Auto Update</strong>, <strong>Disable All WordPress Updates</strong>, <strong>WP Updates Settings</strong>, <strong>WP Disable Automatic Updates</strong>
46
 
47
  == Translations ==
48
  * English - default, always included
 
49
  * Russian
50
 
51
+ #### RECOMMENDED SEPARATE MODULES ####
 
52
  We invite you to check out a few other related free plugins that our team has also produced that you may find especially useful:
53
 
54
  * [Clearfy – WordPress optimization plugin and disable ultimate tweaker](https://wordpress.org/plugins/clearfy/)
55
  * [Disable Comments for Any Post Types (Remove Comments)](https://wordpress.org/plugins/comments-plus/)
56
  * [Cyrlitera – transliteration of links and file names](https://wordpress.org/plugins/cyrlitera/)
57
+ * [Cyr-to-lat reloaded – transliteration of links and file names](https://wordpress.org/plugins/cyr-and-lat/ "Cyr-to-lat reloaded")
58
  * [Disable admin notices individually](https://wordpress.org/plugins/disable-admin-notices/ "Disable admin notices individually")
59
+ * [WordPress Assets manager, dequeue scripts, dequeue styles](https://wordpress.org/plugins/gonzales/ "WordPress Assets manager, dequeue scripts, dequeue styles")
60
+ * [Hide login page](https://wordpress.org/plugins/hide-login-page/ "Hide login page")
61
 
62
  If you want to help with the translation, please contact me through this site or through the contacts inside the plugin.
63
 
73
  2. Control panel (Individualy updates)
74
 
75
  == Changelog ==
76
+ = 1.0.7 =
77
+ * Fixed: Update core
78
+ * Fixed: It was not possible to close notifications about the incompatibility of plugins.
79
+
80
+ = 1.0.6 =
81
+ * Fixed: Update core
82
+ * Fixed: Small bugs
83
+ * Fixed: Translations
84
+
85
  = 1.0.5 =
86
  * Fixed: Compatibility with Clearfy plugin
87
  * Fixed: Slowing down the plugins page when updates were disabled
components/updates-manager/webcraftic-updates-manager.php CHANGED
@@ -4,10 +4,10 @@
4
  * Plugin URI: https://wordpress.org/plugins/webcraftic-updates-manager/
5
  * Description: Manage all your WordPress updates, automatic updates, logs, and loads more.
6
  * Author: Webcraftic <wordpress.webraftic@gmail.com>
7
- * Version: 1.0.5
8
  * Text Domain: webcraftic-updates-manager
9
  * Domain Path: /languages/
10
- * Author URI: http://webcraftic.com
11
  */
12
 
13
  if( defined('WUP_PLUGIN_ACTIVE') || (defined('WCL_PLUGIN_ACTIVE') && !defined('LOADING_UPDATES_MANAGER_AS_ADDON')) ) {
@@ -44,7 +44,7 @@
44
  'prefix' => 'wbcr_updates_manager_',//wbcr_upm_
45
  'plugin_name' => 'wbcr_updates_manager',
46
  'plugin_title' => __('Webcraftic Updates Manager', 'webcraftic-updates-manager'),
47
- 'plugin_version' => '1.0.5',
48
  'required_php_version' => '5.2',
49
  'required_wp_version' => '4.2',
50
  'plugin_build' => 'free',
4
  * Plugin URI: https://wordpress.org/plugins/webcraftic-updates-manager/
5
  * Description: Manage all your WordPress updates, automatic updates, logs, and loads more.
6
  * Author: Webcraftic <wordpress.webraftic@gmail.com>
7
+ * Version: 1.0.7
8
  * Text Domain: webcraftic-updates-manager
9
  * Domain Path: /languages/
10
+ * Author URI: https://clearfy.pro
11
  */
12
 
13
  if( defined('WUP_PLUGIN_ACTIVE') || (defined('WCL_PLUGIN_ACTIVE') && !defined('LOADING_UPDATES_MANAGER_AS_ADDON')) ) {
44
  'prefix' => 'wbcr_updates_manager_',//wbcr_upm_
45
  'plugin_name' => 'wbcr_updates_manager',
46
  'plugin_title' => __('Webcraftic Updates Manager', 'webcraftic-updates-manager'),
47
+ 'plugin_version' => '1.0.7',
48
  'required_php_version' => '5.2',
49
  'required_wp_version' => '4.2',
50
  'plugin_build' => 'free',
includes/boot.php ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Global boot file
4
+ * @author Webcraftic <wordpress.webraftic@gmail.com>
5
+ * @copyright (c) 01.07.2018, Webcraftic
6
+ * @version 1.0
7
+ */
8
+
9
+ // Exit if accessed directly
10
+ if( !defined('ABSPATH') ) {
11
+ exit;
12
+ }
13
+
14
+ /**
15
+ * Assets admin bar scripts
16
+ */
17
+ function wbcr_clr_enqueue_admin_bar_scripts()
18
+ {
19
+ $disable_menu = WCL_Plugin::app()->getOption('disable_clearfy_extra_menu', false);
20
+
21
+ if( !WCL_Plugin::app()->currentUserCan() || $disable_menu ) {
22
+ return;
23
+ }
24
+
25
+ wp_enqueue_style('wbcr-clearfy-adminbar-styles', WCL_PLUGIN_URL . '/assets/css/admin-bar.css', array(), WCL_Plugin::app()
26
+ ->getPluginVersion());
27
+ }
28
+
29
+ add_action('admin_enqueue_scripts', 'wbcr_clr_enqueue_admin_bar_scripts');
30
+ add_action('wp_enqueue_scripts', 'wbcr_clr_enqueue_admin_bar_scripts');
31
+
32
+ /**
33
+ * Cleate admin bar menu
34
+ *
35
+ * @param WP_Admin_Bar $wp_admin_bar
36
+ */
37
+ function wbcr_clr_admin_bar_menu($wp_admin_bar)
38
+ {
39
+ $disable_menu = WCL_Plugin::app()->getOption('disable_clearfy_extra_menu', false);
40
+
41
+ if( !WCL_Plugin::app()->currentUserCan() || $disable_menu) {
42
+ return;
43
+ }
44
+
45
+ $menu_items = array();
46
+ $menu_items = apply_filters('wbcr_clearfy_admin_bar_menu_items', $menu_items);
47
+
48
+ if( empty($menu_items) ) {
49
+ return;
50
+ }
51
+
52
+ $wp_admin_bar->add_menu(array(
53
+ 'id' => 'clearfy-menu',
54
+ 'parent' => 'top-secondary',
55
+ 'title' => '<span class="wbcr-clearfy-admin-bar-menu-icon"></span><span class="wbcr-clearfy-admin-bar-menu-title">' . __('Clearfy menu', 'clearfy') . ' (' . sizeof($menu_items) . ')</span>',
56
+ 'href' => admin_url('options-general.php?page=quick_start-' . WCL_Plugin::app()->getPluginName())
57
+ ));
58
+
59
+ foreach((array)$menu_items as $id => $item) {
60
+ $wp_admin_bar->add_menu(array(
61
+ 'id' => $id,
62
+ 'parent' => 'clearfy-menu',
63
+ 'title' => $item['title'],
64
+ 'href' => $item['href'],
65
+ 'meta' => array(
66
+ 'class' => isset($item['class'])
67
+ ? $item['class']
68
+ : ''
69
+ )
70
+ ));
71
+ }
72
+ }
73
+
74
+ add_action('admin_bar_menu', 'wbcr_clr_admin_bar_menu', 80);
includes/class.plugin.php CHANGED
@@ -11,7 +11,7 @@
11
  exit;
12
  }
13
 
14
- class WCL_Plugin extends Wbcr_Factory400_Plugin {
15
 
16
  /**
17
  * @var WCL_Plugin
@@ -53,14 +53,16 @@
53
  include_once(WCL_PLUGIN_DIR . '/admin/activation.php');
54
  $this->registerActivation('WCL_Activation');
55
  }
 
56
 
57
  protected function setModules()
58
  {
59
  $this->load(array(
60
- array('libs/factory/bootstrap', 'factory_bootstrap_400', 'admin'),
61
- array('libs/factory/forms', 'factory_forms_400', 'admin'),
62
- array('libs/factory/pages', 'factory_pages_401', 'admin'),
63
- array('libs/factory/clearfy', 'factory_clearfy_200', 'all')
 
64
  ));
65
  }
66
 
@@ -68,73 +70,105 @@
68
  {
69
  $addons = array();
70
 
71
- if( $this->isActivateComponent('hide_login_page') ) {
72
- $addons['hide_login_page'] = array(
73
- 'WHLP_Plugin',
74
- WCL_PLUGIN_DIR . '/components/hide-login-page/hide-login-page.php'
 
 
 
 
 
 
 
75
  );
76
  }
77
 
78
  // This module is for Cyrillic users only, for other users it should be disabled
79
- if( $this->isActivateComponent('cyrlitera') ) {
80
  $addons['cyrlitera'] = array(
81
  'WCTR_Plugin',
82
  WCL_PLUGIN_DIR . '/components/cyrlitera/cyrlitera.php'
83
  );
84
  }
85
 
86
- if( $this->isActivateComponent('disable_notices') ) {
87
  $addons['disable_admin_notices'] = array(
88
  'WDN_Plugin',
89
  WCL_PLUGIN_DIR . '/components/disable-admin-notices/disable-admin-notices.php'
90
  );
91
  }
92
 
93
- if( $this->isActivateComponent('updates_manager') ) {
94
  $addons['updates_manager'] = array(
95
  'WUP_Plugin',
96
  WCL_PLUGIN_DIR . '/components/updates-manager/webcraftic-updates-manager.php'
97
  );
98
  }
99
 
100
- if( $this->isActivateComponent('comments_tools') ) {
101
  $addons['comments_plus'] = array(
102
  'WCM_Plugin',
103
  WCL_PLUGIN_DIR . '/components/comments-plus/comments-plus.php'
104
  );
105
  }
106
 
107
- if( $this->isActivateComponent('asset_manager') ) {
108
  $addons['gonzales'] = array(
109
  'WGZ_Plugin',
110
  WCL_PLUGIN_DIR . '/components/assets-manager/gonzales.php'
111
  );
112
  }
113
 
 
 
 
 
 
 
 
114
  /**
115
  * Include plugin components
116
  */
 
 
 
 
 
 
 
 
 
117
  $this->loadAddons($addons);
118
  }
119
 
120
  private function adminScripts()
121
  {
122
-
123
  require_once(WCL_PLUGIN_DIR . '/admin/includes/classes/class.pages.php');
124
  require_once(WCL_PLUGIN_DIR . '/admin/includes/classes/class.option.php');
125
  require_once(WCL_PLUGIN_DIR . '/admin/includes/classes/class.group.php');
126
 
127
  require_once(WCL_PLUGIN_DIR . '/admin/activation.php');
128
 
129
- if( defined('DOING_AJAX') && DOING_AJAX && isset($_REQUEST['action']) && $_REQUEST['action'] == 'wbcr_clearfy_configurate' ) {
130
- require(WCL_PLUGIN_DIR . '/admin/ajax/configurate.php');
131
- }
 
 
 
 
 
132
 
133
- if( defined('DOING_AJAX') && DOING_AJAX && isset($_REQUEST['action']) && $_REQUEST['action'] == 'wbcr_clearfy_import_settings' ) {
134
- require(WCL_PLUGIN_DIR . '/admin/ajax/import-settings.php');
 
 
135
  }
136
 
137
  require_once(WCL_PLUGIN_DIR . '/admin/boot.php');
 
 
 
138
 
139
  $this->initActivation();
140
  $this->registerPages();
@@ -146,12 +180,12 @@
146
  $this->registerPage('WCL_AdvancedPage', WCL_PLUGIN_DIR . '/admin/pages/advanced.php');
147
  $this->registerPage('WCL_PerformancePage', WCL_PLUGIN_DIR . '/admin/pages/performance.php');
148
  $this->registerPage('WCL_PerformanceGooglePage', WCL_PLUGIN_DIR . '/admin/pages/performance-google.php');
149
- $this->registerPage('WCL_PerformanceHtmlMinifyPage', WCL_PLUGIN_DIR . '/admin/pages/performance-html-minify.php');
150
  $this->registerPage('WCL_ComponentsPage', WCL_PLUGIN_DIR . '/admin/pages/components.php');
151
  $this->registerPage('WCL_SeoPage', WCL_PLUGIN_DIR . '/admin/pages/seo.php');
152
  $this->registerPage('WCL_DoublePagesPage', WCL_PLUGIN_DIR . '/admin/pages/seo-double-pages.php');
153
  $this->registerPage('WCL_DefencePage', WCL_PLUGIN_DIR . '/admin/pages/defence.php');
154
- $this->registerPage('WCL_PrivacyContentPage', WCL_PLUGIN_DIR . '/admin/pages/defence-privacy-code.php');
155
 
156
  if( $this->isActivateComponent('widget_tools') ) {
157
  $this->registerPage('WCL_WidgetsPage', WCL_PLUGIN_DIR . '/admin/pages/widgets.php');
@@ -160,6 +194,8 @@
160
 
161
  private function globalScripts()
162
  {
 
 
163
  require_once(WCL_PLUGIN_DIR . '/includes/classes/class.configurate-performance.php');
164
  require_once(WCL_PLUGIN_DIR . '/includes/classes/class.configurate-google-performance.php');
165
  require_once(WCL_PLUGIN_DIR . '/includes/classes/class.configurate-privacy.php');
@@ -175,10 +211,22 @@
175
 
176
  public function pluginsLoaded()
177
  {
 
 
 
 
178
  require_once(WCL_PLUGIN_DIR . '/includes/classes/class.configurate-advanced.php');
179
  new WCL_ConfigAdvanced($this);
180
  }
181
 
 
 
 
 
 
 
 
 
182
  /**
183
  * @param string $component_name
184
  * @return bool
@@ -210,6 +258,8 @@
210
  return true;
211
  }
212
 
 
 
213
  $deactivate_components = $this->getOption('deactive_preinstall_components', array());
214
 
215
  if( !empty($deactivate_components) && is_array($deactivate_components) ) {
@@ -221,6 +271,8 @@
221
 
222
  $this->updateOption('deactive_preinstall_components', $deactivate_components);
223
 
 
 
224
  return true;
225
  }
226
 
@@ -235,6 +287,8 @@
235
  return true;
236
  }
237
 
 
 
238
  $deactivate_components = $this->getOption('deactive_preinstall_components', array());
239
 
240
  if( !empty($deactivate_components) && is_array($deactivate_components) ) {
@@ -244,12 +298,73 @@
244
 
245
  if( empty($deactivate_components) ) {
246
  $this->deleteOption('deactive_preinstall_components');
247
-
248
- return true;
249
  }
250
 
251
- $this->updateOption('deactive_preinstall_components', $deactivate_components);
252
 
253
  return true;
254
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
255
  }
11
  exit;
12
  }
13
 
14
+ class WCL_Plugin extends Wbcr_Factory406_Plugin {
15
 
16
  /**
17
  * @var WCL_Plugin
53
  include_once(WCL_PLUGIN_DIR . '/admin/activation.php');
54
  $this->registerActivation('WCL_Activation');
55
  }
56
+
57
 
58
  protected function setModules()
59
  {
60
  $this->load(array(
61
+ array('libs/factory/bootstrap', 'factory_bootstrap_406', 'admin'),
62
+ array('libs/factory/forms', 'factory_forms_407', 'admin'),
63
+ array('libs/factory/pages', 'factory_pages_407', 'admin'),
64
+ array('libs/factory/notices', 'factory_notices_405', 'admin'),
65
+ array('libs/factory/clearfy', 'factory_clearfy_203', 'all')
66
  ));
67
  }
68
 
70
  {
71
  $addons = array();
72
 
73
+ if( $this->isActivateComponent('html_minify') && !defined('WGA_PLUGIN_ACTIVE') ) {
74
+ $addons['html_minify'] = array(
75
+ 'WHTM_Plugin',
76
+ WCL_PLUGIN_DIR . '/components/html-minify/html-minify.php'
77
+ );
78
+ }
79
+
80
+ if( $this->isActivateComponent('minify_and_combine') && !defined('WMAC_PLUGIN_ACTIVE') ) {
81
+ $addons['minify_and_combine'] = array(
82
+ 'WMAC_Plugin',
83
+ WCL_PLUGIN_DIR . '/components/minify-and-combine/minify-and-combine.php'
84
  );
85
  }
86
 
87
  // This module is for Cyrillic users only, for other users it should be disabled
88
+ if( $this->isActivateComponent('cyrlitera') && !defined('WCTR_PLUGIN_ACTIVE') ) {
89
  $addons['cyrlitera'] = array(
90
  'WCTR_Plugin',
91
  WCL_PLUGIN_DIR . '/components/cyrlitera/cyrlitera.php'
92
  );
93
  }
94
 
95
+ if( $this->isActivateComponent('disable_notices') && !defined('WDN_PLUGIN_ACTIVE') ) {
96
  $addons['disable_admin_notices'] = array(
97
  'WDN_Plugin',
98
  WCL_PLUGIN_DIR . '/components/disable-admin-notices/disable-admin-notices.php'
99
  );
100
  }
101
 
102
+ if( $this->isActivateComponent('updates_manager') && !defined('WUP_PLUGIN_ACTIVE') ) {
103
  $addons['updates_manager'] = array(
104
  'WUP_Plugin',
105
  WCL_PLUGIN_DIR . '/components/updates-manager/webcraftic-updates-manager.php'
106
  );
107
  }
108
 
109
+ if( $this->isActivateComponent('comments_tools') && !defined('WCM_PLUGIN_ACTIVE') ) {
110
  $addons['comments_plus'] = array(
111
  'WCM_Plugin',
112
  WCL_PLUGIN_DIR . '/components/comments-plus/comments-plus.php'
113
  );
114
  }
115
 
116
+ if( $this->isActivateComponent('asset_manager') && !defined('WGZ_PLUGIN_ACTIVE') ) {
117
  $addons['gonzales'] = array(
118
  'WGZ_Plugin',
119
  WCL_PLUGIN_DIR . '/components/assets-manager/gonzales.php'
120
  );
121
  }
122
 
123
+ if( $this->isActivateComponent('ga_cache') && !defined('WGA_PLUGIN_ACTIVE') ) {
124
+ $addons['ga_cache'] = array(
125
+ 'WGA_Plugin',
126
+ WCL_PLUGIN_DIR . '/components/ga-cache/simple_google_analytics.php'
127
+ );
128
+ }
129
+
130
  /**
131
  * Include plugin components
132
  */
133
+
134
+ require_once(WCL_PLUGIN_DIR . '/includes/classes/class.package.php');
135
+
136
+ if( !defined('WCL_PLUGIN_DEBUG') || !WCL_PLUGIN_DEBUG ) {
137
+ $package = WCL_Package::instance();
138
+ $package_addons = $package->getActivedAddons();
139
+ $addons = array_merge($addons, $package_addons);
140
+ }
141
+
142
  $this->loadAddons($addons);
143
  }
144
 
145
  private function adminScripts()
146
  {
 
147
  require_once(WCL_PLUGIN_DIR . '/admin/includes/classes/class.pages.php');
148
  require_once(WCL_PLUGIN_DIR . '/admin/includes/classes/class.option.php');
149
  require_once(WCL_PLUGIN_DIR . '/admin/includes/classes/class.group.php');
150
 
151
  require_once(WCL_PLUGIN_DIR . '/admin/activation.php');
152
 
153
+ if( defined('DOING_AJAX') && DOING_AJAX && isset($_REQUEST['action']) ) {
154
+ if( $_REQUEST['action'] == 'wbcr_clearfy_configurate' ) {
155
+ require(WCL_PLUGIN_DIR . '/admin/ajax/configurate.php');
156
+ }
157
+
158
+ if( $_REQUEST['action'] == 'wbcr_clearfy_import_settings' ) {
159
+ require(WCL_PLUGIN_DIR . '/admin/ajax/import-settings.php');
160
+ }
161
 
162
+ //if( $_REQUEST['action'] == 'wbcr-clearfy-activate-external-addon' ) {
163
+ require(WCL_PLUGIN_DIR . '/admin/ajax/install-addons.php');
164
+ require(WCL_PLUGIN_DIR . '/admin/ajax/update-package.php');
165
+ //}
166
  }
167
 
168
  require_once(WCL_PLUGIN_DIR . '/admin/boot.php');
169
+
170
+ require_once(WCL_PLUGIN_DIR . '/includes/classes/class.licensing.php');
171
+ require_once(WCL_PLUGIN_DIR . '/includes/classes/class.package.php');
172
 
173
  $this->initActivation();
174
  $this->registerPages();
180
  $this->registerPage('WCL_AdvancedPage', WCL_PLUGIN_DIR . '/admin/pages/advanced.php');
181
  $this->registerPage('WCL_PerformancePage', WCL_PLUGIN_DIR . '/admin/pages/performance.php');
182
  $this->registerPage('WCL_PerformanceGooglePage', WCL_PLUGIN_DIR . '/admin/pages/performance-google.php');
183
+ //$this->registerPage('WCL_PerformanceHtmlMinifyPage', WCL_PLUGIN_DIR . '/admin/pages/performance-html-minify.php');
184
  $this->registerPage('WCL_ComponentsPage', WCL_PLUGIN_DIR . '/admin/pages/components.php');
185
  $this->registerPage('WCL_SeoPage', WCL_PLUGIN_DIR . '/admin/pages/seo.php');
186
  $this->registerPage('WCL_DoublePagesPage', WCL_PLUGIN_DIR . '/admin/pages/seo-double-pages.php');
187
  $this->registerPage('WCL_DefencePage', WCL_PLUGIN_DIR . '/admin/pages/defence.php');
188
+ $this->registerPage('WCL_LicensePage', WCL_PLUGIN_DIR . '/admin/pages/license.php');
189
 
190
  if( $this->isActivateComponent('widget_tools') ) {
191
  $this->registerPage('WCL_WidgetsPage', WCL_PLUGIN_DIR . '/admin/pages/widgets.php');
194
 
195
  private function globalScripts()
196
  {
197
+ require_once(WCL_PLUGIN_DIR . '/includes/boot.php');
198
+
199
  require_once(WCL_PLUGIN_DIR . '/includes/classes/class.configurate-performance.php');
200
  require_once(WCL_PLUGIN_DIR . '/includes/classes/class.configurate-google-performance.php');
201
  require_once(WCL_PLUGIN_DIR . '/includes/classes/class.configurate-privacy.php');
211
 
212
  public function pluginsLoaded()
213
  {
214
+ /*if( is_admin() ) {
215
+ $this->registerPages();
216
+ }*/
217
+
218
  require_once(WCL_PLUGIN_DIR . '/includes/classes/class.configurate-advanced.php');
219
  new WCL_ConfigAdvanced($this);
220
  }
221
 
222
+ /**
223
+ * @return bool
224
+ */
225
+ public function currentUserCan()
226
+ {
227
+ return current_user_can('manage_options');
228
+ }
229
+
230
  /**
231
  * @param string $component_name
232
  * @return bool
258
  return true;
259
  }
260
 
261
+ do_action('wbcr_clearfy_pre_deactivate_component', $component_name);
262
+
263
  $deactivate_components = $this->getOption('deactive_preinstall_components', array());
264
 
265
  if( !empty($deactivate_components) && is_array($deactivate_components) ) {
271
 
272
  $this->updateOption('deactive_preinstall_components', $deactivate_components);
273
 
274
+ do_action('wbcr_clearfy_deactivated_component', $component_name);
275
+
276
  return true;
277
  }
278
 
287
  return true;
288
  }
289
 
290
+ do_action('wbcr_clearfy_pre_activate_component', $component_name);
291
+
292
  $deactivate_components = $this->getOption('deactive_preinstall_components', array());
293
 
294
  if( !empty($deactivate_components) && is_array($deactivate_components) ) {
298
 
299
  if( empty($deactivate_components) ) {
300
  $this->deleteOption('deactive_preinstall_components');
301
+ } else {
302
+ $this->updateOption('deactive_preinstall_components', $deactivate_components);
303
  }
304
 
305
+ do_action('wbcr_clearfy_activated_component', $component_name);
306
 
307
  return true;
308
  }
309
+
310
+ /**
311
+ * Allows you to get a button to install the plugin component
312
+ *
313
+ * @param $component_type
314
+ * @param $slug
315
+ * @return WCL_InstallPluginsButton
316
+ */
317
+ public function getInstallComponentsButton($component_type, $slug)
318
+ {
319
+ require_once WCL_PLUGIN_DIR . '/admin/includes/classes/class.install-plugins-button.php';
320
+
321
+ return new WCL_InstallPluginsButton($component_type, $slug);
322
+ }
323
+
324
+ /**
325
+ * Allows you to get a button to delete the plugin component
326
+ *
327
+ * @param $component_type
328
+ * @param $slug
329
+ * @return WCL_InstallPluginsButton
330
+ */
331
+ public function getDeleteComponentsButton($component_type, $slug)
332
+ {
333
+ require_once WCL_PLUGIN_DIR . '/admin/includes/classes/class.install-plugins-button.php';
334
+ require_once WCL_PLUGIN_DIR . '/admin/includes/classes/class.delete-plugins-button.php';
335
+
336
+ return new WCL_DeletePluginsButton($component_type, $slug);
337
+ }
338
+
339
+ /**
340
+ * Get a link to the official website of the developer
341
+ *
342
+ * @return string|null
343
+ */
344
+ public function getAuthorSiteUrl()
345
+ {
346
+ if( get_locale() == 'ru_RU' ) {
347
+ return $this->app()->getPluginInfoAttr('author_ru_site_url');
348
+ }
349
+
350
+ return $this->app()->getPluginInfoAttr('author_site_url');
351
+ }
352
+
353
+ /**
354
+ * Get a link to the official website of the developer
355
+ *
356
+ * @param string $page - page address
357
+ * @param string $utm_content - from which page or part of the plugin user moved to the site
358
+ * @return string
359
+ */
360
+ public function getAuthorSitePageUrl($page, $utm_content = null)
361
+ {
362
+ $build_url = $this->getAuthorSiteUrl() . '/' . $page . '/?utm_source=wordpress.org&utm_campaign=' . $this->getPluginName();
363
+
364
+ if( !empty($utm_content) ) {
365
+ $build_url .= '&utm_content=' . $utm_content;
366
+ }
367
+
368
+ return $build_url;
369
+ }
370
  }
includes/classes/class.configurate-advanced.php CHANGED
@@ -11,7 +11,7 @@
11
  exit;
12
  }
13
 
14
- class WCL_ConfigAdvanced extends Wbcr_FactoryClearfy200_Configurate {
15
 
16
  /**
17
  * @param WCL_Plugin $plugin
@@ -208,7 +208,14 @@
208
  */
209
  public function replaceHowdyText($wp_admin_bar)
210
  {
 
 
 
 
 
 
211
  $my_account = $wp_admin_bar->get_node('my-account');
 
212
  $newtitle = str_replace(__('Howdy', 'clearfy') . ',', __('Welcome', 'clearfy') . ',', $my_account->title);
213
  $wp_admin_bar->add_node(array(
214
  'id' => 'my-account',
11
  exit;
12
  }
13
 
14
+ class WCL_ConfigAdvanced extends Wbcr_FactoryClearfy203_Configurate {
15
 
16
  /**
17
  * @param WCL_Plugin $plugin
208
  */
209
  public function replaceHowdyText($wp_admin_bar)
210
  {
211
+ #Fix bug when the attribute $wp_admin_bar does not belong to the class WP_Admin_Bar
212
+ require_once ABSPATH . "/wp-includes/class-wp-admin-bar.php";
213
+
214
+ if( empty($wp_admin_bar) || !($wp_admin_bar instanceof WP_Admin_Bar) ) {
215
+ return;
216
+ }
217
  $my_account = $wp_admin_bar->get_node('my-account');
218
+
219
  $newtitle = str_replace(__('Howdy', 'clearfy') . ',', __('Welcome', 'clearfy') . ',', $my_account->title);
220
  $wp_admin_bar->add_node(array(
221
  'id' => 'my-account',
includes/classes/class.configurate-google-performance.php CHANGED
@@ -11,7 +11,7 @@
11
  exit;
12
  }
13
 
14
- class WCL_ConfigGooglePerformance extends Wbcr_FactoryClearfy200_Configurate {
15
 
16
  /**
17
  * @param WCL_Plugin $plugin
@@ -41,17 +41,6 @@
41
  add_action("wp_loaded", array($this, 'disableGoogleMapsObStart'));
42
  }
43
  }
44
-
45
- if( $this->getOption('ga_cache') ) {
46
- add_filter('cron_schedules', array($this, 'cronAdditions'));
47
-
48
- // Load update script to schedule in wp_cron.
49
- add_action('wbcr_clearfy_update_local_ga', array($this, 'updateLocalGoogleAnaliticScript'));
50
-
51
- if( !is_admin() ) {
52
- $this->addGoogleAnaliticsScript();
53
- }
54
- }
55
  }
56
 
57
  /** ======================================================================== */
@@ -127,8 +116,8 @@
127
  $ret = array();
128
  if( isset($wp_styles) && !empty($wp_styles) ) {
129
 
130
- $load_google_fonts = $this->getOption('lazy_load_google_fonts');
131
- $load_font_awesome = $this->getOption('lazy_load_font_awesome');
132
 
133
  if( $load_google_fonts || $load_font_awesome ) {
134
 
@@ -146,7 +135,7 @@
146
  if( $load_google_fonts && false !== strpos($wp_styles->registered[$handle]->src, $gfonts_base_url) ) {
147
  $gfonts_links[] = urldecode(str_replace(array('&amp;'), array('&'), $wp_styles->registered[$handle]->src));
148
  wp_dequeue_style($handle);
149
- } elseif( $load_font_awesome && false !== strpos($wp_styles->registered[$handle]->src, $font_awesome_slug) || false !== strpos($wp_styles->registered[$handle]->src, $font_awesome_slug_alt) ) {
150
 
151
  wp_dequeue_style($handle);
152
 
@@ -390,101 +379,4 @@
390
  /** ======================================================================== */
391
  // End Lazy load fonts
392
  /** ======================================================================== */
393
-
394
- public function cronAdditions($schedules)
395
- {
396
- $schedules['weekly'] = array(
397
- 'interval' => DAY_IN_SECONDS * 7,
398
- 'display' => __('Once Weekly'),
399
- );
400
-
401
- $schedules['twicemonthly'] = array(
402
- 'interval' => DAY_IN_SECONDS * 14,
403
- 'display' => __('Twice Monthly'),
404
- );
405
-
406
- $schedules['monthly'] = array(
407
- 'interval' => DAY_IN_SECONDS * 30,
408
- 'display' => __('Once Monthly'),
409
- );
410
-
411
- return $schedules;
412
- }
413
-
414
- public function updateLocalGoogleAnaliticScript()
415
- {
416
- include(WCL_PLUGIN_DIR . '/includes/update-local-ga.php');
417
- }
418
-
419
- private function addGoogleAnaliticsScript()
420
- {
421
- $ga_tracking_id = $this->getOption('ga_tracking_id');
422
-
423
- if( !empty($ga_tracking_id) ) {
424
- $local_ga_file = WCL_PLUGIN_DIR . '/cache/local-ga.js';
425
- // If file is not created yet, create now!
426
- if( !file_exists($local_ga_file) ) {
427
- ob_start();
428
- do_action('wbcr_clearfy_update_local_ga');
429
- ob_end_clean();
430
- }
431
-
432
- $ga_script_position = $this->getOption('ga_script_position', 'footer');
433
- $ga_enqueue_order = $this->getOption('ga_enqueue_order', 0);
434
-
435
- switch( $ga_script_position ) {
436
- case 'header':
437
- add_action('wp_head', array($this, 'printGoogleAnalitics'), $ga_enqueue_order);
438
- break;
439
- default:
440
- add_action('wp_footer', array($this, 'printGoogleAnalitics'), $ga_enqueue_order);
441
- }
442
- }
443
- }
444
-
445
- /**
446
- * Generate tracking code and add to header/footer (default is header).
447
- */
448
- public function printGoogleAnalitics()
449
- {
450
- $ga_tracking_id = $this->getOption('ga_tracking_id');
451
- $ga_track_admin = $this->getOption('ga_track_admin');
452
-
453
- // If user is admin we don't want to render the tracking code, when option is disabled.
454
- if( empty($ga_tracking_id) || (current_user_can('manage_options') && (!$ga_track_admin)) ) {
455
- return;
456
- }
457
-
458
- $ga_adjusted_bounce_rate = $this->getOption('ga_adjusted_bounce_rate', 0);
459
- $ga_anonymize_ip = $this->getOption('ga_anonymize_ip');
460
- $ga_caos_disable_display_features = $this->getOption('ga_caos_disable_display_features');
461
-
462
- echo "<!-- Google Analytics Local by Clearfy -->" . PHP_EOL;
463
-
464
- echo "<script>" . PHP_EOL;
465
- echo "(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
466
- (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
467
- m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
468
- })(window,document,'script','" . WCL_PLUGIN_URL . "/cache/local-ga.js','ga');" . PHP_EOL;
469
-
470
- echo "ga('create', '" . $ga_tracking_id . "', 'auto');" . PHP_EOL;
471
-
472
- echo 'on' === $ga_caos_disable_display_features
473
- ? "ga('set', 'displayFeaturesTask', null);" . PHP_EOL
474
- : '';
475
-
476
- echo 'on' === $ga_anonymize_ip
477
- ? "ga('set', 'anonymizeIp', true);" . PHP_EOL
478
- : '';
479
-
480
- echo "ga('send', 'pageview');";
481
-
482
- echo $ga_adjusted_bounce_rate
483
- ? 'setTimeout("ga(' . "'send','event','adjusted bounce rate','" . $ga_adjusted_bounce_rate . " seconds')" . '"' . ',' . $ga_adjusted_bounce_rate * 1000 . ');' . PHP_EOL
484
- : '';
485
-
486
- echo PHP_EOL . '</script>' . PHP_EOL;
487
-
488
- echo "<!-- end Google Analytics Local by Clearfy -->" . PHP_EOL;
489
- }
490
- }
11
  exit;
12
  }
13
 
14
+ class WCL_ConfigGooglePerformance extends Wbcr_FactoryClearfy203_Configurate {
15
 
16
  /**
17
  * @param WCL_Plugin $plugin
41
  add_action("wp_loaded", array($this, 'disableGoogleMapsObStart'));
42
  }
43
  }
 
 
 
 
 
 
 
 
 
 
 
44
  }
45
 
46
  /** ======================================================================== */
116
  $ret = array();
117
  if( isset($wp_styles) && !empty($wp_styles) ) {
118
 
119
+ $load_google_fonts = $this->getOption('lazy_load_google_fonts', false);
120
+ $load_font_awesome = $this->getOption('lazy_load_font_awesome', false);
121
 
122
  if( $load_google_fonts || $load_font_awesome ) {
123
 
135
  if( $load_google_fonts && false !== strpos($wp_styles->registered[$handle]->src, $gfonts_base_url) ) {
136
  $gfonts_links[] = urldecode(str_replace(array('&amp;'), array('&'), $wp_styles->registered[$handle]->src));
137
  wp_dequeue_style($handle);
138
+ } elseif( $load_font_awesome && ( false !== strpos($wp_styles->registered[$handle]->src, $font_awesome_slug) || false !== strpos($wp_styles->registered[$handle]->src, $font_awesome_slug_alt ) ) ) {
139
 
140
  wp_dequeue_style($handle);
141
 
379
  /** ======================================================================== */
380
  // End Lazy load fonts
381
  /** ======================================================================== */
382
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/classes/class.configurate-performance.php CHANGED
@@ -11,7 +11,7 @@
11
  exit;
12
  }
13
 
14
- class WCL_ConfigPerformance extends Wbcr_FactoryClearfy200_Configurate {
15
 
16
  /**
17
  * @param WCL_Plugin $plugin
@@ -87,6 +87,9 @@
87
  */
88
  public function hideWordpressVersionInScript($src, $handle)
89
  {
 
 
 
90
  $filename_arr = explode('?', basename($src));
91
  $exclude_file_list = $this->getOption('remove_version_exclude', '');
92
  $exclude_files_arr = array_map('trim', explode(PHP_EOL, $exclude_file_list));
@@ -464,4 +467,4 @@
464
 
465
  return $content;
466
  }
467
- }
11
  exit;
12
  }
13
 
14
+ class WCL_ConfigPerformance extends Wbcr_FactoryClearfy203_Configurate {
15
 
16
  /**
17
  * @param WCL_Plugin $plugin
87
  */
88
  public function hideWordpressVersionInScript($src, $handle)
89
  {
90
+ if ( is_user_logged_in() and $this->getOption( 'disable_remove_style_version_for_auth_users', false ) ) {
91
+ return $src;
92
+ }
93
  $filename_arr = explode('?', basename($src));
94
  $exclude_file_list = $this->getOption('remove_version_exclude', '');
95
  $exclude_files_arr = array_map('trim', explode(PHP_EOL, $exclude_file_list));
467
 
468
  return $content;
469
  }
470
+ }
includes/classes/class.configurate-privacy.php CHANGED
@@ -12,7 +12,7 @@
12
  exit;
13
  }
14
 
15
- class WCL_ConfigPrivacy extends Wbcr_FactoryClearfy200_Configurate {
16
 
17
  /**
18
  * @param WCL_Plugin $plugin
@@ -29,6 +29,16 @@
29
  if( !is_admin() ) {
30
  if( $this->getOption('remove_meta_generator') ) {
31
  remove_action('wp_head', 'wp_generator');
 
 
 
 
 
 
 
 
 
 
32
  add_filter('the_generator', '__return_empty_string');
33
  }
34
 
12
  exit;
13
  }
14
 
15
+ class WCL_ConfigPrivacy extends Wbcr_FactoryClearfy203_Configurate {
16
 
17
  /**
18
  * @param WCL_Plugin $plugin
29
  if( !is_admin() ) {
30
  if( $this->getOption('remove_meta_generator') ) {
31
  remove_action('wp_head', 'wp_generator');
32
+
33
+ if( class_exists('WooCommerce') ) {
34
+ remove_action('wp_head', 'woo_version');
35
+ }
36
+
37
+ if( class_exists('SitePress') ) {
38
+ global $sitepress;
39
+ remove_action('wp_head', array($sitepress, 'meta_generator_tag'));
40
+ }
41
+
42
  add_filter('the_generator', '__return_empty_string');
43
  }
44
 
includes/classes/class.configurate-security.php CHANGED
@@ -11,7 +11,7 @@
11
  exit;
12
  }
13
 
14
- class WCL_ConfigSecurity extends Wbcr_FactoryClearfy200_Configurate {
15
 
16
  /**
17
  * @param WCL_Plugin $plugin
11
  exit;
12
  }
13
 
14
+ class WCL_ConfigSecurity extends Wbcr_FactoryClearfy203_Configurate {
15
 
16
  /**
17
  * @param WCL_Plugin $plugin
includes/classes/class.configurate-seo.php CHANGED
@@ -12,7 +12,7 @@
12
  exit;
13
  }
14
 
15
- class WCL_ConfigSeo extends Wbcr_FactoryClearfy200_Configurate {
16
 
17
  /**
18
  * @param WCL_Plugin $plugin
@@ -155,8 +155,9 @@
155
 
156
  /// Get title
157
  $title = get_post_field('post_title', $parent);
158
-
159
- $attr['alt'] = $title;
 
160
  $attr['title'] = $title;
161
 
162
  return $attr;
@@ -349,6 +350,13 @@
349
  if( class_exists('woocommerce') && function_exists('is_cart') && function_exists('is_checkout') && function_exists('is_account_page') && (is_cart() || is_checkout() || is_account_page()) ) {
350
  return;
351
  }
 
 
 
 
 
 
 
352
 
353
  $last_modified_flush = isset($_COOKIE['wbcr_lastmodifed_flush']);
354
 
@@ -455,4 +463,4 @@
455
  setcookie("wbcr_lastmodifed_flush", 1, time() + 3600);
456
  }
457
  }
458
- }
12
  exit;
13
  }
14
 
15
+ class WCL_ConfigSeo extends Wbcr_FactoryClearfy203_Configurate {
16
 
17
  /**
18
  * @param WCL_Plugin $plugin
155
 
156
  /// Get title
157
  $title = get_post_field('post_title', $parent);
158
+ if ( '' === $attr['alt'] ) {
159
+ $attr['alt'] = $title;
160
+ }
161
  $attr['title'] = $title;
162
 
163
  return $attr;
350
  if( class_exists('woocommerce') && function_exists('is_cart') && function_exists('is_checkout') && function_exists('is_account_page') && (is_cart() || is_checkout() || is_account_page()) ) {
351
  return;
352
  }
353
+
354
+ if ( is_front_page() ) {
355
+ $last_modified_exclude_frontpage = $this->getOption('disable_frontpage_last_modified_headers');
356
+ if ( $last_modified_exclude_frontpage ) {
357
+ return;
358
+ }
359
+ }
360
 
361
  $last_modified_flush = isset($_COOKIE['wbcr_lastmodifed_flush']);
362
 
463
  setcookie("wbcr_lastmodifed_flush", 1, time() + 3600);
464
  }
465
  }
466
+ }
includes/classes/class.licensing.php ADDED
@@ -0,0 +1,632 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Класс для работы с системой лицензирования
4
+ * @author Webcraftic <jokerov@gmail.com>
5
+ * @copyright (c) 2018 Webraftic Ltd
6
+ * @version 1.0
7
+ */
8
+
9
+ // Exit if accessed directly
10
+ if( !defined('ABSPATH') ) {
11
+ exit;
12
+ }
13
+
14
+ class WCL_Licensing {
15
+
16
+ /**
17
+ * @var int номер плагина в сервисе freemius
18
+ */
19
+ private $plugin_id;
20
+
21
+ /**
22
+ * @var string приватный ключ плагина
23
+ */
24
+ private $plugin_public_key;
25
+
26
+ /**
27
+ * @var string slug плагина
28
+ */
29
+ private $plugin_slug;
30
+
31
+ /**
32
+ * @var string install_url - url для установки аддонов фримиус
33
+ */
34
+ //private $install_url = 'https://clearfy.pro/zip/zip.php';
35
+
36
+ /**
37
+ * @var WCL_Licensing
38
+ */
39
+ private static $_instance;
40
+
41
+ /**
42
+ * @var array хранилище данных лицензии
43
+ */
44
+ private $_storage = array();
45
+
46
+ /**
47
+ * @var WCL_FreemiusWPApi
48
+ */
49
+ private $_user_api;
50
+
51
+ /**
52
+ * @var WCL_FreemiusWPApi
53
+ */
54
+ private $_site_api;
55
+
56
+ /**
57
+ * Получение системы лицензирования
58
+ *
59
+ * @return WCL_Licensing
60
+ */
61
+ static function instance()
62
+ {
63
+ if( !isset(self::$_instance) ) {
64
+ self::$_instance = new WCL_Licensing;
65
+ }
66
+
67
+ return self::$_instance;
68
+ }
69
+
70
+ /**
71
+ * Инициализация системы лицензирования
72
+ *
73
+ */
74
+ private function __construct()
75
+ {
76
+ // для того, чтобы постоянно не менять настройки фримиус. Константы определяются в конфиге
77
+ $this->plugin_id = defined( 'WBCR_CLR_LICENSING_ID' ) ? WBCR_CLR_LICENSING_ID : WCL_Plugin::app()->getPluginInfoAttr('freemius_plugin_id');
78
+ $this->plugin_public_key = defined( 'WBCR_CLR_LICENSING_KEY' ) ? WBCR_CLR_LICENSING_KEY : WCL_Plugin::app()->getPluginInfoAttr('freemius_public_key');
79
+ $this->plugin_slug = defined( 'WBCR_CLR_LICENSING_SLUG' ) ? WBCR_CLR_LICENSING_SLUG : WCL_Plugin::app()->getPluginInfoAttr('freemius_plugin_slug');
80
+
81
+ $this->include_files();
82
+ $this->_storage = new WCL_Licensing_Storage;
83
+ }
84
+
85
+ /**
86
+ * Подключение необходимых файлов
87
+ *
88
+ */
89
+ private function include_files()
90
+ {
91
+ require_once(WCL_PLUGIN_DIR . '/includes/freemius/class.storage.php');
92
+
93
+ require_once(WCL_PLUGIN_DIR . '/includes/freemius/entities/class.wcl-fs-entity.php');
94
+ require_once(WCL_PLUGIN_DIR . '/includes/freemius/entities/class.wcl-fs-scope-entity.php');
95
+ require_once(WCL_PLUGIN_DIR . '/includes/freemius/entities/class.wcl-fs-user.php');
96
+ require_once(WCL_PLUGIN_DIR . '/includes/freemius/entities/class.wcl-fs-site.php');
97
+ require_once(WCL_PLUGIN_DIR . '/includes/freemius/entities/class.wcl-fs-plugin-license.php');
98
+
99
+ require_once(WCL_PLUGIN_DIR . '/includes/freemius/sdk/FreemiusWordPress.php');
100
+ }
101
+
102
+ /**
103
+ * Возвращает объект хранилища
104
+ *
105
+ * @return WCL_Licensing_Storage
106
+ */
107
+ public function getStorage()
108
+ {
109
+ return $this->_storage;
110
+ }
111
+
112
+ /**
113
+ * Возвращает объект api плагина
114
+ *
115
+ * @return WCL_FreemiusWPApi
116
+ */
117
+ public function getPluginApi()
118
+ {
119
+ return new WCL_FreemiusWPApi('plugin', // scope
120
+ $this->plugin_id, // element_id
121
+ $this->plugin_public_key, //public key
122
+ $this->plugin_public_key, false);
123
+ }
124
+
125
+ /**
126
+ * Возвращает объект api аддона
127
+ *
128
+ * @return WCL_FreemiusWPApi
129
+ */
130
+ public function getAddonApi($addon)
131
+ {
132
+ return new WCL_FreemiusWPApi('plugin', // scope
133
+ $addon->id, // element_id
134
+ $addon->public_key, //public key
135
+ false, false);
136
+ }
137
+
138
+ /**
139
+ * Возвращает объект api инсталла(сайта)
140
+ *
141
+ * @return WCL_FreemiusWPApi
142
+ */
143
+ public function getSiteApi()
144
+ {
145
+ if( isset($this->_site_api) ) {
146
+ return $this->_site_api;
147
+ }
148
+ $site = $this->_storage->get('site');
149
+ $this->_site_api = new WCL_FreemiusWPApi('install', // scope
150
+ $site->id, // element_id
151
+ $site->public_key, //public key
152
+ $site->secret_key, false);
153
+
154
+ return $this->_site_api;
155
+ }
156
+
157
+ /**
158
+ * Возвращает объект api юзера
159
+ *
160
+ * @return WCL_FreemiusWPApi
161
+ */
162
+ public function getUserApi()
163
+ {
164
+ if( isset($this->_user_api) ) {
165
+ return $this->_user_api;
166
+ }
167
+ $user = $this->_storage->get('user');
168
+ $this->_user_api = new WCL_FreemiusWPApi('user', // scope
169
+ $user->id, // element_id
170
+ $user->public_key, //public key
171
+ $user->secret_key, false);
172
+
173
+ return $this->_user_api;
174
+ }
175
+
176
+ /**
177
+ * Деактивирует текущую лицензию
178
+ *
179
+ */
180
+ public function deactivate()
181
+ {
182
+ $site = $this->_storage->get('site');
183
+ $current_license = $this->_storage->get('license');
184
+
185
+ $api_install = $this->getSiteApi();
186
+ $api_user = $this->getUserApi();
187
+
188
+ $api_install->Api('/licenses/' . $current_license->id . '.json?license_key=' . $current_license->secret_key, 'DELETE');
189
+ $api_user->Api('/plugins/' . $this->plugin_id . '/installs.json?ids=' . $site->id, 'DELETE');
190
+
191
+ $this->_storage->delete('site');
192
+ $this->_storage->delete('license');
193
+ $this->_storage->save();
194
+
195
+ $this->_user_api = null;
196
+ $this->_site_api = null;
197
+ }
198
+
199
+ /**
200
+ * Деактивирует текущую лицензию
201
+ *
202
+ */
203
+ public function uninstall()
204
+ {
205
+ $this->deactivate();
206
+
207
+ return new WP_Error('alert-success', __('The license is deactivated.', 'clearfy'));
208
+ }
209
+
210
+ /**
211
+ * Синхронизирует данные текущей лицензии
212
+ *
213
+ */
214
+ public function sync() {
215
+ $site = $this->_storage->get('site');
216
+ $current_license = $this->_storage->get('license');
217
+ $api_install = $this->getSiteApi();
218
+ $api_user = $this->getUserApi();
219
+
220
+ $license = $api_install->Api('/licenses/' . $current_license->id . '.json?license_key=' . urlencode($current_license->secret_key), 'GET');
221
+ $install = $api_user->Api('/plugins/' . $this->plugin_id . '/installs.json?ids=' . $site->id, 'GET');
222
+ if( $install->installs[0]->license_id !== $current_license->id ) {
223
+ $this->uninstall();
224
+
225
+ return new WP_Error('alert-success', __('The license has been updated.', 'clearfy'));
226
+ }
227
+
228
+ $subscriptions = $api_install->Api('/licenses/' . $current_license->id . '/subscriptions.json', 'GET');
229
+ $plan = $api_user->Api('/plugins/' . $this->plugin_id . '/plans/' . $current_license->plan_id . '.json', 'GET');
230
+ $current_license->plan_title = $plan->title;
231
+
232
+ if( isset($subscriptions->subscriptions) and isset($subscriptions->subscriptions[0]) ) {
233
+ if( !is_null($subscriptions->subscriptions[0]->next_payment) ) {
234
+ $current_license->billing_cycle = $subscriptions->subscriptions[0]->billing_cycle;
235
+ }
236
+ }
237
+
238
+ $current_license->sync($license);
239
+ $this->_storage->set('license', $current_license);
240
+ $this->_storage->save();
241
+
242
+ $this->getAddons( true ); // обновляем список аддонов
243
+
244
+ return new WP_Error('alert-success', __('The license has been updated.', 'clearfy'));
245
+ }
246
+
247
+ /**
248
+ * Отписывается от платной подписики на обновления
249
+ *
250
+ * @return WP_Error
251
+ */
252
+ public function unsubscribe()
253
+ {
254
+ $current_license = $this->_storage->get('license');
255
+ $api_install = $this->getSiteApi();
256
+
257
+ $subscriptions = $api_install->Api('/licenses/' . $current_license->id . '/subscriptions.json', 'GET');
258
+ if( isset($subscriptions->subscriptions) and isset($subscriptions->subscriptions[0]) ) {
259
+ $api_install->Api('downgrade.json', 'PUT');
260
+ $current_license->billing_cycle = null;
261
+ $this->_storage->set('license', $current_license);
262
+ $this->_storage->save();
263
+ }
264
+
265
+ return new WP_Error('alert-success', 'Subscription cancelled');
266
+ }
267
+
268
+ /**
269
+ * Активирует лицензию
270
+ *
271
+ * @param string $license_key лицензионный ключ
272
+ */
273
+ public function activate($license_key)
274
+ {
275
+ $site = $this->_storage->get('site');
276
+ $current_license = $this->_storage->get('license');
277
+ if( isset($current_license->id) ) {
278
+ if( $current_license->secret_key == $license_key ) {
279
+ $this->sync();
280
+
281
+ return new WP_Error('alert-success', __('The license has been updated.', 'clearfy'));
282
+ }
283
+ $this->deactivate();
284
+ }
285
+
286
+ $url = 'https://wp.freemius.com/action/service/user/install/';
287
+ $unique_id = md5(get_site_url() . SECURE_AUTH_KEY);
288
+ $request_body = array(
289
+ 'plugin_slug' => $this->plugin_slug,
290
+ 'plugin_id' => $this->plugin_id,
291
+ 'plugin_public_key' => $this->plugin_public_key,
292
+ 'plugin_version' => WCL_Plugin::app()->getPluginVersion(),
293
+ 'is_active' => true,
294
+ 'is_premium' => true,
295
+ 'format' => 'json',
296
+ 'is_disconnected' => false,
297
+ 'license_key' => $license_key,
298
+ 'site_url' => get_home_url(), //site_uid
299
+ 'site_uid' => $unique_id,
300
+ 'language' => get_bloginfo('language'),
301
+ 'charset' => get_bloginfo('charset'),
302
+ 'platform_version' => get_bloginfo('version'),
303
+ 'sdk_version' => '2.1.1',
304
+ 'programming_language_version' => phpversion(),
305
+ );
306
+ $responce = wp_remote_post($url, array(
307
+ 'body' => $request_body,
308
+ 'timeout' => 7,
309
+ ));
310
+ if( is_wp_error($responce) ) {
311
+ return new WP_Error('alert-danger', $responce->get_error_message());
312
+ }
313
+ if( isset($responce['response']['code']) and $responce['response']['code'] == 403 ) {
314
+ return new WP_Error('alert-danger', 'http error');
315
+ }
316
+
317
+ $responce_data = json_decode($responce['body']);
318
+ if( isset($responce_data->error) ) {
319
+ return new WP_Error('alert-danger', $responce_data->error);
320
+ }
321
+ $user = new WCL_FS_User($responce_data);
322
+ $site = new WCL_FS_Site($responce_data);
323
+
324
+ $this->_storage->set('user', $user);
325
+ $this->_storage->set('site', $site);
326
+
327
+ $api_user = $this->getUserApi();
328
+ $api_install = $this->getSiteApi();
329
+
330
+ $user_licensies = $api_user->Api('/plugins/' . $this->plugin_id . '/licenses.json', 'GET');
331
+
332
+ foreach($user_licensies->licenses as $user_license) {
333
+ if( $user_license->secret_key == $license_key ) {
334
+ $current_license = new WCL_FS_Plugin_License($user_license);
335
+ }
336
+ }
337
+
338
+ $plan = $api_user->Api('/plugins/' . $this->plugin_id . '/plans/' . $current_license->plan_id . '.json', 'GET');
339
+
340
+ $subscriptions = $api_install->Api('/licenses/' . $current_license->id . '/subscriptions.json', 'GET');
341
+ $current_license->plan_title = $plan->title;
342
+ if( isset($subscriptions->subscriptions) and isset($subscriptions->subscriptions[0]) ) {
343
+ $current_license->billing_cycle = $subscriptions->subscriptions[0]->billing_cycle;
344
+ }
345
+
346
+ $this->_storage->set('license', $current_license);
347
+ $this->_storage->save();
348
+
349
+ return new WP_Error('alert-success', __('Your license has been successfully activated.','clearfy'));
350
+ }
351
+
352
+ /**
353
+ * Проверяет, не истекла ли текущая лицензия
354
+ * @return bool
355
+ */
356
+ public function isLicenseValid()
357
+ {
358
+ $current_license = $this->_storage->get('license');
359
+ if( !$current_license )
360
+ return false;
361
+
362
+ return $current_license->is_valid();
363
+ }
364
+
365
+ /**
366
+ * Получает аддоны плагина. Кеширует на день
367
+ *
368
+ * @param bool $flush_cache сбрасывает кеш
369
+ * @return stdClass объект ответа с аддонами
370
+ */
371
+
372
+ public function getAddons( $flush_cache = false ) {
373
+ $addons = WCL_Plugin::app()->getOption('freemius_addons', array());
374
+ $addons_last_update = WCL_Plugin::app()->getOption('freemius_addons_last_update', 0);
375
+
376
+ $next_update = $addons_last_update + DAY_IN_SECONDS;
377
+
378
+ if ( ($flush_cache or date('U') > $next_update) || defined('WCL_PLUGIN_FREEMIUS_DEBUG') && WCL_PLUGIN_FREEMIUS_DEBUG ) {
379
+ $api_plugin = $this->getPluginApi();
380
+ $addons = $api_plugin->Api( '/addons.json?enriched=true' );
381
+ WCL_Plugin::app()->updateOption( 'freemius_addons_last_update', date('U') );
382
+ if ( $addons and isset( $addons->plugins ) ) {
383
+ WCL_Plugin::app()->updateOption( 'freemius_addons', $addons );
384
+ }
385
+ }
386
+
387
+ return $addons;
388
+ }
389
+
390
+ public function getAddonData( $slug ) {
391
+ $freemius_addons_data = $this->getAddons();
392
+ $freemius_activated_addons = WCL_Plugin::app()->getOption( 'freemius_activated_addons', array() );
393
+ if ( isset( $freemius_addons_data->plugins ) ) {
394
+ foreach( $freemius_addons_data->plugins as $freemius_addon ) {
395
+ if ( $freemius_addon->slug == $slug ) {
396
+ $addon_data = array(
397
+ 'addon' => $freemius_addon,
398
+ 'slug' => $freemius_addon->slug,
399
+ 'is_actived' => in_array( $freemius_addon->slug, $freemius_activated_addons ) ? true : false,
400
+ 'is_free' => $freemius_addon->free_releases_count ? true : false,
401
+ 'url' => isset( $freemius_addon->info ) ? $freemius_addon->info->url : '#',
402
+ );
403
+ return $addon_data;
404
+ }
405
+ }
406
+ }
407
+ return false;
408
+ }
409
+
410
+ public function isActivePaidAddons() {
411
+ $freemius_addons_data = $this->getAddons();
412
+ $freemius_activated_addons = WCL_Plugin::app()->getOption( 'freemius_activated_addons', array() );
413
+ if ( isset( $freemius_addons_data->plugins ) ) {
414
+ foreach( $freemius_addons_data->plugins as $freemius_addon ) {
415
+ if ( ! $freemius_addon->free_releases_count ) {
416
+ if ( in_array( $freemius_addon->slug, $freemius_activated_addons ) ) {
417
+ return true;
418
+ }
419
+ }
420
+ }
421
+ }
422
+ return false;
423
+ }
424
+
425
+ /**
426
+ * Возвращает данные аддона, полученные с сервиса фримиус
427
+ *
428
+ * @param string $slug слаг аддона
429
+ * @return stdClass объект с описанием аддона или false
430
+ */
431
+ public function getFreemiusAddonData( $slug ) {
432
+ $addons = $this->getAddons();
433
+ foreach ( $addons->plugins as $addon ) {
434
+ if ( $addon->slug == $slug ) {
435
+ return $addon;
436
+ }
437
+ }
438
+ return false;
439
+ }
440
+
441
+ public function getAddonCurrentVersion( $slug ) {
442
+ $package_plugin = WCL_Package::instance();
443
+ $addon = $package_plugin->getAddon( $slug );
444
+ if ( $addon ) {
445
+ return $addon['current_version'];
446
+ }
447
+ return false;
448
+ }
449
+
450
+ /**
451
+ * Устанавливает аддон с сервиса фримиус
452
+ *
453
+ * @param string $slug слаг аддона
454
+ * @return bool
455
+ */
456
+
457
+ public function installAddon( $slug ) {
458
+ /*
459
+ $installed_addons = WCL_Plugin::app()->getOption( 'freemius_installed_addons', array() );
460
+ if ( in_array( $slug, $installed_addons ) ) {
461
+ return new WP_Error( 'addon_exist', 'Аддон уже установлен' );
462
+
463
+ }
464
+ $installed_addons[] = $slug;
465
+
466
+ $components_dir = WCL_PLUGIN_DIR . '/components/';
467
+ $tmp_file = $components_dir . date('U') . '.zip';
468
+
469
+ $current_license = $this->_storage->get('license');
470
+ $site = $this->_storage->get('site');
471
+ $addons = $this->getAddons();
472
+
473
+ $license_key = $current_license->secret_key;
474
+ $license_id = $current_license->id;
475
+ $install_id = $site->id;
476
+ $addon_id = 0;
477
+
478
+ foreach($addons->plugins as $freemius_addon) {
479
+ if( $freemius_addon->slug == $slug ) {
480
+ $addon_id = $freemius_addon->id;
481
+ }
482
+ }
483
+ $url = $this->install_url . '?install_id=' . $install_id . '&addon_id=' . $addon_id . '&license_id=' . $license_id . '&license_key=' . urlencode($license_key);
484
+ $zip = file_get_contents($url);
485
+ file_put_contents($tmp_file, $zip);
486
+
487
+ global $wp_filesystem;
488
+ if( !$wp_filesystem ) {
489
+ if( !function_exists('WP_Filesystem') ) {
490
+ require_once(ABSPATH . 'wp-admin/includes/file.php');
491
+ }
492
+ WP_Filesystem();
493
+ }
494
+ $unzipped = unzip_file($tmp_file, $components_dir);
495
+ unlink($tmp_file);
496
+ if( $unzipped ) {
497
+ // удаляем папку libs если она есть
498
+ $addon_dir = $components_dir . $slug . '/';
499
+ if( !is_dir($addon_dir) ) {
500
+ $addon_dir = $components_dir . $slug . '-premium/';
501
+ }
502
+ $libs_dir = $addon_dir . 'libs/';
503
+ if( is_dir($addon_dir) and is_dir($libs_dir) ) {
504
+ $wp_filesystem->rmdir($libs_dir, true);
505
+ }
506
+ WCL_Plugin::app()->updateOption('freemius_installed_addons', $installed_addons);
507
+ } else {
508
+ return false;
509
+ }
510
+
511
+ */
512
+
513
+ return true;
514
+ }
515
+
516
+ /**
517
+ * Устанавливает аддон
518
+ *
519
+ * @param string $slug слаг аддона
520
+ * @return bool
521
+ */
522
+
523
+ public function deleteAddon( $slug ) {
524
+ $installed_addons = WCL_Plugin::app()->getOption( 'freemius_installed_addons', array() );
525
+ if ( in_array( $slug, $installed_addons ) ) {
526
+ /*
527
+ foreach( $installed_addons as $key => $addon ) {
528
+
529
+ if( $slug == $addon ) {
530
+ unset($installed_addons[$key]);
531
+ global $wp_filesystem;
532
+ if( !$wp_filesystem ) {
533
+ if( !function_exists('WP_Filesystem') ) {
534
+ require_once(ABSPATH . 'wp-admin/includes/file.php');
535
+ }
536
+ WP_Filesystem();
537
+ }
538
+ $addon_dir = WCL_PLUGIN_DIR . '/components/' . $slug . '/';
539
+ if( !is_dir($addon_dir) ) {
540
+ $addon_dir = WCL_PLUGIN_DIR . '/components/' . $slug . '-premium/';
541
+ }
542
+ if( is_dir($addon_dir) ) {
543
+ $wp_filesystem->rmdir($addon_dir, true);
544
+ }
545
+ }
546
+ }
547
+
548
+ */
549
+ $this->deactivateAddon( $slug );
550
+ WCL_Plugin::app()->updateOption( 'freemius_installed_addons', $installed_addons );
551
+
552
+ }
553
+
554
+ return true;
555
+ }
556
+
557
+ /**
558
+ * Активирует аддон
559
+ *
560
+ * @param string $slug слаг аддона
561
+ * @return bool
562
+ */
563
+
564
+ public function activateAddon( $slug ) {
565
+ $freemius_activated_addons = WCL_Plugin::app()->getOption( 'freemius_activated_addons', array() );
566
+
567
+ if( ! in_array( $slug, $freemius_activated_addons ) ) {
568
+ $freemius_activated_addons[] = $slug;
569
+ }
570
+
571
+ $freemius_activated_addons = $this->filteringExistsAddons( $freemius_activated_addons );
572
+
573
+ //$component_info = $this->getFreemiusAddonData( $slug );
574
+ do_action( 'wbcr_clearfy_pre_activate_component', $slug);
575
+
576
+ WCL_Plugin::app()->updateOption( 'freemius_activated_addons', $freemius_activated_addons );
577
+
578
+ do_action( 'wbcr_clearfy_activated_component', $slug);
579
+
580
+ return true;
581
+ }
582
+
583
+ /**
584
+ * Деактивирует аддон
585
+ *
586
+ * @param string $slug слаг аддона
587
+ * @return bool
588
+ */
589
+
590
+ public function deactivateAddon( $slug ) {
591
+ $freemius_activated_addons = WCL_Plugin::app()->getOption( 'freemius_activated_addons', array() );
592
+
593
+ if( in_array( $slug, $freemius_activated_addons ) ) {
594
+ foreach( $freemius_activated_addons as $key => $component ) {
595
+ if( $component == $slug ) {
596
+ unset( $freemius_activated_addons[$key] );
597
+ }
598
+ }
599
+ }
600
+
601
+ //$component_info = $this->getFreemiusAddonData( $slug );
602
+ do_action( 'wbcr_clearfy_pre_deactivate_component', $slug);
603
+
604
+ WCL_Plugin::app()->updateOption( 'freemius_activated_addons', $freemius_activated_addons );
605
+
606
+ do_action( 'wbcr_clearfy_deactivated_component', $slug );
607
+
608
+ return true;
609
+ }
610
+
611
+ /**
612
+ * Фильтрует активированные аддоны
613
+ * Фильтрация нужна для того, чтобы в активированных аддонах были только те, что есть в сервисе фримиус
614
+ * Старые аддоны отфильтруются и не попадут на сборку
615
+ *
616
+ * @param array $freemius_activated_addons активированные аддоны
617
+ * @return array $freemius_activated_addons_filtered
618
+ */
619
+ public function filteringExistsAddons( $freemius_activated_addons ) {
620
+ $freemius_addons = $this->getAddons();
621
+ $freemius_activated_addons_filtered = array();
622
+ foreach ( $freemius_addons->plugins as $addon ) {
623
+ if( in_array( $addon->slug, $freemius_activated_addons ) ) {
624
+ $freemius_activated_addons_filtered[] = $addon->slug;
625
+ }
626
+ }
627
+ return $freemius_activated_addons_filtered;
628
+ }
629
+
630
+ }
631
+
632
+
includes/classes/class.package.php ADDED
@@ -0,0 +1,279 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WCL_Package {
4
+ private static $instance = null;
5
+ private $packages = array();
6
+
7
+ private $is_need_update_addons = false;
8
+
9
+ private $plugin_slug = 'clearfy-package';
10
+
11
+ private $plugin_dir = 'clearfy_package';
12
+
13
+ private $plugin_basename = ''; // заполняется в конструкторе
14
+
15
+ private $builder_url = 'https://clearfy.pro/package/';
16
+
17
+ public static function instance() {
18
+ if (null === self::$instance) {
19
+ self::$instance = new self();
20
+ }
21
+ return self::$instance;
22
+ }
23
+ private function __clone() {}
24
+
25
+ private function __construct() {
26
+ $this->plugin_basename = $this->plugin_dir . '/' . $this->plugin_slug . '.php';
27
+
28
+ if(defined('WCL_PLUGIN_DEBUG') && WCL_PLUGIN_DEBUG) {
29
+ $this->builder_url = 'https://clearfy.pro/package-dev/';
30
+ }
31
+ }
32
+
33
+ public function info() {
34
+ return array(
35
+ 'plugin_basename' => $this->plugin_basename,
36
+ 'plugin_slug' => $this->plugin_basename,
37
+ );
38
+ }
39
+
40
+ public function add( $packages = array() ) {
41
+ if ( ! $packages ) return false;
42
+ foreach( $packages as $package ) {
43
+ $key = $package['slug'];
44
+ $this->packages[ $key ] = $package;
45
+ }
46
+ }
47
+
48
+ public function getAll() {
49
+ return $this->packages;
50
+ }
51
+
52
+ public function getSlugs() {
53
+ $slugs = array();
54
+ if ( $this->packages ) {
55
+ foreach ( $this->packages as $package ) {
56
+ $slugs[] = $package['slug'];
57
+ }
58
+ }
59
+ return $slugs;
60
+ }
61
+
62
+ public function getAddon( $slug ) {
63
+ if ( isset( $this->packages[ $slug ] ) ) {
64
+ return $this->packages[ $slug ];
65
+ }
66
+ return false;
67
+ }
68
+
69
+ public function isActive() {
70
+ if( is_plugin_active( $this->plugin_basename ) ) {
71
+ return true;
72
+ }
73
+ return false;
74
+ }
75
+
76
+ public function isInstalled() {
77
+ if( file_exists( WP_PLUGIN_DIR . '/' . $this->plugin_basename ) ) {
78
+ return true;
79
+ }
80
+ return false;
81
+ }
82
+
83
+ /**
84
+ * Метод проверяет, нужно ли обновлять сами аддоны
85
+ *
86
+ * @return bool
87
+ */
88
+ public function isNeedUpdateAddons() {
89
+ return $this->is_need_update_addons;
90
+ }
91
+
92
+ /**
93
+ * Метод проверяет, нужно ли обновлять весь пакет в целом.
94
+ * Пакет может быть обновлен по двум причинам:
95
+ * 1) Активирован аддон, которого ещё нет в пакете(или пакет не установлен)
96
+ * 2) Для аддонов проявились новые версии
97
+ *
98
+ * @return bool
99
+ */
100
+ public function isNeedUpdate() {
101
+ $need_update_package = false;
102
+ $freemius_activated_addons = WCL_Plugin::app()->getOption( 'freemius_activated_addons', array() );
103
+
104
+ if( $this->isActive() ) {
105
+ // если плагин clearfy-package установлен, то проверяем в нём наличие фримиус аддонов
106
+ $addons = $this->getAll();
107
+ $licensing = WCL_Licensing::instance();
108
+ $freemius_addons_data = $licensing->getAddons();
109
+ foreach ( $freemius_activated_addons as $freemius_active_addon ) {
110
+ if ( isset( $addons[ $freemius_active_addon ] ) ) {
111
+ // проверяем, актуальна ли версия аддона
112
+ foreach( $freemius_addons_data->plugins as $freemius_addon ) {
113
+ if ( $freemius_addon->slug != $freemius_active_addon ) {
114
+ continue;
115
+ }
116
+ // если во фримиусе не указана версия, то делаем её равной текущей версии аддона. Для того, чтобы уведомление об обновлении вечно не висело.
117
+ $actual_version = isset( $freemius_addon->info ) ? $freemius_addon->info->selling_point_0 : '';
118
+ if ( ! $actual_version ) {
119
+ $actual_version = $addons[ $freemius_active_addon ]['current_version'];
120
+ }
121
+ if ( version_compare( $actual_version, $addons[ $freemius_active_addon ]['current_version'], '>' ) ) {
122
+ $this->is_need_update_addons = true;
123
+ $need_update_package = true;
124
+ }
125
+ }
126
+ } else {
127
+ $need_update_package = true;
128
+ }
129
+ }
130
+
131
+ } else {
132
+ // если плагин clearfy-package НЕ установлен, то любая активация фримиус аддона требует обновления пакета
133
+ if ( count( $freemius_activated_addons ) ) {
134
+ $need_update_package = true;
135
+ }
136
+ }
137
+ return $need_update_package;
138
+ }
139
+
140
+ public function active() {
141
+ // если плагин установлен и не активирован, то активируем
142
+ if ( $this->isInstalled() and ! $this->isActive() ) {
143
+ activate_plugin( $this->plugin_basename );
144
+ }
145
+ }
146
+
147
+ public function deactive() {
148
+ // если плагин установлен и не активирован, то активируем
149
+ if ( $this->isInstalled() and $this->isActive() ) {
150
+ deactivate_plugins( $this->plugin_basename );
151
+ }
152
+ }
153
+
154
+ public function downloadUrl() {
155
+ $freemius_activated_addons = WCL_Plugin::app()->getOption( 'freemius_activated_addons', array() );
156
+ $licensing = WCL_Licensing::instance();
157
+ $package_slugs = array();
158
+
159
+ if( $this->isActive() ) {
160
+ $package_slugs = $this->getSlugs();
161
+ foreach ( $freemius_activated_addons as $freemius_addon ) {
162
+ if ( ! in_array( $freemius_addon, $package_slugs ) ) {
163
+ $package_slugs[] = $freemius_addon;
164
+ }
165
+ }
166
+ }
167
+ if ( ! $package_slugs ) {
168
+ $package_slugs = $freemius_activated_addons;
169
+ }
170
+ //$package_slugs[] = 'test-addon'; // для тестирования ошибки. Сборщик не отдаст архив
171
+ $url = $this->builder_url .'assembly-package.php?addons='. join( ',', $package_slugs );
172
+ if ( $licensing->isLicenseValid() ) {
173
+ $storage = $licensing->getStorage();
174
+ $license = $storage->get('license');
175
+ $site = $storage->get('site');
176
+ $license_id = isset( $license->id ) ? $license->id : '';
177
+ $license_key = isset( $license->secret_key ) ? $license->secret_key : '';
178
+ $install_id = isset( $site->id ) ? $site->id : '';
179
+ $url .= '&license_id=' . $license_id . '&license_key=' . urlencode( $license_key ) . '&install_id=' . $install_id;
180
+ }
181
+ return $url;
182
+ }
183
+
184
+
185
+ public function update() {
186
+ $url = $this->downloadUrl();
187
+
188
+ global $wp_filesystem;
189
+ if( !$wp_filesystem ) {
190
+ if( !function_exists('WP_Filesystem') ) {
191
+ require_once(ABSPATH . 'wp-admin/includes/file.php');
192
+ }
193
+ WP_Filesystem();
194
+ }
195
+
196
+ if( !WP_Filesystem(false, WP_PLUGIN_DIR) || 'direct' !== $wp_filesystem->method ) {
197
+ throw new Exception('You are not allowed to edt folders/files on this site');
198
+ } else {
199
+ ob_start();
200
+
201
+ require_once(ABSPATH . 'wp-admin/includes/file.php');
202
+ require_once(ABSPATH . 'wp-admin/includes/misc.php');
203
+ require_once(ABSPATH . 'wp-admin/includes/class-wp-upgrader.php');
204
+ require_once(WCL_PLUGIN_DIR . '/admin/includes/classes/class.upgrader-skin.php');
205
+ require_once(WCL_PLUGIN_DIR . '/admin/includes/classes/class.upgrader.php');
206
+ add_filter('async_update_translation', '__return_false', 1);
207
+
208
+ $upgrader = new WCL_Plugin_Upgrader(new WCL_Upgrader_Skin);
209
+ if( $this->isInstalled() ) {
210
+ $result = $upgrader->run( array(
211
+ 'package' => $url,
212
+ 'destination' => WP_PLUGIN_DIR,
213
+ 'clear_destination' => true,
214
+ 'clear_working' => true,
215
+ 'hook_extra' => array(
216
+ 'plugin' => $this->plugin_basename,
217
+ 'type' => 'plugin',
218
+ 'action' => 'update',
219
+ ),
220
+ ) );
221
+ } else {
222
+ $result = $upgrader->install( $url );
223
+ }
224
+ if ( is_wp_error( $result ) ) {
225
+ return $result;
226
+ }
227
+ $this->active();
228
+
229
+ ob_end_clean();
230
+
231
+ if( null === $result ) {
232
+ return new WP_Error( 'addon_install_error', 'An unknown error occurred during the delivery of the component package. Please report this problem to our support team <b>wordpress.webraftic@gmail.com</b>' ); // пока думаю как получать сообщение об ошибке с сервера
233
+ }
234
+
235
+ return $result;
236
+ }
237
+ }
238
+
239
+ public function getUpdateNotice() {
240
+ $need_update_package = $this->isNeedUpdate();
241
+ $message = '';
242
+ if ( $need_update_package ) {
243
+ if ( $this->isNeedUpdateAddons() ) {
244
+ // доступны обновления компонентов
245
+ $message = __( 'Updates are available for one of the components. Please, update your current package of components to the newest version.', 'clearfy' );
246
+ } else {
247
+ // нужно обновить весь пакет
248
+ $message = __( 'You’ve changed the component configuration. For the further work, please, update the current package of components!', 'clearfy' );
249
+ }
250
+ $message .= ' <button class="wbcr-clr-update-package button button-default" type="button" data-wpnonce="' . wp_create_nonce( 'package' ) . '" data-loading="' . __( 'Update in progress...', 'clearfy' ) . '">' . __( 'Update now', 'clearfy' ) . '</button>';
251
+ return $message;
252
+ }
253
+ return false;
254
+ }
255
+
256
+ public function getActivedAddons() {
257
+ $addons = array();
258
+ if ( $this->isInstalled() ) {
259
+ $package_dir = WP_PLUGIN_DIR . '/' . $this->plugin_dir;
260
+ $package_config = $package_dir . '/config.php';
261
+ if ( file_exists( $package_config ) ) {
262
+ $packages = require( $package_config );
263
+ $this->add( $packages );
264
+ }
265
+ if ( $this->packages ) {
266
+ $freemius_activated_addons = WCL_Plugin::app()->getOption( 'freemius_activated_addons', array() );
267
+ foreach ( $this->packages as $addon ) {
268
+ if ( in_array( $addon['slug'], $freemius_activated_addons ) ) {
269
+ $addons[ $addon['slug'] ] = array(
270
+ $addon['class_name'],
271
+ $package_dir . '/components/' . $addon['base_dir']
272
+ );
273
+ }
274
+ }
275
+ }
276
+ }
277
+ return $addons;
278
+ }
279
+ }
includes/freemius/class.storage.php ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Класс работы с данными лицензирования
5
+ * @author Webcraftic <jokerov@gmail.com>
6
+ * @copyright (c) 2018 Webraftic Ltd
7
+ * @version 1.0
8
+ */
9
+
10
+ // Exit if accessed directly
11
+ if( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ class WCL_Licensing_Storage {
16
+
17
+ /**
18
+ * @var WCL_Licensing_Storage
19
+ */
20
+ private $_storage = array();
21
+
22
+ /**
23
+ * Инициализация системы хранения данных
24
+ *
25
+ */
26
+ public function __construct() {
27
+ $this->load();
28
+ }
29
+
30
+ /**
31
+ * Загрузка данных из хранилища
32
+ *
33
+ */
34
+ public function load() {
35
+ $this->_storage = WCL_Plugin::app()->getOption( 'license_storage', false );
36
+
37
+ if ( isset( $this->_storage['user']->id ) and $this->_storage['user']->id ) {
38
+ $this->_storage['user'] = new WCL_FS_User( $this->_storage['user'] );
39
+ }
40
+ if ( isset( $this->_storage['site']->id ) and $this->_storage['site']->id ) {
41
+ $this->_storage['site'] = new WCL_FS_Site( $this->_storage['site'] );
42
+ }
43
+ if ( isset( $this->_storage['license']->id ) and $this->_storage['license']->id ) {
44
+ $this->_storage['license'] = new WCL_FS_Plugin_License( $this->_storage['license'] );
45
+ }
46
+ }
47
+
48
+ /**
49
+ * Сохранение данных
50
+ *
51
+ */
52
+ public function save() {
53
+ WCL_Plugin::app()->updateOption( 'license_storage', $this->_storage );
54
+ }
55
+
56
+ /**
57
+ * Получает элемент хранилища по его имени
58
+ *
59
+ * @param string $property ключ
60
+ * @return mixed
61
+ */
62
+ public function get( $property ) {
63
+ if ( isset( $this->_storage[ $property ] ) ) {
64
+ return $this->_storage[ $property ];
65
+ }
66
+ return false;
67
+ }
68
+
69
+ public function getAll() {
70
+ return $this->_storage;
71
+ }
72
+
73
+ /**
74
+ * Устанавливает значение для элемента хранилища
75
+ *
76
+ * @param string $property ключ
77
+ * @param string $value значение
78
+ */
79
+ public function set( $property, $value ) {
80
+ $this->_storage[ $property ] = $value;
81
+ }
82
+
83
+ /**
84
+ * Удаляет значение их хранилища
85
+ *
86
+ * @param string $property ключ
87
+ */
88
+ public function delete( $property ) {
89
+ if ( isset( $this->_storage[ $property ] ) ) {
90
+ $this->_storage[ $property ] = false;
91
+ }
92
+ }
93
+ }
includes/freemius/entities/class.wcl-fs-entity.php ADDED
@@ -0,0 +1,164 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package Freemius
4
+ * @copyright Copyright (c) 2015, Freemius, Inc.
5
+ * @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
6
+ * @since 1.0.3
7
+ */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit;
11
+ }
12
+
13
+ /**
14
+ * Get object's public variables.
15
+ *
16
+ * @author Vova Feldman (@svovaf)
17
+ * @since 1.0.0
18
+ *
19
+ * @param object $object
20
+ *
21
+ * @return array
22
+ */
23
+ function wcl_fs_get_object_public_vars( $object ) {
24
+ return get_object_vars( $object );
25
+ }
26
+
27
+ /**
28
+ * Класс для работы с записями freemius
29
+ * @author Webcraftic <jokerov@gmail.com>
30
+ * @copyright (c) 2018 Webraftic Ltd
31
+ * @version 1.0
32
+ */
33
+ class WCL_FS_Entity {
34
+ /**
35
+ * @var number
36
+ */
37
+ public $id;
38
+ /**
39
+ * @var string Datetime value in 'YYYY-MM-DD HH:MM:SS' format.
40
+ */
41
+ public $updated;
42
+ /**
43
+ * @var string Datetime value in 'YYYY-MM-DD HH:MM:SS' format.
44
+ */
45
+ public $created;
46
+
47
+ /**
48
+ * @param bool|object $entity
49
+ */
50
+ public function __construct( $entity = false ) {
51
+ if ( ! ( $entity instanceof stdClass ) && ! ( $entity instanceof WCL_FS_Entity ) ) {
52
+ return;
53
+ }
54
+
55
+ $props = wcl_fs_get_object_public_vars( $this );
56
+
57
+ foreach ( $props as $key => $def_value ) {
58
+ $this->{$key} = isset( $entity->{$key} ) ? $entity->{$key} : $def_value;
59
+ }
60
+ }
61
+
62
+ public function populate( $data ) {
63
+ $props = wcl_fs_get_object_public_vars( $this );
64
+ foreach ( $props as $key => $def_value ) {
65
+ $this->{$key} = isset( $data[ $key ] ) ? $data[ $key ] : $def_value;
66
+ }
67
+ }
68
+
69
+ public function toArray() {
70
+ return wcl_fs_get_object_public_vars( $this );
71
+ }
72
+
73
+ static function get_type() {
74
+ return 'type';
75
+ }
76
+
77
+ /**
78
+ * @author Vova Feldman (@svovaf)
79
+ * @since 1.0.6
80
+ *
81
+ * @param FS_Entity $entity1
82
+ * @param FS_Entity $entity2
83
+ *
84
+ * @return bool
85
+ */
86
+ static function equals( $entity1, $entity2 ) {
87
+ if ( is_null( $entity1 ) && is_null( $entity2 ) ) {
88
+ return true;
89
+ } else if ( is_object( $entity1 ) && is_object( $entity2 ) ) {
90
+ return ( $entity1->id == $entity2->id );
91
+ } else if ( is_object( $entity1 ) ) {
92
+ return is_null( $entity1->id );
93
+ } else {
94
+ return is_null( $entity2->id );
95
+ }
96
+ }
97
+
98
+ private $_is_updated = false;
99
+
100
+ /**
101
+ * Update object property.
102
+ *
103
+ * @author Vova Feldman (@svovaf)
104
+ * @since 1.0.9
105
+ *
106
+ * @param string|array[string]mixed $key
107
+ * @param string|bool $val
108
+ *
109
+ * @return bool
110
+ */
111
+ function update( $key, $val = false ) {
112
+ if ( ! is_array( $key ) ) {
113
+ $key = array( $key => $val );
114
+ }
115
+
116
+ $is_updated = false;
117
+
118
+ foreach ( $key as $k => $v ) {
119
+ if ( $this->{$k} === $v ) {
120
+ continue;
121
+ }
122
+
123
+ if ( ( is_string( $this->{$k} ) && is_numeric( $v ) ||
124
+ ( is_numeric( $this->{$k} ) && is_string( $v ) ) ) &&
125
+ $this->{$k} == $v
126
+ ) {
127
+ continue;
128
+ }
129
+
130
+ // Update value.
131
+ $this->{$k} = $v;
132
+
133
+ $is_updated = true;
134
+ }
135
+
136
+ $this->_is_updated = $is_updated;
137
+
138
+ return $is_updated;
139
+ }
140
+
141
+ /**
142
+ * Checks if entity was updated.
143
+ *
144
+ * @author Vova Feldman (@svovaf)
145
+ * @since 1.0.9
146
+ *
147
+ * @return bool
148
+ */
149
+ function is_updated() {
150
+ return $this->_is_updated;
151
+ }
152
+
153
+ /**
154
+ * @param $id
155
+ *
156
+ * @author Vova Feldman (@svovaf)
157
+ * @since 1.1.2
158
+ *
159
+ * @return bool
160
+ */
161
+ static function is_valid_id($id){
162
+ return is_numeric($id);
163
+ }
164
+ }
includes/freemius/entities/class.wcl-fs-plugin-license.php ADDED
@@ -0,0 +1,296 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package Freemius
4
+ * @copyright Copyright (c) 2015, Freemius, Inc.
5
+ * @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
6
+ * @since 1.0.5
7
+ */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit;
11
+ }
12
+
13
+ /**
14
+ * Класс для хранения данных лицензии
15
+ * @author Webcraftic <jokerov@gmail.com>
16
+ * @copyright (c) 2018 Webraftic Ltd
17
+ * @version 1.0
18
+ */
19
+ class WCL_FS_Plugin_License extends WCL_FS_Entity {
20
+
21
+ #region Properties
22
+
23
+ /**
24
+ * @var number
25
+ */
26
+ public $plugin_id;
27
+ /**
28
+ * @var number
29
+ */
30
+ public $user_id;
31
+ /**
32
+ * @var number
33
+ */
34
+ public $plan_id;
35
+
36
+ public $plan_title;
37
+
38
+ public $billing_cycle;
39
+ /**
40
+ * @var number
41
+ */
42
+ public $pricing_id;
43
+ /**
44
+ * @var int|null
45
+ */
46
+ public $quota;
47
+ /**
48
+ * @var int
49
+ */
50
+ public $activated;
51
+ /**
52
+ * @var int
53
+ */
54
+ public $activated_local;
55
+ /**
56
+ * @var string
57
+ */
58
+ public $expiration;
59
+ /**
60
+ * @var string
61
+ */
62
+ public $secret_key;
63
+ /**
64
+ * @var bool $is_free_localhost Defaults to true. If true, allow unlimited localhost installs with the same
65
+ * license.
66
+ */
67
+ public $is_free_localhost;
68
+ /**
69
+ * @var bool $is_block_features Defaults to true. If false, don't block features after license expiry - only
70
+ * block updates and support.
71
+ */
72
+ public $is_block_features;
73
+ /**
74
+ * @var bool
75
+ */
76
+ public $is_cancelled;
77
+
78
+ #endregion Properties
79
+
80
+ /**
81
+ * @param stdClass|bool $license
82
+ */
83
+ function __construct( $license = false ) {
84
+ parent::__construct( $license );
85
+ }
86
+
87
+ /**
88
+ * Get entity type.
89
+ *
90
+ * @return string
91
+ */
92
+ static function get_type() {
93
+ return 'license';
94
+ }
95
+
96
+ /**
97
+ * Check how many site activations left.
98
+ *
99
+ * @author Vova Feldman (@svovaf)
100
+ * @since 1.0.5
101
+ *
102
+ * @return int
103
+ */
104
+ function left() {
105
+ if ( ! $this->is_active() || $this->is_expired() ) {
106
+ return 0;
107
+ }
108
+
109
+ if ( $this->is_unlimited() ) {
110
+ return 999;
111
+ }
112
+
113
+ return ( $this->quota - $this->activated - ( $this->is_free_localhost ? 0 : $this->activated_local ) );
114
+ }
115
+
116
+ /**
117
+ * Check if single site license.
118
+ *
119
+ * @author Vova Feldman (@svovaf)
120
+ * @since 1.1.8.1
121
+ *
122
+ * @return bool
123
+ */
124
+ function is_single_site() {
125
+ return ( is_numeric( $this->quota ) && 1 == $this->quota );
126
+ }
127
+
128
+ /**
129
+ * @author Vova Feldman (@svovaf)
130
+ * @since 1.0.5
131
+ *
132
+ * @return bool
133
+ */
134
+ function is_expired() {
135
+ return ! $this->is_lifetime() && ( strtotime( $this->expiration ) < date('U') );
136
+ }
137
+
138
+ /**
139
+ * Check if license is not expired.
140
+ *
141
+ * @author Vova Feldman (@svovaf)
142
+ * @since 1.2.1
143
+ *
144
+ * @return bool
145
+ */
146
+ function is_valid() {
147
+ return ! $this->is_expired();
148
+ }
149
+
150
+ /**
151
+ * @author Vova Feldman (@svovaf)
152
+ * @since 1.0.6
153
+ *
154
+ * @return bool
155
+ */
156
+ function is_lifetime() {
157
+ return is_null( $this->expiration );
158
+ }
159
+
160
+ /**
161
+ * @author Vova Feldman (@svovaf)
162
+ * @since 1.2.0
163
+ *
164
+ * @return bool
165
+ */
166
+ function is_unlimited() {
167
+ return is_null( $this->quota );
168
+ }
169
+
170
+ /**
171
+ * Check if license is fully utilized.
172
+ *
173
+ * @author Vova Feldman (@svovaf)
174
+ * @since 1.0.6
175
+ *
176
+ * @param bool|null $is_localhost
177
+ *
178
+ * @return bool
179
+ */
180
+ function is_utilized( $is_localhost = null ) {
181
+ if ( is_null( $is_localhost ) ) {
182
+ $is_localhost = false; // была WP_FS__IS_LOCALHOST_FOR_SERVER
183
+ }
184
+
185
+ if ( $this->is_unlimited() ) {
186
+ return false;
187
+ }
188
+
189
+ return ! ( $this->is_free_localhost && $is_localhost ) &&
190
+ ( $this->quota <= $this->activated + ( $this->is_free_localhost ? 0 : $this->activated_local ) );
191
+ }
192
+
193
+ /**
194
+ * Check if license can be activated.
195
+ *
196
+ * @author Vova Feldman (@svovaf)
197
+ * @since 2.0.0
198
+ *
199
+ * @param bool|null $is_localhost
200
+ *
201
+ * @return bool
202
+ */
203
+ function can_activate( $is_localhost = null ) {
204
+ return ! $this->is_utilized( $is_localhost ) && $this->is_features_enabled();
205
+ }
206
+
207
+ /**
208
+ * Check if license can be activated on a given number of production and localhost sites.
209
+ *
210
+ * @author Vova Feldman (@svovaf)
211
+ * @since 2.0.0
212
+ *
213
+ * @param int $production_count
214
+ * @param int $localhost_count
215
+ *
216
+ * @return bool
217
+ */
218
+ function can_activate_bulk( $production_count, $localhost_count ) {
219
+ if ( $this->is_unlimited() ) {
220
+ return true;
221
+ }
222
+
223
+ /**
224
+ * For simplicity, the logic will work as following: when given X sites to activate the license on, if it's
225
+ * possible to activate on ALL of them, do the activation. If it's not possible to activate on ALL of them,
226
+ * do NOT activate on any of them.
227
+ */
228
+ return ( $this->quota >= $this->activated + $production_count + ( $this->is_free_localhost ? 0 : $this->activated_local + $localhost_count ) );
229
+ }
230
+
231
+ /**
232
+ * @author Vova Feldman (@svovaf)
233
+ * @since 1.2.1
234
+ *
235
+ * @return bool
236
+ */
237
+ function is_active() {
238
+ return ( ! $this->is_cancelled );
239
+ }
240
+
241
+ /**
242
+ * Check if license's plan features are enabled.
243
+ *
244
+ * - Either if plan not expired
245
+ * - If expired, based on the configuration to block features or not.
246
+ *
247
+ * @author Vova Feldman (@svovaf)
248
+ * @since 1.0.6
249
+ *
250
+ * @return bool
251
+ */
252
+ function is_features_enabled() {
253
+ return $this->is_active() && ( ! $this->is_block_features || ! $this->is_expired() );
254
+ }
255
+
256
+ /**
257
+ * Subscription considered to be new without any payments
258
+ * if the license expires in less than 24 hours
259
+ * from the license creation.
260
+ *
261
+ * @author Vova Feldman (@svovaf)
262
+ * @since 1.0.9
263
+ *
264
+ * @return bool
265
+ */
266
+ function is_first_payment_pending() {
267
+ return ( 86400 >= strtotime( $this->expiration ) - strtotime( $this->created ) );
268
+ }
269
+
270
+ /**
271
+ * @return int
272
+ */
273
+ function total_activations() {
274
+ return ( $this->activated + $this->activated_local );
275
+ }
276
+
277
+ public function remainingDays() {
278
+ if ( $this->is_lifetime() ) {
279
+ return 999;
280
+ }
281
+ $remaining = strtotime( $this->expiration ) - date('U');
282
+ $days_remaining = floor( $remaining / 86400 );
283
+ return $days_remaining;
284
+ }
285
+
286
+ public function sync( $actual_license_data ) {
287
+ $props = wcl_fs_get_object_public_vars( $this );
288
+
289
+ foreach ( $props as $key => $def_value ) {
290
+ $this->{$key} = isset( $actual_license_data->{$key} ) ? $actual_license_data->{$key} : $def_value;
291
+ }
292
+ if ( isset( $actual_license_data->expiration ) and is_null( $actual_license_data->expiration ) ) {
293
+ $this->expiration = null;
294
+ }
295
+ }
296
+ }
includes/freemius/entities/class.wcl-fs-scope-entity.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package Freemius
4
+ * @copyright Copyright (c) 2015, Freemius, Inc.
5
+ * @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
6
+ * @since 1.0.4
7
+ */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit;
11
+ }
12
+
13
+ class WCL_FS_ScopeEntity extends WCL_FS_Entity {
14
+ /**
15
+ * @var string
16
+ */
17
+ public $public_key;
18
+ /**
19
+ * @var string
20
+ */
21
+ public $secret_key;
22
+
23
+ /**
24
+ * @param bool|stdClass $scope_entity
25
+ */
26
+ function __construct( $scope_entity = false ) {
27
+ parent::__construct( $scope_entity );
28
+ }
29
+ }
includes/freemius/entities/class.wcl-fs-site.php ADDED
@@ -0,0 +1,240 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package Freemius
4
+ * @copyright Copyright (c) 2015, Freemius, Inc.
5
+ * @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
6
+ * @since 1.0.3
7
+ */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit;
11
+ }
12
+
13
+ /**
14
+ * Класс для хранения данных инсталла(сайта) freemius
15
+ * @author Webcraftic <jokerov@gmail.com>
16
+ * @copyright (c) 2018 Webraftic Ltd
17
+ * @version 1.0
18
+ */
19
+ class WCL_FS_Site extends WCL_FS_ScopeEntity {
20
+ /**
21
+ * @var number
22
+ */
23
+ public $site_id;
24
+ /**
25
+ * @var number
26
+ */
27
+ public $plugin_id;
28
+ /**
29
+ * @var number
30
+ */
31
+ public $user_id;
32
+ /**
33
+ * @var string
34
+ */
35
+ public $title;
36
+ /**
37
+ * @var string
38
+ */
39
+ public $url;
40
+ /**
41
+ * @var string
42
+ */
43
+ public $version;
44
+ /**
45
+ * @var string E.g. en-GB
46
+ */
47
+ public $language;
48
+ /**
49
+ * @var string E.g. UTF-8
50
+ */
51
+ public $charset;
52
+ /**
53
+ * @var string Platform version (e.g WordPress version).
54
+ */
55
+ public $platform_version;
56
+ /**
57
+ * Freemius SDK version
58
+ *
59
+ * @author Leo Fajardo (@leorw)
60
+ * @since 1.2.2
61
+ *
62
+ * @var string SDK version (e.g.: 1.2.2)
63
+ */
64
+ public $sdk_version;
65
+ /**
66
+ * @var string Programming language version (e.g PHP version).
67
+ */
68
+ public $programming_language_version;
69
+ /**
70
+ * @var number|null
71
+ */
72
+ public $plan_id;
73
+ /**
74
+ * @var number|null
75
+ */
76
+ public $license_id;
77
+ /**
78
+ * @var number|null
79
+ */
80
+ public $trial_plan_id;
81
+ /**
82
+ * @var string|null
83
+ */
84
+ public $trial_ends;
85
+ /**
86
+ * @since 1.0.9
87
+ *
88
+ * @var bool
89
+ */
90
+ public $is_premium = false;
91
+ /**
92
+ * @author Leo Fajardo (@leorw)
93
+ *
94
+ * @since 1.2.1.5
95
+ *
96
+ * @var bool
97
+ */
98
+ public $is_disconnected = false;
99
+ /**
100
+ * @since 2.0.0
101
+ *
102
+ * @var bool
103
+ */
104
+ public $is_active = true;
105
+ /**
106
+ * @since 2.0.0
107
+ *
108
+ * @var bool
109
+ */
110
+ public $is_uninstalled = false;
111
+
112
+ /**
113
+ * @param stdClass|bool $site
114
+ */
115
+ function __construct( $site = false ) {
116
+ parent::__construct( $site );
117
+
118
+ if ( is_object( $site ) and isset( $site->plan_id ) ) {
119
+ $this->plan_id = $site->plan_id;
120
+ }
121
+
122
+ if ( ! is_bool( $this->is_disconnected ) ) {
123
+ $this->is_disconnected = false;
124
+ }
125
+
126
+ $props = wcl_fs_get_object_public_vars( $this );
127
+
128
+ foreach ( $props as $key => $def_value ) {
129
+ $this->{$key} = isset( $site->{ 'install_' . $key } ) ? $site->{ 'install_' . $key } : $def_value;
130
+ }
131
+ if ( isset ( $site->install_id ) ) {
132
+ $this->site_id = $site->install_id;
133
+ }
134
+ }
135
+
136
+ static function get_type() {
137
+ return 'install';
138
+ }
139
+
140
+ /**
141
+ * @author Vova Feldman (@svovaf)
142
+ * @since 2.0.0
143
+ *
144
+ * @param string $url
145
+ *
146
+ * @return bool
147
+ */
148
+ static function is_localhost_by_address( $url ) {
149
+ if ( false !== strpos( $url, '127.0.0.1' ) ||
150
+ false !== strpos( $url, 'localhost' )
151
+ ) {
152
+ return true;
153
+ }
154
+
155
+ if ( ! fs_starts_with( $url, 'http' ) ) {
156
+ $url = 'http://' . $url;
157
+ }
158
+
159
+ $url_parts = parse_url( $url );
160
+
161
+ $subdomain = $url_parts['host'];
162
+
163
+ return (
164
+ // Starts with.
165
+ fs_starts_with( $subdomain, 'local.' ) ||
166
+ fs_starts_with( $subdomain, 'dev.' ) ||
167
+ fs_starts_with( $subdomain, 'test.' ) ||
168
+ fs_starts_with( $subdomain, 'staging.' ) ||
169
+
170
+ // Ends with.
171
+ fs_ends_with( $subdomain, '.dev' ) ||
172
+ fs_ends_with( $subdomain, '.test' ) ||
173
+ fs_ends_with( $subdomain, '.staging' ) ||
174
+ fs_ends_with( $subdomain, '.local' ) ||
175
+ fs_ends_with( $subdomain, '.example' ) ||
176
+ fs_ends_with( $subdomain, '.invalid' ) ||
177
+ // GoDaddy test/dev.
178
+ fs_ends_with( $subdomain, '.myftpupload.com' ) ||
179
+ // ngrok tunneling.
180
+ fs_ends_with( $subdomain, '.ngrok.io' ) ||
181
+ // SiteGround staging.
182
+ fs_starts_with( $subdomain, 'staging' ) ||
183
+ // WPEngine staging.
184
+ fs_ends_with( $subdomain, '.staging.wpengine.com' ) ||
185
+ // Pantheon
186
+ ( fs_ends_with($subdomain, 'pantheonsite.io') &&
187
+ (fs_starts_with($subdomain, 'test-') || fs_starts_with($subdomain, 'dev-'))) ||
188
+ // Cloudways
189
+ fs_ends_with( $subdomain, '.cloudwaysapps.com' )
190
+ );
191
+ }
192
+
193
+ function is_localhost() {
194
+ return ( WP_FS__IS_LOCALHOST_FOR_SERVER || self::is_localhost_by_address( $this->url ) );
195
+ }
196
+
197
+ /**
198
+ * Check if site in trial.
199
+ *
200
+ * @author Vova Feldman (@svovaf)
201
+ * @since 1.0.9
202
+ *
203
+ * @return bool
204
+ */
205
+ function is_trial() {
206
+ return is_numeric( $this->trial_plan_id ) && ( strtotime( $this->trial_ends ) > WP_FS__SCRIPT_START_TIME );
207
+ }
208
+
209
+ /**
210
+ * Check if user already utilized the trial with the current install.
211
+ *
212
+ * @author Vova Feldman (@svovaf)
213
+ * @since 1.0.9
214
+ *
215
+ * @return bool
216
+ */
217
+ function is_trial_utilized() {
218
+ return is_numeric( $this->trial_plan_id );
219
+ }
220
+
221
+ /**
222
+ * @author Vova Feldman (@svovaf)
223
+ * @since 2.0.0
224
+ *
225
+ * @return bool
226
+ */
227
+ function is_tracking_allowed() {
228
+ return ( true !== $this->is_disconnected );
229
+ }
230
+
231
+ /**
232
+ * @author Vova Feldman (@svovaf)
233
+ * @since 2.0.0
234
+ *
235
+ * @return bool
236
+ */
237
+ function is_tracking_prohibited() {
238
+ return ! $this->is_tracking_allowed();
239
+ }
240
+ }
includes/freemius/entities/class.wcl-fs-user.php ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package Freemius
4
+ * @copyright Copyright (c) 2015, Freemius, Inc.
5
+ * @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
6
+ * @since 1.0.3
7
+ */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit;
11
+ }
12
+
13
+ /**
14
+ * Класс для хранения данных пользователя с freemius
15
+ * @author Webcraftic <jokerov@gmail.com>
16
+ * @copyright (c) 2018 Webraftic Ltd
17
+ * @version 1.0
18
+ */
19
+ class WCL_FS_User extends WCL_FS_ScopeEntity {
20
+
21
+ /**
22
+ * @var string
23
+ */
24
+ public $email;
25
+ /**
26
+ * @var string
27
+ */
28
+ public $first;
29
+ /**
30
+ * @var string
31
+ */
32
+ public $last;
33
+ /**
34
+ * @var bool
35
+ */
36
+ public $is_verified;
37
+ /**
38
+ * @var string|null
39
+ */
40
+ public $customer_id;
41
+ /**
42
+ * @var float
43
+ */
44
+ public $gross;
45
+
46
+
47
+ /**
48
+ * @param object|bool $user
49
+ */
50
+ public function __construct( $user = false ) {
51
+ parent::__construct( $user );
52
+ $props = wcl_fs_get_object_public_vars( $this );
53
+
54
+ foreach ( $props as $key => $def_value ) {
55
+ $this->{$key} = isset( $user->{ 'user_' . $key } ) ? $user->{ 'user_' . $key } : $def_value;
56
+ }
57
+ }
58
+
59
+ public function get_name() {
60
+ return trim( ucfirst( trim( is_string( $this->first ) ? $this->first : '' ) ) . ' ' . ucfirst( trim( is_string( $this->last ) ? $this->last : '' ) ) );
61
+ }
62
+
63
+ public function is_verified() {
64
+ return ( isset( $this->is_verified ) && true === $this->is_verified );
65
+ }
66
+
67
+ static function get_type() {
68
+ return 'user';
69
+ }
70
+
71
+ }
includes/freemius/sdk/Exceptions/ArgumentNotExistException.php ADDED
@@ -0,0 +1,2 @@
 
 
1
+ <?php
2
+ class WCL_Freemius_ArgumentNotExistException extends WCL_Freemius_InvalidArgumentException { }
includes/freemius/sdk/Exceptions/EmptyArgumentException.php ADDED
@@ -0,0 +1,2 @@
 
 
1
+ <?php
2
+ class WCL_Freemius_EmptyArgumentException extends WCL_Freemius_InvalidArgumentException { }
includes/freemius/sdk/Exceptions/Exception.php ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Thrown when an API call returns an exception.
4
+ *
5
+ */
6
+
7
+ if( !class_exists('WCL_Freemius_Exception') ) {
8
+
9
+ class WCL_Freemius_Exception extends Exception {
10
+
11
+ protected $_result;
12
+ protected $_type;
13
+ protected $_code;
14
+
15
+ /**
16
+ * Make a new API Exception with the given result.
17
+ *
18
+ * @param array $result The result from the API server.
19
+ */
20
+ public function __construct($result)
21
+ {
22
+ $this->_result = $result;
23
+
24
+ $code = 0;
25
+ $message = 'Unknown error, please check GetResult().';
26
+ $type = '';
27
+
28
+ if( isset($result['error']) && is_array($result['error']) ) {
29
+ if( isset($result['error']['code']) ) {
30
+ $code = $result['error']['code'];
31
+ }
32
+ if( isset($result['error']['message']) ) {
33
+ $message = $result['error']['message'];
34
+ }
35
+ if( isset($result['error']['type']) ) {
36
+ $type = $result['error']['type'];
37
+ }
38
+ }
39
+
40
+ $this->_type = $type;
41
+ $this->_code = $code;
42
+
43
+ parent::__construct($message, is_numeric($code)
44
+ ? $code
45
+ : 0);
46
+ }
47
+
48
+ /**
49
+ * Return the associated result object returned by the API server.
50
+ *
51
+ * @return array The result from the API server
52
+ */
53
+ public function getResult()
54
+ {
55
+ return $this->_result;
56
+ }
57
+
58
+ public function getStringCode()
59
+ {
60
+ return $this->_code;
61
+ }
62
+
63
+ public function getType()
64
+ {
65
+ return $this->_type;
66
+ }
67
+
68
+ /**
69
+ * To make debugging easier.
70
+ *
71
+ * @return string The string representation of the error
72
+ */
73
+ public function __toString()
74
+ {
75
+ $str = $this->getType() . ': ';
76
+
77
+ if( $this->code != 0 ) {
78
+ $str .= $this->getStringCode() . ': ';
79
+ }
80
+
81
+ return $str . $this->getMessage();
82
+ }
83
+ }
84
+ }
includes/freemius/sdk/Exceptions/InvalidArgumentException.php ADDED
@@ -0,0 +1,2 @@
 
 
1
+ <?php
2
+ class WCL_Freemius_InvalidArgumentException extends WCL_Freemius_Exception { }
includes/freemius/sdk/Exceptions/OAuthException.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WCL_Freemius_OAuthException extends WCL_Freemius_Exception {
4
+
5
+ public function __construct($pResult)
6
+ {
7
+ parent::__construct($pResult);
8
+ }
9
+ }
includes/freemius/sdk/Exceptions/index.php ADDED
File without changes
includes/freemius/sdk/FreemiusBase.php ADDED
@@ -0,0 +1,204 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright 2014 Freemius, Inc.
4
+ *
5
+ * Licensed under the GPL v2 (the "License"); you may
6
+ * not use this file except in compliance with the License. You may obtain
7
+ * a copy of the License at
8
+ *
9
+ * http://choosealicense.com/licenses/gpl-v2/
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14
+ * License for the specific language governing permissions and limitations
15
+ * under the License.
16
+ */
17
+
18
+ define('WCL_FS_API__VERSION', '1');
19
+ define('WCL_FS_SDK__PATH', dirname(__FILE__));
20
+ define('WCL_FS_SDK__EXCEPTIONS_PATH', WCL_FS_SDK__PATH . '/Exceptions/');
21
+
22
+ if (!function_exists('json_decode'))
23
+ throw new Exception('Freemius needs the JSON PHP extension.');
24
+
25
+ // Include all exception files.
26
+ $exceptions = array(
27
+ 'Exception',
28
+ 'InvalidArgumentException',
29
+ 'ArgumentNotExistException',
30
+ 'EmptyArgumentException',
31
+ 'OAuthException'
32
+ );
33
+
34
+ foreach ($exceptions as $e)
35
+ require WCL_FS_SDK__EXCEPTIONS_PATH . $e . '.php';
36
+
37
+ abstract class WCL_Freemius_Api_Base
38
+ {
39
+ const VERSION = '1.0.4';
40
+ const FORMAT = 'json';
41
+
42
+ protected $_id;
43
+ protected $_public;
44
+ protected $_secret;
45
+ protected $_scope;
46
+ protected $_sandbox;
47
+
48
+ /**
49
+ * @param string $pScope 'app', 'developer', 'user' or 'install'.
50
+ * @param number $pID Element's id.
51
+ * @param string $pPublic Public key.
52
+ * @param string $pSecret Element's secret key.
53
+ * @param bool $pSandbox Whether or not to run API in sandbox mode.
54
+ */
55
+ public function Init($pScope, $pID, $pPublic, $pSecret, $pSandbox = false)
56
+ {
57
+ $this->_id = $pID;
58
+ $this->_public = $pPublic;
59
+ $this->_secret = $pSecret;
60
+ $this->_scope = $pScope;
61
+ $this->_sandbox = $pSandbox;
62
+ }
63
+
64
+ public function IsSandbox()
65
+ {
66
+ return $this->_sandbox;
67
+ }
68
+
69
+ function CanonizePath($pPath)
70
+ {
71
+ $pPath = trim($pPath, '/');
72
+ $query_pos = strpos($pPath, '?');
73
+ $query = '';
74
+
75
+ if (false !== $query_pos) {
76
+ $query = substr($pPath, $query_pos);
77
+ $pPath = substr($pPath, 0, $query_pos);
78
+ }
79
+
80
+ // Trim '.json' suffix.
81
+ $format_length = strlen('.' . self::FORMAT);
82
+ $start = $format_length * (-1); //negative
83
+ if (substr(strtolower($pPath), $start) === ('.' . self::FORMAT))
84
+ $pPath = substr($pPath, 0, strlen($pPath) - $format_length);
85
+
86
+ switch ($this->_scope) {
87
+ case 'app':
88
+ $base = '/apps/' . $this->_id;
89
+ break;
90
+ case 'developer':
91
+ $base = '/developers/' . $this->_id;
92
+ break;
93
+ case 'user':
94
+ $base = '/users/' . $this->_id;
95
+ break;
96
+ case 'plugin':
97
+ $base = '/plugins/' . $this->_id;
98
+ break;
99
+ case 'install':
100
+ $base = '/installs/' . $this->_id;
101
+ break;
102
+ default:
103
+ throw new WCL_Freemius_Exception('Scope not implemented.');
104
+ }
105
+
106
+ return '/v' . WCL_FS_API__VERSION . $base .
107
+ (!empty($pPath) ? '/' : '') . $pPath .
108
+ ((false === strpos($pPath, '.')) ? '.' . self::FORMAT : '') . $query;
109
+ }
110
+
111
+ abstract function MakeRequest($pCanonizedPath, $pMethod = 'GET', $pParams = array(), $pFileParams = array());
112
+
113
+ private function _Api($pPath, $pMethod = 'GET', $pParams = array(), $pFileParams = array())
114
+ {
115
+ $pMethod = strtoupper($pMethod);
116
+
117
+ try {
118
+ $result = $this->MakeRequest($pPath, $pMethod, $pParams, $pFileParams);
119
+ }
120
+ catch (WCL_Freemius_Exception $e)
121
+ {
122
+ // Map to error object.
123
+ $result = json_encode($e->getResult());
124
+ } catch (Exception $e) {
125
+ // Map to error object.
126
+ $result = json_encode(array(
127
+ 'error' => array(
128
+ 'type' => 'Unknown',
129
+ 'message' => $e->getMessage() . ' (' . $e->getFile() . ': ' . $e->getLine() . ')',
130
+ 'code' => 'unknown',
131
+ 'http' => 402
132
+ )
133
+ ));
134
+ }
135
+
136
+ $decoded = null;
137
+ if ( ! is_object( $result ) ) {
138
+ $decoded = json_decode($result);
139
+ }
140
+
141
+ return (null === $decoded) ? $result : $decoded;
142
+ }
143
+
144
+ /**
145
+ * @return bool True if successful connectivity to the API endpoint using ping.json endpoint.
146
+ */
147
+ public function Test()
148
+ {
149
+ $pong = $this->_Api('/v' . WCL_FS_API__VERSION . '/ping.json');
150
+
151
+ return (is_object($pong) && isset($pong->api) && 'pong' === $pong->api);
152
+ }
153
+
154
+ /**
155
+ * Find clock diff between current server to API server.
156
+ *
157
+ * @since 1.0.2
158
+ * @return int Clock diff in seconds.
159
+ */
160
+ public function FindClockDiff()
161
+ {
162
+ $time = time();
163
+ $pong = $this->_Api('/v' . WCL_FS_API__VERSION . '/ping.json');
164
+ return ($time - strtotime($pong->timestamp));
165
+ }
166
+
167
+ public function Api($pPath, $pMethod = 'GET', $pParams = array(), $pFileParams = array())
168
+ {
169
+ return $this->_Api($this->CanonizePath($pPath), $pMethod, $pParams, $pFileParams);
170
+ }
171
+
172
+ /**
173
+ * Base64 encoding that does not need to be urlencode()ed.
174
+ * Exactly the same as base64_encode except it uses
175
+ * - instead of +
176
+ * _ instead of /
177
+ * No padded =
178
+ *
179
+ * @param string $input base64UrlEncoded string
180
+ * @return string
181
+ */
182
+ protected static function Base64UrlDecode($input)
183
+ {
184
+ return base64_decode(strtr($input, '-_', '+/'));
185
+ }
186
+
187
+ /**
188
+ * Base64 encoding that does not need to be urlencode()ed.
189
+ * Exactly the same as base64_encode except it uses
190
+ * - instead of +
191
+ * _ instead of /
192
+ *
193
+ * @param string $input string
194
+ * @return string base64Url encoded string
195
+ */
196
+ protected static function Base64UrlEncode($input)
197
+ {
198
+ $str = strtr(base64_encode($input), '+/', '-_');
199
+ $str = str_replace('=', '', $str);
200
+
201
+ return $str;
202
+ }
203
+
204
+ }
includes/freemius/sdk/FreemiusWordPress.php ADDED
@@ -0,0 +1,704 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright 2016 Freemius, Inc.
4
+ *
5
+ * Licensed under the GPL v2 (the "License"); you may
6
+ * not use this file except in compliance with the License. You may obtain
7
+ * a copy of the License at
8
+ *
9
+ * http://choosealicense.com/licenses/gpl-v2/
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14
+ * License for the specific language governing permissions and limitations
15
+ * under the License.
16
+ */
17
+
18
+ require_once dirname( __FILE__ ) . '/FreemiusBase.php';
19
+
20
+ if ( ! defined( 'WCL_FS_SDK__USER_AGENT' ) ) {
21
+ define( 'WCL_FS_SDK__USER_AGENT', 'fs-php-' . WCL_Freemius_Api_Base::VERSION );
22
+ }
23
+
24
+ if ( ! defined( 'WCL_FS_SDK__SIMULATE_NO_CURL' ) ) {
25
+ define( 'WCL_FS_SDK__SIMULATE_NO_CURL', false );
26
+ }
27
+
28
+ if ( ! defined( 'WCL_FS_SDK__SIMULATE_NO_API_CONNECTIVITY_CLOUDFLARE' ) ) {
29
+ define( 'WCL_FS_SDK__SIMULATE_NO_API_CONNECTIVITY_CLOUDFLARE', false );
30
+ }
31
+
32
+ if ( ! defined( 'WCL_FS_SDK__SIMULATE_NO_API_CONNECTIVITY_SQUID_ACL' ) ) {
33
+ define( 'WCL_FS_SDK__SIMULATE_NO_API_CONNECTIVITY_SQUID_ACL', false );
34
+ }
35
+
36
+ if ( ! defined( 'WCL_FS_SDK__HAS_CURL' ) ) {
37
+ if ( WCL_FS_SDK__SIMULATE_NO_CURL ) {
38
+ define( 'WCL_FS_SDK__HAS_CURL', false );
39
+ } else {
40
+ $curl_required_methods = array(
41
+ 'curl_version',
42
+ 'curl_exec',
43
+ 'curl_init',
44
+ 'curl_close',
45
+ 'curl_setopt',
46
+ 'curl_setopt_array',
47
+ 'curl_error',
48
+ );
49
+
50
+ $has_curl = true;
51
+ foreach ( $curl_required_methods as $m ) {
52
+ if ( ! function_exists( $m ) ) {
53
+ $has_curl = false;
54
+ break;
55
+ }
56
+ }
57
+
58
+ define( 'WCL_FS_SDK__HAS_CURL', $has_curl );
59
+ }
60
+ }
61
+
62
+ $curl_version = WCL_FS_SDK__HAS_CURL ?
63
+ curl_version() :
64
+ array( 'version' => '7.37' );
65
+
66
+ if ( ! defined( 'WCL_FS_API__PROTOCOL' ) ) {
67
+ define( 'WCL_FS_API__PROTOCOL', version_compare( $curl_version['version'], '7.37', '>=' ) ? 'https' : 'http' );
68
+ }
69
+
70
+ if ( ! defined( 'WCL_FS_API__LOGGER_ON' ) ) {
71
+ define( 'WCL_FS_API__LOGGER_ON', false );
72
+ }
73
+
74
+ if ( ! defined( 'WCL_FS_API__ADDRESS' ) ) {
75
+ define( 'WCL_FS_API__ADDRESS', '://api.freemius.com' );
76
+ }
77
+ if ( ! defined( 'WCL_FS_API__SANDBOX_ADDRESS' ) ) {
78
+ define( 'WCL_FS_API__SANDBOX_ADDRESS', '://sandbox-api.freemius.com' );
79
+ }
80
+
81
+ if ( class_exists( 'WCL_FreemiusWPApi' ) ) {
82
+ return;
83
+ }
84
+
85
+ class WCL_FreemiusWPApi extends WCL_Freemius_Api_Base {
86
+ private static $_logger = array();
87
+
88
+ /**
89
+ * @param string $pScope 'app', 'developer', 'user' or 'install'.
90
+ * @param number $pID Element's id.
91
+ * @param string $pPublic Public key.
92
+ * @param string|bool $pSecret Element's secret key.
93
+ * @param bool $pSandbox Whether or not to run API in sandbox mode.
94
+ */
95
+ public function __construct( $pScope, $pID, $pPublic, $pSecret = false, $pSandbox = false ) {
96
+ // If secret key not provided, use public key encryption.
97
+ if ( is_bool( $pSecret ) ) {
98
+ $pSecret = $pPublic;
99
+ }
100
+
101
+ parent::Init( $pScope, $pID, $pPublic, $pSecret, $pSandbox );
102
+ }
103
+
104
+ public static function GetUrl( $pCanonizedPath = '', $pIsSandbox = false ) {
105
+ $address = ( $pIsSandbox ? WCL_FS_API__SANDBOX_ADDRESS : WCL_FS_API__ADDRESS );
106
+
107
+ if ( ':' === $address[0] ) {
108
+ $address = self::$_protocol . $address;
109
+ }
110
+
111
+ return $address . $pCanonizedPath;
112
+ }
113
+
114
+ #----------------------------------------------------------------------------------
115
+ #region Servers Clock Diff
116
+ #----------------------------------------------------------------------------------
117
+
118
+ /**
119
+ * @var int Clock diff in seconds between current server to API server.
120
+ */
121
+ private static $_clock_diff = 0;
122
+
123
+ /**
124
+ * Set clock diff for all API calls.
125
+ *
126
+ * @since 1.0.3
127
+ *
128
+ * @param $pSeconds
129
+ */
130
+ public static function SetClockDiff( $pSeconds ) {
131
+ self::$_clock_diff = $pSeconds;
132
+ }
133
+
134
+ /**
135
+ * Find clock diff between current server to API server.
136
+ *
137
+ * @since 1.0.2
138
+ * @return int Clock diff in seconds.
139
+ */
140
+ public function FindClockDiff() {
141
+ $time = time();
142
+ $pong = self::Ping();
143
+
144
+ return ( $time - strtotime( $pong->timestamp ) );
145
+ }
146
+
147
+ #endregion
148
+
149
+ /**
150
+ * @var string http or https
151
+ */
152
+ private static $_protocol = WCL_FS_API__PROTOCOL;
153
+
154
+ /**
155
+ * Set API connection protocol.
156
+ *
157
+ * @since 1.0.4
158
+ */
159
+ public static function SetHttp() {
160
+ self::$_protocol = 'http';
161
+ }
162
+
163
+ /**
164
+ * @since 1.0.4
165
+ *
166
+ * @return bool
167
+ */
168
+ public static function IsHttps() {
169
+ return ( 'https' === self::$_protocol );
170
+ }
171
+
172
+ /**
173
+ * Sign request with the following HTTP headers:
174
+ * Content-MD5: MD5(HTTP Request body)
175
+ * Date: Current date (i.e Sat, 14 Feb 2016 20:24:46 +0000)
176
+ * Authorization: FS {scope_entity_id}:{scope_entity_public_key}:base64encode(sha256(string_to_sign,
177
+ * {scope_entity_secret_key}))
178
+ *
179
+ * @param string $pResourceUrl
180
+ * @param array $pWPRemoteArgs
181
+ *
182
+ * @return array
183
+ */
184
+ function SignRequest( $pResourceUrl, $pWPRemoteArgs ) {
185
+ $auth = $this->GenerateAuthorizationParams(
186
+ $pResourceUrl,
187
+ $pWPRemoteArgs['method'],
188
+ ! empty( $pWPRemoteArgs['body'] ) ? $pWPRemoteArgs['body'] : ''
189
+ );
190
+
191
+ $pWPRemoteArgs['headers']['Date'] = $auth['date'];
192
+ $pWPRemoteArgs['headers']['Authorization'] = $auth['authorization'];
193
+
194
+ if ( ! empty( $auth['content_md5'] ) ) {
195
+ $pWPRemoteArgs['headers']['Content-MD5'] = $auth['content_md5'];
196
+ }
197
+
198
+ return $pWPRemoteArgs;
199
+ }
200
+
201
+ /**
202
+ * Generate Authorization request headers:
203
+ *
204
+ * Content-MD5: MD5(HTTP Request body)
205
+ * Date: Current date (i.e Sat, 14 Feb 2016 20:24:46 +0000)
206
+ * Authorization: FS {scope_entity_id}:{scope_entity_public_key}:base64encode(sha256(string_to_sign,
207
+ * {scope_entity_secret_key}))
208
+ *
209
+ * @author Vova Feldman
210
+ *
211
+ * @param string $pResourceUrl
212
+ * @param string $pMethod
213
+ * @param string $pPostParams
214
+ *
215
+ * @return array
216
+ * @throws WCL_Freemius_Exception
217
+ */
218
+ function GenerateAuthorizationParams(
219
+ $pResourceUrl,
220
+ $pMethod = 'GET',
221
+ $pPostParams = ''
222
+ ) {
223
+ $pMethod = strtoupper( $pMethod );
224
+
225
+ $eol = "\n";
226
+ $content_md5 = '';
227
+ $content_type = '';
228
+ $now = ( time() - self::$_clock_diff );
229
+ $date = date( 'r', $now );
230
+
231
+ if ( in_array( $pMethod, array( 'POST', 'PUT' ) ) && ! empty( $pPostParams ) ) {
232
+ $content_md5 = md5( $pPostParams );
233
+ $content_type = 'application/json';
234
+ }
235
+
236
+ $string_to_sign = implode( $eol, array(
237
+ $pMethod,
238
+ $content_md5,
239
+ $content_type,
240
+ $date,
241
+ $pResourceUrl
242
+ ) );
243
+
244
+ // If secret and public keys are identical, it means that
245
+ // the signature uses public key hash encoding.
246
+ $auth_type = ( $this->_secret !== $this->_public ) ? 'FS' : 'FSP';
247
+
248
+ $auth = array(
249
+ 'date' => $date,
250
+ 'authorization' => $auth_type . ' ' . $this->_id . ':' .
251
+ $this->_public . ':' .
252
+ self::Base64UrlEncode( hash_hmac(
253
+ 'sha256', $string_to_sign, $this->_secret
254
+ ) )
255
+ );
256
+
257
+ if ( ! empty( $content_md5 ) ) {
258
+ $auth['content_md5'] = $content_md5;
259
+ }
260
+
261
+ return $auth;
262
+ }
263
+
264
+ /**
265
+ * Get API request URL signed via query string.
266
+ *
267
+ * @since 1.2.3 Stopped using http_build_query(). Instead, use urlencode(). In some environments the encoding of http_build_query() can generate a URL that once used with a redirect, the `&` querystring separator is escaped to `&amp;` which breaks the URL (Added by @svovaf).
268
+ *
269
+ * @param string $pPath
270
+ *
271
+ * @throws WCL_Freemius_Exception
272
+ *
273
+ * @return string
274
+ */
275
+ function GetSignedUrl( $pPath ) {
276
+ $resource = explode( '?', $this->CanonizePath( $pPath ) );
277
+ $pResourceUrl = $resource[0];
278
+
279
+ $auth = $this->GenerateAuthorizationParams( $pResourceUrl );
280
+
281
+ return Freemius_Api_WordPress::GetUrl(
282
+ $pResourceUrl . '?' .
283
+ ( 1 < count( $resource ) && ! empty( $resource[1] ) ? $resource[1] . '&' : '' ) .
284
+ 'authorization=' . urlencode( $auth['authorization'] ) .
285
+ '&auth_date=' . urlencode( $auth['date'] )
286
+ , $this->_sandbox );
287
+ }
288
+
289
+ /**
290
+ * @author Vova Feldman
291
+ *
292
+ * @param string $pUrl
293
+ * @param array $pWPRemoteArgs
294
+ *
295
+ * @return mixed
296
+ */
297
+ private static function ExecuteRequest( $pUrl, &$pWPRemoteArgs ) {
298
+ $start = microtime( true );
299
+
300
+ $response = wp_remote_request( $pUrl, $pWPRemoteArgs );
301
+
302
+ if ( WCL_FS_API__LOGGER_ON ) {
303
+ $end = microtime( true );
304
+
305
+ $has_body = ( isset( $pWPRemoteArgs['body'] ) && ! empty( $pWPRemoteArgs['body'] ) );
306
+ $is_http_error = is_wp_error( $response );
307
+
308
+ self::$_logger[] = array(
309
+ 'id' => count( self::$_logger ),
310
+ 'start' => $start,
311
+ 'end' => $end,
312
+ 'total' => ( $end - $start ),
313
+ 'method' => $pWPRemoteArgs['method'],
314
+ 'path' => $pUrl,
315
+ 'body' => $has_body ? $pWPRemoteArgs['body'] : null,
316
+ 'result' => ! $is_http_error ?
317
+ $response['body'] :
318
+ json_encode( $response->get_error_messages() ),
319
+ 'code' => ! $is_http_error ? $response['response']['code'] : null,
320
+ 'backtrace' => debug_backtrace(),
321
+ );
322
+ }
323
+
324
+ return $response;
325
+ }
326
+
327
+ /**
328
+ * @return array
329
+ */
330
+ static function GetLogger() {
331
+ return self::$_logger;
332
+ }
333
+
334
+ /**
335
+ * @param string $pCanonizedPath
336
+ * @param string $pMethod
337
+ * @param array $pParams
338
+ * @param null|array $pWPRemoteArgs
339
+ * @param bool $pIsSandbox
340
+ * @param null|callable $pBeforeExecutionFunction
341
+ *
342
+ * @return object[]|object|null
343
+ *
344
+ * @throws \WCL_Freemius_Exception
345
+ */
346
+ private static function MakeStaticRequest(
347
+ $pCanonizedPath,
348
+ $pMethod = 'GET',
349
+ $pParams = array(),
350
+ $pWPRemoteArgs = null,
351
+ $pIsSandbox = false,
352
+ $pBeforeExecutionFunction = null
353
+ ) {
354
+ // Connectivity errors simulation.
355
+ if ( WCL_FS_SDK__SIMULATE_NO_API_CONNECTIVITY_CLOUDFLARE ) {
356
+ self::ThrowCloudFlareDDoSException();
357
+ } else if ( WCL_FS_SDK__SIMULATE_NO_API_CONNECTIVITY_SQUID_ACL ) {
358
+ self::ThrowSquidAclException();
359
+ }
360
+
361
+ if ( empty( $pWPRemoteArgs ) ) {
362
+ $user_agent = 'Freemius/WordPress-SDK/' . WCL_Freemius_Api_Base::VERSION . '; ' .
363
+ home_url();
364
+
365
+ $pWPRemoteArgs = array(
366
+ 'method' => strtoupper( $pMethod ),
367
+ 'connect_timeout' => 10,
368
+ 'timeout' => 60,
369
+ 'follow_redirects' => true,
370
+ 'redirection' => 5,
371
+ 'user-agent' => $user_agent,
372
+ 'blocking' => true,
373
+ );
374
+ }
375
+
376
+ if ( ! isset( $pWPRemoteArgs['headers'] ) ||
377
+ ! is_array( $pWPRemoteArgs['headers'] )
378
+ ) {
379
+ $pWPRemoteArgs['headers'] = array();
380
+ }
381
+
382
+ if ( in_array( $pMethod, array( 'POST', 'PUT' ) ) ) {
383
+ if ( is_array( $pParams ) && 0 < count( $pParams ) ) {
384
+ $pWPRemoteArgs['headers']['Content-type'] = 'application/json';
385
+ $pWPRemoteArgs['body'] = json_encode( $pParams );
386
+ }
387
+ }
388
+
389
+ $request_url = self::GetUrl( $pCanonizedPath, $pIsSandbox );
390
+
391
+ $resource = explode( '?', $pCanonizedPath );
392
+
393
+ if ( WCL_FS_SDK__HAS_CURL ) {
394
+ // Disable the 'Expect: 100-continue' behaviour. This causes cURL to wait
395
+ // for 2 seconds if the server does not support this header.
396
+ $pWPRemoteArgs['headers']['Expect'] = '';
397
+ }
398
+
399
+ if ( 'https' === substr( strtolower( $request_url ), 0, 5 ) ) {
400
+ $pWPRemoteArgs['sslverify'] = false;
401
+ }
402
+
403
+ if ( false !== $pBeforeExecutionFunction &&
404
+ is_callable( $pBeforeExecutionFunction )
405
+ ) {
406
+ $pWPRemoteArgs = call_user_func( $pBeforeExecutionFunction, $resource[0], $pWPRemoteArgs );
407
+ }
408
+
409
+ $result = self::ExecuteRequest( $request_url, $pWPRemoteArgs );
410
+
411
+ if ( is_wp_error( $result ) ) {
412
+ /**
413
+ * @var WP_Error $result
414
+ */
415
+ if ( self::IsCurlError( $result ) ) {
416
+ /**
417
+ * With dual stacked DNS responses, it's possible for a server to
418
+ * have IPv6 enabled but not have IPv6 connectivity. If this is
419
+ * the case, cURL will try IPv4 first and if that fails, then it will
420
+ * fall back to IPv6 and the error EHOSTUNREACH is returned by the
421
+ * operating system.
422
+ */
423
+ $matches = array();
424
+ $regex = '/Failed to connect to ([^:].*): Network is unreachable/';
425
+ if ( preg_match( $regex, $result->get_error_message( 'http_request_failed' ), $matches ) ) {
426
+ /**
427
+ * Validate IP before calling `inet_pton()` to avoid PHP un-catchable warning.
428
+ * @author Vova Feldman (@svovaf)
429
+ */
430
+ if ( filter_var( $matches[1], FILTER_VALIDATE_IP ) ) {
431
+ if ( strlen( inet_pton( $matches[1] ) ) === 16 ) {
432
+ // error_log('Invalid IPv6 configuration on server, Please disable or get native IPv6 on your server.');
433
+ // Hook to an action triggered just before cURL is executed to resolve the IP version to v4.
434
+ add_action( 'http_api_curl', 'Freemius_Api_WordPress::CurlResolveToIPv4', 10, 1 );
435
+
436
+ // Re-run request.
437
+ $result = self::ExecuteRequest( $request_url, $pWPRemoteArgs );
438
+ }
439
+ }
440
+ }
441
+ }
442
+
443
+ if ( is_wp_error( $result ) ) {
444
+ self::ThrowWPRemoteException( $result );
445
+ }
446
+ }
447
+
448
+ $response_body = $result['body'];
449
+
450
+ if ( empty( $response_body ) ) {
451
+ return null;
452
+ }
453
+
454
+ $decoded = json_decode( $response_body );
455
+
456
+ if ( is_null( $decoded ) ) {
457
+ if ( preg_match( '/Please turn JavaScript on/i', $response_body ) &&
458
+ preg_match( '/text\/javascript/', $response_body )
459
+ ) {
460
+ self::ThrowCloudFlareDDoSException( $response_body );
461
+ } else if ( preg_match( '/Access control configuration prevents your request from being allowed at this time. Please contact your service provider if you feel this is incorrect./', $response_body ) &&
462
+ preg_match( '/squid/', $response_body )
463
+ ) {
464
+ self::ThrowSquidAclException( $response_body );
465
+ } else {
466
+ $decoded = (object) array(
467
+ 'error' => (object) array(
468
+ 'type' => 'Unknown',
469
+ 'message' => $response_body,
470
+ 'code' => 'unknown',
471
+ 'http' => 402
472
+ )
473
+ );
474
+ }
475
+ }
476
+
477
+ return $decoded;
478
+ }
479
+
480
+
481
+ /**
482
+ * Makes an HTTP request. This method can be overridden by subclasses if
483
+ * developers want to do fancier things or use something other than wp_remote_request()
484
+ * to make the request.
485
+ *
486
+ * @param string $pCanonizedPath The URL to make the request to
487
+ * @param string $pMethod HTTP method
488
+ * @param array $pParams The parameters to use for the POST body
489
+ * @param null|array $pWPRemoteArgs wp_remote_request options.
490
+ *
491
+ * @return object[]|object|null
492
+ *
493
+ * @throws WCL_Freemius_Exception
494
+ */
495
+ public function MakeRequest(
496
+ $pCanonizedPath,
497
+ $pMethod = 'GET',
498
+ $pParams = array(),
499
+ $pWPRemoteArgs = null
500
+ ) {
501
+ $resource = explode( '?', $pCanonizedPath );
502
+
503
+ // Only sign request if not ping.json connectivity test.
504
+ $sign_request = ( '/v1/ping.json' !== strtolower( substr( $resource[0], - strlen( '/v1/ping.json' ) ) ) );
505
+
506
+ return self::MakeStaticRequest(
507
+ $pCanonizedPath,
508
+ $pMethod,
509
+ $pParams,
510
+ $pWPRemoteArgs,
511
+ $this->_sandbox,
512
+ $sign_request ? array( &$this, 'SignRequest' ) : null
513
+ );
514
+ }
515
+
516
+ /**
517
+ * Sets CURLOPT_IPRESOLVE to CURL_IPRESOLVE_V4 for cURL-Handle provided as parameter
518
+ *
519
+ * @param resource $handle A cURL handle returned by curl_init()
520
+ *
521
+ * @return resource $handle A cURL handle returned by curl_init() with CURLOPT_IPRESOLVE set to
522
+ * CURL_IPRESOLVE_V4
523
+ *
524
+ * @link https://gist.github.com/golderweb/3a2aaec2d56125cc004e
525
+ */
526
+ static function CurlResolveToIPv4( $handle ) {
527
+ curl_setopt( $handle, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 );
528
+
529
+ return $handle;
530
+ }
531
+
532
+ #----------------------------------------------------------------------------------
533
+ #region Connectivity Test
534
+ #----------------------------------------------------------------------------------
535
+
536
+ /**
537
+ * If successful connectivity to the API endpoint using ping.json endpoint.
538
+ *
539
+ * - OR -
540
+ *
541
+ * Validate if ping result object is valid.
542
+ *
543
+ * @param mixed $pPong
544
+ *
545
+ * @return bool
546
+ */
547
+ public function Test( $pPong = null ) {
548
+ $pong = is_null( $pPong ) ?
549
+ self::Ping() :
550
+ $pPong;
551
+
552
+ return (
553
+ is_object( $pong ) &&
554
+ isset( $pong->api ) &&
555
+ 'pong' === $pong->api
556
+ );
557
+ }
558
+
559
+ /**
560
+ * Ping API to test connectivity.
561
+ *
562
+ * @return object
563
+ */
564
+ public static function Ping() {
565
+ try {
566
+ $result = self::MakeStaticRequest( '/v' . WCL_FS_API__VERSION . '/ping.json' );
567
+ } catch ( WCL_Freemius_Exception $e ) {
568
+ // Map to error object.
569
+ $result = (object) $e->getResult();
570
+ } catch ( Exception $e ) {
571
+ // Map to error object.
572
+ $result = (object) array(
573
+ 'error' => array(
574
+ 'type' => 'Unknown',
575
+ 'message' => $e->getMessage() . ' (' . $e->getFile() . ': ' . $e->getLine() . ')',
576
+ 'code' => 'unknown',
577
+ 'http' => 402
578
+ )
579
+ );
580
+ }
581
+
582
+ return $result;
583
+ }
584
+
585
+ #endregion
586
+
587
+ #----------------------------------------------------------------------------------
588
+ #region Connectivity Exceptions
589
+ #----------------------------------------------------------------------------------
590
+
591
+ /**
592
+ * @param \WP_Error $pError
593
+ *
594
+ * @return bool
595
+ */
596
+ private static function IsCurlError( WP_Error $pError ) {
597
+ $message = $pError->get_error_message( 'http_request_failed' );
598
+
599
+ return ( 0 === strpos( $message, 'cURL' ) );
600
+ }
601
+
602
+ /**
603
+ * @param WP_Error $pError
604
+ *
605
+ * @throws WCL_Freemius_Exception
606
+ */
607
+ private static function ThrowWPRemoteException( WP_Error $pError ) {
608
+ if ( self::IsCurlError( $pError ) ) {
609
+ $message = $pError->get_error_message( 'http_request_failed' );
610
+
611
+ #region Check if there are any missing cURL methods.
612
+
613
+ $curl_required_methods = array(
614
+ 'curl_version',
615
+ 'curl_exec',
616
+ 'curl_init',
617
+ 'curl_close',
618
+ 'curl_setopt',
619
+ 'curl_setopt_array',
620
+ 'curl_error',
621
+ );
622
+
623
+ // Find all missing methods.
624
+ $missing_methods = array();
625
+ foreach ( $curl_required_methods as $m ) {
626
+ if ( ! function_exists( $m ) ) {
627
+ $missing_methods[] = $m;
628
+ }
629
+ }
630
+
631
+ if ( ! empty( $missing_methods ) ) {
632
+ throw new WCL_Freemius_Exception( array(
633
+ 'error' => (object) array(
634
+ 'type' => 'cUrlMissing',
635
+ 'message' => $message,
636
+ 'code' => 'curl_missing',
637
+ 'http' => 402
638
+ ),
639
+ 'missing_methods' => $missing_methods,
640
+ ) );
641
+ }
642
+
643
+ #endregion
644
+
645
+ // cURL error - "cURL error {{errno}}: {{error}}".
646
+ $parts = explode( ':', substr( $message, strlen( 'cURL error ' ) ), 2 );
647
+
648
+ $code = ( 0 < count( $parts ) ) ? $parts[0] : 'http_request_failed';
649
+ $message = ( 1 < count( $parts ) ) ? $parts[1] : $message;
650
+
651
+ $e = new WCL_Freemius_Exception( array(
652
+ 'error' => array(
653
+ 'code' => $code,
654
+ 'message' => $message,
655
+ 'type' => 'CurlException',
656
+ ),
657
+ ) );
658
+ } else {
659
+ $e = new WCL_Freemius_Exception( array(
660
+ 'error' => array(
661
+ 'code' => $pError->get_error_code(),
662
+ 'message' => $pError->get_error_message(),
663
+ 'type' => 'WPRemoteException',
664
+ ),
665
+ ) );
666
+ }
667
+
668
+ throw $e;
669
+ }
670
+
671
+ /**
672
+ * @param string $pResult
673
+ *
674
+ * @throws WCL_Freemius_Exception
675
+ */
676
+ private static function ThrowCloudFlareDDoSException( $pResult = '' ) {
677
+ throw new WCL_Freemius_Exception( array(
678
+ 'error' => (object) array(
679
+ 'type' => 'CloudFlareDDoSProtection',
680
+ 'message' => $pResult,
681
+ 'code' => 'cloudflare_ddos_protection',
682
+ 'http' => 402
683
+ )
684
+ ) );
685
+ }
686
+
687
+ /**
688
+ * @param string $pResult
689
+ *
690
+ * @throws WCL_Freemius_Exception
691
+ */
692
+ private static function ThrowSquidAclException( $pResult = '' ) {
693
+ throw new WCL_Freemius_Exception( array(
694
+ 'error' => (object) array(
695
+ 'type' => 'SquidCacheBlock',
696
+ 'message' => $pResult,
697
+ 'code' => 'squid_cache_block',
698
+ 'http' => 402
699
+ )
700
+ ) );
701
+ }
702
+
703
+ #endregion
704
+ }
includes/freemius/sdk/LICENSE.txt ADDED
@@ -0,0 +1,340 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ GNU GENERAL PUBLIC LICENSE
2
+ Version 2, June 1991
3
+
4
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/>
5
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6
+ Everyone is permitted to copy and distribute verbatim copies
7
+ of this license document, but changing it is not allowed.
8
+
9
+ Preamble
10
+
11
+ The licenses for most software are designed to take away your
12
+ freedom to share and change it. By contrast, the GNU General Public
13
+ License is intended to guarantee your freedom to share and change free
14
+ software--to make sure the software is free for all its users. This
15
+ General Public License applies to most of the Free Software
16
+ Foundation's software and to any other program whose authors commit to
17
+ using it. (Some other Free Software Foundation software is covered by
18
+ the GNU Lesser General Public License instead.) You can apply it to
19
+ your programs, too.
20
+
21
+ When we speak of free software, we are referring to freedom, not
22
+ price. Our General Public Licenses are designed to make sure that you
23
+ have the freedom to distribute copies of free software (and charge for
24
+ this service if you wish), that you receive source code or can get it
25
+ if you want it, that you can change the software or use pieces of it
26
+ in new free programs; and that you know you can do these things.
27
+
28
+ To protect your rights, we need to make restrictions that forbid
29
+ anyone to deny you these rights or to ask you to surrender the rights.
30
+ These restrictions translate to certain responsibilities for you if you
31
+ distribute copies of the software, or if you modify it.
32
+
33
+ For example, if you distribute copies of such a program, whether
34
+ gratis or for a fee, you must give the recipients all the rights that
35
+ you have. You must make sure that they, too, receive or can get the
36
+ source code. And you must show them these terms so they know their
37
+ rights.
38
+
39
+ We protect your rights with two steps: (1) copyright the software, and
40
+ (2) offer you this license which gives you legal permission to copy,
41
+ distribute and/or modify the software.
42
+
43
+ Also, for each author's protection and ours, we want to make certain
44
+ that everyone understands that there is no warranty for this free
45
+ software. If the software is modified by someone else and passed on, we
46
+ want its recipients to know that what they have is not the original, so
47
+ that any problems introduced by others will not reflect on the original
48
+ authors' reputations.
49
+
50
+ Finally, any free program is threatened constantly by software
51
+ patents. We wish to avoid the danger that redistributors of a free
52
+ program will individually obtain patent licenses, in effect making the
53
+ program proprietary. To prevent this, we have made it clear that any
54
+ patent must be licensed for everyone's free use or not licensed at all.
55
+
56
+ The precise terms and conditions for copying, distribution and
57
+ modification follow.
58
+
59
+ GNU GENERAL PUBLIC LICENSE
60
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61
+
62
+ 0. This License applies to any program or other work which contains
63
+ a notice placed by the copyright holder saying it may be distributed
64
+ under the terms of this General Public License. The "Program", below,
65
+ refers to any such program or work, and a "work based on the Program"
66
+ means either the Program or any derivative work under copyright law:
67
+ that is to say, a work containing the Program or a portion of it,
68
+ either verbatim or with modifications and/or translated into another
69
+ language. (Hereinafter, translation is included without limitation in
70
+ the term "modification".) Each licensee is addressed as "you".
71
+
72
+ Activities other than copying, distribution and modification are not
73
+ covered by this License; they are outside its scope. The act of
74
+ running the Program is not restricted, and the output from the Program
75
+ is covered only if its contents constitute a work based on the
76
+ Program (independent of having been made by running the Program).
77
+ Whether that is true depends on what the Program does.
78
+
79
+ 1. You may copy and distribute verbatim copies of the Program's
80
+ source code as you receive it, in any medium, provided that you
81
+ conspicuously and appropriately publish on each copy an appropriate
82
+ copyright notice and disclaimer of warranty; keep intact all the
83
+ notices that refer to this License and to the absence of any warranty;
84
+ and give any other recipients of the Program a copy of this License
85
+ along with the Program.
86
+
87
+ You may charge a fee for the physical act of transferring a copy, and
88
+ you may at your option offer warranty protection in exchange for a fee.
89
+
90
+ 2. You may modify your copy or copies of the Program or any portion
91
+ of it, thus forming a work based on the Program, and copy and
92
+ distribute such modifications or work under the terms of Section 1
93
+ above, provided that you also meet all of these conditions:
94
+
95
+ a) You must cause the modified files to carry prominent notices
96
+ stating that you changed the files and the date of any change.
97
+
98
+ b) You must cause any work that you distribute or publish, that in
99
+ whole or in part contains or is derived from the Program or any
100
+ part thereof, to be licensed as a whole at no charge to all third
101
+ parties under the terms of this License.
102
+
103
+ c) If the modified program normally reads commands interactively
104
+ when run, you must cause it, when started running for such
105
+ interactive use in the most ordinary way, to print or display an
106
+ announcement including an appropriate copyright notice and a
107
+ notice that there is no warranty (or else, saying that you provide
108
+ a warranty) and that users may redistribute the program under
109
+ these conditions, and telling the user how to view a copy of this
110
+ License. (Exception: if the Program itself is interactive but
111
+ does not normally print such an announcement, your work based on
112
+ the Program is not required to print an announcement.)
113
+
114
+ These requirements apply to the modified work as a whole. If
115
+ identifiable sections of that work are not derived from the Program,
116
+ and can be reasonably considered independent and separate works in
117
+ themselves, then this License, and its terms, do not apply to those
118
+ sections when you distribute them as separate works. But when you
119
+ distribute the same sections as part of a whole which is a work based
120
+ on the Program, the distribution of the whole must be on the terms of
121
+ this License, whose permissions for other licensees extend to the
122
+ entire whole, and thus to each and every part regardless of who wrote it.
123
+
124
+ Thus, it is not the intent of this section to claim rights or contest
125
+ your rights to work written entirely by you; rather, the intent is to
126
+ exercise the right to control the distribution of derivative or
127
+ collective works based on the Program.
128
+
129
+ In addition, mere aggregation of another work not based on the Program
130
+ with the Program (or with a work based on the Program) on a volume of
131
+ a storage or distribution medium does not bring the other work under
132
+ the scope of this License.
133
+
134
+ 3. You may copy and distribute the Program (or a work based on it,
135
+ under Section 2) in object code or executable form under the terms of
136
+ Sections 1 and 2 above provided that you also do one of the following:
137
+
138
+ a) Accompany it with the complete corresponding machine-readable
139
+ source code, which must be distributed under the terms of Sections
140
+ 1 and 2 above on a medium customarily used for software interchange; or,
141
+
142
+ b) Accompany it with a written offer, valid for at least three
143
+ years, to give any third party, for a charge no more than your
144
+ cost of physically performing source distribution, a complete
145
+ machine-readable copy of the corresponding source code, to be
146
+ distributed under the terms of Sections 1 and 2 above on a medium
147
+ customarily used for software interchange; or,
148
+
149
+ c) Accompany it with the information you received as to the offer
150
+ to distribute corresponding source code. (This alternative is
151
+ allowed only for noncommercial distribution and only if you
152
+ received the program in object code or executable form with such
153
+ an offer, in accord with Subsection b above.)
154
+
155
+ The source code for a work means the preferred form of the work for
156
+ making modifications to it. For an executable work, complete source
157
+ code means all the source code for all modules it contains, plus any
158
+ associated interface definition files, plus the scripts used to
159
+ control compilation and installation of the executable. However, as a
160
+ special exception, the source code distributed need not include
161
+ anything that is normally distributed (in either source or binary
162
+ form) with the major components (compiler, kernel, and so on) of the
163
+ operating system on which the executable runs, unless that component
164
+ itself accompanies the executable.
165
+
166
+ If distribution of executable or object code is made by offering
167
+ access to copy from a designated place, then offering equivalent
168
+ access to copy the source code from the same place counts as
169
+ distribution of the source code, even though third parties are not
170
+ compelled to copy the source along with the object code.
171
+
172
+ 4. You may not copy, modify, sublicense, or distribute the Program
173
+ except as expressly provided under this License. Any attempt
174
+ otherwise to copy, modify, sublicense or distribute the Program is
175
+ void, and will automatically terminate your rights under this License.
176
+ However, parties who have received copies, or rights, from you under
177
+ this License will not have their licenses terminated so long as such
178
+ parties remain in full compliance.
179
+
180
+ 5. You are not required to accept this License, since you have not
181
+ signed it. However, nothing else grants you permission to modify or
182
+ distribute the Program or its derivative works. These actions are
183
+ prohibited by law if you do not accept this License. Therefore, by
184
+ modifying or distributing the Program (or any work based on the
185
+ Program), you indicate your acceptance of this License to do so, and
186
+ all its terms and conditions for copying, distributing or modifying
187
+ the Program or works based on it.
188
+
189
+ 6. Each time you redistribute the Program (or any work based on the
190
+ Program), the recipient automatically receives a license from the
191
+ original licensor to copy, distribute or modify the Program subject to
192
+ these terms and conditions. You may not impose any further
193
+ restrictions on the recipients' exercise of the rights granted herein.
194
+ You are not responsible for enforcing compliance by third parties to
195
+ this License.
196
+
197
+ 7. If, as a consequence of a court judgment or allegation of patent
198
+ infringement or for any other reason (not limited to patent issues),
199
+ conditions are imposed on you (whether by court order, agreement or
200
+ otherwise) that contradict the conditions of this License, they do not
201
+ excuse you from the conditions of this License. If you cannot
202
+ distribute so as to satisfy simultaneously your obligations under this
203
+ License and any other pertinent obligations, then as a consequence you
204
+ may not distribute the Program at all. For example, if a patent
205
+ license would not permit royalty-free redistribution of the Program by
206
+ all those who receive copies directly or indirectly through you, then
207
+ the only way you could satisfy both it and this License would be to
208
+ refrain entirely from distribution of the Program.
209
+
210
+ If any portion of this section is held invalid or unenforceable under
211
+ any particular circumstance, the balance of the section is intended to
212
+ apply and the section as a whole is intended to apply in other
213
+ circumstances.
214
+
215
+ It is not the purpose of this section to induce you to infringe any
216
+ patents or other property right claims or to contest validity of any
217
+ such claims; this section has the sole purpose of protecting the
218
+ integrity of the free software distribution system, which is
219
+ implemented by public license practices. Many people have made
220
+ generous contributions to the wide range of software distributed
221
+ through that system in reliance on consistent application of that
222
+ system; it is up to the author/donor to decide if he or she is willing
223
+ to distribute software through any other system and a licensee cannot
224
+ impose that choice.
225
+
226
+ This section is intended to make thoroughly clear what is believed to
227
+ be a consequence of the rest of this License.
228
+
229
+ 8. If the distribution and/or use of the Program is restricted in
230
+ certain countries either by patents or by copyrighted interfaces, the
231
+ original copyright holder who places the Program under this License
232
+ may add an explicit geographical distribution limitation excluding
233
+ those countries, so that distribution is permitted only in or among
234
+ countries not thus excluded. In such case, this License incorporates
235
+ the limitation as if written in the body of this License.
236
+
237
+ 9. The Free Software Foundation may publish revised and/or new versions
238
+ of the General Public License from time to time. Such new versions will
239
+ be similar in spirit to the present version, but may differ in detail to
240
+ address new problems or concerns.
241
+
242
+ Each version is given a distinguishing version number. If the Program
243
+ specifies a version number of this License which applies to it and "any
244
+ later version", you have the option of following the terms and conditions
245
+ either of that version or of any later version published by the Free
246
+ Software Foundation. If the Program does not specify a version number of
247
+ this License, you may choose any version ever published by the Free Software
248
+ Foundation.
249
+
250
+ 10. If you wish to incorporate parts of the Program into other free
251
+ programs whose distribution conditions are different, write to the author
252
+ to ask for permission. For software which is copyrighted by the Free
253
+ Software Foundation, write to the Free Software Foundation; we sometimes
254
+ make exceptions for this. Our decision will be guided by the two goals
255
+ of preserving the free status of all derivatives of our free software and
256
+ of promoting the sharing and reuse of software generally.
257
+
258
+ NO WARRANTY
259
+
260
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261
+ FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262
+ OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263
+ PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264
+ OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266
+ TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267
+ PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268
+ REPAIR OR CORRECTION.
269
+
270
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271
+ WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272
+ REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273
+ INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274
+ OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275
+ TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276
+ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277
+ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278
+ POSSIBILITY OF SUCH DAMAGES.
279
+
280
+ END OF TERMS AND CONDITIONS
281
+
282
+ How to Apply These Terms to Your New Programs
283
+
284
+ If you develop a new program, and you want it to be of the greatest
285
+ possible use to the public, the best way to achieve this is to make it
286
+ free software which everyone can redistribute and change under these terms.
287
+
288
+ To do so, attach the following notices to the program. It is safest
289
+ to attach them to the start of each source file to most effectively
290
+ convey the exclusion of warranty; and each file should have at least
291
+ the "copyright" line and a pointer to where the full notice is found.
292
+
293
+ {description}
294
+ Copyright (C) {year} {fullname}
295
+
296
+ This program is free software; you can redistribute it and/or modify
297
+ it under the terms of the GNU General Public License as published by
298
+ the Free Software Foundation; either version 2 of the License, or
299
+ (at your option) any later version.
300
+
301
+ This program is distributed in the hope that it will be useful,
302
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
303
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304
+ GNU General Public License for more details.
305
+
306
+ You should have received a copy of the GNU General Public License along
307
+ with this program; if not, write to the Free Software Foundation, Inc.,
308
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
309
+
310
+ Also add information on how to contact you by electronic and paper mail.
311
+
312
+ If the program is interactive, make it output a short notice like this
313
+ when it starts in an interactive mode:
314
+
315
+ Gnomovision version 69, Copyright (C) year name of author
316
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317
+ This is free software, and you are welcome to redistribute it
318
+ under certain conditions; type `show c' for details.
319
+
320
+ The hypothetical commands `show w' and `show c' should show the appropriate
321
+ parts of the General Public License. Of course, the commands you use may
322
+ be called something other than `show w' and `show c'; they could even be
323
+ mouse-clicks or menu items--whatever suits your program.
324
+
325
+ You should also get your employer (if you work as a programmer) or your
326
+ school, if any, to sign a "copyright disclaimer" for the program, if
327
+ necessary. Here is a sample; alter the names:
328
+
329
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
330
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
331
+
332
+ {signature of Ty Coon}, 1 April 1989
333
+ Ty Coon, President of Vice
334
+
335
+ This General Public License does not permit incorporating your program into
336
+ proprietary programs. If your program is a subroutine library, you may
337
+ consider it more useful to permit linking proprietary applications with the
338
+ library. If this is what you want to do, use the GNU Lesser General
339
+ Public License instead of this License.
340
+
includes/freemius/sdk/index.php ADDED
File without changes
includes/helpers.php CHANGED
@@ -14,6 +14,86 @@
14
 
15
  class WCL_Helper {
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  /**
18
  * Is permalink enabled?
19
  * @global WP_Rewrite $wp_rewrite
@@ -65,6 +145,10 @@
65
  }
66
  }
67
  }
 
 
 
 
68
 
69
  if( $return == 'array' ) {
70
  return $export_options;
@@ -73,34 +157,6 @@
73
  return WCL_Helper::getEscapeJson($export_options);
74
  }
75
 
76
- /**
77
- * Merge arrays, inserting $arr2 into $arr1 before/after certain key
78
- *
79
- * @param array $arr Modifyed array
80
- * @param array $inserted Inserted array
81
- * @param string $position 'before' / 'after' / 'top' / 'bottom'
82
- * @param string $key Associative key of $arr1 for before/after insertion
83
- *
84
- * @return array
85
- */
86
- public static function arrayMergeInsert(array $arr, array $inserted, $position = 'bottom', $key = null)
87
- {
88
- if( $position == 'top' ) {
89
- return array_merge($inserted, $arr);
90
- }
91
- $key_position = ($key === null)
92
- ? false
93
- : array_search($key, array_keys($arr));
94
- if( $key_position === false OR ($position != 'before' AND $position != 'after') ) {
95
- return array_merge($arr, $inserted);
96
- }
97
- if( $position == 'after' ) {
98
- $key_position++;
99
- }
100
-
101
- return array_merge(array_slice($arr, 0, $key_position, true), $inserted, array_slice($arr, $key_position, null, true));
102
- }
103
-
104
  /**
105
  * Try to get variable from JSON-encoded post variable
106
  *
@@ -134,150 +190,6 @@
134
  return htmlspecialchars(json_encode($data), ENT_QUOTES, 'UTF-8');
135
  }
136
 
137
- /**
138
- * Html minify function by Tim Eckel<tim@leethost.com>
139
- * @param $buffer
140
- * @return mixed
141
- */
142
-
143
- public static function minifyHtml($buffer)
144
- {
145
- if( substr(ltrim($buffer), 0, 5) == '<?xml' ) {
146
- return ($buffer);
147
- }
148
-
149
- $minify_javascript = WCL_Plugin::app()->getOption('minify_javascript');
150
- $minify_html_comments = WCL_Plugin::app()->getOption('minify_html_comments');
151
- $minify_html_utf8 = WCL_Plugin::app()->getOption('minify_html_utf8');
152
-
153
- if( $minify_html_utf8 && mb_detect_encoding($buffer, 'UTF-8', true) ) {
154
- $mod = '/u';
155
- } else {
156
- $mod = '/s';
157
- }
158
- $buffer = str_replace(array(chr(13) . chr(10), chr(9)), array(chr(10), ''), $buffer);
159
- $buffer = str_ireplace(array(
160
- '<script',
161
- '/script>',
162
- '<pre',
163
- '/pre>',
164
- '<textarea',
165
- '/textarea>',
166
- '<style',
167
- '/style>'
168
- ), array(
169
- 'M1N1FY-ST4RT<script',
170
- '/script>M1N1FY-3ND',
171
- 'M1N1FY-ST4RT<pre',
172
- '/pre>M1N1FY-3ND',
173
- 'M1N1FY-ST4RT<textarea',
174
- '/textarea>M1N1FY-3ND',
175
- 'M1N1FY-ST4RT<style',
176
- '/style>M1N1FY-3ND'
177
- ), $buffer);
178
- $split = explode('M1N1FY-3ND', $buffer);
179
- $buffer = '';
180
- for($i = 0; $i < count($split); $i++) {
181
- $ii = strpos($split[$i], 'M1N1FY-ST4RT');
182
- if( $ii !== false ) {
183
- $process = substr($split[$i], 0, $ii);
184
- $asis = substr($split[$i], $ii + 12);
185
- if( substr($asis, 0, 7) == '<script' ) {
186
- $split2 = explode(chr(10), $asis);
187
- $asis = '';
188
- for($iii = 0; $iii < count($split2); $iii++) {
189
- if( $split2[$iii] ) {
190
- $asis .= trim($split2[$iii]) . chr(10);
191
- }
192
- if( $minify_javascript != 'no' ) {
193
- if( strpos($split2[$iii], '//') !== false && substr(trim($split2[$iii]), -1) == ';' ) {
194
- $asis .= chr(10);
195
- }
196
- }
197
- }
198
- if( $asis ) {
199
- $asis = substr($asis, 0, -1);
200
- }
201
- if( $minify_html_comments ) {
202
- $asis = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $asis);
203
- }
204
- if( $minify_javascript != 'no' ) {
205
- $asis = str_replace(array(
206
- ';' . chr(10),
207
- '>' . chr(10),
208
- '{' . chr(10),
209
- '}' . chr(10),
210
- ',' . chr(10)
211
- ), array(';', '>', '{', '}', ','), $asis);
212
- }
213
- } else if( substr($asis, 0, 6) == '<style' ) {
214
- $asis = preg_replace(array('/\>[^\S ]+' . $mod, '/[^\S ]+\<' . $mod, '/(\s)+' . $mod), array(
215
- '>',
216
- '<',
217
- '\\1'
218
- ), $asis);
219
- if( $minify_html_comments ) {
220
- $asis = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $asis);
221
- }
222
- $asis = str_replace(array(
223
- chr(10),
224
- ' {',
225
- '{ ',
226
- ' }',
227
- '} ',
228
- '( ',
229
- ' )',
230
- ' :',
231
- ': ',
232
- ' ;',
233
- '; ',
234
- ' ,',
235
- ', ',
236
- ';}'
237
- ), array('', '{', '{', '}', '}', '(', ')', ':', ':', ';', ';', ',', ',', '}'), $asis);
238
- }
239
- } else {
240
- $process = $split[$i];
241
- $asis = '';
242
- }
243
- $process = preg_replace(array('/\>[^\S ]+' . $mod, '/[^\S ]+\<' . $mod, '/(\s)+' . $mod), array(
244
- '>',
245
- '<',
246
- '\\1'
247
- ), $process);
248
- if( $minify_html_comments ) {
249
- $process = preg_replace('/<!--(?!\s*(?:\[if [^\]]+]|<!|\s?ngg_resource|>))(?:(?!-->).)*-->' . $mod, '', $process);
250
- }
251
- $buffer .= $process . $asis;
252
- }
253
- $buffer = str_replace(array(
254
- chr(10) . '<script',
255
- chr(10) . '<style',
256
- '*/' . chr(10),
257
- 'M1N1FY-ST4RT'
258
- ), array('<script', '<style', '*/', ''), $buffer);
259
-
260
- $minify_html_xhtml = WCL_Plugin::app()->getOption('minify_html_xhtml');
261
- $minify_html_relative = WCL_Plugin::app()->getOption('minify_html_relative');
262
- $minify_html_scheme = WCL_Plugin::app()->getOption('minify_html_scheme');
263
-
264
- if( $minify_html_xhtml && strtolower(substr(ltrim($buffer), 0, 15)) == '<!doctype html>' ) {
265
- $buffer = str_replace(' />', '>', $buffer);
266
- }
267
- if( $minify_html_relative ) {
268
- $buffer = str_replace(array(
269
- 'https://' . $_SERVER['HTTP_HOST'] . '/',
270
- 'http://' . $_SERVER['HTTP_HOST'] . '/',
271
- '//' . $_SERVER['HTTP_HOST'] . '/'
272
- ), array('/', '/', '/'), $buffer);
273
- }
274
- if( $minify_html_scheme ) {
275
- $buffer = str_replace(array('http://', 'https://'), '//', $buffer);
276
- }
277
-
278
- return ($buffer);
279
- }
280
-
281
  /**
282
  * Componate content for robot.txt
283
  * @return string
14
 
15
  class WCL_Helper {
16
 
17
+ /**
18
+ * Allows you to get the base path to the plugin in the directory wp-content/plugins/
19
+ *
20
+ * @param $slug - slug for example "clearfy", "hide-login-page"
21
+ * @return int|null|string - "clearfy/clearfy.php"
22
+ */
23
+ public static function getPluginBasePathBySlug($slug)
24
+ {
25
+ // Check if the function get_plugins() is registered. It is necessary for the front-end
26
+ // usually get_plugins() only works in the admin panel.
27
+ if( !function_exists('get_plugins') ) {
28
+ require_once ABSPATH . 'wp-admin/includes/plugin.php';
29
+ }
30
+
31
+ $plugins = get_plugins();
32
+
33
+ foreach($plugins as $base_path => $plugin) {
34
+ if( strpos($base_path, rtrim(trim($slug))) !== false ) {
35
+ return $base_path;
36
+ }
37
+ }
38
+
39
+ return null;
40
+ }
41
+
42
+ /**
43
+ * Static method will check whether the plugin is activated or not. You can check whether the plugin exists
44
+ * by using its slug or the base path.
45
+ *
46
+ * @param string $slug - slug for example "clearfy", "hide-login-page" or base path "clearfy/clearfy.php"
47
+ * @return bool
48
+ */
49
+ public static function isPluginActivated($slug)
50
+ {
51
+ if( strpos(rtrim(trim($slug)), '/') === false ) {
52
+ $plugin_base_path = self::getPluginBasePathBySlug($slug);
53
+
54
+ if( empty($plugin_base_path) ) {
55
+ return false;
56
+ }
57
+ } else {
58
+ $plugin_base_path = $slug;
59
+ }
60
+
61
+ return is_plugin_active($plugin_base_path);
62
+ }
63
+
64
+ /**
65
+ * Static method will check whether the plugin is installed or not. You can check whether the plugin exists
66
+ * by using its slug or the base path.
67
+ *
68
+ * @param string $slug - slug "clearfy" or base_path "clearfy/clearfy.php"
69
+ * @return bool
70
+ */
71
+ public static function isPluginInstalled($slug)
72
+ {
73
+ if( strpos(rtrim(trim($slug)), '/') === false ) {
74
+ $plugin_base_path = self::getPluginBasePathBySlug($slug);
75
+
76
+ if( !empty($plugin_base_path) ) {
77
+ return true;
78
+ }
79
+ } else {
80
+
81
+ // Check if the function get_plugins() is registered. It is necessary for the front-end
82
+ // usually get_plugins() only works in the admin panel.
83
+ if( !function_exists('get_plugins') ) {
84
+ require_once ABSPATH . 'wp-admin/includes/plugin.php';
85
+ }
86
+
87
+ $plugins = get_plugins();
88
+
89
+ if( isset($plugins[$slug]) ) {
90
+ return true;
91
+ }
92
+ }
93
+
94
+ return false;
95
+ }
96
+
97
  /**
98
  * Is permalink enabled?
99
  * @global WP_Rewrite $wp_rewrite
145
  }
146
  }
147
  }
148
+
149
+ $freemius_addons = WCL_Plugin::app()->getPrefix() . 'freemius_activated_addons';
150
+ $export_options[$freemius_addons] = WCL_Plugin::app()->getOption( 'freemius_activated_addons', array() );
151
+
152
 
153
  if( $return == 'array' ) {
154
  return $export_options;
157
  return WCL_Helper::getEscapeJson($export_options);
158
  }
159
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
160
  /**
161
  * Try to get variable from JSON-encoded post variable
162
  *
190
  return htmlspecialchars(json_encode($data), ENT_QUOTES, 'UTF-8');
191
  }
192
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
193
  /**
194
  * Componate content for robot.txt
195
  * @return string
languages/clearfy-ru_RU.mo CHANGED
Binary file
languages/clearfy-ru_RU.po CHANGED
@@ -1,15 +1,15 @@
1
  msgid ""
2
  msgstr ""
3
  "Project-Id-Version: clearfy\n"
4
- "POT-Creation-Date: 2018-03-23 21:45+0300\n"
5
- "PO-Revision-Date: 2018-03-23 21:49+0300\n"
6
  "Last-Translator: alex.kovalevv@gmail.com <alex.kovalevv@gmail.com>\n"
7
  "Language-Team: Alex Kovalev <alex.kovalevv@gmail.com>\n"
8
  "Language: ru_RU\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
12
- "X-Generator: Poedit 1.8.8\n"
13
  "X-Poedit-Basepath: ..\n"
14
  "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
15
  "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
@@ -21,6 +21,7 @@ msgstr ""
21
  "X-Poedit-SearchPathExcluded-2: cache\n"
22
 
23
  #: admin/ajax/configurate.php:19 admin/ajax/import-settings.php:21
 
24
  msgid "You don't have enough capability to edit this information."
25
  msgstr "У вас недостаточно возможностей для редактирования этой информации."
26
 
@@ -32,7 +33,32 @@ msgstr "Неопределенный режим."
32
  msgid "Settings are not defined or do not exist."
33
  msgstr "Настройки не определены или не существуют."
34
 
35
- #: admin/boot.php:22
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  #, php-format
37
  msgid ""
38
  "We found that you have the plugin %s installed. The functions of this plugin "
@@ -43,7 +69,7 @@ msgstr ""
43
  "есть в %s. Пожалуйста, деактивируйте плагин %s во избежание конфликтов между "
44
  "функциями плагинов."
45
 
46
- #: admin/boot.php:23
47
  #, php-format
48
  msgid ""
49
  "If you do not want to deactivate the plugin %s for some reason, we strongly "
@@ -53,44 +79,175 @@ msgstr ""
53
  "настоятельно рекомендуем не использовать похожие функции плагинов "
54
  "одновременно!"
55
 
56
- #: admin/boot.php:72
57
- #, php-format
58
- msgid "Welcome to Clearfy (%s)"
59
- msgstr "Вас приветствует Clearfy (%s)"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
 
61
  #: admin/boot.php:73
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  msgid ""
63
- "There are new optimization and protection features in the plugin. We "
64
- "recommend you to look at them maybe they will be useful!"
65
  msgstr ""
66
- "В плагине появились новые функции оптимизации и защиты. Мы рекомендуем вам "
67
- "ознакомится с ними, возможно они будут полезны!"
68
 
69
- #: admin/boot.php:75
70
- msgid "The section \"Code cleaning\" was renamed"
71
- msgstr "Переименован раздел \"Очистка кода\""
72
 
73
- #: admin/boot.php:76
74
  msgid ""
75
- "Asynchronous Google fonts loading, Google Analytics optimization, disabling "
76
- "Google Fonts and Maps, disabling of gravatars, Font Awesome icons was added."
 
77
  msgstr ""
78
- "Добавлена асинхронная загрузка Google шрифтов, оптимизация Google Analytics, "
79
- "отключение Google шрифтов и карт, отключение граваторов, иконок Font Awesome."
 
 
 
 
 
80
 
81
- #: admin/boot.php:78
82
- msgid "Login page protection added"
83
- msgstr "Добавлена защита страницы логина"
84
 
85
- #: admin/boot.php:79
86
  msgid ""
87
- "With the new Clearfy version, you can use the hide login page function. "
88
- "Nobody will know the address of your login page, which means there will be "
89
- "no password bruteforce and the attempts of your website hack will decrease."
90
  msgstr ""
91
- "В новой версии Clearfy, вы можете использовать функции скрытия страницы "
92
- "логина. Никто не узнает адрес вашей страницы логина, а значит не будет "
93
- "переборов пароля и уменьшатся попытки взлома вашего сайта."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
 
95
  #: admin/includes/options.php:18 admin/pages/performance-google.php:92
96
  msgid "Google Fonts asynchronous"
@@ -108,323 +265,285 @@ msgstr "Удалить Google карты (iframe)"
108
  msgid "Exclude pages from Disable Google Maps filter"
109
  msgstr "Не отключать Google карты на установленных страницах"
110
 
111
- #: admin/includes/options.php:38 admin/pages/performance-google.php:153
112
- msgid "Google analytic cache"
113
- msgstr "Кеш Google аналитики"
114
-
115
- #: admin/includes/options.php:43 admin/pages/performance-google.php:174
116
- msgid "Google analytic Code"
117
- msgstr "Код Google аналитики"
118
-
119
- #: admin/includes/options.php:48 admin/pages/performance-google.php:195
120
- msgid "Use adjusted bounce rate?"
121
- msgstr "Показатель отказов?"
122
-
123
- #: admin/includes/options.php:53 admin/pages/performance-google.php:204
124
- msgid "Change enqueue order?"
125
- msgstr "Сортировка скрипта?"
126
-
127
- #: admin/includes/options.php:58 admin/pages/performance-google.php:213
128
- msgid "Disable all display features functionality?"
129
- msgstr "Отключить все функции для контекстно-медийной сети?"
130
-
131
- #: admin/includes/options.php:63 admin/pages/performance-google.php:222
132
- msgid "Use Anonymize IP? (Required by law for some countries)"
133
- msgstr ""
134
- "Использовать анонимный IP-адрес? (Требуется по закону для некоторых стран)"
135
-
136
- #: admin/includes/options.php:68 admin/pages/performance-google.php:231
137
- #: admin/pages/performance-google.php:233
138
- msgid "Track logged in Administrators?"
139
- msgstr "Отслеживать, если вы авторизованы под администратором?"
140
-
141
- #: admin/includes/options.php:73 admin/pages/performance-google.php:240
142
- msgid "Remove script from wp-cron?"
143
- msgstr "Удалить кеширования скрипта из крона?"
144
-
145
- #: admin/includes/options.php:79 admin/pages/performance-google.php:113
146
  msgid "Disable Google maps"
147
  msgstr "Отключить Google карты"
148
 
149
- #: admin/includes/options.php:85 admin/pages/performance.php:164
150
  msgid "Removing XFN (XHTML Friends Network) Profile Link"
151
  msgstr "Удалить профиль XFN (XHTML Friends Network)"
152
 
153
- #: admin/includes/options.php:90 admin/pages/performance.php:216
154
  msgid "Font Awesome asynchronous"
155
  msgstr "Асинхронный Fontawesome"
156
 
157
- #: admin/includes/options.php:95 admin/pages/performance.php:226
158
  msgid "Disable Dashicons"
159
  msgstr "Отключить Wordpress иконки (для фронтенда)"
160
 
161
- #: admin/includes/options.php:100 admin/pages/performance.php:236
162
  msgid "Disable gravatars"
163
  msgstr "Отключить граватары"
164
 
165
- #: admin/includes/options.php:105 admin/pages/performance.php:106
166
  msgid "Remove REST API Links"
167
  msgstr "Отключить Rest API"
168
 
169
- #: admin/includes/options.php:110 admin/pages/performance.php:116
170
  msgid "Disable Emojis"
171
  msgstr "Отключить Emojis (эмоции)"
172
 
173
- #: admin/includes/options.php:121 admin/pages/performance.php:155
174
  msgid "Remove RSD Link"
175
  msgstr "Удаляет RSD ссылку"
176
 
177
- #: admin/includes/options.php:126 admin/pages/performance.php:176
178
  msgid "Remove wlwmanifest Link"
179
  msgstr "Удалить wlwmanifest Link"
180
 
181
- #: admin/includes/options.php:131 admin/pages/performance.php:186
182
  msgid "Remove Shortlink"
183
  msgstr "Удалить короткие ссылки"
184
 
185
- #: admin/includes/options.php:136 admin/pages/performance.php:196
186
  msgid "Remove links to previous, next post"
187
  msgstr "Удалить ссылки следующая, предыдущая запись"
188
 
189
- #: admin/includes/options.php:141 admin/pages/performance.php:206
190
  msgid "Remove .recentcomments styles"
191
  msgstr "Удалить стили .recentcomments"
192
 
193
- #: admin/includes/options.php:147 admin/pages/seo.php:76
194
  msgid "Automatically set the alt attribute"
195
  msgstr "Автоматически устанавливать атрибут alt"
196
 
197
- #: admin/includes/options.php:152 admin/pages/seo.php:115
198
  msgid "Automatically insert the Last Modified header"
199
  msgstr "Автоматически вставлять заголовок Last Modified"
200
 
201
- #: admin/includes/options.php:157 admin/pages/seo.php:138
202
  msgid "Return an If-Modified-Since responce"
203
  msgstr "Возвращать заголовок If-Modified-Since"
204
 
205
- #: admin/includes/options.php:162 admin/pages/seo.php:152
206
  msgid "Remove duplicate names in breadcrumbs WP SEO by Yoast"
207
  msgstr "Удалить дубли имен в хлебных крошках WP SEO Yoast"
208
 
209
- #: admin/includes/options.php:167 admin/pages/seo.php:162
210
  #, php-format
211
  msgid "Remove the tag %s from XML site map"
212
  msgstr "Удаляет тег %s из XML карты сайта плагин Yoast SEO."
213
 
214
- #: admin/includes/options.php:174 admin/pages/seo.php:180
215
  msgid "Disable JSON-LD sitelinks searchbox"
216
  msgstr "Отключить ссылки JSON-LD"
217
 
218
- #: admin/includes/options.php:179 admin/pages/seo.php:190
219
  msgid "Disable Yoast Structured Data"
220
  msgstr "Отключить структурирование данных"
221
 
222
- #: admin/includes/options.php:184 admin/pages/seo.php:202
223
  #, php-format
224
  msgid "Remove comment from %s section"
225
  msgstr "Удалить комментарии из секции %s"
226
 
227
- #: admin/includes/options.php:189 admin/pages/seo-double-pages.php:93
228
  msgid "Remove archives date"
229
  msgstr "Удалить архивы дат"
230
 
231
- #: admin/includes/options.php:194 admin/pages/seo-double-pages.php:103
232
  msgid "Remove author archives "
233
- msgstr "Удалить архивы автора"
234
 
235
- #: admin/includes/options.php:199 admin/pages/seo-double-pages.php:113
236
  msgid "Remove archives tag"
237
  msgstr "Удалить метки архивов"
238
 
239
- #: admin/includes/options.php:204 admin/pages/seo-double-pages.php:123
240
  msgid "Remove attachment pages"
241
  msgstr "Удалить страницы вложений"
242
 
243
- #: admin/includes/options.php:209 admin/pages/seo-double-pages.php:133
244
  msgid "Remove post pagination"
245
  msgstr "Удалить постраничную навигацию записей"
246
 
247
- #: admin/includes/options.php:214 admin/pages/seo-double-pages.php:143
248
  msgid "Remove ?replytocom"
249
  msgstr "Удалить ?replytocom"
250
 
251
- #: admin/includes/options.php:219 admin/pages/defence-privacy-code.php:74
252
  msgid "Remove meta generator"
253
  msgstr "Удалить meta generator"
254
 
255
- #: admin/includes/options.php:224 admin/pages/defence.php:60
256
  msgid "Hide author login"
257
  msgstr "Убрать возможность узнать логин автора"
258
 
259
- #: admin/includes/options.php:229 admin/pages/defence.php:70
260
  msgid "Hide errors when logging into the site"
261
  msgstr "Спрятать ошибки при входе на сайт"
262
 
263
- #: admin/includes/options.php:234 admin/includes/options.php:351
264
- #: admin/pages/performance.php:248
265
  msgid "Remove Version from Stylesheet"
266
  msgstr "Удалить версию у файлов стилей"
267
 
268
- #: admin/includes/options.php:239 admin/includes/options.php:356
269
- #: admin/pages/performance.php:259
270
  msgid "Remove Version from Script"
271
  msgstr "Удаляет версию у javascript файлов"
272
 
273
- #: admin/includes/options.php:244 admin/pages/widgets.php:59
274
  msgid "Remove the \"Pages\" widget"
275
- msgstr "Удалите виджет «Страницы»"
276
 
277
- #: admin/includes/options.php:249 admin/pages/widgets.php:68
278
  msgid "Remove calendar widget"
279
  msgstr "Удалить виджет календаря"
280
 
281
- #: admin/includes/options.php:254 admin/pages/widgets.php:77
282
  msgid "Remove the \"Cloud of tags\" widget"
283
- msgstr "Удалите виджет «Облако тегов»"
284
 
285
- #: admin/includes/options.php:259 admin/pages/widgets.php:86
286
  msgid "Remove the \"Archives\" widget"
287
- msgstr "Удалите виджет «Архивы»"
288
 
289
- #: admin/includes/options.php:264 admin/pages/widgets.php:95
290
  msgid "Remove the \"Links\" widget"
291
- msgstr "Удалите виджет «Ссылки»"
292
 
293
- #: admin/includes/options.php:269 admin/pages/widgets.php:104
294
  msgid "Remove the \"Meta\" widget"
295
- msgstr "Удалите виджет «Мета»"
296
 
297
- #: admin/includes/options.php:274 admin/pages/widgets.php:113
298
  msgid "Remove the \"Search\" widget"
299
- msgstr "Удалите виджет «Поиск»"
300
 
301
- #: admin/includes/options.php:279 admin/includes/options.php:299
302
  #: admin/pages/widgets.php:122
303
  msgid "Remove the \"Text\" widget"
304
- msgstr "Удалите виджет «Текст»"
305
 
306
- #: admin/includes/options.php:284 admin/pages/widgets.php:131
307
  msgid "Remove the \"Categories\" widget"
308
- msgstr "Удалите виджет «Категории»"
309
 
310
- #: admin/includes/options.php:289 admin/pages/widgets.php:140
311
  msgid "Remove the \"Recent Posts\" widget"
312
- msgstr "Удалите виджет «Последние записи»"
313
 
314
- #: admin/includes/options.php:294 admin/pages/widgets.php:149
315
  msgid "Remove the \"Recent Comments\" widget"
316
- msgstr "Удалите виджет «Свежие комментарии»"
317
 
318
- #: admin/includes/options.php:304 admin/pages/widgets.php:158
319
  msgid "Remove the \"RSS\" widget"
320
- msgstr "Удалить виджет «RSS»"
321
 
322
- #: admin/includes/options.php:309 admin/pages/widgets.php:167
323
  msgid "Remove the \"Menu\" widget"
324
- msgstr "Удалите виджет «Меню»"
325
 
326
- #: admin/includes/options.php:314 admin/pages/widgets.php:176
327
  msgid "Remove the \"Twenty Eleven Ephemera\" widget"
328
  msgstr "Удалите виджет \"Twenty Eleven Ephemera\""
329
 
330
- #: admin/includes/options.php:317 admin/includes/options.php:386
331
  #: admin/pages/advanced.php:207
332
  msgid "Disable revision"
333
  msgstr "Отключить ревизии"
334
 
335
- #: admin/includes/options.php:318 admin/includes/options.php:391
336
  #: admin/pages/advanced.php:220
337
  msgid "Limit Post Revisions"
338
  msgstr "Установить лимит ревизий"
339
 
340
- #: admin/includes/options.php:319 admin/pages/seo.php:129
341
  msgid "Exclude pages:"
342
  msgstr "Исключить страницы:"
343
 
344
- #: admin/includes/options.php:322 admin/pages/seo.php:86
345
  msgid "Create right robots.txt"
346
  msgstr "Создайте правильный robots.txt"
347
 
348
- #: admin/includes/options.php:327 admin/pages/seo.php:101
349
  msgid "You can edit the robots.txt file in the box below:"
350
  msgstr "Вы можете отредактировать файл robots.txt в поле ниже:"
351
 
352
- #: admin/includes/options.php:330
353
  msgid "Quick mode"
354
  msgstr "Быстрый старт"
355
 
356
- #: admin/includes/options.php:333 admin/pages/performance.php:126
357
  msgid "Remove jQuery Migrate"
358
  msgstr "Удалить jQuery Migrate"
359
 
360
- #: admin/includes/options.php:336 admin/pages/performance.php:136
361
  msgid "Disable Embeds"
362
  msgstr "Отключить Embeds"
363
 
364
- #: admin/includes/options.php:337 admin/pages/performance.php:76
365
  msgid "Disable RSS feeds"
366
  msgstr "Отключить RSS каналы"
367
 
368
- #: admin/includes/options.php:340
369
  msgid "Removes links to wordpress.org site from the admin bar"
370
  msgstr "Удаляет ссылки на wordpress.org сайт из панели администратора"
371
 
372
- #: admin/includes/options.php:343 admin/pages/performance-html-minify.php:72
373
- msgid "HTML minify"
374
- msgstr "Html сжатие"
375
-
376
- #: admin/includes/options.php:346
377
- msgid "Redirect Http to Https"
378
- msgstr "Перенаправление Http на Https"
379
-
380
- #: admin/includes/options.php:361
381
  msgid "Eclude stylesheet/script file names"
382
  msgstr "Исключает файлы стилей/сприптов"
383
 
384
- #: admin/includes/options.php:366
385
  msgid "Enable Sanitization of WordPress"
386
  msgstr "Включить Wordpress Sanitization"
387
 
388
- #: admin/includes/options.php:371 admin/pages/advanced.php:158
389
  msgid "Disable admin top bar"
390
  msgstr "Скрыть верхнюю панель администратора"
391
 
392
- #: admin/includes/options.php:376 admin/pages/advanced.php:176
393
  msgid "Remove admin bar WP logo"
394
  msgstr "Удалить логотип Wordpress из админбара"
395
 
396
- #: admin/includes/options.php:381 admin/pages/advanced.php:186
397
  msgid "Replace \"Howdy\" text with \"Welcome\""
398
  msgstr "Заменить текст \"Привет\", на \"Добро пожаловать\""
399
 
400
- #: admin/includes/options.php:396 admin/pages/advanced.php:244
401
  msgid "Disable autosave"
402
  msgstr "Отключить автосохранения"
403
 
404
- #: admin/includes/options.php:401 admin/pages/advanced.php:254
405
  msgid "Disable Texturization - Smart Quotes"
406
  msgstr "Отключить \"Умные кавычки\""
407
 
408
- #: admin/includes/options.php:406 admin/pages/advanced.php:264
409
  msgid "Disable capitalization in Wordpress branding"
410
  msgstr "Отключить верблюжий шрифт в WordPress брендинге"
411
 
412
- #: admin/includes/options.php:411 admin/pages/advanced.php:274
413
  msgid "Disable auto inserted paragraphs (i.e. p tags)"
414
  msgstr "Отключить автоматические параграфы (т.е p теги)"
415
 
416
- #: admin/includes/options.php:416 admin/pages/advanced.php:89
417
  msgid "Disable Heartbeat"
418
  msgstr "Отключить пульсацию Wordpress"
419
 
420
- #: admin/includes/options.php:421 admin/pages/advanced.php:118
421
  msgid "Heartbeat frequency"
422
  msgstr "Интервал пульсации Wordpress"
423
 
424
- #: admin/includes/options.php:426 admin/pages/defence-privacy-code.php:64
425
  msgid "Remove html comments"
426
  msgstr "Удалить html комментарии"
427
 
 
 
 
 
428
  #: admin/pages/advanced.php:36
429
  msgid "Advanced"
430
  msgstr "Дополнительно"
@@ -631,32 +750,88 @@ msgstr "Отключить автоматически вставленные а
631
  msgid "Components"
632
  msgstr "Компоненты"
633
 
634
- #: admin/pages/components.php:71
 
 
 
 
 
 
 
 
 
 
 
 
 
 
635
  msgid "Hide login page"
636
- msgstr "Скрыть страницу логина"
637
 
638
- #: admin/pages/components.php:74
639
  msgid ""
640
  "Hide Login Page is a very light plugin that lets you easily and safely "
641
  "change the url of the login form page to anything you want."
642
  msgstr ""
643
- "Простой модуль, который позволяет вам легко и безопасно изменять URL-адрес "
644
- "страницы формы входа на свой собственный."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
645
 
646
- #: admin/pages/components.php:78
 
 
 
 
 
 
 
 
 
 
 
 
 
 
647
  msgid "Updates manager"
648
  msgstr "Менеджер обновлений"
649
 
650
- #: admin/pages/components.php:81
651
  msgid "Disable updates enable auto updates for themes, plugins and WordPress."
652
  msgstr ""
653
  "Отключает обновления, включает автообновления плагинов, тем, WordPress."
654
 
655
- #: admin/pages/components.php:85
656
  msgid "Comments tools"
657
  msgstr "Инструменты комментариев"
658
 
659
- #: admin/pages/components.php:88
660
  msgid ""
661
  "Bulk disable and remove comments, disable “Website” field, hides external "
662
  "links, disable XML-RPC."
@@ -664,31 +839,31 @@ msgstr ""
664
  "Позволяет массово отключать и удалять комментарии, отключает поле сайт, "
665
  "скрывает внешние ссылки, отключает XML-RPC."
666
 
667
- #: admin/pages/components.php:92
668
  msgid "Widgets tools"
669
  msgstr "Инструменты для виджетов"
670
 
671
- #: admin/pages/components.php:95
672
  msgid "Disable unused widgets such as tag cloud, links, calendar etc."
673
  msgstr ""
674
  "Позволяет отключить неиспользуемые виджеты, такие как облако тегов, ссылки, "
675
  "календарь и т.д."
676
 
677
- #: admin/pages/components.php:99
678
  msgid "Asset manager"
679
  msgstr "Менеджер скриптов"
680
 
681
- #: admin/pages/components.php:102
682
  msgid ""
683
  "Selectively disable unused scripts and styles on the pages of your website."
684
  msgstr ""
685
  "Выборочно отключает неиспользуемые скрипты и стили на страницах вашего сайта."
686
 
687
- #: admin/pages/components.php:106
688
  msgid "Disable admin notices"
689
  msgstr "Отключить уведомления"
690
 
691
- #: admin/pages/components.php:109
692
  msgid ""
693
  "Disables admin notices bulk or individually. Collects notices into the admin "
694
  "bar."
@@ -696,20 +871,20 @@ msgstr ""
696
  "Отключает уведомления администратора индивидуально или все разом. Собирает "
697
  "уведомления в админ баре."
698
 
699
- #: admin/pages/components.php:113
700
  msgid "Admin bar manager"
701
  msgstr "Управление админбаром"
702
 
703
- #: admin/pages/components.php:116
704
  msgid "Disables admin bar. Allows to change and remove admin bar elements."
705
  msgstr ""
706
  "Отключает админ бар. Позволяет изменять и удалять элементы из админбара."
707
 
708
- #: admin/pages/components.php:120
709
  msgid "Posts tools"
710
  msgstr "Инструменты для записей"
711
 
712
- #: admin/pages/components.php:123
713
  msgid ""
714
  "Disable revisions, disable posts autosave, disable smart quotes and disable "
715
  "auto paragraphs."
@@ -717,19 +892,19 @@ msgstr ""
717
  "Отключение ревизий, отключение автосохранений записей, отключение «умных "
718
  "кавычек», отключение автоматических параграфов."
719
 
720
- #: admin/pages/components.php:127
721
  msgid "Yoast SEO optimization"
722
  msgstr "Оптимизация Yoast Seo"
723
 
724
- #: admin/pages/components.php:130
725
  msgid "Set of optimization functions for the popular Yoast SEO plugin."
726
  msgstr "Набор функций для оптимизации популярного плагина Yoast Seo."
727
 
728
- #: admin/pages/components.php:136
729
  msgid "Transliteration of Cyrillic alphabet"
730
  msgstr "Транслитерация кириллицы"
731
 
732
- #: admin/pages/components.php:139
733
  msgid ""
734
  "Converts Cyrillic permalinks of post, pages, taxonomies and media files to "
735
  "the Latin alphabet. Supports Russian, Ukrainian, Georgian, Bulgarian "
@@ -738,25 +913,13 @@ msgstr ""
738
  "Конвертирует кириллические постоянные ссылки записей, страниц, таксономий и "
739
  "медиафайлов в латиницу. Поддерживает Русский, Украинский, Грузинский, "
740
  "Болгарский языки. Пример: http://site.dev/последние-новости -> http://site."
741
- "dev/poslednie-novosti"
742
-
743
- #: admin/pages/components.php:145
744
- msgid "Privacy Wordpress"
745
- msgstr "Приватный Wordpress"
746
 
747
- #: admin/pages/components.php:148
748
- msgid ""
749
- "This component is to protect your site, Wordpress runs private mode. Nobody "
750
- "will know that you will use Wordpress!"
751
- msgstr ""
752
- "Этот компонент предназначен для защиты вашего сайта, Wordpress работает в "
753
- "приватном режиме. Никто не будет знать, что вы будете использовать Wordpress!"
754
-
755
- #: admin/pages/components.php:152
756
  msgid "<strong>Plugin Components</strong>."
757
  msgstr "<strong>Компоненты плагина</strong>."
758
 
759
- #: admin/pages/components.php:154
760
  msgid ""
761
  "These are components of the plugin bundle. When you activate the plugin, all "
762
  "the components turned on by default. If you don’t need some function, you "
@@ -766,65 +929,9 @@ msgstr ""
766
  "все компоненты включены по умолчанию. Если какая-то функция вам не нужна, вы "
767
  "можете легко отключить её на этой странице."
768
 
769
- #: admin/pages/components.php:186
770
- msgid "Activate"
771
- msgstr "Включить"
772
-
773
- #: admin/pages/components.php:188
774
- msgid "Deactivate"
775
- msgstr "Отключить"
776
-
777
- #: admin/pages/defence-privacy-code.php:38
778
- msgid "Code privacy"
779
- msgstr "Приватный код"
780
-
781
- #: admin/pages/defence-privacy-code.php:57
782
- msgid "<strong>Hide WordPress plugins versions</strong>."
783
- msgstr "<strong>Скрыть версии Wordpress и плагинов</strong>."
784
-
785
- #: admin/pages/defence-privacy-code.php:57
786
- msgid ""
787
- "WordPress itself and many plugins shows their version at the public areas of "
788
- "your site. An attacker received this information may be aware of the "
789
- "vulnerabilities found in the version of the WordPress core or plugins."
790
- msgstr ""
791
- "Сам WordPress и многие плагины, публикуют свою версию в публичных областях "
792
- "вашего сайта. Получив эту информацию, злоумышленник может знать об "
793
- "уязвимостях обнаруженных в полученной им версии ядра WordPress или плагинов."
794
-
795
- #: admin/pages/defence-privacy-code.php:66
796
- msgid ""
797
- "This function will remove all html comments in the source code, except for "
798
- "special and hidden comments. This is necessary to hide the version of "
799
- "installed plugins."
800
- msgstr ""
801
- "Эта функция удалит все html-комментарии в исходном коде, за исключением "
802
- "специальных и скрытых комментариев. Это необходимо, чтобы скрыть версию "
803
- "установленных плагинов."
804
-
805
- #: admin/pages/defence-privacy-code.php:66
806
- msgid "Remove html comments in source code."
807
- msgstr "Удалить Html комментарии в исходном коде страницы."
808
-
809
- #: admin/pages/defence-privacy-code.php:74 admin/pages/performance.php:248
810
- #: admin/pages/performance.php:259 admin/pages/seo.php:76
811
- #: admin/pages/seo.php:115 admin/pages/seo.php:138 admin/pages/seo.php:152
812
- #: admin/pages/seo.php:162 admin/pages/seo.php:202
813
- msgid "Recommended"
814
- msgstr "Рекомендовано"
815
-
816
- #: admin/pages/defence-privacy-code.php:76
817
- msgid ""
818
- "Allows attacker to learn the version of WP installed on the site. This meta "
819
- "tag has no useful function."
820
- msgstr ""
821
- "Позволяет злоумышленнику узнать версию Wordpress, установленую на вашем "
822
- "сайте. Этот мета-тег не несет никакой пользы."
823
-
824
- #: admin/pages/defence-privacy-code.php:76
825
- #, php-format
826
- msgid "Removes the meta tag from the %s section"
827
- msgstr "Удаляет мета-тег из раздел %s"
828
 
829
  #: admin/pages/defence.php:34
830
  msgid "Defence"
@@ -887,6 +994,254 @@ msgstr ""
887
  msgid "Removes the server responses a reference to the xmlrpc file."
888
  msgstr "Удаляет ссылку на xmlrpc-файл и ответ сервера."
889
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
890
  #: admin/pages/performance-google.php:46
891
  msgid "Google services"
892
  msgstr "Google сервисы"
@@ -966,175 +1321,6 @@ msgstr ""
966
  msgid "Posts or Pages IDs separated by a ,"
967
  msgstr "ID записей или страниц, разделенные запятой ,"
968
 
969
- #: admin/pages/performance-google.php:146
970
- msgid "<strong>Google Analytics cache</strong>."
971
- msgstr "<strong>Кеширование Google аналитики</strong>."
972
-
973
- #: admin/pages/performance-google.php:146
974
- msgid ""
975
- "To improve Google Page Speed indicators Analytics caching is needed. "
976
- "However, it can also slightly increase your website loading speed, because "
977
- "Analytics js files will load locally. The second case that you might need "
978
- "these settings is the usual Google Analytics connection to your website. You "
979
- "do not need to do this with other plugins or insert the tracking code into "
980
- "your theme."
981
- msgstr ""
982
- "Кеширование Analytics нужно для улучшения показателей Google Page Speed, но "
983
- "это также может незначительно повысить скорость загрузки вашего сайта, "
984
- "потому что js файлы Analytics будут подгружаться локально. Второй случай, "
985
- "когда вам могут понадобиться эти настройки — обычное подключение Google "
986
- "Analytics к сайту. Вам не нужно делать это с помощью других плагинов или "
987
- "просто вставлять код отслеживания в вашу тему."
988
-
989
- #: admin/pages/performance-google.php:155
990
- msgid ""
991
- "If you enable this option, the plugin will begin to save a local copy of "
992
- "Google Analytics to speed up the loading of your website and improve Google "
993
- "Page Speed."
994
- msgstr ""
995
- "Если включить эту опцию, плагин начнет сохранять локальную копию Google "
996
- "Analytics, чтобы ускорить загрузку вашего сайта и улучшить показатели Google "
997
- "Page speed. ВНИМАНИЕ! Перед использованием этой опции, удалите ранее "
998
- "установленный код Google Analytics в вашей теме или плагины, связанные с "
999
- "этой функцией!"
1000
-
1001
- #: admin/pages/performance-google.php:155
1002
- msgid ""
1003
- "ATTENTION! Before using this option, remove the previously installed Google "
1004
- "Analytics code inside your theme or plugins associated with this feature!"
1005
- msgstr ""
1006
- "ВНИМАНИЕ! Перед использованием этой опции, удалите ранее установленный код "
1007
- "Google Analytics в вашей теме или плагины, связанные с этой функцией!"
1008
-
1009
- #: admin/pages/performance-google.php:176
1010
- msgid "Set the Google Analytics tracking code."
1011
- msgstr "Установите код отслеживания Google Analytics."
1012
-
1013
- #: admin/pages/performance-google.php:187
1014
- msgid "Save GA in"
1015
- msgstr "Использовать код аналитики в"
1016
-
1017
- #: admin/pages/performance-google.php:188
1018
- msgid "Select location for the Google Analytics code."
1019
- msgstr "Выберите местоположение для кода Google Analytics."
1020
-
1021
- #: admin/pages/performance-google.php:198
1022
- msgid ""
1023
- "Essentially, you set up an event which is triggered after a user spends a "
1024
- "certain amount of time on the landing page, telling Google Analytics not to "
1025
- "count these users as bounces. A user may come to your website, find all of "
1026
- "the information they need (a phone number, for example) and then leave the "
1027
- "site without visiting another page. Without adjusted bounce rate, such a "
1028
- "user would be considered a bounce, even though they had a successful "
1029
- "experience. By defining a time limit after which you can consider a user to "
1030
- "be \"engaged,\" that user would no longer count as a bounce, and you'd get a "
1031
- "more accurate idea of whether they found what they were looking for."
1032
- msgstr ""
1033
- "По сути, вы настраиваете событие, которое запускается после того, как "
1034
- "пользователь тратит определенное количество времени на целевую страницу, "
1035
- "сообщая Google Analytics не считать этих пользователей как отказы. "
1036
- "Пользователь может зайти на ваш сайт, найти всю необходимую информацию "
1037
- "(например, номер телефона), а затем покинуть сайт, не посещая другую "
1038
- "страницу. Без скорректированного коэффициента отказов такой пользователь "
1039
- "будет считаться отказом, хотя у них был успешный опыт. Определив лимит "
1040
- "времени, после которого вы можете считать пользователя «включенным», этот "
1041
- "пользователь больше не будет считаться отказом, и вы получите более точное "
1042
- "представление о том, нашли ли они то, что искали."
1043
-
1044
- #: admin/pages/performance-google.php:207
1045
- msgid ""
1046
- "By default, Google Analytics code is loaded before other scripts and "
1047
- "javasscript code, but if you set the value to 100, the GA code will be "
1048
- "loaded after all other scripts. By changing the priority, you can set code "
1049
- "position on the page."
1050
- msgstr ""
1051
- "По умолчанию код Google Analytics загружается раньше остальных скриптов и "
1052
- "javasscript кода, но если вы установите к примеру значение 100, то код GA "
1053
- "будет загружен после всех остальных скриптов. Изменяя приоритет, вы можете "
1054
- "задавать положение кода на странице."
1055
-
1056
- #: admin/pages/performance-google.php:215
1057
- #, php-format
1058
- msgid "Disable all <a href=\"%s\">display features functionality?</a>"
1059
- msgstr "Отключить <a href=\"%s\">все функции для контекстно-медийной сети?</a>"
1060
-
1061
- #: admin/pages/performance-google.php:224
1062
- #, php-format
1063
- msgid ""
1064
- "Use <a href=\"%s\">Anonymize IP?</a> (Required by law for some countries)"
1065
- msgstr ""
1066
- "Использовать <a href=\"%s\">анонимный IP-адрес?</a> (Требуется по закону для "
1067
- "некоторых стран)"
1068
-
1069
- #: admin/pages/performance-google.php:242
1070
- msgid ""
1071
- "Clearfy creates a cron job to daily update Google Analytics cache scripts. "
1072
- "After enabling this option, the plugin will not update Google Analytics "
1073
- "cache file. Do not use this option if you do not understand why you need it!"
1074
- msgstr ""
1075
- "Плагин создает cron задание, чтобы ежедневно обновлять кеш скриптов Google "
1076
- "Analytics. После включения этой опции, плагин не будет обновлять кэш файл "
1077
- "Google Analytics. Не используйте эту опцию, если вы не понимаете, для чего "
1078
- "вам это нужно!"
1079
-
1080
- #: admin/pages/performance-html-minify.php:46
1081
- msgid "Html Minify"
1082
- msgstr "Html сжатие"
1083
-
1084
- #: admin/pages/performance-html-minify.php:65
1085
- msgid ""
1086
- "<strong>Make your website’s markup look professional by using Minify HTML "
1087
- "options</strong>."
1088
- msgstr ""
1089
- "<strong>Уменьшите вес ваших страниц, за счет удаления лишнего мусора, "
1090
- "пробелов и комментариев.</strong>."
1091
-
1092
- #: admin/pages/performance-html-minify.php:65
1093
- msgid ""
1094
- "Ever look at the HTML markup of your website and notice how sloppy and "
1095
- "amateurish it looks? The Minify HTML options cleans up sloppy looking markup "
1096
- "and minifies, which also speeds up download time."
1097
- msgstr ""
1098
- "Вы когда-нибудь видели HTML разметку на своем веб-сайте, замечали насколько "
1099
- "она неаккуратна и раздута? Настройки HTML сжатия позволят грамотно "
1100
- "установить правила формирования html разметки, а также регулировать вес "
1101
- "ваших страниц."
1102
-
1103
- #: admin/pages/performance-html-minify.php:74
1104
- msgid ""
1105
- "Reduces the weight of the page by removing line breaks, tabs, spaces, etc."
1106
- msgstr ""
1107
- "Уменьшает вес страницы путем удаления разрывов строк, вкладок, пробелов и т. "
1108
- "Д."
1109
-
1110
- #: admin/pages/performance-html-minify.php:74
1111
- msgid "Minify pages."
1112
- msgstr "Минимизировать страницы."
1113
-
1114
- #: admin/pages/performance-html-minify.php:92
1115
- msgid "Minify inline JavaScript"
1116
- msgstr "Сжимать строчный JavaScript"
1117
-
1118
- #: admin/pages/performance-html-minify.php:100
1119
- msgid "Remove HTML, JavaScript and CSS comments"
1120
- msgstr "Удалять HTML, JavaScript and CSS комментарии"
1121
-
1122
- #: admin/pages/performance-html-minify.php:108
1123
- msgid "Remove XHTML closing tags from HTML5 void elements"
1124
- msgstr "Удалить XHTML закрывающие теги из HTML5 для пустых элементов"
1125
-
1126
- #: admin/pages/performance-html-minify.php:116
1127
- msgid "Remove relative domain from internal URLs"
1128
- msgstr "Удалить относительные домены из внутренних Urls"
1129
-
1130
- #: admin/pages/performance-html-minify.php:124
1131
- msgid "Remove schemes (HTTP: and HTTPS:) from all URLs"
1132
- msgstr "Удалить протоколы (HTTP: и HTTPS:) для всех URLs"
1133
-
1134
- #: admin/pages/performance-html-minify.php:132
1135
- msgid "Support multi-byte UTF-8 encoding (if you see odd characters)"
1136
- msgstr "Поддержка многобайтовой кодировки UTF-8 (для кириллицы)"
1137
-
1138
  #: admin/pages/performance.php:41
1139
  msgid "Performance"
1140
  msgstr "Производительность"
@@ -1224,7 +1410,7 @@ msgstr ""
1224
 
1225
  #: admin/pages/performance.php:118
1226
  msgid "Removes WordPress Emojis JavaScript file (wp-emoji-release.min.js)."
1227
- msgstr "Удаляет код Emojis из исходного кода страницы"
1228
 
1229
  #: admin/pages/performance.php:128
1230
  msgid ""
@@ -1417,46 +1603,9 @@ msgstr ""
1417
  "конфиденциальности, или если вы просто хотите предотвратить потенциально "
1418
  "глупые или неловкие аватары."
1419
 
1420
- #: admin/pages/performance.php:250 admin/pages/performance.php:261
1421
- msgid ""
1422
- "To make it more difficult for others to hack your website you can remove the "
1423
- "WordPress version number from your site, your css and js. Without that "
1424
- "number it's not possible to see if you run not the current version to "
1425
- "exploit bugs from the older versions. <br><br>\n"
1426
- "\t\t\t\t\tAdditionally it can improve the loading speed of your site, "
1427
- "because without query strings in the URL the css and js files can be cached."
1428
- msgstr ""
1429
- "Активировав эту функцию вы усложните работу злоумышленника. <br><br>Кроме "
1430
- "того, это может улучшить скорость загрузки вашего сайта, потому что без "
1431
- "строки запроса в URL-адрес css и js файлов могут быть кэшированы."
1432
-
1433
- #: admin/pages/performance.php:251
1434
- msgid ""
1435
- "Removes the wordpress version number from stylesheets (not logged in user "
1436
- "only)."
1437
- msgstr "Удаляет номер версии из файлов стилей стилей (только для фронтенда)."
1438
-
1439
- #: admin/pages/performance.php:262
1440
- msgid ""
1441
- "Removes wordpress version number from scripts (not logged in user only)."
1442
- msgstr "Удаляет номер версии из javascript файлов (только для фронтенда)."
1443
-
1444
- #: admin/pages/performance.php:270
1445
- msgid "Exclude stylesheet/script file names"
1446
- msgstr "Исключает файлы стилей/сприптов"
1447
-
1448
- #: admin/pages/performance.php:272
1449
- msgid ""
1450
- "Enter Stylesheet/Script file names to exclude from version removal (each "
1451
- "exclude file starts with a new line)"
1452
- msgstr ""
1453
- "Введите абсолютный путь к файлу, чтобы исключить его из списка файлов у "
1454
- "которых, будет удалена версия (каждое исключение, должно быть с новой "
1455
- "строки)."
1456
-
1457
- #: admin/pages/performance.php:272
1458
- msgid "Example"
1459
- msgstr "Например"
1460
 
1461
  #: admin/pages/quick-start.php:62
1462
  msgid "Clearfy menu"
@@ -1466,7 +1615,7 @@ msgstr "Clearfy меню"
1466
  msgid "Quick start"
1467
  msgstr "Быстрый старт"
1468
 
1469
- #: admin/pages/quick-start.php:105
1470
  msgid ""
1471
  "On this page you can quickly configure the plug-in without going into "
1472
  "details."
@@ -1474,10 +1623,6 @@ msgstr ""
1474
  "На этой странице вы можете быстро настроить плагин, не вдаваясь в "
1475
  "подробности."
1476
 
1477
- #: admin/pages/quick-start.php:184
1478
- msgid "Set the recommened for me"
1479
- msgstr "Установить рекомендуемые для меня"
1480
-
1481
  #: admin/pages/quick-start.php:187
1482
  msgid "One click code clearing"
1483
  msgstr "Очистка кода в один клик"
@@ -1571,19 +1716,19 @@ msgstr ""
1571
  "Во время установки произошла неизвестная ошибка, повторите попытку или "
1572
  "обратитесь в службу поддержки плагинов."
1573
 
1574
- #: admin/pages/quick-start.php:288
1575
  msgid "Import/Export settings"
1576
  msgstr "Импорт/Экспорт настроек"
1577
 
1578
- #: admin/pages/quick-start.php:291
1579
  msgid "Import options"
1580
  msgstr "Импортировать настройки"
1581
 
1582
- #: admin/pages/quick-start.php:297
1583
  msgid "Support"
1584
  msgstr "Поддержка"
1585
 
1586
- #: admin/pages/quick-start.php:299
1587
  msgid ""
1588
  "If you faced with any issues, please follow the steps below to get quickly "
1589
  "quality support:"
@@ -1591,7 +1736,7 @@ msgstr ""
1591
  "Если вы столкнулись с какими-либо проблемами, выполните следующие действия, "
1592
  "чтобы быстро получить качественную поддержку:"
1593
 
1594
- #: admin/pages/quick-start.php:302
1595
  msgid ""
1596
  "Generate a debug report which will contains inforamtion about your "
1597
  "configuratin and installed plugins"
@@ -1599,11 +1744,11 @@ msgstr ""
1599
  "Создайте отчет об ошибках, который будет содержать информацию о вашей "
1600
  "конфигурации и установленных плагинах."
1601
 
1602
- #: admin/pages/quick-start.php:305
1603
  msgid "Generate Debug Report"
1604
  msgstr "Сгенерировать отчет об ошибках"
1605
 
1606
- #: admin/pages/quick-start.php:309
1607
  msgid ""
1608
  "Send a message to <b>wordpress.webraftic@gmail.com</b> include the debug "
1609
  "report into the message body."
@@ -1611,7 +1756,7 @@ msgstr ""
1611
  "Отправьте ваше сообщение на <b>wordpress.webraftic@gmail.com</b>, к "
1612
  "сообщению прикрепите отчет об ошибках"
1613
 
1614
- #: admin/pages/quick-start.php:312
1615
  msgid "We guarantee to respond you within 7 business day."
1616
  msgstr "Мы гарантируем ответ на ваш вопрос в течении 7 дней."
1617
 
@@ -1780,7 +1925,11 @@ msgstr ""
1780
  "WordPress не знает, как отдать заголовок Last Modified. Вы можете сделать "
1781
  "это с помощью параметров ниже."
1782
 
1783
- #: admin/pages/seo.php:131
 
 
 
 
1784
  #, php-format
1785
  msgid ""
1786
  "You can specify a page mask, for example: %s or %s. All pages that contain "
@@ -1790,11 +1939,11 @@ msgstr ""
1790
  "содержат эти строки, будут исключены. Каждое исключение должно начинаться с "
1791
  "новой строки."
1792
 
1793
- #: admin/pages/seo.php:145
1794
  msgid "For the Yoast SEO plugin"
1795
  msgstr "Для плагина Yoast SEO"
1796
 
1797
- #: admin/pages/seo.php:145
1798
  msgid ""
1799
  "These settings will help you eliminate some problems associated with the "
1800
  "popular Yoast SEO plugin"
@@ -1802,7 +1951,7 @@ msgstr ""
1802
  "Эти параметры помогут вам устранить некоторые проблемы, связанные с "
1803
  "популярной Yoast SEO plugin"
1804
 
1805
- #: admin/pages/seo.php:154
1806
  msgid ""
1807
  "The last element in the breadcrumbs in the Yoast SEO plugin duplicates the "
1808
  "title of the article. Some SEO-specialists consider this duplication to be "
@@ -1811,13 +1960,13 @@ msgstr ""
1811
  "Последний элемент в хлебных крошках Yoast SEO дублирует название статьи. "
1812
  "Некоторые SEO-специалисты считают это дублирование излишним."
1813
 
1814
- #: admin/pages/seo.php:154
1815
  msgid ""
1816
  "Removes duplication of the name in the breadcrumbs of the WP SEO plugin from "
1817
  "Yoast."
1818
  msgstr "Удаляет последний элемент в хлебных крошках Yoast SEO."
1819
 
1820
- #: admin/pages/seo.php:164
1821
  msgid ""
1822
  "Yandex.Webmaster swears on a standard XML card from the plugin Yoast, tk. it "
1823
  "has a specific tag"
@@ -1825,12 +1974,12 @@ msgstr ""
1825
  "Яндекс вебмастер ругается на стандартной карты XML из плагина Yoast SEO, из-"
1826
  "за определенного тега "
1827
 
1828
- #: admin/pages/seo.php:164
1829
  #, php-format
1830
  msgid "Remove the tag %s from XML site map of the plugin Yoast SEO."
1831
  msgstr "Удаляет тег %s из XML карта сайта плагин Yoast SEO."
1832
 
1833
- #: admin/pages/seo.php:164
1834
  msgid ""
1835
  "Attention! After activation, turn off the site map and enable it back to "
1836
  "regenerate it."
@@ -1838,13 +1987,13 @@ msgstr ""
1838
  "Внимание! После активации, выключите карту сайта и включите ее обратно, "
1839
  "чтобы обновить ее."
1840
 
1841
- #: admin/pages/seo.php:164
1842
  msgid "In older versions of Yoast SEO may not work - update the plugin Yoast"
1843
  msgstr ""
1844
  "В более старых версиях Yoast SEO не может работать - обновите плагин Yoast "
1845
  "SEO"
1846
 
1847
- #: admin/pages/seo.php:182
1848
  msgid ""
1849
  "If you’re not familiar with Search Action it’s the mark-up that helps search "
1850
  "engines add a shiny Sitelinks Search Box below your search engine results. "
@@ -1859,12 +2008,12 @@ msgstr ""
1859
  "нужна. Особенно, если на сайте всего несколько страниц или есть собственный "
1860
  "поиск, который ищет только записи блога, но не страницы."
1861
 
1862
- #: admin/pages/seo.php:182
1863
  msgid ""
1864
  "Disable JSON-LD sitelinks searchbox using WordPress in plugin Yoast SEO."
1865
  msgstr "Отключает JSON-LD ссылки используемые Wordpress в плагине Yoast SEO."
1866
 
1867
- #: admin/pages/seo.php:192
1868
  msgid ""
1869
  "Prevents output of the script tag of type application/ld+json containing\n"
1870
  "schema.org data from the popular Yoast SEO and Yoast SEO Premium plugins.\n"
@@ -1874,16 +2023,16 @@ msgstr ""
1874
  "schema.org о сайте и его владельце. Эту ссылку создают популярные плагины "
1875
  "Yoast SEO и Yoast SEO Premium"
1876
 
1877
- #: admin/pages/seo.php:194
1878
  msgid "Disable Structured Data in plugin Yoast SEO."
1879
- msgstr "Отключает структурированные данные в плагине Yoast SEO"
1880
 
1881
- #: admin/pages/seo.php:204
1882
  #, php-format
1883
  msgid "The Yoast SEO plugin displays a comment of the form %s in %s section"
1884
  msgstr "Yoast SEO плагин отображает комментарий формы %s в секции %s"
1885
 
1886
- #: admin/pages/seo.php:204
1887
  #, php-format
1888
  msgid "Removes the Yoast SEO plugin comment of their section %s"
1889
  msgstr "Удаляет комментрии Yoast SEO из %s"
@@ -1912,7 +2061,7 @@ msgstr ""
1912
  "всего, то отключение неиспользуемого функционала — первый шаг к его "
1913
  "оптимизации и ускорению."
1914
 
1915
- #: clearfy.php:63
1916
  msgid "Clearfy"
1917
  msgstr "Clearfy"
1918
 
@@ -1924,26 +2073,291 @@ msgstr "Привет"
1924
  msgid "Welcome"
1925
  msgstr "Добро пожаловать"
1926
 
1927
- #: includes/classes/class.configurate-google-performance.php:398
1928
- msgid "Once Weekly"
1929
- msgstr "Один раз в неделю"
1930
-
1931
- #: includes/classes/class.configurate-google-performance.php:403
1932
- msgid "Twice Monthly"
1933
- msgstr "Дважды в месяц"
1934
-
1935
- #: includes/classes/class.configurate-google-performance.php:408
1936
- msgid "Once Monthly"
1937
- msgstr "Один раз в месяц"
1938
-
1939
  #: includes/classes/class.configurate-security.php:51
1940
  msgid "<strong>ERROR</strong>: Wrong login or password"
1941
  msgstr "<strong>Ошибка</strong>: Неправильный логин или пароль"
1942
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1943
  #: includes/classes/class.zip-archive.php:15
1944
  msgid "The ZipArchive class does not exist in this version of php."
1945
  msgstr "Класса ZipArchive не существует в этой версии php."
1946
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1947
  #~ msgid "Hide wp-admin"
1948
  #~ msgstr "Скрыть wp-admin"
1949
 
1
  msgid ""
2
  msgstr ""
3
  "Project-Id-Version: clearfy\n"
4
+ "POT-Creation-Date: 2018-08-15 01:21+0300\n"
5
+ "PO-Revision-Date: 2018-08-15 05:36+0300\n"
6
  "Last-Translator: alex.kovalevv@gmail.com <alex.kovalevv@gmail.com>\n"
7
  "Language-Team: Alex Kovalev <alex.kovalevv@gmail.com>\n"
8
  "Language: ru_RU\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
12
+ "X-Generator: Poedit 2.0.8\n"
13
  "X-Poedit-Basepath: ..\n"
14
  "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
15
  "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
21
  "X-Poedit-SearchPathExcluded-2: cache\n"
22
 
23
  #: admin/ajax/configurate.php:19 admin/ajax/import-settings.php:21
24
+ #: admin/ajax/install-addons.php:26
25
  msgid "You don't have enough capability to edit this information."
26
  msgstr "У вас недостаточно возможностей для редактирования этой информации."
27
 
33
  msgid "Settings are not defined or do not exist."
34
  msgstr "Настройки не определены или не существуют."
35
 
36
+ #: admin/ajax/install-addons.php:30
37
+ msgid "Required attributes are not passed or empty."
38
+ msgstr "Обязательные атрибуты не переданы и не пусты."
39
+
40
+ #: admin/ajax/install-addons.php:53 admin/ajax/install-addons.php:77
41
+ msgid "You are trying to perform an invalid action."
42
+ msgstr "Вы пытаетесь выполнить недопустимое действие."
43
+
44
+ #: admin/ajax/install-addons.php:110 admin/ajax/update-package.php:45
45
+ msgid "An unknown error occurred during the activation of the component."
46
+ msgstr "При активации компонента произошла неизвестная ошибка."
47
+
48
+ #: admin/ajax/update-package.php:25
49
+ msgid "To use premium components, you need activate a license!"
50
+ msgstr ""
51
+ "Чтобы использовать премиум компоненты, вам необходимо активировать лицензию!"
52
+
53
+ #: admin/ajax/update-package.php:25
54
+ msgid "Activate license"
55
+ msgstr "Активировать лицензию"
56
+
57
+ #: admin/ajax/update-package.php:37
58
+ msgid "Configuration updated."
59
+ msgstr "Конфигурация обновлена."
60
+
61
+ #: admin/boot.php:42
62
  #, php-format
63
  msgid ""
64
  "We found that you have the plugin %s installed. The functions of this plugin "
69
  "есть в %s. Пожалуйста, деактивируйте плагин %s во избежание конфликтов между "
70
  "функциями плагинов."
71
 
72
+ #: admin/boot.php:43
73
  #, php-format
74
  msgid ""
75
  "If you do not want to deactivate the plugin %s for some reason, we strongly "
79
  "настоятельно рекомендуем не использовать похожие функции плагинов "
80
  "одновременно!"
81
 
82
+ #: admin/boot.php:60
83
+ msgid "Robin image optimizer – saves your money on image optimization!"
84
+ msgstr ""
85
+ "Robin image optimizer – сохранит ваши деньги на оптимизации изображений!"
86
+
87
+ #: admin/boot.php:61
88
+ msgid "Our new component!"
89
+ msgstr "Наш новый компонент!"
90
+
91
+ #: admin/boot.php:61
92
+ msgid ""
93
+ "We’ve created a fully free solution for image optimization, which is as good "
94
+ "as the paid products. The plugin optimizes your images automatically, "
95
+ "reducing their weight with no quality loss. More details in here:"
96
+ msgstr ""
97
+ "Мы создали полностью бесплатное решение для оптимизации изображений, ничем "
98
+ "не уступающее платным аналогам. Плагин автоматически оптимизирует ваши "
99
+ "изображения, уменьшая их вес без потери качества. Вы можете узнать больше о "
100
+ "плагине тут:"
101
+
102
+ #: admin/boot.php:67
103
+ msgid "Hide login page (Reloaded) – hides your login page!"
104
+ msgstr "Hide login page (Reloaded) – скроет вашу страницу входа!"
105
+
106
+ #: admin/boot.php:68
107
+ msgid ""
108
+ "Attention! If you’ve ever used features associated with hiding login page, "
109
+ "then, please, re-activate this component."
110
+ msgstr ""
111
+ "Внимание! Если вы использовали функции отвечающие за скрытие страницы входа, "
112
+ "пожалуйста активируйте этот компонент снова."
113
+
114
+ #: admin/boot.php:68
115
+ msgid ""
116
+ "This simple module changes the login page URL to a custom link quickly and "
117
+ "safely. The plugin requires installation."
118
+ msgstr ""
119
+ "Простой модуль, который позволяет вам легко и безопасно изменять URL-адрес "
120
+ "страницы формы входа на свой собственный. Этот компонент теперь требует "
121
+ "установки."
122
 
123
  #: admin/boot.php:73
124
+ msgid "Hide my wp (Premium) – hides your WordPress from hackers and bots!"
125
+ msgstr "Hide my wp (Премиум) – скроет ваш Wordpress от хакеров и ботов!"
126
+
127
+ #: admin/boot.php:74 admin/boot.php:82 admin/boot.php:89
128
+ msgid "Our new component! "
129
+ msgstr "Наш новый компонент! "
130
+
131
+ #: admin/boot.php:74
132
+ msgid ""
133
+ "This premium component helps in hiding your WordPress from hackers and bots. "
134
+ "Basically, it disables identification of your CMS by changing directories "
135
+ "and files names, removing meta data and replacing HTML content which can "
136
+ "provide all information about the platform you use.\n"
137
+ "Most websites can be hacked easily, as hackers and bots know all security "
138
+ "flaws in plugins, themes and the WordPress core. You can secure the website "
139
+ "from the attack by hiding the information the hackers will need.\n"
140
+ msgstr ""
141
+ "Этот премиум компонент позволяет скрыть ваш WordPress от хакеров и ботов. Он "
142
+ "фактически предотвращает обнаружение вашей системы управления контентом "
143
+ "(CMS), подменяя имена директорий и файлов, удаляя мета данные и заменяя html "
144
+ "контент, который может выдать информацию о вашей платформе. Большинство "
145
+ "сайтов легко взламываются, потому что хакеры и боты знают о всех дырах в "
146
+ "безопасности плагинов, тем и самого ядра Wordpress. Вы можете предотвратить "
147
+ "взлом вашего сайта просто скрыв нужную для хакера информацию. \n"
148
+
149
+ #: admin/boot.php:81
150
+ msgid "Minify and Combine (JS, CSS) – optimizes your scripts and styles!"
151
+ msgstr "Minify and Combine (JS, CSS) – оптимизирует ваши скрипты и стили!"
152
+
153
+ #: admin/boot.php:82
154
  msgid ""
155
+ "This component combines all your scripts and styles in one file, compresses "
156
+ "& caches it. "
157
  msgstr ""
158
+ "Этот компонент объединяет ваши скрипты и стили в один файл, сжимает его и "
159
+ "кеширует."
160
 
161
+ #: admin/boot.php:88
162
+ msgid "Html minify (Reloaded) reduces the amount of code on your pages!"
163
+ msgstr "Html minify (перезагружен) - уменьшит объем кода ваших страниц!"
164
 
165
+ #: admin/boot.php:89
166
  msgid ""
167
+ "We’ve completely redesigned HTML compression of the pages and added these "
168
+ "features to another component. It’s more stable and reliable solution for "
169
+ "HTML code optimization of your pages."
170
  msgstr ""
171
+ "Мы полностью переделали Html сжатие страниц и вынесли эти функции в "
172
+ "отдельный компонент. Это более стабильное и надежное решение для оптимизации "
173
+ "html кода ваших страниц."
174
+
175
+ #: admin/boot.php:96
176
+ msgid "Welcome to Clearfy!"
177
+ msgstr "Вас приветствует Clearfy 1.3.x!"
178
 
179
+ #: admin/boot.php:97
180
+ msgid "We apologize for the delay in updates!"
181
+ msgstr "Мы приносим свои извинения за задержку обновлений!"
182
 
183
+ #: admin/boot.php:98
184
  msgid ""
185
+ "Our team has spent a lot of time designing new, useful, and the most "
186
+ "important free! features of the Clearfy plugin! "
 
187
  msgstr ""
188
+ "Наша команда потратила много времени на создание новых, полезных, а главное "
189
+ "бесплатных функций для плагина Clearfy! И вот наступил момент, когда вы "
190
+ "можете их попробовать"
191
+
192
+ #: admin/boot.php:99
193
+ msgid "Now it is time to try it."
194
+ msgstr "И вот наступил момент, когда вы можете их попробовать."
195
+
196
+ #: admin/boot.php:155
197
+ msgid "Images optimization"
198
+ msgstr "Оптимизация изображений"
199
+
200
+ #: admin/boot.php:187 admin/pages/license.php:258
201
+ msgid "Activation Clearfy Business"
202
+ msgstr "Активировать Clearfy Бизнес"
203
+
204
+ #: admin/boot.php:191 admin/pages/license.php:260
205
+ msgid ""
206
+ "<b>Clearfy Business</b> is a paid package of components for the popular free "
207
+ "WordPress plugin named Clearfy. You get access to all paid components at one "
208
+ "price."
209
+ msgstr ""
210
+ "Clearfy Bussines это платный пакет компонентов для популярного WordPress "
211
+ "плагина Clearfy, который поставляется бесплатно. Вы покупаете доступ ко всем "
212
+ "платным компонентам плагина по одной цене. "
213
+
214
+ #: admin/boot.php:193 admin/pages/license.php:262
215
+ msgid ""
216
+ "Paid license guarantees that you can download and update existing and future "
217
+ "paid components of the plugin."
218
+ msgstr ""
219
+ "После покупки лицензии, вы имеете возможность скачивать и обновлять все "
220
+ "платные компоненты плагина, которые существуют на момент покупки и которые "
221
+ "будут выпущены в будущем. "
222
+
223
+ #: admin/boot.php:196
224
+ #, php-format
225
+ msgid "Upgrade to Clearfy Business for $%s"
226
+ msgstr "Обновится до Clearfy Бизнес за $%s"
227
+
228
+ #: admin/includes/classes/class.install-plugins-button.php:357
229
+ msgid "Activate"
230
+ msgstr "Включить"
231
+
232
+ #: admin/includes/classes/class.install-plugins-button.php:358
233
+ msgid "Install"
234
+ msgstr "Установить"
235
+
236
+ #: admin/includes/classes/class.install-plugins-button.php:359
237
+ msgid "Deactivate"
238
+ msgstr "Отключить"
239
+
240
+ #: admin/includes/classes/class.install-plugins-button.php:360
241
+ msgid "Delete"
242
+ msgstr "Удалить"
243
+
244
+ #: admin/includes/classes/class.install-plugins-button.php:361
245
+ msgid "Please wait..."
246
+ msgstr "Пожалуйста, подождите..."
247
+
248
+ #: admin/includes/classes/class.install-plugins-button.php:362
249
+ msgid "Read more"
250
+ msgstr "Подробнее"
251
 
252
  #: admin/includes/options.php:18 admin/pages/performance-google.php:92
253
  msgid "Google Fonts asynchronous"
265
  msgid "Exclude pages from Disable Google Maps filter"
266
  msgstr "Не отключать Google карты на установленных страницах"
267
 
268
+ #: admin/includes/options.php:39 admin/pages/performance-google.php:113
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
269
  msgid "Disable Google maps"
270
  msgstr "Отключить Google карты"
271
 
272
+ #: admin/includes/options.php:45 admin/pages/performance.php:164
273
  msgid "Removing XFN (XHTML Friends Network) Profile Link"
274
  msgstr "Удалить профиль XFN (XHTML Friends Network)"
275
 
276
+ #: admin/includes/options.php:50 admin/pages/performance.php:216
277
  msgid "Font Awesome asynchronous"
278
  msgstr "Асинхронный Fontawesome"
279
 
280
+ #: admin/includes/options.php:55 admin/pages/performance.php:226
281
  msgid "Disable Dashicons"
282
  msgstr "Отключить Wordpress иконки (для фронтенда)"
283
 
284
+ #: admin/includes/options.php:60 admin/pages/performance.php:236
285
  msgid "Disable gravatars"
286
  msgstr "Отключить граватары"
287
 
288
+ #: admin/includes/options.php:65 admin/pages/performance.php:106
289
  msgid "Remove REST API Links"
290
  msgstr "Отключить Rest API"
291
 
292
+ #: admin/includes/options.php:70 admin/pages/performance.php:116
293
  msgid "Disable Emojis"
294
  msgstr "Отключить Emojis (эмоции)"
295
 
296
+ #: admin/includes/options.php:81 admin/pages/performance.php:155
297
  msgid "Remove RSD Link"
298
  msgstr "Удаляет RSD ссылку"
299
 
300
+ #: admin/includes/options.php:86 admin/pages/performance.php:176
301
  msgid "Remove wlwmanifest Link"
302
  msgstr "Удалить wlwmanifest Link"
303
 
304
+ #: admin/includes/options.php:91 admin/pages/performance.php:186
305
  msgid "Remove Shortlink"
306
  msgstr "Удалить короткие ссылки"
307
 
308
+ #: admin/includes/options.php:96 admin/pages/performance.php:196
309
  msgid "Remove links to previous, next post"
310
  msgstr "Удалить ссылки следующая, предыдущая запись"
311
 
312
+ #: admin/includes/options.php:101 admin/pages/performance.php:206
313
  msgid "Remove .recentcomments styles"
314
  msgstr "Удалить стили .recentcomments"
315
 
316
+ #: admin/includes/options.php:107 admin/pages/seo.php:76
317
  msgid "Automatically set the alt attribute"
318
  msgstr "Автоматически устанавливать атрибут alt"
319
 
320
+ #: admin/includes/options.php:112 admin/pages/seo.php:115
321
  msgid "Automatically insert the Last Modified header"
322
  msgstr "Автоматически вставлять заголовок Last Modified"
323
 
324
+ #: admin/includes/options.php:117 admin/pages/seo.php:146
325
  msgid "Return an If-Modified-Since responce"
326
  msgstr "Возвращать заголовок If-Modified-Since"
327
 
328
+ #: admin/includes/options.php:122 admin/pages/seo.php:160
329
  msgid "Remove duplicate names in breadcrumbs WP SEO by Yoast"
330
  msgstr "Удалить дубли имен в хлебных крошках WP SEO Yoast"
331
 
332
+ #: admin/includes/options.php:127 admin/pages/seo.php:170
333
  #, php-format
334
  msgid "Remove the tag %s from XML site map"
335
  msgstr "Удаляет тег %s из XML карты сайта плагин Yoast SEO."
336
 
337
+ #: admin/includes/options.php:134 admin/pages/seo.php:188
338
  msgid "Disable JSON-LD sitelinks searchbox"
339
  msgstr "Отключить ссылки JSON-LD"
340
 
341
+ #: admin/includes/options.php:139 admin/pages/seo.php:198
342
  msgid "Disable Yoast Structured Data"
343
  msgstr "Отключить структурирование данных"
344
 
345
+ #: admin/includes/options.php:144 admin/pages/seo.php:210
346
  #, php-format
347
  msgid "Remove comment from %s section"
348
  msgstr "Удалить комментарии из секции %s"
349
 
350
+ #: admin/includes/options.php:149 admin/pages/seo-double-pages.php:93
351
  msgid "Remove archives date"
352
  msgstr "Удалить архивы дат"
353
 
354
+ #: admin/includes/options.php:154 admin/pages/seo-double-pages.php:103
355
  msgid "Remove author archives "
356
+ msgstr "Удалить архивы автора "
357
 
358
+ #: admin/includes/options.php:159 admin/pages/seo-double-pages.php:113
359
  msgid "Remove archives tag"
360
  msgstr "Удалить метки архивов"
361
 
362
+ #: admin/includes/options.php:164 admin/pages/seo-double-pages.php:123
363
  msgid "Remove attachment pages"
364
  msgstr "Удалить страницы вложений"
365
 
366
+ #: admin/includes/options.php:169 admin/pages/seo-double-pages.php:133
367
  msgid "Remove post pagination"
368
  msgstr "Удалить постраничную навигацию записей"
369
 
370
+ #: admin/includes/options.php:174 admin/pages/seo-double-pages.php:143
371
  msgid "Remove ?replytocom"
372
  msgstr "Удалить ?replytocom"
373
 
374
+ #: admin/includes/options.php:179 admin/pages/defence.php:105
375
  msgid "Remove meta generator"
376
  msgstr "Удалить meta generator"
377
 
378
+ #: admin/includes/options.php:184 admin/pages/defence.php:60
379
  msgid "Hide author login"
380
  msgstr "Убрать возможность узнать логин автора"
381
 
382
+ #: admin/includes/options.php:189 admin/pages/defence.php:70
383
  msgid "Hide errors when logging into the site"
384
  msgstr "Спрятать ошибки при входе на сайт"
385
 
386
+ #: admin/includes/options.php:194 admin/includes/options.php:305
387
+ #: admin/pages/defence.php:120 admin/pages/performance.php:248
388
  msgid "Remove Version from Stylesheet"
389
  msgstr "Удалить версию у файлов стилей"
390
 
391
+ #: admin/includes/options.php:199 admin/includes/options.php:310
392
+ #: admin/pages/defence.php:131 admin/pages/performance.php:274
393
  msgid "Remove Version from Script"
394
  msgstr "Удаляет версию у javascript файлов"
395
 
396
+ #: admin/includes/options.php:204 admin/pages/widgets.php:59
397
  msgid "Remove the \"Pages\" widget"
398
+ msgstr "Удалите виджет \"Страницы\""
399
 
400
+ #: admin/includes/options.php:209 admin/pages/widgets.php:68
401
  msgid "Remove calendar widget"
402
  msgstr "Удалить виджет календаря"
403
 
404
+ #: admin/includes/options.php:214 admin/pages/widgets.php:77
405
  msgid "Remove the \"Cloud of tags\" widget"
406
+ msgstr "Удалите виджет \"Облако тегов\""
407
 
408
+ #: admin/includes/options.php:219 admin/pages/widgets.php:86
409
  msgid "Remove the \"Archives\" widget"
410
+ msgstr "Удалите виджет \"Архивы\""
411
 
412
+ #: admin/includes/options.php:224 admin/pages/widgets.php:95
413
  msgid "Remove the \"Links\" widget"
414
+ msgstr "Удалите виджет \"Ссылки\""
415
 
416
+ #: admin/includes/options.php:229 admin/pages/widgets.php:104
417
  msgid "Remove the \"Meta\" widget"
418
+ msgstr "Удалите виджет \"Мета\""
419
 
420
+ #: admin/includes/options.php:234 admin/pages/widgets.php:113
421
  msgid "Remove the \"Search\" widget"
422
+ msgstr "Удалите виджет \"Поиск\""
423
 
424
+ #: admin/includes/options.php:239 admin/includes/options.php:259
425
  #: admin/pages/widgets.php:122
426
  msgid "Remove the \"Text\" widget"
427
+ msgstr "Удалите виджет \"Текст\""
428
 
429
+ #: admin/includes/options.php:244 admin/pages/widgets.php:131
430
  msgid "Remove the \"Categories\" widget"
431
+ msgstr "Удалите виджет \"Категории\""
432
 
433
+ #: admin/includes/options.php:249 admin/pages/widgets.php:140
434
  msgid "Remove the \"Recent Posts\" widget"
435
+ msgstr "Удалите виджет \"Последние записи\""
436
 
437
+ #: admin/includes/options.php:254 admin/pages/widgets.php:149
438
  msgid "Remove the \"Recent Comments\" widget"
439
+ msgstr "Удалите виджет \"Свежие комментарии\""
440
 
441
+ #: admin/includes/options.php:264 admin/pages/widgets.php:158
442
  msgid "Remove the \"RSS\" widget"
443
+ msgstr "Удалить виджет \"RSS\""
444
 
445
+ #: admin/includes/options.php:269 admin/pages/widgets.php:167
446
  msgid "Remove the \"Menu\" widget"
447
+ msgstr "Удалите виджет \"Меню\""
448
 
449
+ #: admin/includes/options.php:274 admin/pages/widgets.php:176
450
  msgid "Remove the \"Twenty Eleven Ephemera\" widget"
451
  msgstr "Удалите виджет \"Twenty Eleven Ephemera\""
452
 
453
+ #: admin/includes/options.php:277 admin/includes/options.php:340
454
  #: admin/pages/advanced.php:207
455
  msgid "Disable revision"
456
  msgstr "Отключить ревизии"
457
 
458
+ #: admin/includes/options.php:278 admin/includes/options.php:345
459
  #: admin/pages/advanced.php:220
460
  msgid "Limit Post Revisions"
461
  msgstr "Установить лимит ревизий"
462
 
463
+ #: admin/includes/options.php:279 admin/pages/seo.php:137
464
  msgid "Exclude pages:"
465
  msgstr "Исключить страницы:"
466
 
467
+ #: admin/includes/options.php:282 admin/pages/seo.php:86
468
  msgid "Create right robots.txt"
469
  msgstr "Создайте правильный robots.txt"
470
 
471
+ #: admin/includes/options.php:287 admin/pages/seo.php:101
472
  msgid "You can edit the robots.txt file in the box below:"
473
  msgstr "Вы можете отредактировать файл robots.txt в поле ниже:"
474
 
475
+ #: admin/includes/options.php:290
476
  msgid "Quick mode"
477
  msgstr "Быстрый старт"
478
 
479
+ #: admin/includes/options.php:293 admin/pages/performance.php:126
480
  msgid "Remove jQuery Migrate"
481
  msgstr "Удалить jQuery Migrate"
482
 
483
+ #: admin/includes/options.php:296 admin/pages/performance.php:136
484
  msgid "Disable Embeds"
485
  msgstr "Отключить Embeds"
486
 
487
+ #: admin/includes/options.php:297 admin/pages/performance.php:76
488
  msgid "Disable RSS feeds"
489
  msgstr "Отключить RSS каналы"
490
 
491
+ #: admin/includes/options.php:300
492
  msgid "Removes links to wordpress.org site from the admin bar"
493
  msgstr "Удаляет ссылки на wordpress.org сайт из панели администратора"
494
 
495
+ #: admin/includes/options.php:315
 
 
 
 
 
 
 
 
496
  msgid "Eclude stylesheet/script file names"
497
  msgstr "Исключает файлы стилей/сприптов"
498
 
499
+ #: admin/includes/options.php:320
500
  msgid "Enable Sanitization of WordPress"
501
  msgstr "Включить Wordpress Sanitization"
502
 
503
+ #: admin/includes/options.php:325 admin/pages/advanced.php:158
504
  msgid "Disable admin top bar"
505
  msgstr "Скрыть верхнюю панель администратора"
506
 
507
+ #: admin/includes/options.php:330 admin/pages/advanced.php:176
508
  msgid "Remove admin bar WP logo"
509
  msgstr "Удалить логотип Wordpress из админбара"
510
 
511
+ #: admin/includes/options.php:335 admin/pages/advanced.php:186
512
  msgid "Replace \"Howdy\" text with \"Welcome\""
513
  msgstr "Заменить текст \"Привет\", на \"Добро пожаловать\""
514
 
515
+ #: admin/includes/options.php:350 admin/pages/advanced.php:244
516
  msgid "Disable autosave"
517
  msgstr "Отключить автосохранения"
518
 
519
+ #: admin/includes/options.php:355 admin/pages/advanced.php:254
520
  msgid "Disable Texturization - Smart Quotes"
521
  msgstr "Отключить \"Умные кавычки\""
522
 
523
+ #: admin/includes/options.php:360 admin/pages/advanced.php:264
524
  msgid "Disable capitalization in Wordpress branding"
525
  msgstr "Отключить верблюжий шрифт в WordPress брендинге"
526
 
527
+ #: admin/includes/options.php:365 admin/pages/advanced.php:274
528
  msgid "Disable auto inserted paragraphs (i.e. p tags)"
529
  msgstr "Отключить автоматические параграфы (т.е p теги)"
530
 
531
+ #: admin/includes/options.php:370 admin/pages/advanced.php:89
532
  msgid "Disable Heartbeat"
533
  msgstr "Отключить пульсацию Wordpress"
534
 
535
+ #: admin/includes/options.php:375 admin/pages/advanced.php:118
536
  msgid "Heartbeat frequency"
537
  msgstr "Интервал пульсации Wordpress"
538
 
539
+ #: admin/includes/options.php:380 admin/pages/defence.php:95
540
  msgid "Remove html comments"
541
  msgstr "Удалить html комментарии"
542
 
543
+ #: admin/includes/options.php:385
544
+ msgid "Deactivate preinstall components"
545
+ msgstr "Деактивировать предустановленные компоненты"
546
+
547
  #: admin/pages/advanced.php:36
548
  msgid "Advanced"
549
  msgstr "Дополнительно"
750
  msgid "Components"
751
  msgstr "Компоненты"
752
 
753
+ #: admin/pages/components.php:129
754
+ msgid "Robin image optimizer"
755
+ msgstr "Оптимизатор изображений"
756
+
757
+ #: admin/pages/components.php:134
758
+ msgid ""
759
+ "Automatic image optimization without any quality loss. No limitations, no "
760
+ "paid plans. The best Wordpress image optimization plugin allows optimizing "
761
+ "any amount of images for free!"
762
+ msgstr ""
763
+ "Автоматически оптимизирует изображения без потери качества. Результатом его "
764
+ "работы будет ускорение сайта и серьезное улучшение показателей GTmetrix, "
765
+ "Pingdom Tools и Google PageSpeed Insights."
766
+
767
+ #: admin/pages/components.php:138
768
  msgid "Hide login page"
769
+ msgstr "Скрыть страницу входа"
770
 
771
+ #: admin/pages/components.php:143
772
  msgid ""
773
  "Hide Login Page is a very light plugin that lets you easily and safely "
774
  "change the url of the login form page to anything you want."
775
  msgstr ""
776
+ "Позволяет вам легко и безопасно изменять URL-адрес страницы формы входа на "
777
+ "свой собственный, а также блокировать доступ к директории wp-admin. "
778
+ "Результатом его работы будет повышение безопасности вашего сайта."
779
+
780
+ #: admin/pages/components.php:147
781
+ msgid "Html minify"
782
+ msgstr "Html сжатие"
783
+
784
+ #: admin/pages/components.php:151
785
+ msgid ""
786
+ "Ever look at the HTML markup of your website and notice how sloppy and "
787
+ "amateurish it looks? The Minify HTML options cleans up sloppy looking markup "
788
+ "and minifies, which also speeds up download"
789
+ msgstr ""
790
+ "Удаляет неиспользуемые части кода, символы, комментарии из html кода ваших "
791
+ "страниц. Результатом его работы будет улучшение Html разметки, ускорение "
792
+ "вашего сайта и улучшение безопасности."
793
+
794
+ #: admin/pages/components.php:155
795
+ msgid "Minify and combine (JS, CSS)"
796
+ msgstr "Сжатие и объединение (JS, CSS)"
797
+
798
+ #: admin/pages/components.php:159
799
+ msgid ""
800
+ "Improve your speed score on GTmetrix, Pingdom Tools and Google PageSpeed "
801
+ "Insights by merging and minifying CSS, JavaScript."
802
+ msgstr ""
803
+ "Автоматически объединяет и сжимает CSS, JavaScript скрипты и части кода. "
804
+ "Результатом его работы будет ускорение сайта, серьезное улучшение "
805
+ "показателей GTmetrix, Pingdom Tools и Google PageSpeed Insights."
806
 
807
+ #: admin/pages/components.php:163
808
+ msgid "Google Analytics Cache"
809
+ msgstr "Кеширование Google Аналитки"
810
+
811
+ #: admin/pages/components.php:167
812
+ msgid ""
813
+ "To improve Google Page Speed indicators Analytics caching is needed. "
814
+ "However, it can also slightly increase your website loading speed, because "
815
+ "Analytics js files will load locally."
816
+ msgstr ""
817
+ "Чтобы улучшить показатели скорости страницы Google, требуется кэширование "
818
+ "аналитики. Этот компонент также немного увеличивает скорость загрузки вашего "
819
+ "сайта, поскольку файлы Google Analytics будут загружаться локально."
820
+
821
+ #: admin/pages/components.php:171
822
  msgid "Updates manager"
823
  msgstr "Менеджер обновлений"
824
 
825
+ #: admin/pages/components.php:175
826
  msgid "Disable updates enable auto updates for themes, plugins and WordPress."
827
  msgstr ""
828
  "Отключает обновления, включает автообновления плагинов, тем, WordPress."
829
 
830
+ #: admin/pages/components.php:179
831
  msgid "Comments tools"
832
  msgstr "Инструменты комментариев"
833
 
834
+ #: admin/pages/components.php:183
835
  msgid ""
836
  "Bulk disable and remove comments, disable “Website” field, hides external "
837
  "links, disable XML-RPC."
839
  "Позволяет массово отключать и удалять комментарии, отключает поле сайт, "
840
  "скрывает внешние ссылки, отключает XML-RPC."
841
 
842
+ #: admin/pages/components.php:187
843
  msgid "Widgets tools"
844
  msgstr "Инструменты для виджетов"
845
 
846
+ #: admin/pages/components.php:191
847
  msgid "Disable unused widgets such as tag cloud, links, calendar etc."
848
  msgstr ""
849
  "Позволяет отключить неиспользуемые виджеты, такие как облако тегов, ссылки, "
850
  "календарь и т.д."
851
 
852
+ #: admin/pages/components.php:195
853
  msgid "Asset manager"
854
  msgstr "Менеджер скриптов"
855
 
856
+ #: admin/pages/components.php:199
857
  msgid ""
858
  "Selectively disable unused scripts and styles on the pages of your website."
859
  msgstr ""
860
  "Выборочно отключает неиспользуемые скрипты и стили на страницах вашего сайта."
861
 
862
+ #: admin/pages/components.php:203
863
  msgid "Disable admin notices"
864
  msgstr "Отключить уведомления"
865
 
866
+ #: admin/pages/components.php:207
867
  msgid ""
868
  "Disables admin notices bulk or individually. Collects notices into the admin "
869
  "bar."
871
  "Отключает уведомления администратора индивидуально или все разом. Собирает "
872
  "уведомления в админ баре."
873
 
874
+ #: admin/pages/components.php:211
875
  msgid "Admin bar manager"
876
  msgstr "Управление админбаром"
877
 
878
+ #: admin/pages/components.php:215
879
  msgid "Disables admin bar. Allows to change and remove admin bar elements."
880
  msgstr ""
881
  "Отключает админ бар. Позволяет изменять и удалять элементы из админбара."
882
 
883
+ #: admin/pages/components.php:219
884
  msgid "Posts tools"
885
  msgstr "Инструменты для записей"
886
 
887
+ #: admin/pages/components.php:223
888
  msgid ""
889
  "Disable revisions, disable posts autosave, disable smart quotes and disable "
890
  "auto paragraphs."
892
  "Отключение ревизий, отключение автосохранений записей, отключение «умных "
893
  "кавычек», отключение автоматических параграфов."
894
 
895
+ #: admin/pages/components.php:227
896
  msgid "Yoast SEO optimization"
897
  msgstr "Оптимизация Yoast Seo"
898
 
899
+ #: admin/pages/components.php:231
900
  msgid "Set of optimization functions for the popular Yoast SEO plugin."
901
  msgstr "Набор функций для оптимизации популярного плагина Yoast Seo."
902
 
903
+ #: admin/pages/components.php:237
904
  msgid "Transliteration of Cyrillic alphabet"
905
  msgstr "Транслитерация кириллицы"
906
 
907
+ #: admin/pages/components.php:241
908
  msgid ""
909
  "Converts Cyrillic permalinks of post, pages, taxonomies and media files to "
910
  "the Latin alphabet. Supports Russian, Ukrainian, Georgian, Bulgarian "
913
  "Конвертирует кириллические постоянные ссылки записей, страниц, таксономий и "
914
  "медиафайлов в латиницу. Поддерживает Русский, Украинский, Грузинский, "
915
  "Болгарский языки. Пример: http://site.dev/последние-новости -> http://site."
916
+ "dev/poslednie-novosti."
 
 
 
 
917
 
918
+ #: admin/pages/components.php:281
 
 
 
 
 
 
 
 
919
  msgid "<strong>Plugin Components</strong>."
920
  msgstr "<strong>Компоненты плагина</strong>."
921
 
922
+ #: admin/pages/components.php:283
923
  msgid ""
924
  "These are components of the plugin bundle. When you activate the plugin, all "
925
  "the components turned on by default. If you don’t need some function, you "
929
  "все компоненты включены по умолчанию. Если какая-то функция вам не нужна, вы "
930
  "можете легко отключить её на этой странице."
931
 
932
+ #: admin/pages/components.php:329
933
+ msgid "Premium"
934
+ msgstr "Премиум"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
935
 
936
  #: admin/pages/defence.php:34
937
  msgid "Defence"
994
  msgid "Removes the server responses a reference to the xmlrpc file."
995
  msgstr "Удаляет ссылку на xmlrpc-файл и ответ сервера."
996
 
997
+ #: admin/pages/defence.php:88
998
+ msgid "<strong>Hide WordPress versions</strong>"
999
+ msgstr "<strong>Скрыть версии WordPress</strong>"
1000
+
1001
+ #: admin/pages/defence.php:88
1002
+ msgid ""
1003
+ "WordPress itself and many plugins shows their version at the public areas of "
1004
+ "your site. An attacker received this information may be aware of the "
1005
+ "vulnerabilities found in the version of the WordPress core or plugins."
1006
+ msgstr ""
1007
+ "Сам WordPress и многие плагины, публикуют свою версию в публичных областях "
1008
+ "вашего сайта. Получив эту информацию, злоумышленник может знать об "
1009
+ "уязвимостях обнаруженных в полученной им версии ядра WordPress или плагинов."
1010
+
1011
+ #: admin/pages/defence.php:97
1012
+ msgid ""
1013
+ "This function will remove all html comments in the source code, except for "
1014
+ "special and hidden comments. This is necessary to hide the version of "
1015
+ "installed plugins."
1016
+ msgstr ""
1017
+ "Эта функция удалит все html-комментарии в исходном коде, за исключением "
1018
+ "специальных и скрытых комментариев. Это необходимо, чтобы скрыть версию "
1019
+ "установленных плагинов."
1020
+
1021
+ #: admin/pages/defence.php:97
1022
+ msgid "Remove html comments in source code."
1023
+ msgstr "Удалить Html комментарии в исходном коде страницы."
1024
+
1025
+ #: admin/pages/defence.php:105 admin/pages/defence.php:120
1026
+ #: admin/pages/defence.php:131 admin/pages/performance.php:248
1027
+ #: admin/pages/performance.php:265 admin/pages/performance.php:274
1028
+ #: admin/pages/seo.php:76 admin/pages/seo.php:115 admin/pages/seo.php:129
1029
+ #: admin/pages/seo.php:146 admin/pages/seo.php:160 admin/pages/seo.php:170
1030
+ #: admin/pages/seo.php:210
1031
+ msgid "Recommended"
1032
+ msgstr "Рекомендовано"
1033
+
1034
+ #: admin/pages/defence.php:107
1035
+ msgid ""
1036
+ "Allows attacker to learn the version of WP installed on the site. This meta "
1037
+ "tag has no useful function."
1038
+ msgstr ""
1039
+ "Позволяет злоумышленнику узнать версию Wordpress, установленую на вашем "
1040
+ "сайте. Этот мета-тег не несет никакой пользы."
1041
+
1042
+ #: admin/pages/defence.php:107
1043
+ #, php-format
1044
+ msgid "Removes the meta tag from the %s section"
1045
+ msgstr "Удаляет мета-тег из раздел %s"
1046
+
1047
+ #: admin/pages/defence.php:113
1048
+ msgid "Remove query strings from static resources"
1049
+ msgstr "Удалить переменные запроса для статических ресурсов"
1050
+
1051
+ #: admin/pages/defence.php:113
1052
+ msgid ""
1053
+ "This funcitons will remove query strings from static resources like CSS & JS "
1054
+ "files inside the HTML <head> element to improve your speed scores in "
1055
+ "services like Pingdom, GTmetrix, PageSpeed and YSlow."
1056
+ msgstr ""
1057
+ "Эти функции удалят строки запроса из статических ресурсов, таких как CSS и "
1058
+ "JS-файлы внутри элемента HTML <head>, чтобы улучшить показатели скорости в "
1059
+ "таких сервисах, как Pingdom, GTmetrix, PageSpeed и YSlow. А также усилить "
1060
+ "безопасность вашего сайта."
1061
+
1062
+ #: admin/pages/defence.php:122 admin/pages/defence.php:133
1063
+ #: admin/pages/performance.php:250 admin/pages/performance.php:276
1064
+ msgid ""
1065
+ "To make it more difficult for others to hack your website you can remove the "
1066
+ "WordPress version number from your site, your css and js. Without that "
1067
+ "number it's not possible to see if you run not the current version to "
1068
+ "exploit bugs from the older versions. <br><br>\n"
1069
+ "\t\t\t\t\tAdditionally it can improve the loading speed of your site, "
1070
+ "because without query strings in the URL the css and js files can be cached."
1071
+ msgstr ""
1072
+ "Активировав эту функцию вы усложните работу злоумышленника. <br><br>Кроме "
1073
+ "того, это может улучшить скорость загрузки вашего сайта, потому что без "
1074
+ "строки запроса в URL-адрес css и js файлов могут быть кэшированы."
1075
+
1076
+ #: admin/pages/defence.php:123 admin/pages/performance.php:251
1077
+ msgid ""
1078
+ "Removes the wordpress version number from stylesheets (not logged in user "
1079
+ "only)."
1080
+ msgstr "Удаляет номер версии из файлов стилей стилей (только для фронтенда)."
1081
+
1082
+ #: admin/pages/defence.php:134 admin/pages/performance.php:277
1083
+ msgid ""
1084
+ "Removes wordpress version number from scripts (not logged in user only)."
1085
+ msgstr "Удаляет номер версии из javascript файлов (только для фронтенда)."
1086
+
1087
+ #: admin/pages/defence.php:142 admin/pages/performance.php:285
1088
+ msgid "Exclude stylesheet/script file names"
1089
+ msgstr "Исключает файлы стилей/сприптов"
1090
+
1091
+ #: admin/pages/defence.php:144 admin/pages/performance.php:287
1092
+ msgid ""
1093
+ "Enter Stylesheet/Script file names to exclude from version removal (each "
1094
+ "exclude file starts with a new line)"
1095
+ msgstr ""
1096
+ "Введите абсолютный путь к файлу, чтобы исключить его из списка файлов у "
1097
+ "которых, будет удалена версия (каждое исключение, должно быть с новой "
1098
+ "строки)."
1099
+
1100
+ #: admin/pages/defence.php:144 admin/pages/performance.php:287
1101
+ msgid "Example"
1102
+ msgstr "Например"
1103
+
1104
+ #: admin/pages/license.php:52
1105
+ msgid "License"
1106
+ msgstr "Лицензия"
1107
+
1108
+ #: admin/pages/license.php:139 includes/classes/class.package.php:250
1109
+ msgid "Update in progress..."
1110
+ msgstr "Идет обновление..."
1111
+
1112
+ #: admin/pages/license.php:139
1113
+ msgid "Components have been successfully updated!"
1114
+ msgstr "Компонент был успешно обновлен!"
1115
+
1116
+ #: admin/pages/license.php:139
1117
+ msgid "update now"
1118
+ msgstr "обновить сейчас"
1119
+
1120
+ #: admin/pages/license.php:151
1121
+ msgid "Updates are available for one of the components."
1122
+ msgstr "Для одного из компонентов доступны обновления."
1123
+
1124
+ #: admin/pages/license.php:277
1125
+ #, php-format
1126
+ msgid "Upgrade to Premium for $%s"
1127
+ msgstr "Обновить до премиум за $%s"
1128
+
1129
+ #: admin/pages/license.php:282
1130
+ #, php-format
1131
+ msgid "Your current license for %1$s:"
1132
+ msgstr "Ваша текущая лицензия для %1$s:"
1133
+
1134
+ #: admin/pages/license.php:286
1135
+ msgid "Delete Key"
1136
+ msgstr "Удалить"
1137
+
1138
+ #: admin/pages/license.php:288
1139
+ msgid "Synchronization"
1140
+ msgstr "Синхронизация"
1141
+
1142
+ #: admin/pages/license.php:305
1143
+ msgid ""
1144
+ "Public License is a GPLv2 compatible license allowing you to change and use "
1145
+ "this version of the plugin for free. Please keep in mind this license covers "
1146
+ "only free edition of the plugin. Premium versions are distributed with other "
1147
+ "type of a license."
1148
+ msgstr ""
1149
+ "Public License это GPLv2-совместимая лицензия, которая позволяет изменять и "
1150
+ "использовать эту версию плагина бесплатно. Пожалуйста, имейте в виду, что "
1151
+ "эта лицензия относиться только к бесплатной редакции плагина. Премимум "
1152
+ "версии плагина распространяются в рамках другой лицензии."
1153
+
1154
+ #: admin/pages/license.php:309
1155
+ msgid ""
1156
+ "You use a paid subscription for the plugin updates. In case you don’t want "
1157
+ "to receive paid updates, please, click <a data-action=\"unsubscribe\" class="
1158
+ "\"wcl-control-btn\" href=\"#\">cancel subscription</a>"
1159
+ msgstr ""
1160
+ "Вы используете платную подписку на обновления плагина, нажмите <a data-"
1161
+ "action=\"unsubscribe\" class=\"wcl-control-btn\" href=\"#\">отменить "
1162
+ "подписку</a>, если вы не хотите больше получать платные обновления"
1163
+
1164
+ #: admin/pages/license.php:314
1165
+ msgid ""
1166
+ "Your license has expired, please extend the license to get updates and "
1167
+ "support."
1168
+ msgstr ""
1169
+ "Срок действия вашей лицензии истек, пожалуйста, продлите лицензию, чтобы "
1170
+ "получать обновления и поддержку."
1171
+
1172
+ #: admin/pages/license.php:322
1173
+ msgid "domain"
1174
+ msgstr "домен"
1175
+
1176
+ #: admin/pages/license.php:326
1177
+ msgid "plan"
1178
+ msgstr "тарифный план"
1179
+
1180
+ #: admin/pages/license.php:330
1181
+ msgid "of"
1182
+ msgstr "до"
1183
+
1184
+ #: admin/pages/license.php:331
1185
+ msgid "active sites"
1186
+ msgstr "активировано"
1187
+
1188
+ #: admin/pages/license.php:336
1189
+ msgid "version"
1190
+ msgstr "версия"
1191
+
1192
+ #: admin/pages/license.php:337
1193
+ msgid "up-to-date"
1194
+ msgstr "текущая версия"
1195
+
1196
+ #: admin/pages/license.php:342
1197
+ msgid "EXPIRED!"
1198
+ msgstr "ИСТЕКЛА!"
1199
+
1200
+ #: admin/pages/license.php:343
1201
+ msgid "please update the key"
1202
+ msgstr "пожалуйста, обновите лицензионный ключ"
1203
+
1204
+ #: admin/pages/license.php:352
1205
+ msgid "day(s)"
1206
+ msgstr "дней"
1207
+
1208
+ #: admin/pages/license.php:354
1209
+ msgid "remained"
1210
+ msgstr "осталось"
1211
+
1212
+ #: admin/pages/license.php:365
1213
+ msgid "Have a key to activate the premium version? Paste it here:"
1214
+ msgstr "Есть ключ для активации премиум версии? Вставьте его здесь:"
1215
+
1216
+ #: admin/pages/license.php:367
1217
+ msgid "Have a key to activate the plugin? Paste it here:"
1218
+ msgstr "Есть ключ для активации плагина? Вставьте его здесь:"
1219
+
1220
+ #: admin/pages/license.php:373
1221
+ msgid "Submit Key"
1222
+ msgstr "Отправить"
1223
+
1224
+ #: admin/pages/license.php:381
1225
+ #, php-format
1226
+ msgid ""
1227
+ "<a href=\"%s\" target=\"_blank\" rel=\"noopener\">Lean more</a> about the "
1228
+ "premium version and get the license key to activate it now!"
1229
+ msgstr ""
1230
+ "Перейдите на <a href=\"%s\" target=\"_blank\" rel=\"noopener\">эту страницу</"
1231
+ "a>, чтобы узнать подробнее как получить лицензионный ключ для премиум версии "
1232
+ "плагина!"
1233
+
1234
+ #: admin/pages/license.php:385
1235
+ #, php-format
1236
+ msgid ""
1237
+ "Can’t find your key? Go to <a href=\"%s\" target=\"_blank\" rel=\"noopener"
1238
+ "\">this page</a> and login using the e-mail address associated with your "
1239
+ "purchase."
1240
+ msgstr ""
1241
+ "Не можете найти свой ключ? Перейдите на <a href=\"%s\" target=\"_blank\" rel="
1242
+ "\"noopener\">эту страницу</a> и авторизуйтесь используя свой email, на "
1243
+ "который вы делали покупку."
1244
+
1245
  #: admin/pages/performance-google.php:46
1246
  msgid "Google services"
1247
  msgstr "Google сервисы"
1321
  msgid "Posts or Pages IDs separated by a ,"
1322
  msgstr "ID записей или страниц, разделенные запятой ,"
1323
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1324
  #: admin/pages/performance.php:41
1325
  msgid "Performance"
1326
  msgstr "Производительность"
1410
 
1411
  #: admin/pages/performance.php:118
1412
  msgid "Removes WordPress Emojis JavaScript file (wp-emoji-release.min.js)."
1413
+ msgstr "Удаляет код Emojis из исходного кода страницы."
1414
 
1415
  #: admin/pages/performance.php:128
1416
  msgid ""
1603
  "конфиденциальности, или если вы просто хотите предотвратить потенциально "
1604
  "глупые или неловкие аватары."
1605
 
1606
+ #: admin/pages/performance.php:265
1607
+ msgid "Disable remove Stylesheet version for auth users"
1608
+ msgstr "Не удалять строки запроса для авторизованных пользователей"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1609
 
1610
  #: admin/pages/quick-start.php:62
1611
  msgid "Clearfy menu"
1615
  msgid "Quick start"
1616
  msgstr "Быстрый старт"
1617
 
1618
+ #: admin/pages/quick-start.php:109
1619
  msgid ""
1620
  "On this page you can quickly configure the plug-in without going into "
1621
  "details."
1623
  "На этой странице вы можете быстро настроить плагин, не вдаваясь в "
1624
  "подробности."
1625
 
 
 
 
 
1626
  #: admin/pages/quick-start.php:187
1627
  msgid "One click code clearing"
1628
  msgstr "Очистка кода в один клик"
1716
  "Во время установки произошла неизвестная ошибка, повторите попытку или "
1717
  "обратитесь в службу поддержки плагинов."
1718
 
1719
+ #: admin/pages/quick-start.php:291
1720
  msgid "Import/Export settings"
1721
  msgstr "Импорт/Экспорт настроек"
1722
 
1723
+ #: admin/pages/quick-start.php:294
1724
  msgid "Import options"
1725
  msgstr "Импортировать настройки"
1726
 
1727
+ #: admin/pages/quick-start.php:300
1728
  msgid "Support"
1729
  msgstr "Поддержка"
1730
 
1731
+ #: admin/pages/quick-start.php:302
1732
  msgid ""
1733
  "If you faced with any issues, please follow the steps below to get quickly "
1734
  "quality support:"
1736
  "Если вы столкнулись с какими-либо проблемами, выполните следующие действия, "
1737
  "чтобы быстро получить качественную поддержку:"
1738
 
1739
+ #: admin/pages/quick-start.php:305
1740
  msgid ""
1741
  "Generate a debug report which will contains inforamtion about your "
1742
  "configuratin and installed plugins"
1744
  "Создайте отчет об ошибках, который будет содержать информацию о вашей "
1745
  "конфигурации и установленных плагинах."
1746
 
1747
+ #: admin/pages/quick-start.php:308
1748
  msgid "Generate Debug Report"
1749
  msgstr "Сгенерировать отчет об ошибках"
1750
 
1751
+ #: admin/pages/quick-start.php:312
1752
  msgid ""
1753
  "Send a message to <b>wordpress.webraftic@gmail.com</b> include the debug "
1754
  "report into the message body."
1756
  "Отправьте ваше сообщение на <b>wordpress.webraftic@gmail.com</b>, к "
1757
  "сообщению прикрепите отчет об ошибках"
1758
 
1759
+ #: admin/pages/quick-start.php:315
1760
  msgid "We guarantee to respond you within 7 business day."
1761
  msgstr "Мы гарантируем ответ на ваш вопрос в течении 7 дней."
1762
 
1925
  "WordPress не знает, как отдать заголовок Last Modified. Вы можете сделать "
1926
  "это с помощью параметров ниже."
1927
 
1928
+ #: admin/pages/seo.php:129
1929
+ msgid "Disable Last Modified header on front page"
1930
+ msgstr "Отключить заголовок Last Modified для главной странице"
1931
+
1932
+ #: admin/pages/seo.php:139
1933
  #, php-format
1934
  msgid ""
1935
  "You can specify a page mask, for example: %s or %s. All pages that contain "
1939
  "содержат эти строки, будут исключены. Каждое исключение должно начинаться с "
1940
  "новой строки."
1941
 
1942
+ #: admin/pages/seo.php:153
1943
  msgid "For the Yoast SEO plugin"
1944
  msgstr "Для плагина Yoast SEO"
1945
 
1946
+ #: admin/pages/seo.php:153
1947
  msgid ""
1948
  "These settings will help you eliminate some problems associated with the "
1949
  "popular Yoast SEO plugin"
1951
  "Эти параметры помогут вам устранить некоторые проблемы, связанные с "
1952
  "популярной Yoast SEO plugin"
1953
 
1954
+ #: admin/pages/seo.php:162
1955
  msgid ""
1956
  "The last element in the breadcrumbs in the Yoast SEO plugin duplicates the "
1957
  "title of the article. Some SEO-specialists consider this duplication to be "
1960
  "Последний элемент в хлебных крошках Yoast SEO дублирует название статьи. "
1961
  "Некоторые SEO-специалисты считают это дублирование излишним."
1962
 
1963
+ #: admin/pages/seo.php:162
1964
  msgid ""
1965
  "Removes duplication of the name in the breadcrumbs of the WP SEO plugin from "
1966
  "Yoast."
1967
  msgstr "Удаляет последний элемент в хлебных крошках Yoast SEO."
1968
 
1969
+ #: admin/pages/seo.php:172
1970
  msgid ""
1971
  "Yandex.Webmaster swears on a standard XML card from the plugin Yoast, tk. it "
1972
  "has a specific tag"
1974
  "Яндекс вебмастер ругается на стандартной карты XML из плагина Yoast SEO, из-"
1975
  "за определенного тега "
1976
 
1977
+ #: admin/pages/seo.php:172
1978
  #, php-format
1979
  msgid "Remove the tag %s from XML site map of the plugin Yoast SEO."
1980
  msgstr "Удаляет тег %s из XML карта сайта плагин Yoast SEO."
1981
 
1982
+ #: admin/pages/seo.php:172
1983
  msgid ""
1984
  "Attention! After activation, turn off the site map and enable it back to "
1985
  "regenerate it."
1987
  "Внимание! После активации, выключите карту сайта и включите ее обратно, "
1988
  "чтобы обновить ее."
1989
 
1990
+ #: admin/pages/seo.php:172
1991
  msgid "In older versions of Yoast SEO may not work - update the plugin Yoast"
1992
  msgstr ""
1993
  "В более старых версиях Yoast SEO не может работать - обновите плагин Yoast "
1994
  "SEO"
1995
 
1996
+ #: admin/pages/seo.php:190
1997
  msgid ""
1998
  "If you’re not familiar with Search Action it’s the mark-up that helps search "
1999
  "engines add a shiny Sitelinks Search Box below your search engine results. "
2008
  "нужна. Особенно, если на сайте всего несколько страниц или есть собственный "
2009
  "поиск, который ищет только записи блога, но не страницы."
2010
 
2011
+ #: admin/pages/seo.php:190
2012
  msgid ""
2013
  "Disable JSON-LD sitelinks searchbox using WordPress in plugin Yoast SEO."
2014
  msgstr "Отключает JSON-LD ссылки используемые Wordpress в плагине Yoast SEO."
2015
 
2016
+ #: admin/pages/seo.php:200
2017
  msgid ""
2018
  "Prevents output of the script tag of type application/ld+json containing\n"
2019
  "schema.org data from the popular Yoast SEO and Yoast SEO Premium plugins.\n"
2023
  "schema.org о сайте и его владельце. Эту ссылку создают популярные плагины "
2024
  "Yoast SEO и Yoast SEO Premium"
2025
 
2026
+ #: admin/pages/seo.php:202
2027
  msgid "Disable Structured Data in plugin Yoast SEO."
2028
+ msgstr "Отключает структурированные данные в плагине Yoast SEO."
2029
 
2030
+ #: admin/pages/seo.php:212
2031
  #, php-format
2032
  msgid "The Yoast SEO plugin displays a comment of the form %s in %s section"
2033
  msgstr "Yoast SEO плагин отображает комментарий формы %s в секции %s"
2034
 
2035
+ #: admin/pages/seo.php:212
2036
  #, php-format
2037
  msgid "Removes the Yoast SEO plugin comment of their section %s"
2038
  msgstr "Удаляет комментрии Yoast SEO из %s"
2061
  "всего, то отключение неиспользуемого функционала — первый шаг к его "
2062
  "оптимизации и ускорению."
2063
 
2064
+ #: clearfy.php:67 includes/boot.php:50
2065
  msgid "Clearfy"
2066
  msgstr "Clearfy"
2067
 
2073
  msgid "Welcome"
2074
  msgstr "Добро пожаловать"
2075
 
 
 
 
 
 
 
 
 
 
 
 
 
2076
  #: includes/classes/class.configurate-security.php:51
2077
  msgid "<strong>ERROR</strong>: Wrong login or password"
2078
  msgstr "<strong>Ошибка</strong>: Неправильный логин или пароль"
2079
 
2080
+ #: includes/classes/class.licensing.php:207
2081
+ msgid "The license is deactivated."
2082
+ msgstr "Лицензия деактивирована."
2083
+
2084
+ #: includes/classes/class.licensing.php:225
2085
+ #: includes/classes/class.licensing.php:244
2086
+ #: includes/classes/class.licensing.php:281
2087
+ msgid "The license has been updated."
2088
+ msgstr "Лицензия обновлена."
2089
+
2090
+ #: includes/classes/class.licensing.php:349
2091
+ msgid "Your license has been successfully activated."
2092
+ msgstr "Ваша лицензия успешно активирована."
2093
+
2094
+ #: includes/classes/class.package.php:245
2095
+ msgid ""
2096
+ "Updates are available for one of the components. Please, update your current "
2097
+ "package of components to the newest version."
2098
+ msgstr ""
2099
+ "Для одного из компонентов доступны обновления, пожалуйста, обновите текущую "
2100
+ "сборку компонентов до актуальной версии."
2101
+
2102
+ #: includes/classes/class.package.php:248
2103
+ msgid ""
2104
+ "You’ve changed the component configuration. For the further work, please, "
2105
+ "update the current package of components!"
2106
+ msgstr ""
2107
+ "Вы изменили конфигурацию компонентов, для работы плагина нужно обновить "
2108
+ "текущую сборку компонентов!"
2109
+
2110
+ #: includes/classes/class.package.php:250
2111
+ msgid "Update now"
2112
+ msgstr "Обновить сейчас"
2113
+
2114
  #: includes/classes/class.zip-archive.php:15
2115
  msgid "The ZipArchive class does not exist in this version of php."
2116
  msgstr "Класса ZipArchive не существует в этой версии php."
2117
 
2118
+ #~ msgid "Welcome to Clearfy (%s)"
2119
+ #~ msgstr "Вас приветствует Clearfy (%s)"
2120
+
2121
+ #~ msgid ""
2122
+ #~ "There are new optimization and protection features in the plugin. We "
2123
+ #~ "recommend you to look at them maybe they will be useful!"
2124
+ #~ msgstr ""
2125
+ #~ "В плагине появились новые функции оптимизации и защиты. Мы рекомендуем "
2126
+ #~ "вам ознакомится с ними, возможно они будут полезны!"
2127
+
2128
+ #~ msgid "The section \"Code cleaning\" was renamed"
2129
+ #~ msgstr "Переименован раздел \"Очистка кода\""
2130
+
2131
+ #~ msgid ""
2132
+ #~ "Asynchronous Google fonts loading, Google Analytics optimization, "
2133
+ #~ "disabling Google Fonts and Maps, disabling of gravatars, Font Awesome "
2134
+ #~ "icons was added."
2135
+ #~ msgstr ""
2136
+ #~ "Добавлена асинхронная загрузка Google шрифтов, оптимизация Google "
2137
+ #~ "Analytics, отключение Google шрифтов и карт, отключение граваторов, "
2138
+ #~ "иконок Font Awesome."
2139
+
2140
+ #~ msgid "Login page protection added"
2141
+ #~ msgstr "Добавлена защита страницы логина"
2142
+
2143
+ #~ msgid ""
2144
+ #~ "With the new Clearfy version, you can use the hide login page function. "
2145
+ #~ "Nobody will know the address of your login page, which means there will "
2146
+ #~ "be no password bruteforce and the attempts of your website hack will "
2147
+ #~ "decrease."
2148
+ #~ msgstr ""
2149
+ #~ "В новой версии Clearfy, вы можете использовать функции скрытия страницы "
2150
+ #~ "логина. Никто не узнает адрес вашей страницы логина, а значит не будет "
2151
+ #~ "переборов пароля и уменьшатся попытки взлома вашего сайта."
2152
+
2153
+ #~ msgid "Google analytic cache"
2154
+ #~ msgstr "Кеш Google аналитики"
2155
+
2156
+ #~ msgid "Google analytic Code"
2157
+ #~ msgstr "Код Google аналитики"
2158
+
2159
+ #~ msgid "Use adjusted bounce rate?"
2160
+ #~ msgstr "Показатель отказов?"
2161
+
2162
+ #~ msgid "Change enqueue order?"
2163
+ #~ msgstr "Сортировка скрипта?"
2164
+
2165
+ #~ msgid "Disable all display features functionality?"
2166
+ #~ msgstr "Отключить все функции для контекстно-медийной сети?"
2167
+
2168
+ #~ msgid "Use Anonymize IP? (Required by law for some countries)"
2169
+ #~ msgstr ""
2170
+ #~ "Использовать анонимный IP-адрес? (Требуется по закону для некоторых стран)"
2171
+
2172
+ #~ msgid "Track logged in Administrators?"
2173
+ #~ msgstr "Отслеживать, если вы авторизованы под администратором?"
2174
+
2175
+ #~ msgid "Remove script from wp-cron?"
2176
+ #~ msgstr "Удалить кеширования скрипта из крона?"
2177
+
2178
+ #~ msgid "HTML minify"
2179
+ #~ msgstr "Html сжатие"
2180
+
2181
+ #~ msgid "Redirect Http to Https"
2182
+ #~ msgstr "Перенаправление Http на Https"
2183
+
2184
+ #~ msgid "Privacy Wordpress"
2185
+ #~ msgstr "Приватный Wordpress"
2186
+
2187
+ #~ msgid ""
2188
+ #~ "This component is to protect your site, Wordpress runs private mode. "
2189
+ #~ "Nobody will know that you will use Wordpress!"
2190
+ #~ msgstr ""
2191
+ #~ "Этот компонент предназначен для защиты вашего сайта, Wordpress работает в "
2192
+ #~ "приватном режиме. Никто не будет знать, что вы будете использовать "
2193
+ #~ "Wordpress!"
2194
+
2195
+ #~ msgid "Code privacy"
2196
+ #~ msgstr "Приватный код"
2197
+
2198
+ #~ msgid "<strong>Hide WordPress plugins versions</strong>."
2199
+ #~ msgstr "<strong>Скрыть версии Wordpress и плагинов</strong>."
2200
+
2201
+ #~ msgid "<strong>Google Analytics cache</strong>."
2202
+ #~ msgstr "<strong>Кеширование Google аналитики</strong>."
2203
+
2204
+ #~ msgid ""
2205
+ #~ "To improve Google Page Speed indicators Analytics caching is needed. "
2206
+ #~ "However, it can also slightly increase your website loading speed, "
2207
+ #~ "because Analytics js files will load locally. The second case that you "
2208
+ #~ "might need these settings is the usual Google Analytics connection to "
2209
+ #~ "your website. You do not need to do this with other plugins or insert the "
2210
+ #~ "tracking code into your theme."
2211
+ #~ msgstr ""
2212
+ #~ "Кеширование Analytics нужно для улучшения показателей Google Page Speed, "
2213
+ #~ "но это также может незначительно повысить скорость загрузки вашего сайта, "
2214
+ #~ "потому что js файлы Analytics будут подгружаться локально. Второй случай, "
2215
+ #~ "когда вам могут понадобиться эти настройки — обычное подключение Google "
2216
+ #~ "Analytics к сайту. Вам не нужно делать это с помощью других плагинов или "
2217
+ #~ "просто вставлять код отслеживания в вашу тему."
2218
+
2219
+ #~ msgid ""
2220
+ #~ "If you enable this option, the plugin will begin to save a local copy of "
2221
+ #~ "Google Analytics to speed up the loading of your website and improve "
2222
+ #~ "Google Page Speed."
2223
+ #~ msgstr ""
2224
+ #~ "Если включить эту опцию, плагин начнет сохранять локальную копию Google "
2225
+ #~ "Analytics, чтобы ускорить загрузку вашего сайта и улучшить показатели "
2226
+ #~ "Google Page speed. ВНИМАНИЕ! Перед использованием этой опции, удалите "
2227
+ #~ "ранее установленный код Google Analytics в вашей теме или плагины, "
2228
+ #~ "связанные с этой функцией!"
2229
+
2230
+ #~ msgid ""
2231
+ #~ "ATTENTION! Before using this option, remove the previously installed "
2232
+ #~ "Google Analytics code inside your theme or plugins associated with this "
2233
+ #~ "feature!"
2234
+ #~ msgstr ""
2235
+ #~ "ВНИМАНИЕ! Перед использованием этой опции, удалите ранее установленный "
2236
+ #~ "код Google Analytics в вашей теме или плагины, связанные с этой функцией!"
2237
+
2238
+ #~ msgid "Set the Google Analytics tracking code."
2239
+ #~ msgstr "Установите код отслеживания Google Analytics."
2240
+
2241
+ #~ msgid "Save GA in"
2242
+ #~ msgstr "Использовать код аналитики в"
2243
+
2244
+ #~ msgid "Select location for the Google Analytics code."
2245
+ #~ msgstr "Выберите местоположение для кода Google Analytics."
2246
+
2247
+ #~ msgid ""
2248
+ #~ "Essentially, you set up an event which is triggered after a user spends a "
2249
+ #~ "certain amount of time on the landing page, telling Google Analytics not "
2250
+ #~ "to count these users as bounces. A user may come to your website, find "
2251
+ #~ "all of the information they need (a phone number, for example) and then "
2252
+ #~ "leave the site without visiting another page. Without adjusted bounce "
2253
+ #~ "rate, such a user would be considered a bounce, even though they had a "
2254
+ #~ "successful experience. By defining a time limit after which you can "
2255
+ #~ "consider a user to be \"engaged,\" that user would no longer count as a "
2256
+ #~ "bounce, and you'd get a more accurate idea of whether they found what "
2257
+ #~ "they were looking for."
2258
+ #~ msgstr ""
2259
+ #~ "По сути, вы настраиваете событие, которое запускается после того, как "
2260
+ #~ "пользователь тратит определенное количество времени на целевую страницу, "
2261
+ #~ "сообщая Google Analytics не считать этих пользователей как отказы. "
2262
+ #~ "Пользователь может зайти на ваш сайт, найти всю необходимую информацию "
2263
+ #~ "(например, номер телефона), а затем покинуть сайт, не посещая другую "
2264
+ #~ "страницу. Без скорректированного коэффициента отказов такой пользователь "
2265
+ #~ "будет считаться отказом, хотя у них был успешный опыт. Определив лимит "
2266
+ #~ "времени, после которого вы можете считать пользователя «включенным», этот "
2267
+ #~ "пользователь больше не будет считаться отказом, и вы получите более "
2268
+ #~ "точное представление о том, нашли ли они то, что искали."
2269
+
2270
+ #~ msgid ""
2271
+ #~ "By default, Google Analytics code is loaded before other scripts and "
2272
+ #~ "javasscript code, but if you set the value to 100, the GA code will be "
2273
+ #~ "loaded after all other scripts. By changing the priority, you can set "
2274
+ #~ "code position on the page."
2275
+ #~ msgstr ""
2276
+ #~ "По умолчанию код Google Analytics загружается раньше остальных скриптов и "
2277
+ #~ "javasscript кода, но если вы установите к примеру значение 100, то код GA "
2278
+ #~ "будет загружен после всех остальных скриптов. Изменяя приоритет, вы "
2279
+ #~ "можете задавать положение кода на странице."
2280
+
2281
+ #~ msgid "Disable all <a href=\"%s\">display features functionality?</a>"
2282
+ #~ msgstr ""
2283
+ #~ "Отключить <a href=\"%s\">все функции для контекстно-медийной сети?</a>"
2284
+
2285
+ #~ msgid ""
2286
+ #~ "Use <a href=\"%s\">Anonymize IP?</a> (Required by law for some countries)"
2287
+ #~ msgstr ""
2288
+ #~ "Использовать <a href=\"%s\">анонимный IP-адрес?</a> (Требуется по закону "
2289
+ #~ "для некоторых стран)"
2290
+
2291
+ #~ msgid ""
2292
+ #~ "Clearfy creates a cron job to daily update Google Analytics cache "
2293
+ #~ "scripts. After enabling this option, the plugin will not update Google "
2294
+ #~ "Analytics cache file. Do not use this option if you do not understand why "
2295
+ #~ "you need it!"
2296
+ #~ msgstr ""
2297
+ #~ "Плагин создает cron задание, чтобы ежедневно обновлять кеш скриптов "
2298
+ #~ "Google Analytics. После включения этой опции, плагин не будет обновлять "
2299
+ #~ "кэш файл Google Analytics. Не используйте эту опцию, если вы не "
2300
+ #~ "понимаете, для чего вам это нужно!"
2301
+
2302
+ #~ msgid "Html Minify"
2303
+ #~ msgstr "Html сжатие"
2304
+
2305
+ #~ msgid ""
2306
+ #~ "<strong>Make your website’s markup look professional by using Minify HTML "
2307
+ #~ "options</strong>."
2308
+ #~ msgstr ""
2309
+ #~ "<strong>Уменьшите вес ваших страниц, за счет удаления лишнего мусора, "
2310
+ #~ "пробелов и комментариев.</strong>."
2311
+
2312
+ #~ msgid ""
2313
+ #~ "Ever look at the HTML markup of your website and notice how sloppy and "
2314
+ #~ "amateurish it looks? The Minify HTML options cleans up sloppy looking "
2315
+ #~ "markup and minifies, which also speeds up download time."
2316
+ #~ msgstr ""
2317
+ #~ "Вы когда-нибудь видели HTML разметку на своем веб-сайте, замечали "
2318
+ #~ "насколько она неаккуратна и раздута? Настройки HTML сжатия позволят "
2319
+ #~ "грамотно установить правила формирования html разметки, а также "
2320
+ #~ "регулировать вес ваших страниц."
2321
+
2322
+ #~ msgid ""
2323
+ #~ "Reduces the weight of the page by removing line breaks, tabs, spaces, etc."
2324
+ #~ msgstr ""
2325
+ #~ "Уменьшает вес страницы путем удаления разрывов строк, вкладок, пробелов и "
2326
+ #~ "т. Д."
2327
+
2328
+ #~ msgid "Minify pages."
2329
+ #~ msgstr "Минимизировать страницы."
2330
+
2331
+ #~ msgid "Minify inline JavaScript"
2332
+ #~ msgstr "Сжимать строчный JavaScript"
2333
+
2334
+ #~ msgid "Remove HTML, JavaScript and CSS comments"
2335
+ #~ msgstr "Удалять HTML, JavaScript and CSS комментарии"
2336
+
2337
+ #~ msgid "Remove XHTML closing tags from HTML5 void elements"
2338
+ #~ msgstr "Удалить XHTML закрывающие теги из HTML5 для пустых элементов"
2339
+
2340
+ #~ msgid "Remove relative domain from internal URLs"
2341
+ #~ msgstr "Удалить относительные домены из внутренних Urls"
2342
+
2343
+ #~ msgid "Remove schemes (HTTP: and HTTPS:) from all URLs"
2344
+ #~ msgstr "Удалить протоколы (HTTP: и HTTPS:) для всех URLs"
2345
+
2346
+ #~ msgid "Support multi-byte UTF-8 encoding (if you see odd characters)"
2347
+ #~ msgstr "Поддержка многобайтовой кодировки UTF-8 (для кириллицы)"
2348
+
2349
+ #~ msgid "Set the recommened for me"
2350
+ #~ msgstr "Установить рекомендуемые для меня"
2351
+
2352
+ #~ msgid "Once Weekly"
2353
+ #~ msgstr "Один раз в неделю"
2354
+
2355
+ #~ msgid "Twice Monthly"
2356
+ #~ msgstr "Дважды в месяц"
2357
+
2358
+ #~ msgid "Once Monthly"
2359
+ #~ msgstr "Один раз в месяц"
2360
+
2361
  #~ msgid "Hide wp-admin"
2362
  #~ msgstr "Скрыть wp-admin"
2363
 
libs/factory/bootstrap/assets/css-min/bootstrap.accordion.min.css CHANGED
@@ -8,4 +8,4 @@
8
  */
9
 
10
 
11
- .factory-bootstrap-400 .factory-accordion{margin:0 0 30px;border-top:1px solid #DDD;border-right:1px solid #DDD;border-left:1px solid #DDD;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.factory-bootstrap-400 .factory-accordion>h3{border-bottom:1px solid #DDD;cursor:pointer;padding:8px 15px;margin:0}.factory-bootstrap-400 .factory-accordion>div{display:none;margin:0;border-bottom:1px solid #DDD}.factory-bootstrap-400 .factory-accordion-item{display:none}.factory-bootstrap-400 .inner-factory-accordion-item{padding:10px 0}.factory-bootstrap-400 .factory-accordion>h3.active:hover{cursor:default}
8
  */
9
 
10
 
11
+ .factory-bootstrap-406 .factory-accordion{margin:0 0 30px;border-top:1px solid #DDD;border-right:1px solid #DDD;border-left:1px solid #DDD;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.factory-bootstrap-406 .factory-accordion>h3{border-bottom:1px solid #DDD;cursor:pointer;padding:8px 15px;margin:0}.factory-bootstrap-406 .factory-accordion>div{display:none;margin:0;border-bottom:1px solid #DDD}.factory-bootstrap-406 .factory-accordion-item{display:none}.factory-bootstrap-406 .inner-factory-accordion-item{padding:10px 0}.factory-bootstrap-406 .factory-accordion>h3.active:hover{cursor:default}
libs/factory/bootstrap/assets/css-min/bootstrap.blue.min.css CHANGED
@@ -8,4 +8,4 @@
8
  */
9
 
10
 
11
- .factory-bootstrap-400 .btn-primary{background:#e1a948;border-color:#d39323;color:#fff;-webkit-box-shadow:inset 0 1px 0 #ecc88a,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #ecc88a,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-400 .btn-primary:focus,.factory-bootstrap-400 .btn-primary:hover{background:#db9825;border-color:#bd831f;color:#fff;-webkit-box-shadow:inset 0 1px 0 #e8be74,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #e8be74,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-400 .btn-primary:active{background:#db9825;border-color:#bd831f;color:#fff;-webkit-box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5);box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5)}.factory-bootstrap-400 .btn-primary:disabled,.factory-bootstrap-400 .btn-primary[disabled]{color:#d1cdc7!important;background:#db9825!important;border-color:#bd831f!important;text-shadow:none!important}.factory-bootstrap-400 .btn-group .btn.active.value{background-color:#e1a948;-webkit-box-shadow:inset 0 1px 2px #d39323;box-shadow:inset 0 1px 2px #d39323;border-top:1px solid #d39323;border-bottom:1px solid #d39323;border-left:1px solid #d39323}.factory-bootstrap-400 .pagination>.active>a,.factory-bootstrap-400 .pagination>.active>a:focus,.factory-bootstrap-400 .pagination>.active>a:hover,.factory-bootstrap-400 .pagination>.active>span,.factory-bootstrap-400 .pagination>.active>span:focus,.factory-bootstrap-400 .pagination>.active>span:hover{background-color:#e1a948;border-color:#d39323}
8
  */
9
 
10
 
11
+ .factory-bootstrap-406 .btn-primary{background:#e1a948;border-color:#d39323;color:#fff;-webkit-box-shadow:inset 0 1px 0 #ecc88a,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #ecc88a,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-406 .btn-primary:focus,.factory-bootstrap-406 .btn-primary:hover{background:#db9825;border-color:#bd831f;color:#fff;-webkit-box-shadow:inset 0 1px 0 #e8be74,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #e8be74,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-406 .btn-primary:active{background:#db9825;border-color:#bd831f;color:#fff;-webkit-box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5);box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5)}.factory-bootstrap-406 .btn-primary:disabled,.factory-bootstrap-406 .btn-primary[disabled]{color:#d1cdc7!important;background:#db9825!important;border-color:#bd831f!important;text-shadow:none!important}.factory-bootstrap-406 .btn-group .btn.active.value{background-color:#e1a948;-webkit-box-shadow:inset 0 1px 2px #d39323;box-shadow:inset 0 1px 2px #d39323;border-top:1px solid #d39323;border-bottom:1px solid #d39323;border-left:1px solid #d39323}.factory-bootstrap-406 .pagination>.active>a,.factory-bootstrap-406 .pagination>.active>a:focus,.factory-bootstrap-406 .pagination>.active>a:hover,.factory-bootstrap-406 .pagination>.active>span,.factory-bootstrap-406 .pagination>.active>span:focus,.factory-bootstrap-406 .pagination>.active>span:hover{background-color:#e1a948;border-color:#d39323}
libs/factory/bootstrap/assets/css-min/bootstrap.coffee.min.css CHANGED
@@ -8,4 +8,4 @@
8
  */
9
 
10
 
11
- .factory-bootstrap-400 .btn-primary{background:#c7a589;border-color:#b78a66;color:#fff;-webkit-box-shadow:inset 0 1px 0 #e0cdbd,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #e0cdbd,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-400 .btn-primary:focus,.factory-bootstrap-400 .btn-primary:hover{background:#ba906d;border-color:#ae7d55;color:#fff;-webkit-box-shadow:inset 0 1px 0 #d7bfac,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #d7bfac,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-400 .btn-primary:active{background:#ba906d;border-color:#ae7d55;color:#fff;-webkit-box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5);box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5)}.factory-bootstrap-400 .btn-primary:disabled,.factory-bootstrap-400 .btn-primary[disabled]{color:#d1cbc7!important;background:#ba906d!important;border-color:#ae7d55!important;text-shadow:none!important}.factory-bootstrap-400 .btn-group .btn.active.value{background-color:#c7a589;-webkit-box-shadow:inset 0 1px 2px #b78a66;box-shadow:inset 0 1px 2px #b78a66;border-top:1px solid #b78a66;border-bottom:1px solid #b78a66;border-left:1px solid #b78a66}.factory-bootstrap-400 .pagination>.active>a,.factory-bootstrap-400 .pagination>.active>a:focus,.factory-bootstrap-400 .pagination>.active>a:hover,.factory-bootstrap-400 .pagination>.active>span,.factory-bootstrap-400 .pagination>.active>span:focus,.factory-bootstrap-400 .pagination>.active>span:hover{background-color:#c7a589;border-color:#b78a66}
8
  */
9
 
10
 
11
+ .factory-bootstrap-406 .btn-primary{background:#c7a589;border-color:#b78a66;color:#fff;-webkit-box-shadow:inset 0 1px 0 #e0cdbd,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #e0cdbd,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-406 .btn-primary:focus,.factory-bootstrap-406 .btn-primary:hover{background:#ba906d;border-color:#ae7d55;color:#fff;-webkit-box-shadow:inset 0 1px 0 #d7bfac,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #d7bfac,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-406 .btn-primary:active{background:#ba906d;border-color:#ae7d55;color:#fff;-webkit-box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5);box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5)}.factory-bootstrap-406 .btn-primary:disabled,.factory-bootstrap-406 .btn-primary[disabled]{color:#d1cbc7!important;background:#ba906d!important;border-color:#ae7d55!important;text-shadow:none!important}.factory-bootstrap-406 .btn-group .btn.active.value{background-color:#c7a589;-webkit-box-shadow:inset 0 1px 2px #b78a66;box-shadow:inset 0 1px 2px #b78a66;border-top:1px solid #b78a66;border-bottom:1px solid #b78a66;border-left:1px solid #b78a66}.factory-bootstrap-406 .pagination>.active>a,.factory-bootstrap-406 .pagination>.active>a:focus,.factory-bootstrap-406 .pagination>.active>a:hover,.factory-bootstrap-406 .pagination>.active>span,.factory-bootstrap-406 .pagination>.active>span:focus,.factory-bootstrap-406 .pagination>.active>span:hover{background-color:#c7a589;border-color:#b78a66}
libs/factory/bootstrap/assets/css-min/bootstrap.core.min.css CHANGED
@@ -8,7 +8,7 @@
8
  */
9
 
10
 
11
- .factory-bootstrap-400 article,.factory-bootstrap-400 aside,.factory-bootstrap-400 details,.factory-bootstrap-400 figcaption,.factory-bootstrap-400 figure,.factory-bootstrap-400 footer,.factory-bootstrap-400 header,.factory-bootstrap-400 hgroup,.factory-bootstrap-400 main,.factory-bootstrap-400 nav,.factory-bootstrap-400 section,.factory-bootstrap-400 summary{display:block}.factory-bootstrap-400 audio,.factory-bootstrap-400 canvas,.factory-bootstrap-400 video{display:inline-block}.factory-bootstrap-400 audio:not([controls]){display:none;height:0}.factory-bootstrap-400 [hidden],.factory-bootstrap-400 template{display:none}.factory-bootstrap-400 body{margin:0}.factory-bootstrap-400 a{background:0 0}.factory-bootstrap-400 a:focus{outline:thin dotted}.factory-bootstrap-400 a:active,.factory-bootstrap-400 a:hover{outline:0}.factory-bootstrap-400 h1{margin:.67em 0}.factory-bootstrap-400 b,.factory-bootstrap-400 strong{font-weight:700}.factory-bootstrap-400 dfn{font-style:italic}.factory-bootstrap-400 hr{height:0;-moz-box-sizing:content-box;box-sizing:content-box}.factory-bootstrap-400 mark{color:#000;background:#ff0}.factory-bootstrap-400 code,.factory-bootstrap-400 kbd,.factory-bootstrap-400 pre,.factory-bootstrap-400 samp{font-size:1em}.factory-bootstrap-400 pre{white-space:pre-wrap}.factory-bootstrap-400 q{quotes:"\201C" "\201D" "\2018" "\2019"}.factory-bootstrap-400 sub,.factory-bootstrap-400 sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}.factory-bootstrap-400 sup{top:-.5em}.factory-bootstrap-400 sub{bottom:-.25em}.factory-bootstrap-400 img{border:0}.factory-bootstrap-400 svg:not(:root){overflow:hidden}.factory-bootstrap-400 figure{margin:0}.factory-bootstrap-400 button,.factory-bootstrap-400 input,.factory-bootstrap-400 select,.factory-bootstrap-400 textarea{margin:0}.factory-bootstrap-400 button,.factory-bootstrap-400 select{text-transform:none}.factory-bootstrap-400 select{padding-right:4px!important}.factory-bootstrap-400 button,.factory-bootstrap-400 input[type=reset],.factory-bootstrap-400 input[type=submit],html .factory-bootstrap-400 input[type=button]{cursor:pointer;-webkit-appearance:button}.factory-bootstrap-400 button[disabled],html .factory-bootstrap-400 input[disabled]{cursor:default}.factory-bootstrap-400 input[type=checkbox],.factory-bootstrap-400 input[type=radio]{padding:0;box-sizing:border-box}.factory-bootstrap-400 input[type=search]{-webkit-appearance:textfield}.factory-bootstrap-400 input[type=search]::-webkit-search-cancel-button,.factory-bootstrap-400 input[type=search]::-webkit-search-decoration{-webkit-appearance:none}.factory-bootstrap-400 button::-moz-focus-inner,.factory-bootstrap-400 input::-moz-focus-inner{padding:0;border:0}.factory-bootstrap-400 textarea{overflow:auto;vertical-align:top}.factory-bootstrap-400 table{border-collapse:collapse;border-spacing:0}@media print{.factory-bootstrap-400 *{color:#000!important;text-shadow:none!important;background:transparent!important;box-shadow:none!important}.factory-bootstrap-400 a,.factory-bootstrap-400 a:visited{text-decoration:underline}.factory-bootstrap-400 a[href]:after{content:" (" attr(href) ")"}.factory-bootstrap-400 abbr[title]:after{content:" (" attr(title) ")"}.factory-bootstrap-400 a[href^="javascript:"]:after,.factory-bootstrap-400 a[href^="#"]:after{content:""}.factory-bootstrap-400 blockquote,.factory-bootstrap-400 pre{border:1px solid #999;page-break-inside:avoid}.factory-bootstrap-400 thead{display:table-header-group}.factory-bootstrap-400 img,.factory-bootstrap-400 tr{page-break-inside:avoid}.factory-bootstrap-400 img{max-width:100%!important}@page{margin:2cm .5cm}.factory-bootstrap-400 h2,.factory-bootstrap-400 h3,.factory-bootstrap-400 p{orphans:3;widows:3}.factory-bootstrap-400 h2,.factory-bootstrap-400 h3{page-break-after:avoid}.factory-bootstrap-400 select{background:#fff!important}.factory-bootstrap-400 .navbar{display:none}.factory-bootstrap-400 .table td,.factory-bootstrap-400 .table th{background-color:#fff!important}.factory-bootstrap-400 .btn>.caret,.factory-bootstrap-400 .dropup>.btn>.caret{border-top-color:#000!important}.factory-bootstrap-400 .label{border:1px solid #000}.factory-bootstrap-400 .table{border-collapse:collapse!important}.factory-bootstrap-400 .table-bordered td,.factory-bootstrap-400 .table-bordered th{border:1px solid #ddd!important}}.factory-bootstrap-400 *,.factory-bootstrap-400 :after,.factory-bootstrap-400 :before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html .factory-bootstrap-400{-webkit-tap-highlight-color:rgba(0,0,0,0)}.factory-bootstrap-400 body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.428571429;color:#333;background-color:#fff}.factory-bootstrap-400 button,.factory-bootstrap-400 input,.factory-bootstrap-400 select,.factory-bootstrap-400 textarea{font-family:inherit;font-size:inherit;line-height:inherit}.factory-bootstrap-400 img{vertical-align:middle}.factory-bootstrap-400 .img-responsive{display:block;height:auto;max-width:100%}.factory-bootstrap-400 .img-rounded{border-radius:6px}.factory-bootstrap-400 .img-thumbnail{display:inline-block;height:auto;max-width:100%;padding:4px;line-height:1.428571429;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.factory-bootstrap-400 .img-circle{border-radius:50%}.factory-bootstrap-400 hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.factory-bootstrap-400 .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.factory-bootstrap-400 .h1,.factory-bootstrap-400 .h2,.factory-bootstrap-400 .h3,.factory-bootstrap-400 .h4,.factory-bootstrap-400 .h5,.factory-bootstrap-400 .h6,.factory-bootstrap-400 h1,.factory-bootstrap-400 h2,.factory-bootstrap-400 h3,.factory-bootstrap-400 h4,.factory-bootstrap-400 h5,.factory-bootstrap-400 h6{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:500;line-height:1.1;color:inherit}.factory-bootstrap-400 .h1 .small,.factory-bootstrap-400 .h1 small,.factory-bootstrap-400 .h2 .small,.factory-bootstrap-400 .h2 small,.factory-bootstrap-400 .h3 .small,.factory-bootstrap-400 .h3 small,.factory-bootstrap-400 .h4 .small,.factory-bootstrap-400 .h4 small,.factory-bootstrap-400 .h5 .small,.factory-bootstrap-400 .h5 small,.factory-bootstrap-400 .h6 .small,.factory-bootstrap-400 .h6 small,.factory-bootstrap-400 h1 .small,.factory-bootstrap-400 h1 small,.factory-bootstrap-400 h2 .small,.factory-bootstrap-400 h2 small,.factory-bootstrap-400 h3 .small,.factory-bootstrap-400 h3 small,.factory-bootstrap-400 h4 .small,.factory-bootstrap-400 h4 small,.factory-bootstrap-400 h5 .small,.factory-bootstrap-400 h5 small,.factory-bootstrap-400 h6 .small,.factory-bootstrap-400 h6 small{font-weight:400;line-height:1;color:#999}.factory-bootstrap-400 h1,.factory-bootstrap-400 h2,.factory-bootstrap-400 h3{margin-top:20px;margin-bottom:10px}.factory-bootstrap-400 h1 .small,.factory-bootstrap-400 h1 small,.factory-bootstrap-400 h2 .small,.factory-bootstrap-400 h2 small,.factory-bootstrap-400 h3 .small,.factory-bootstrap-400 h3 small{font-size:65%}.factory-bootstrap-400 h4,.factory-bootstrap-400 h5,.factory-bootstrap-400 h6{margin-top:10px;margin-bottom:10px}.factory-bootstrap-400 h4 .small,.factory-bootstrap-400 h4 small,.factory-bootstrap-400 h5 .small,.factory-bootstrap-400 h5 small,.factory-bootstrap-400 h6 .small,.factory-bootstrap-400 h6 small{font-size:75%}.factory-bootstrap-400 .h1,.factory-bootstrap-400 h1{font-size:36px}.factory-bootstrap-400 .h2,.factory-bootstrap-400 h2{font-size:30px}.factory-bootstrap-400 .h3,.factory-bootstrap-400 h3{font-size:24px}.factory-bootstrap-400 .h4,.factory-bootstrap-400 h4{font-size:18px}.factory-bootstrap-400 .h5,.factory-bootstrap-400 h5{font-size:14px}.factory-bootstrap-400 .h6,.factory-bootstrap-400 h6{font-size:12px}.factory-bootstrap-400 p{margin:0 0 10px}.factory-bootstrap-400 .lead{margin-bottom:20px;font-size:16px;font-weight:200;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.factory-bootstrap-400 .small,.factory-bootstrap-400 small{font-size:85%}.factory-bootstrap-400 cite{font-style:normal}.factory-bootstrap-400 .text-muted{color:#999}.factory-bootstrap-400 .text-primary{color:#428bca}.factory-bootstrap-400 .text-primary:hover{color:#3071a9}.factory-bootstrap-400 .text-warning{color:#8a6d3b}.factory-bootstrap-400 .text-warning:hover{color:#66512c}.factory-bootstrap-400 .text-danger{color:#a94442}.factory-bootstrap-400 .text-danger:hover{color:#843534}.factory-bootstrap-400 .text-success{color:#3c763d}.factory-bootstrap-400 .text-success:hover{color:#2b542c}.factory-bootstrap-400 .text-info{color:#31708f}.factory-bootstrap-400 .text-info:hover{color:#245269}.factory-bootstrap-400 .text-left{text-align:left}.factory-bootstrap-400 .text-right{text-align:right}.factory-bootstrap-400 .text-center{text-align:center}.factory-bootstrap-400 .page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}.factory-bootstrap-400 ol,.factory-bootstrap-400 ul{margin-top:0;margin-bottom:10px}.factory-bootstrap-400 ol ol,.factory-bootstrap-400 ol ul,.factory-bootstrap-400 ul ol,.factory-bootstrap-400 ul ul{margin-bottom:0}.factory-bootstrap-400 .list-inline,.factory-bootstrap-400 .list-unstyled{padding-left:0;list-style:none}.factory-bootstrap-400 .list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}.factory-bootstrap-400 .list-inline>li:first-child{padding-left:0}.factory-bootstrap-400 dl{margin-top:0;margin-bottom:20px}.factory-bootstrap-400 dd,.factory-bootstrap-400 dt{line-height:1.428571429}.factory-bootstrap-400 dt{font-weight:700}.factory-bootstrap-400 dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}.dl-horizontal dd:after,.dl-horizontal dd:before{display:table;content:" "}.dl-horizontal dd:after{clear:both}}.factory-bootstrap-400 abbr[data-original-title],.factory-bootstrap-400 abbr[title]{cursor:help;border-bottom:1px dotted #999}.factory-bootstrap-400 .initialism{font-size:90%;text-transform:uppercase}.factory-bootstrap-400 blockquote{padding:10px 20px;margin:0 0 20px;border-left:5px solid #eee}.factory-bootstrap-400 blockquote p{font-size:17.5px;font-weight:300;line-height:1.25}.factory-bootstrap-400 blockquote p:last-child{margin-bottom:0}.factory-bootstrap-400 blockquote .small,.factory-bootstrap-400 blockquote small{display:block;line-height:1.428571429;color:#999}.factory-bootstrap-400 blockquote .small:before,.factory-bootstrap-400 blockquote small:before{content:'\2014 \00A0'}.factory-bootstrap-400 blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0}.factory-bootstrap-400 blockquote.pull-right .small,.factory-bootstrap-400 blockquote.pull-right p,.factory-bootstrap-400 blockquote.pull-right small{text-align:right}.factory-bootstrap-400 blockquote.pull-right .small:before,.factory-bootstrap-400 blockquote.pull-right small:before{content:''}.factory-bootstrap-400 blockquote.pull-right .small:after,.factory-bootstrap-400 blockquote.pull-right small:after{content:'\00A0 \2014'}.factory-bootstrap-400 blockquote:after,.factory-bootstrap-400 blockquote:before{content:""}.factory-bootstrap-400 address{margin-bottom:20px;font-style:normal;line-height:1.428571429}.factory-bootstrap-400 code,.factory-bootstrap-400 kbd,.factory-bootstrap-400 pre,.factory-bootstrap-400 samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}.factory-bootstrap-400 code{padding:2px 4px;font-size:90%;color:#c7254e;white-space:nowrap;background-color:#f9f2f4;border-radius:4px}.factory-bootstrap-400 pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.428571429;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}.factory-bootstrap-400 pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.factory-bootstrap-400 .pre-scrollable{max-height:340px;overflow-y:scroll}.factory-bootstrap-400 .container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.factory-bootstrap-400 .container:after,.factory-bootstrap-400 .container:before{display:table;content:" "}.factory-bootstrap-400 .container:after{clear:both}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.factory-bootstrap-400 .row{margin-right:-15px;margin-left:-15px}.factory-bootstrap-400 .row:after,.factory-bootstrap-400 .row:before{display:table;content:" "}.factory-bootstrap-400 .row:after{clear:both}.factory-bootstrap-400 .col-lg-1,.factory-bootstrap-400 .col-lg-10,.factory-bootstrap-400 .col-lg-11,.factory-bootstrap-400 .col-lg-12,.factory-bootstrap-400 .col-lg-2,.factory-bootstrap-400 .col-lg-3,.factory-bootstrap-400 .col-lg-4,.factory-bootstrap-400 .col-lg-5,.factory-bootstrap-400 .col-lg-6,.factory-bootstrap-400 .col-lg-7,.factory-bootstrap-400 .col-lg-8,.factory-bootstrap-400 .col-lg-9,.factory-bootstrap-400 .col-md-1,.factory-bootstrap-400 .col-md-10,.factory-bootstrap-400 .col-md-11,.factory-bootstrap-400 .col-md-12,.factory-bootstrap-400 .col-md-2,.factory-bootstrap-400 .col-md-3,.factory-bootstrap-400 .col-md-4,.factory-bootstrap-400 .col-md-5,.factory-bootstrap-400 .col-md-6,.factory-bootstrap-400 .col-md-7,.factory-bootstrap-400 .col-md-8,.factory-bootstrap-400 .col-md-9,.factory-bootstrap-400 .col-sm-1,.factory-bootstrap-400 .col-sm-10,.factory-bootstrap-400 .col-sm-11,.factory-bootstrap-400 .col-sm-12,.factory-bootstrap-400 .col-sm-2,.factory-bootstrap-400 .col-sm-3,.factory-bootstrap-400 .col-sm-4,.factory-bootstrap-400 .col-sm-5,.factory-bootstrap-400 .col-sm-6,.factory-bootstrap-400 .col-sm-7,.factory-bootstrap-400 .col-sm-8,.factory-bootstrap-400 .col-sm-9,.factory-bootstrap-400 .col-xs-1,.factory-bootstrap-400 .col-xs-10,.factory-bootstrap-400 .col-xs-11,.factory-bootstrap-400 .col-xs-12,.factory-bootstrap-400 .col-xs-2,.factory-bootstrap-400 .col-xs-3,.factory-bootstrap-400 .col-xs-4,.factory-bootstrap-400 .col-xs-5,.factory-bootstrap-400 .col-xs-6,.factory-bootstrap-400 .col-xs-7,.factory-bootstrap-400 .col-xs-8,.factory-bootstrap-400 .col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.factory-bootstrap-400 .col-xs-1,.factory-bootstrap-400 .col-xs-10,.factory-bootstrap-400 .col-xs-11,.factory-bootstrap-400 .col-xs-12,.factory-bootstrap-400 .col-xs-2,.factory-bootstrap-400 .col-xs-3,.factory-bootstrap-400 .col-xs-4,.factory-bootstrap-400 .col-xs-5,.factory-bootstrap-400 .col-xs-6,.factory-bootstrap-400 .col-xs-7,.factory-bootstrap-400 .col-xs-8,.factory-bootstrap-400 .col-xs-9{float:left}.factory-bootstrap-400 .col-xs-12{width:100%}.factory-bootstrap-400 .col-xs-11{width:91.66666666666666%}.factory-bootstrap-400 .col-xs-10{width:83.33333333333334%}.factory-bootstrap-400 .col-xs-9{width:75%}.factory-bootstrap-400 .col-xs-8{width:66.66666666666666%}.factory-bootstrap-400 .col-xs-7{width:58.333333333333336%}.factory-bootstrap-400 .col-xs-6{width:50%}.factory-bootstrap-400 .col-xs-5{width:41.66666666666667%}.factory-bootstrap-400 .col-xs-4{width:33.33333333333333%}.factory-bootstrap-400 .col-xs-3{width:25%}.factory-bootstrap-400 .col-xs-2{width:16.666666666666664%}.factory-bootstrap-400 .col-xs-1{width:8.333333333333332%}.factory-bootstrap-400 .col-xs-pull-12{right:100%}.factory-bootstrap-400 .col-xs-pull-11{right:91.66666666666666%}.factory-bootstrap-400 .col-xs-pull-10{right:83.33333333333334%}.factory-bootstrap-400 .col-xs-pull-9{right:75%}.factory-bootstrap-400 .col-xs-pull-8{right:66.66666666666666%}.factory-bootstrap-400 .col-xs-pull-7{right:58.333333333333336%}.factory-bootstrap-400 .col-xs-pull-6{right:50%}.factory-bootstrap-400 .col-xs-pull-5{right:41.66666666666667%}.factory-bootstrap-400 .col-xs-pull-4{right:33.33333333333333%}.factory-bootstrap-400 .col-xs-pull-3{right:25%}.factory-bootstrap-400 .col-xs-pull-2{right:16.666666666666664%}.factory-bootstrap-400 .col-xs-pull-1{right:8.333333333333332%}.factory-bootstrap-400 .col-xs-pull-0{right:0}.factory-bootstrap-400 .col-xs-push-12{left:100%}.factory-bootstrap-400 .col-xs-push-11{left:91.66666666666666%}.factory-bootstrap-400 .col-xs-push-10{left:83.33333333333334%}.factory-bootstrap-400 .col-xs-push-9{left:75%}.factory-bootstrap-400 .col-xs-push-8{left:66.66666666666666%}.factory-bootstrap-400 .col-xs-push-7{left:58.333333333333336%}.factory-bootstrap-400 .col-xs-push-6{left:50%}.factory-bootstrap-400 .col-xs-push-5{left:41.66666666666667%}.factory-bootstrap-400 .col-xs-push-4{left:33.33333333333333%}.factory-bootstrap-400 .col-xs-push-3{left:25%}.factory-bootstrap-400 .col-xs-push-2{left:16.666666666666664%}.factory-bootstrap-400 .col-xs-push-1{left:8.333333333333332%}.factory-bootstrap-400 .col-xs-push-0{left:0}.factory-bootstrap-400 .col-xs-offset-12{margin-left:100%}.factory-bootstrap-400 .col-xs-offset-11{margin-left:91.66666666666666%}.factory-bootstrap-400 .col-xs-offset-10{margin-left:83.33333333333334%}.factory-bootstrap-400 .col-xs-offset-9{margin-left:75%}.factory-bootstrap-400 .col-xs-offset-8{margin-left:66.66666666666666%}.factory-bootstrap-400 .col-xs-offset-7{margin-left:58.333333333333336%}.factory-bootstrap-400 .col-xs-offset-6{margin-left:50%}.factory-bootstrap-400 .col-xs-offset-5{margin-left:41.66666666666667%}.factory-bootstrap-400 .col-xs-offset-4{margin-left:33.33333333333333%}.factory-bootstrap-400 .col-xs-offset-3{margin-left:25%}.factory-bootstrap-400 .col-xs-offset-2{margin-left:16.666666666666664%}.factory-bootstrap-400 .col-xs-offset-1{margin-left:8.333333333333332%}.factory-bootstrap-400 .col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666666666666%}.col-sm-10{width:83.33333333333334%}.col-sm-9{width:75%}.col-sm-8{width:66.66666666666666%}.col-sm-7{width:58.333333333333336%}.col-sm-6{width:50%}.col-sm-5{width:41.66666666666667%}.col-sm-4{width:33.33333333333333%}.col-sm-3{width:25%}.col-sm-2{width:16.666666666666664%}.col-sm-1{width:8.333333333333332%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666666666666%}.col-sm-pull-10{right:83.33333333333334%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666666666666%}.col-sm-pull-7{right:58.333333333333336%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666666666667%}.col-sm-pull-4{right:33.33333333333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.666666666666664%}.col-sm-pull-1{right:8.333333333333332%}.col-sm-pull-0{right:0}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666666666666%}.col-sm-push-10{left:83.33333333333334%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666666666666%}.col-sm-push-7{left:58.333333333333336%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666666666667%}.col-sm-push-4{left:33.33333333333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.666666666666664%}.col-sm-push-1{left:8.333333333333332%}.col-sm-push-0{left:0}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666666666666%}.col-sm-offset-10{margin-left:83.33333333333334%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666666666666%}.col-sm-offset-7{margin-left:58.333333333333336%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666666666667%}.col-sm-offset-4{margin-left:33.33333333333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.666666666666664%}.col-sm-offset-1{margin-left:8.333333333333332%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666666666666%}.col-md-10{width:83.33333333333334%}.col-md-9{width:75%}.col-md-8{width:66.66666666666666%}.col-md-7{width:58.333333333333336%}.col-md-6{width:50%}.col-md-5{width:41.66666666666667%}.col-md-4{width:33.33333333333333%}.col-md-3{width:25%}.col-md-2{width:16.666666666666664%}.col-md-1{width:8.333333333333332%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666666666666%}.col-md-pull-10{right:83.33333333333334%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666666666666%}.col-md-pull-7{right:58.333333333333336%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666666666667%}.col-md-pull-4{right:33.33333333333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.666666666666664%}.col-md-pull-1{right:8.333333333333332%}.col-md-pull-0{right:0}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666666666666%}.col-md-push-10{left:83.33333333333334%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666666666666%}.col-md-push-7{left:58.333333333333336%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666666666667%}.col-md-push-4{left:33.33333333333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.666666666666664%}.col-md-push-1{left:8.333333333333332%}.col-md-push-0{left:0}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666666666666%}.col-md-offset-10{margin-left:83.33333333333334%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666666666666%}.col-md-offset-7{margin-left:58.333333333333336%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666666666667%}.col-md-offset-4{margin-left:33.33333333333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.666666666666664%}.col-md-offset-1{margin-left:8.333333333333332%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666666666666%}.col-lg-10{width:83.33333333333334%}.col-lg-9{width:75%}.col-lg-8{width:66.66666666666666%}.col-lg-7{width:58.333333333333336%}.col-lg-6{width:50%}.col-lg-5{width:41.66666666666667%}.col-lg-4{width:33.33333333333333%}.col-lg-3{width:25%}.col-lg-2{width:16.666666666666664%}.col-lg-1{width:8.333333333333332%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666666666666%}.col-lg-pull-10{right:83.33333333333334%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666666666666%}.col-lg-pull-7{right:58.333333333333336%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666666666667%}.col-lg-pull-4{right:33.33333333333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.666666666666664%}.col-lg-pull-1{right:8.333333333333332%}.col-lg-pull-0{right:0}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666666666666%}.col-lg-push-10{left:83.33333333333334%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666666666666%}.col-lg-push-7{left:58.333333333333336%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666666666667%}.col-lg-push-4{left:33.33333333333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.666666666666664%}.col-lg-push-1{left:8.333333333333332%}.col-lg-push-0{left:0}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666666666666%}.col-lg-offset-10{margin-left:83.33333333333334%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666666666666%}.col-lg-offset-7{margin-left:58.333333333333336%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666666666667%}.col-lg-offset-4{margin-left:33.33333333333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.666666666666664%}.col-lg-offset-1{margin-left:8.333333333333332%}.col-lg-offset-0{margin-left:0}}.factory-bootstrap-400 table{max-width:100%;background-color:transparent}.factory-bootstrap-400 th{text-align:left}.factory-bootstrap-400 .table{width:100%;margin-bottom:20px}.factory-bootstrap-400 .table>tbody>tr>td,.factory-bootstrap-400 .table>tbody>tr>th,.factory-bootstrap-400 .table>tfoot>tr>td,.factory-bootstrap-400 .table>tfoot>tr>th,.factory-bootstrap-400 .table>thead>tr>td,.factory-bootstrap-400 .table>thead>tr>th{padding:8px;line-height:1.428571429;vertical-align:top;border-top:1px solid #ddd}.factory-bootstrap-400 .table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.factory-bootstrap-400 .table>caption+thead>tr:first-child>td,.factory-bootstrap-400 .table>caption+thead>tr:first-child>th,.factory-bootstrap-400 .table>colgroup+thead>tr:first-child>td,.factory-bootstrap-400 .table>colgroup+thead>tr:first-child>th,.factory-bootstrap-400 .table>thead:first-child>tr:first-child>td,.factory-bootstrap-400 .table>thead:first-child>tr:first-child>th{border-top:0}.factory-bootstrap-400 .table>tbody+tbody{border-top:2px solid #ddd}.factory-bootstrap-400 .table .table{background-color:#fff}.factory-bootstrap-400 .table-condensed>tbody>tr>td,.factory-bootstrap-400 .table-condensed>tbody>tr>th,.factory-bootstrap-400 .table-condensed>tfoot>tr>td,.factory-bootstrap-400 .table-condensed>tfoot>tr>th,.factory-bootstrap-400 .table-condensed>thead>tr>td,.factory-bootstrap-400 .table-condensed>thead>tr>th{padding:5px}.factory-bootstrap-400 .table-bordered,.factory-bootstrap-400 .table-bordered>tbody>tr>td,.factory-bootstrap-400 .table-bordered>tbody>tr>th,.factory-bootstrap-400 .table-bordered>tfoot>tr>td,.factory-bootstrap-400 .table-bordered>tfoot>tr>th,.factory-bootstrap-400 .table-bordered>thead>tr>td,.factory-bootstrap-400 .table-bordered>thead>tr>th{border:1px solid #ddd}.factory-bootstrap-400 .table-bordered>thead>tr>td,.factory-bootstrap-400 .table-bordered>thead>tr>th{border-bottom-width:2px}.factory-bootstrap-400 .table-striped>tbody>tr:nth-child(odd)>td,.factory-bootstrap-400 .table-striped>tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.factory-bootstrap-400 .table-hover>tbody>tr:hover>td,.factory-bootstrap-400 .table-hover>tbody>tr:hover>th{background-color:#f5f5f5}.factory-bootstrap-400 table col[class*=col-]{position:static;display:table-column;float:none}.factory-bootstrap-400 table td[class*=col-],.factory-bootstrap-400 table th[class*=col-]{display:table-cell;float:none}.factory-bootstrap-400 .table>tbody>.active>td,.factory-bootstrap-400 .table>tbody>.active>th,.factory-bootstrap-400 .table>tbody>tr>.active,.factory-bootstrap-400 .table>tfoot>.active>td,.factory-bootstrap-400 .table>tfoot>.active>th,.factory-bootstrap-400 .table>tfoot>tr>.active,.factory-bootstrap-400 .table>thead>.active>td,.factory-bootstrap-400 .table>thead>.active>th,.factory-bootstrap-400 .table>thead>tr>.active{background-color:#f5f5f5}.factory-bootstrap-400 .table-hover>tbody>.active:hover>td,.factory-bootstrap-400 .table-hover>tbody>.active:hover>th,.factory-bootstrap-400 .table-hover>tbody>tr>.active:hover{background-color:#e8e8e8}.factory-bootstrap-400 .table>tbody>.success>td,.factory-bootstrap-400 .table>tbody>.success>th,.factory-bootstrap-400 .table>tbody>tr>.success,.factory-bootstrap-400 .table>tfoot>.success>td,.factory-bootstrap-400 .table>tfoot>.success>th,.factory-bootstrap-400 .table>tfoot>tr>.success,.factory-bootstrap-400 .table>thead>.success>td,.factory-bootstrap-400 .table>thead>.success>th,.factory-bootstrap-400 .table>thead>tr>.success{background-color:#dff0d8}.factory-bootstrap-400 .table-hover>tbody>.success:hover>td,.factory-bootstrap-400 .table-hover>tbody>.success:hover>th,.factory-bootstrap-400 .table-hover>tbody>tr>.success:hover{background-color:#d0e9c6}.factory-bootstrap-400 .table>tbody>.danger>td,.factory-bootstrap-400 .table>tbody>.danger>th,.factory-bootstrap-400 .table>tbody>tr>.danger,.factory-bootstrap-400 .table>tfoot>.danger>td,.factory-bootstrap-400 .table>tfoot>.danger>th,.factory-bootstrap-400 .table>tfoot>tr>.danger,.factory-bootstrap-400 .table>thead>.danger>td,.factory-bootstrap-400 .table>thead>.danger>th,.factory-bootstrap-400 .table>thead>tr>.danger{background-color:#f2dede}.factory-bootstrap-400 .table-hover>tbody>.danger:hover>td,.factory-bootstrap-400 .table-hover>tbody>.danger:hover>th,.factory-bootstrap-400 .table-hover>tbody>tr>.danger:hover{background-color:#ebcccc}.factory-bootstrap-400 .table>tbody>.warning>td,.factory-bootstrap-400 .table>tbody>.warning>th,.factory-bootstrap-400 .table>tbody>tr>.warning,.factory-bootstrap-400 .table>tfoot>.warning>td,.factory-bootstrap-400 .table>tfoot>.warning>th,.factory-bootstrap-400 .table>tfoot>tr>.warning,.factory-bootstrap-400 .table>thead>.warning>td,.factory-bootstrap-400 .table>thead>.warning>th,.factory-bootstrap-400 .table>thead>tr>.warning{background-color:#fcf8e3}.factory-bootstrap-400 .table-hover>tbody>.warning:hover>td,.factory-bootstrap-400 .table-hover>tbody>.warning:hover>th,.factory-bootstrap-400 .table-hover>tbody>tr>.warning:hover{background-color:#faf2cc}@media (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-x:scroll;overflow-y:hidden;border:1px solid #ddd;-ms-overflow-style:-ms-autohiding-scrollbar;-webkit-overflow-scrolling:touch}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}.factory-bootstrap-400 fieldset{padding:0;margin:0;border:0}.factory-bootstrap-400 legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5;-moz-box-sizing:content-box;box-sizing:content-box}.factory-bootstrap-400 label{display:inline-block;margin-bottom:5px;font-weight:700}.factory-bootstrap-400 input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.factory-bootstrap-400 input[type=checkbox],.factory-bootstrap-400 input[type=radio]{margin:4px 0 0;margin-top:1px \9;line-height:normal}.factory-bootstrap-400 input[type=file]{display:block}.factory-bootstrap-400 select[multiple],.factory-bootstrap-400 select[size]{height:auto}.factory-bootstrap-400 select optgroup{font-family:inherit;font-size:inherit;font-style:inherit}.factory-bootstrap-400 input[type=checkbox]:focus,.factory-bootstrap-400 input[type=file]:focus,.factory-bootstrap-400 input[type=radio]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.factory-bootstrap-400 input[type=number]::-webkit-inner-spin-button,.factory-bootstrap-400 input[type=number]::-webkit-outer-spin-button{height:auto}.factory-bootstrap-400 output{display:block;padding-top:7px;font-size:14px;line-height:1.428571429;color:#555;vertical-align:middle}.factory-bootstrap-400 .form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.428571429;color:#555;vertical-align:middle;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:3px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.factory-bootstrap-400 .form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.factory-bootstrap-400 .form-control:-moz-placeholder{color:#999}.factory-bootstrap-400 .form-control::-moz-placeholder{color:#999;opacity:1}.factory-bootstrap-400 .form-control:-ms-input-placeholder{color:#999}.factory-bootstrap-400 .form-control::-webkit-input-placeholder{color:#999}.factory-bootstrap-400 .form-control[disabled],.factory-bootstrap-400 .form-control[readonly],.factory-bootstrap-400 fieldset[disabled] .form-control{cursor:not-allowed;background-color:#eee}.factory-bootstrap-400 textarea.form-control{height:auto}.factory-bootstrap-400 .form-group{margin-bottom:15px}.factory-bootstrap-400 .checkbox,.factory-bootstrap-400 .radio{display:block;min-height:20px;padding-left:20px;margin-top:10px;margin-bottom:10px;vertical-align:middle}.factory-bootstrap-400 .checkbox label,.factory-bootstrap-400 .radio label{display:inline;margin-bottom:0;font-weight:400;cursor:pointer}.factory-bootstrap-400 .checkbox input[type=checkbox],.factory-bootstrap-400 .checkbox-inline input[type=checkbox],.factory-bootstrap-400 .radio input[type=radio],.factory-bootstrap-400 .radio-inline input[type=radio]{float:left;margin-left:-20px}.factory-bootstrap-400 .checkbox+.checkbox,.factory-bootstrap-400 .radio+.radio{margin-top:-5px}.factory-bootstrap-400 .checkbox-inline,.factory-bootstrap-400 .radio-inline{display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.factory-bootstrap-400 .checkbox-inline+.checkbox-inline,.factory-bootstrap-400 .radio-inline+.radio-inline{margin-top:0;margin-left:10px}.factory-bootstrap-400 .checkbox-inline[disabled],.factory-bootstrap-400 .checkbox[disabled],.factory-bootstrap-400 .radio-inline[disabled],.factory-bootstrap-400 .radio[disabled],.factory-bootstrap-400 fieldset[disabled] .checkbox,.factory-bootstrap-400 fieldset[disabled] .checkbox-inline,.factory-bootstrap-400 fieldset[disabled] .radio,.factory-bootstrap-400 fieldset[disabled] .radio-inline,.factory-bootstrap-400 fieldset[disabled] input[type=checkbox],.factory-bootstrap-400 fieldset[disabled] input[type=radio],.factory-bootstrap-400 input[type=checkbox][disabled],.factory-bootstrap-400 input[type=radio][disabled]{cursor:not-allowed}.factory-bootstrap-400 .input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.factory-bootstrap-400 select.input-sm{height:30px;line-height:30px}.factory-bootstrap-400 textarea.input-sm{height:auto}.factory-bootstrap-400 .input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.factory-bootstrap-400 select.input-lg{height:46px;line-height:46px}.factory-bootstrap-400 textarea.input-lg{height:auto}.factory-bootstrap-400 .has-warning .checkbox,.factory-bootstrap-400 .has-warning .checkbox-inline,.factory-bootstrap-400 .has-warning .control-label,.factory-bootstrap-400 .has-warning .help-block,.factory-bootstrap-400 .has-warning .radio,.factory-bootstrap-400 .has-warning .radio-inline{color:#8a6d3b}.factory-bootstrap-400 .has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.factory-bootstrap-400 .has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.factory-bootstrap-400 .has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.factory-bootstrap-400 .has-error .checkbox,.factory-bootstrap-400 .has-error .checkbox-inline,.factory-bootstrap-400 .has-error .control-label,.factory-bootstrap-400 .has-error .help-block,.factory-bootstrap-400 .has-error .radio,.factory-bootstrap-400 .has-error .radio-inline{color:#a94442}.factory-bootstrap-400 .controls{display:block}.factory-bootstrap-400 .has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.factory-bootstrap-400 .has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.factory-bootstrap-400 .has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.factory-bootstrap-400 .has-success .checkbox,.factory-bootstrap-400 .has-success .checkbox-inline,.factory-bootstrap-400 .has-success .control-label,.factory-bootstrap-400 .has-success .help-block,.factory-bootstrap-400 .has-success .radio,.factory-bootstrap-400 .has-success .radio-inline{color:#3c763d}.factory-bootstrap-400 .has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.factory-bootstrap-400 .has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.factory-bootstrap-400 .has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.factory-bootstrap-400 .form-control-static{margin-bottom:0}.factory-bootstrap-400 .help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373;font-weight:400}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block}.form-inline select.form-control{width:auto}.form-inline .checkbox,.form-inline .radio{display:inline-block;padding-left:0;margin-top:0;margin-bottom:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{float:none;margin-left:0}}.factory-bootstrap-400 .form-horizontal .checkbox,.factory-bootstrap-400 .form-horizontal .checkbox-inline,.factory-bootstrap-400 .form-horizontal .control-label,.factory-bootstrap-400 .form-horizontal .radio,.factory-bootstrap-400 .form-horizontal .radio-inline{position:relative;padding-top:7px;margin-top:0;margin-bottom:0}.factory-bootstrap-400 .form-horizontal .control-label{max-width:200px}.factory-bootstrap-400 .form-horizontal .checkbox,.factory-bootstrap-400 .form-horizontal .radio{min-height:27px}.factory-bootstrap-400 .form-horizontal .form-group{margin-right:-15px;margin-left:-15px}.factory-bootstrap-400 .form-horizontal .form-group:after,.factory-bootstrap-400 .form-horizontal .form-group:before{display:table;content:" "}.factory-bootstrap-400 .form-horizontal .form-group:after{clear:both}.factory-bootstrap-400 .form-horizontal .form-control-static{padding-top:7px}@media (min-width:768px){.form-horizontal .control-label{text-align:right}}.factory-bootstrap-400 .btn{display:inline-block;padding:5px 12px;margin-bottom:0;font-size:13px;font-weight:400;line-height:1.428571429;text-align:center;white-space:nowrap;vertical-align:middle;cursor:pointer;background-image:none;border:1px solid transparent;border-radius:3px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}.factory-bootstrap-400 .btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.factory-bootstrap-400 .btn{text-decoration:none}.factory-bootstrap-400 .btn:focus,.factory-bootstrap-400 .btn:hover{color:#333;text-decoration:none}.factory-bootstrap-400 .btn.disabled,.factory-bootstrap-400 .btn[disabled],.factory-bootstrap-400 fieldset[disabled] .btn{pointer-events:none;cursor:not-allowed;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}.factory-bootstrap-400 .btn-default.active,.factory-bootstrap-400 .btn-default:active,.factory-bootstrap-400 .btn-default:focus,.factory-bootstrap-400 .btn-default:hover,.factory-bootstrap-400 .open .dropdown-toggle.btn-default{background:#fafafa;border-color:#999;color:#222}.factory-bootstrap-400 .btn-default.active,.factory-bootstrap-400 .btn-default:active,.factory-bootstrap-400 .open .dropdown-toggle.btn-default{background-image:none}.factory-bootstrap-400 .btn-default.disabled,.factory-bootstrap-400 .btn-default.disabled.active,.factory-bootstrap-400 .btn-default.disabled:active,.factory-bootstrap-400 .btn-default.disabled:focus,.factory-bootstrap-400 .btn-default.disabled:hover,.factory-bootstrap-400 .btn-default[disabled],.factory-bootstrap-400 .btn-default[disabled].active,.factory-bootstrap-400 .btn-default[disabled]:active,.factory-bootstrap-400 .btn-default[disabled]:focus,.factory-bootstrap-400 .btn-default[disabled]:hover,.factory-bootstrap-400 fieldset[disabled] .btn-default,.factory-bootstrap-400 fieldset[disabled] .btn-default.active,.factory-bootstrap-400 fieldset[disabled] .btn-default:active,.factory-bootstrap-400 fieldset[disabled] .btn-default:focus,.factory-bootstrap-400 fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.factory-bootstrap-400 .btn-default .badge{color:#fff;background-color:#fff}.factory-bootstrap-400 .btn-primary.active,.factory-bootstrap-400 .btn-primary:active,.factory-bootstrap-400 .btn-primary:focus,.factory-bootstrap-400 .btn-primary:hover,.factory-bootstrap-400 .open .dropdown-toggle.btn-primary{color:#fff;background-color:#3276b1;border-color:#285e8e}.factory-bootstrap-400 .btn-primary.active,.factory-bootstrap-400 .btn-primary:active,.factory-bootstrap-400 .open .dropdown-toggle.btn-primary{background-image:none}.factory-bootstrap-400 .btn-primary.disabled,.factory-bootstrap-400 .btn-primary.disabled.active,.factory-bootstrap-400 .btn-primary.disabled:active,.factory-bootstrap-400 .btn-primary.disabled:focus,.factory-bootstrap-400 .btn-primary.disabled:hover,.factory-bootstrap-400 .btn-primary[disabled],.factory-bootstrap-400 .btn-primary[disabled].active,.factory-bootstrap-400 .btn-primary[disabled]:active,.factory-bootstrap-400 .btn-primary[disabled]:focus,.factory-bootstrap-400 .btn-primary[disabled]:hover,.factory-bootstrap-400 fieldset[disabled] .btn-primary,.factory-bootstrap-400 fieldset[disabled] .btn-primary.active,.factory-bootstrap-400 fieldset[disabled] .btn-primary:active,.factory-bootstrap-400 fieldset[disabled] .btn-primary:focus,.factory-bootstrap-400 fieldset[disabled] .btn-primary:hover{background-color:#428bca;border-color:#357ebd}.factory-bootstrap-400 .btn-primary .badge{color:#428bca;background-color:#fff}.factory-bootstrap-400 .btn-warning{color:#fff;background-color:#f0ad4e}.factory-bootstrap-400 .btn-warning.active,.factory-bootstrap-400 .btn-warning:active,.factory-bootstrap-400 .btn-warning:focus,.factory-bootstrap-400 .btn-warning:hover,.factory-bootstrap-400 .open .dropdown-toggle.btn-warning{color:#fff;background-color:#ed9c28;border-color:#d58512}.factory-bootstrap-400 .btn-warning.active,.factory-bootstrap-400 .btn-warning:active,.factory-bootstrap-400 .open .dropdown-toggle.btn-warning{background-image:none}.factory-bootstrap-400 .btn-warning.disabled,.factory-bootstrap-400 .btn-warning.disabled.active,.factory-bootstrap-400 .btn-warning.disabled:active,.factory-bootstrap-400 .btn-warning.disabled:focus,.factory-bootstrap-400 .btn-warning.disabled:hover,.factory-bootstrap-400 .btn-warning[disabled],.factory-bootstrap-400 .btn-warning[disabled].active,.factory-bootstrap-400 .btn-warning[disabled]:active,.factory-bootstrap-400 .btn-warning[disabled]:focus,.factory-bootstrap-400 .btn-warning[disabled]:hover,.factory-bootstrap-400 fieldset[disabled] .btn-warning,.factory-bootstrap-400 fieldset[disabled] .btn-warning.active,.factory-bootstrap-400 fieldset[disabled] .btn-warning:active,.factory-bootstrap-400 fieldset[disabled] .btn-warning:focus,.factory-bootstrap-400 fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.factory-bootstrap-400 .btn-warning .badge{color:#f0ad4e;background-color:#fff}.factory-bootstrap-400 .btn-success{color:#fff;background-color:#5cb85c}.factory-bootstrap-400 .btn-success.active,.factory-bootstrap-400 .btn-success:active,.factory-bootstrap-400 .btn-success:focus,.factory-bootstrap-400 .btn-success:hover,.factory-bootstrap-400 .open .dropdown-toggle.btn-success{color:#fff;background-color:#47a447;border-color:#398439}.factory-bootstrap-400 .btn-success.active,.factory-bootstrap-400 .btn-success:active,.factory-bootstrap-400 .open .dropdown-toggle.btn-success{background-image:none}.factory-bootstrap-400 .btn-success.disabled,.factory-bootstrap-400 .btn-success.disabled.active,.factory-bootstrap-400 .btn-success.disabled:active,.factory-bootstrap-400 .btn-success.disabled:focus,.factory-bootstrap-400 .btn-success.disabled:hover,.factory-bootstrap-400 .btn-success[disabled],.factory-bootstrap-400 .btn-success[disabled].active,.factory-bootstrap-400 .btn-success[disabled]:active,.factory-bootstrap-400 .btn-success[disabled]:focus,.factory-bootstrap-400 .btn-success[disabled]:hover,.factory-bootstrap-400 fieldset[disabled] .btn-success,.factory-bootstrap-400 fieldset[disabled] .btn-success.active,.factory-bootstrap-400 fieldset[disabled] .btn-success:active,.factory-bootstrap-400 fieldset[disabled] .btn-success:focus,.factory-bootstrap-400 fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.factory-bootstrap-400 .btn-success .badge{color:#5cb85c;background-color:#fff}.factory-bootstrap-400 .btn-info{color:#fff;background-color:#5bc0de}.factory-bootstrap-400 .btn-info.active,.factory-bootstrap-400 .btn-info:active,.factory-bootstrap-400 .btn-info:focus,.factory-bootstrap-400 .btn-info:hover,.factory-bootstrap-400 .open .dropdown-toggle.btn-info{color:#fff;background-color:#39b3d7;border-color:#269abc}.factory-bootstrap-400 .btn-info.active,.factory-bootstrap-400 .btn-info:active,.factory-bootstrap-400 .open .dropdown-toggle.btn-info{background-image:none}.factory-bootstrap-400 .btn-info.disabled,.factory-bootstrap-400 .btn-info.disabled.active,.factory-bootstrap-400 .btn-info.disabled:active,.factory-bootstrap-400 .btn-info.disabled:focus,.factory-bootstrap-400 .btn-info.disabled:hover,.factory-bootstrap-400 .btn-info[disabled],.factory-bootstrap-400 .btn-info[disabled].active,.factory-bootstrap-400 .btn-info[disabled]:active,.factory-bootstrap-400 .btn-info[disabled]:focus,.factory-bootstrap-400 .btn-info[disabled]:hover,.factory-bootstrap-400 fieldset[disabled] .btn-info,.factory-bootstrap-400 fieldset[disabled] .btn-info.active,.factory-bootstrap-400 fieldset[disabled] .btn-info:active,.factory-bootstrap-400 fieldset[disabled] .btn-info:focus,.factory-bootstrap-400 fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.factory-bootstrap-400 .btn-info .badge{color:#5bc0de;background-color:#fff}.factory-bootstrap-400 .btn-link{font-weight:400;color:#428bca;cursor:pointer;border-radius:0}.factory-bootstrap-400 .btn-link,.factory-bootstrap-400 .btn-link:active,.factory-bootstrap-400 .btn-link[disabled],.factory-bootstrap-400 fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.factory-bootstrap-400 .btn-link,.factory-bootstrap-400 .btn-link:active,.factory-bootstrap-400 .btn-link:focus,.factory-bootstrap-400 .btn-link:hover{border-color:transparent}.factory-bootstrap-400 .btn-link:focus,.factory-bootstrap-400 .btn-link:hover{color:#2a6496;text-decoration:underline;background-color:transparent}.factory-bootstrap-400 .btn-link[disabled]:focus,.factory-bootstrap-400 .btn-link[disabled]:hover,.factory-bootstrap-400 fieldset[disabled] .btn-link:focus,.factory-bootstrap-400 fieldset[disabled] .btn-link:hover{color:#999;text-decoration:none}.factory-bootstrap-400 .btn-lg{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.factory-bootstrap-400 .btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.factory-bootstrap-400 .btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.factory-bootstrap-400 .btn-block{display:block;width:100%;padding-right:0;padding-left:0}.factory-bootstrap-400 .btn-block+.btn-block{margin-top:5px}.factory-bootstrap-400 input[type=button].btn-block,.factory-bootstrap-400 input[type=reset].btn-block,.factory-bootstrap-400 input[type=submit].btn-block{width:100%}.factory-bootstrap-400 .fade{opacity:0;-webkit-transition:opacity .15s linear;transition:opacity .15s linear}.factory-bootstrap-400 .fade.in{opacity:1}.factory-bootstrap-400 .collapse{display:none}.factory-bootstrap-400 .collapse.in{display:block}.factory-bootstrap-400 .collapsing{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;transition:height .35s ease}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons-halflingsregular) format('svg')}.factory-bootstrap-400 .glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';-webkit-font-smoothing:antialiased;font-style:normal;font-weight:400;line-height:1;-moz-osx-font-smoothing:grayscale}.factory-bootstrap-400 .glyphicon:empty{width:1em}.factory-bootstrap-400 .glyphicon-asterisk:before{content:"\2a"}.factory-bootstrap-400 .glyphicon-plus:before{content:"\2b"}.factory-bootstrap-400 .glyphicon-euro:before{content:"\20ac"}.factory-bootstrap-400 .glyphicon-minus:before{content:"\2212"}.factory-bootstrap-400 .glyphicon-cloud:before{content:"\2601"}.factory-bootstrap-400 .glyphicon-envelope:before{content:"\2709"}.factory-bootstrap-400 .glyphicon-pencil:before{content:"\270f"}.factory-bootstrap-400 .glyphicon-glass:before{content:"\e001"}.factory-bootstrap-400 .glyphicon-music:before{content:"\e002"}.factory-bootstrap-400 .glyphicon-search:before{content:"\e003"}.factory-bootstrap-400 .glyphicon-heart:before{content:"\e005"}.factory-bootstrap-400 .glyphicon-star:before{content:"\e006"}.factory-bootstrap-400 .glyphicon-star-empty:before{content:"\e007"}.factory-bootstrap-400 .glyphicon-user:before{content:"\e008"}.factory-bootstrap-400 .glyphicon-film:before{content:"\e009"}.factory-bootstrap-400 .glyphicon-th-large:before{content:"\e010"}.factory-bootstrap-400 .glyphicon-th:before{content:"\e011"}.factory-bootstrap-400 .glyphicon-th-list:before{content:"\e012"}.factory-bootstrap-400 .glyphicon-ok:before{content:"\e013"}.factory-bootstrap-400 .glyphicon-remove:before{content:"\e014"}.factory-bootstrap-400 .glyphicon-zoom-in:before{content:"\e015"}.factory-bootstrap-400 .glyphicon-zoom-out:before{content:"\e016"}.factory-bootstrap-400 .glyphicon-off:before{content:"\e017"}.factory-bootstrap-400 .glyphicon-signal:before{content:"\e018"}.factory-bootstrap-400 .glyphicon-cog:before{content:"\e019"}.factory-bootstrap-400 .glyphicon-trash:before{content:"\e020"}.factory-bootstrap-400 .glyphicon-home:before{content:"\e021"}.factory-bootstrap-400 .glyphicon-file:before{content:"\e022"}.factory-bootstrap-400 .glyphicon-time:before{content:"\e023"}.factory-bootstrap-400 .glyphicon-road:before{content:"\e024"}.factory-bootstrap-400 .glyphicon-download-alt:before{content:"\e025"}.factory-bootstrap-400 .glyphicon-download:before{content:"\e026"}.factory-bootstrap-400 .glyphicon-upload:before{content:"\e027"}.factory-bootstrap-400 .glyphicon-inbox:before{content:"\e028"}.factory-bootstrap-400 .glyphicon-play-circle:before{content:"\e029"}.factory-bootstrap-400 .glyphicon-repeat:before{content:"\e030"}.factory-bootstrap-400 .glyphicon-refresh:before{content:"\e031"}.factory-bootstrap-400 .glyphicon-list-alt:before{content:"\e032"}.factory-bootstrap-400 .glyphicon-lock:before{content:"\e033"}.factory-bootstrap-400 .glyphicon-flag:before{content:"\e034"}.factory-bootstrap-400 .glyphicon-headphones:before{content:"\e035"}.factory-bootstrap-400 .glyphicon-volume-off:before{content:"\e036"}.factory-bootstrap-400 .glyphicon-volume-down:before{content:"\e037"}.factory-bootstrap-400 .glyphicon-volume-up:before{content:"\e038"}.factory-bootstrap-400 .glyphicon-qrcode:before{content:"\e039"}.factory-bootstrap-400 .glyphicon-barcode:before{content:"\e040"}.factory-bootstrap-400 .glyphicon-tag:before{content:"\e041"}.factory-bootstrap-400 .glyphicon-tags:before{content:"\e042"}.factory-bootstrap-400 .glyphicon-book:before{content:"\e043"}.factory-bootstrap-400 .glyphicon-bookmark:before{content:"\e044"}.factory-bootstrap-400 .glyphicon-print:before{content:"\e045"}.factory-bootstrap-400 .glyphicon-camera:before{content:"\e046"}.factory-bootstrap-400 .glyphicon-font:before{content:"\e047"}.factory-bootstrap-400 .glyphicon-bold:before{content:"\e048"}.factory-bootstrap-400 .glyphicon-italic:before{content:"\e049"}.factory-bootstrap-400 .glyphicon-text-height:before{content:"\e050"}.factory-bootstrap-400 .glyphicon-text-width:before{content:"\e051"}.factory-bootstrap-400 .glyphicon-align-left:before{content:"\e052"}.factory-bootstrap-400 .glyphicon-align-center:before{content:"\e053"}.factory-bootstrap-400 .glyphicon-align-right:before{content:"\e054"}.factory-bootstrap-400 .glyphicon-align-justify:before{content:"\e055"}.factory-bootstrap-400 .glyphicon-list:before{content:"\e056"}.factory-bootstrap-400 .glyphicon-indent-left:before{content:"\e057"}.factory-bootstrap-400 .glyphicon-indent-right:before{content:"\e058"}.factory-bootstrap-400 .glyphicon-facetime-video:before{content:"\e059"}.factory-bootstrap-400 .glyphicon-picture:before{content:"\e060"}.factory-bootstrap-400 .glyphicon-map-marker:before{content:"\e062"}.factory-bootstrap-400 .glyphicon-adjust:before{content:"\e063"}.factory-bootstrap-400 .glyphicon-tint:before{content:"\e064"}.factory-bootstrap-400 .glyphicon-edit:before{content:"\e065"}.factory-bootstrap-400 .glyphicon-share:before{content:"\e066"}.factory-bootstrap-400 .glyphicon-check:before{content:"\e067"}.factory-bootstrap-400 .glyphicon-move:before{content:"\e068"}.factory-bootstrap-400 .glyphicon-step-backward:before{content:"\e069"}.factory-bootstrap-400 .glyphicon-fast-backward:before{content:"\e070"}.factory-bootstrap-400 .glyphicon-backward:before{content:"\e071"}.factory-bootstrap-400 .glyphicon-play:before{content:"\e072"}.factory-bootstrap-400 .glyphicon-pause:before{content:"\e073"}.factory-bootstrap-400 .glyphicon-stop:before{content:"\e074"}.factory-bootstrap-400 .glyphicon-forward:before{content:"\e075"}.factory-bootstrap-400 .glyphicon-fast-forward:before{content:"\e076"}.factory-bootstrap-400 .glyphicon-step-forward:before{content:"\e077"}.factory-bootstrap-400 .glyphicon-eject:before{content:"\e078"}.factory-bootstrap-400 .glyphicon-chevron-left:before{content:"\e079"}.factory-bootstrap-400 .glyphicon-chevron-right:before{content:"\e080"}.factory-bootstrap-400 .glyphicon-plus-sign:before{content:"\e081"}.factory-bootstrap-400 .glyphicon-minus-sign:before{content:"\e082"}.factory-bootstrap-400 .glyphicon-remove-sign:before{content:"\e083"}.factory-bootstrap-400 .glyphicon-ok-sign:before{content:"\e084"}.factory-bootstrap-400 .glyphicon-question-sign:before{content:"\e085"}.factory-bootstrap-400 .glyphicon-info-sign:before{content:"\e086"}.factory-bootstrap-400 .glyphicon-screenshot:before{content:"\e087"}.factory-bootstrap-400 .glyphicon-remove-circle:before{content:"\e088"}.factory-bootstrap-400 .glyphicon-ok-circle:before{content:"\e089"}.factory-bootstrap-400 .glyphicon-ban-circle:before{content:"\e090"}.factory-bootstrap-400 .glyphicon-arrow-left:before{content:"\e091"}.factory-bootstrap-400 .glyphicon-arrow-right:before{content:"\e092"}.factory-bootstrap-400 .glyphicon-arrow-up:before{content:"\e093"}.factory-bootstrap-400 .glyphicon-arrow-down:before{content:"\e094"}.factory-bootstrap-400 .glyphicon-share-alt:before{content:"\e095"}.factory-bootstrap-400 .glyphicon-resize-full:before{content:"\e096"}.factory-bootstrap-400 .glyphicon-resize-small:before{content:"\e097"}.factory-bootstrap-400 .glyphicon-exclamation-sign:before{content:"\e101"}.factory-bootstrap-400 .glyphicon-gift:before{content:"\e102"}.factory-bootstrap-400 .glyphicon-leaf:before{content:"\e103"}.factory-bootstrap-400 .glyphicon-fire:before{content:"\e104"}.factory-bootstrap-400 .glyphicon-eye-open:before{content:"\e105"}.factory-bootstrap-400 .glyphicon-eye-close:before{content:"\e106"}.factory-bootstrap-400 .glyphicon-warning-sign:before{content:"\e107"}.factory-bootstrap-400 .glyphicon-plane:before{content:"\e108"}.factory-bootstrap-400 .glyphicon-calendar:before{content:"\e109"}.factory-bootstrap-400 .glyphicon-random:before{content:"\e110"}.factory-bootstrap-400 .glyphicon-comment:before{content:"\e111"}.factory-bootstrap-400 .glyphicon-magnet:before{content:"\e112"}.factory-bootstrap-400 .glyphicon-chevron-up:before{content:"\e113"}.factory-bootstrap-400 .glyphicon-chevron-down:before{content:"\e114"}.factory-bootstrap-400 .glyphicon-retweet:before{content:"\e115"}.factory-bootstrap-400 .glyphicon-shopping-cart:before{content:"\e116"}.factory-bootstrap-400 .glyphicon-folder-close:before{content:"\e117"}.factory-bootstrap-400 .glyphicon-folder-open:before{content:"\e118"}.factory-bootstrap-400 .glyphicon-resize-vertical:before{content:"\e119"}.factory-bootstrap-400 .glyphicon-resize-horizontal:before{content:"\e120"}.factory-bootstrap-400 .glyphicon-hdd:before{content:"\e121"}.factory-bootstrap-400 .glyphicon-bullhorn:before{content:"\e122"}.factory-bootstrap-400 .glyphicon-bell:before{content:"\e123"}.factory-bootstrap-400 .glyphicon-certificate:before{content:"\e124"}.factory-bootstrap-400 .glyphicon-thumbs-up:before{content:"\e125"}.factory-bootstrap-400 .glyphicon-thumbs-down:before{content:"\e126"}.factory-bootstrap-400 .glyphicon-hand-right:before{content:"\e127"}.factory-bootstrap-400 .glyphicon-hand-left:before{content:"\e128"}.factory-bootstrap-400 .glyphicon-hand-up:before{content:"\e129"}.factory-bootstrap-400 .glyphicon-hand-down:before{content:"\e130"}.factory-bootstrap-400 .glyphicon-circle-arrow-right:before{content:"\e131"}.factory-bootstrap-400 .glyphicon-circle-arrow-left:before{content:"\e132"}.factory-bootstrap-400 .glyphicon-circle-arrow-up:before{content:"\e133"}.factory-bootstrap-400 .glyphicon-circle-arrow-down:before{content:"\e134"}.factory-bootstrap-400 .glyphicon-globe:before{content:"\e135"}.factory-bootstrap-400 .glyphicon-wrench:before{content:"\e136"}.factory-bootstrap-400 .glyphicon-tasks:before{content:"\e137"}.factory-bootstrap-400 .glyphicon-filter:before{content:"\e138"}.factory-bootstrap-400 .glyphicon-briefcase:before{content:"\e139"}.factory-bootstrap-400 .glyphicon-fullscreen:before{content:"\e140"}.factory-bootstrap-400 .glyphicon-dashboard:before{content:"\e141"}.factory-bootstrap-400 .glyphicon-paperclip:before{content:"\e142"}.factory-bootstrap-400 .glyphicon-heart-empty:before{content:"\e143"}.factory-bootstrap-400 .glyphicon-link:before{content:"\e144"}.factory-bootstrap-400 .glyphicon-phone:before{content:"\e145"}.factory-bootstrap-400 .glyphicon-pushpin:before{content:"\e146"}.factory-bootstrap-400 .glyphicon-usd:before{content:"\e148"}.factory-bootstrap-400 .glyphicon-gbp:before{content:"\e149"}.factory-bootstrap-400 .glyphicon-sort:before{content:"\e150"}.factory-bootstrap-400 .glyphicon-sort-by-alphabet:before{content:"\e151"}.factory-bootstrap-400 .glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.factory-bootstrap-400 .glyphicon-sort-by-order:before{content:"\e153"}.factory-bootstrap-400 .glyphicon-sort-by-order-alt:before{content:"\e154"}.factory-bootstrap-400 .glyphicon-sort-by-attributes:before{content:"\e155"}.factory-bootstrap-400 .glyphicon-sort-by-attributes-alt:before{content:"\e156"}.factory-bootstrap-400 .glyphicon-unchecked:before{content:"\e157"}.factory-bootstrap-400 .glyphicon-expand:before{content:"\e158"}.factory-bootstrap-400 .glyphicon-collapse-down:before{content:"\e159"}.factory-bootstrap-400 .glyphicon-collapse-up:before{content:"\e160"}.factory-bootstrap-400 .glyphicon-log-in:before{content:"\e161"}.factory-bootstrap-400 .glyphicon-flash:before{content:"\e162"}.factory-bootstrap-400 .glyphicon-log-out:before{content:"\e163"}.factory-bootstrap-400 .glyphicon-new-window:before{content:"\e164"}.factory-bootstrap-400 .glyphicon-record:before{content:"\e165"}.factory-bootstrap-400 .glyphicon-save:before{content:"\e166"}.factory-bootstrap-400 .glyphicon-open:before{content:"\e167"}.factory-bootstrap-400 .glyphicon-saved:before{content:"\e168"}.factory-bootstrap-400 .glyphicon-import:before{content:"\e169"}.factory-bootstrap-400 .glyphicon-export:before{content:"\e170"}.factory-bootstrap-400 .glyphicon-send:before{content:"\e171"}.factory-bootstrap-400 .glyphicon-floppy-disk:before{content:"\e172"}.factory-bootstrap-400 .glyphicon-floppy-saved:before{content:"\e173"}.factory-bootstrap-400 .glyphicon-floppy-remove:before{content:"\e174"}.factory-bootstrap-400 .glyphicon-floppy-save:before{content:"\e175"}.factory-bootstrap-400 .glyphicon-floppy-open:before{content:"\e176"}.factory-bootstrap-400 .glyphicon-credit-card:before{content:"\e177"}.factory-bootstrap-400 .glyphicon-transfer:before{content:"\e178"}.factory-bootstrap-400 .glyphicon-cutlery:before{content:"\e179"}.factory-bootstrap-400 .glyphicon-header:before{content:"\e180"}.factory-bootstrap-400 .glyphicon-compressed:before{content:"\e181"}.factory-bootstrap-400 .glyphicon-earphone:before{content:"\e182"}.factory-bootstrap-400 .glyphicon-phone-alt:before{content:"\e183"}.factory-bootstrap-400 .glyphicon-tower:before{content:"\e184"}.factory-bootstrap-400 .glyphicon-stats:before{content:"\e185"}.factory-bootstrap-400 .glyphicon-sd-video:before{content:"\e186"}.factory-bootstrap-400 .glyphicon-hd-video:before{content:"\e187"}.factory-bootstrap-400 .glyphicon-subtitles:before{content:"\e188"}.factory-bootstrap-400 .glyphicon-sound-stereo:before{content:"\e189"}.factory-bootstrap-400 .glyphicon-sound-dolby:before{content:"\e190"}.factory-bootstrap-400 .glyphicon-sound-5-1:before{content:"\e191"}.factory-bootstrap-400 .glyphicon-sound-6-1:before{content:"\e192"}.factory-bootstrap-400 .glyphicon-sound-7-1:before{content:"\e193"}.factory-bootstrap-400 .glyphicon-copyright-mark:before{content:"\e194"}.factory-bootstrap-400 .glyphicon-registration-mark:before{content:"\e195"}.factory-bootstrap-400 .glyphicon-cloud-download:before{content:"\e197"}.factory-bootstrap-400 .glyphicon-cloud-upload:before{content:"\e198"}.factory-bootstrap-400 .glyphicon-tree-conifer:before{content:"\e199"}.factory-bootstrap-400 .glyphicon-tree-deciduous:before{content:"\e200"}.factory-bootstrap-400 .caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px solid;border-right:4px solid transparent;border-left:4px solid transparent}.factory-bootstrap-400 .dropdown{position:relative}.factory-bootstrap-400 .dropdown-toggle:focus{outline:0}.factory-bootstrap-400 .dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;list-style:none;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);background-clip:padding-box}.factory-bootstrap-400 .dropdown-menu.pull-right{right:0;left:auto}.factory-bootstrap-400 .dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.factory-bootstrap-400 .dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.428571429;color:#333;white-space:nowrap}.factory-bootstrap-400 .dropdown-menu>li>a:focus,.factory-bootstrap-400 .dropdown-menu>li>a:hover{color:#262626;text-decoration:none}.factory-bootstrap-400 .dropdown-menu>.active>a,.factory-bootstrap-400 .dropdown-menu>.active>a:focus,.factory-bootstrap-400 .dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;outline:0}.factory-bootstrap-400 .dropdown-menu>.disabled>a,.factory-bootstrap-400 .dropdown-menu>.disabled>a:focus,.factory-bootstrap-400 .dropdown-menu>.disabled>a:hover{color:#999}.factory-bootstrap-400 .dropdown-menu>.disabled>a:focus,.factory-bootstrap-400 .dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.factory-bootstrap-400 .open>.dropdown-menu{display:block}.factory-bootstrap-400 .open>a{outline:0}.factory-bootstrap-400 .dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.428571429;color:#999}.factory-bootstrap-400 .dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.factory-bootstrap-400 .pull-right>.dropdown-menu{right:0;left:auto}.factory-bootstrap-400 .dropup .caret,.factory-bootstrap-400 .navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid;content:""}.factory-bootstrap-400 .dropup .dropdown-menu,.factory-bootstrap-400 .navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}}.factory-bootstrap-400 .btn-group,.factory-bootstrap-400 .btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.factory-bootstrap-400 .btn-group-vertical>.btn,.factory-bootstrap-400 .btn-group>.btn{position:relative;float:left}.factory-bootstrap-400 .btn-group-vertical>.btn.active,.factory-bootstrap-400 .btn-group-vertical>.btn:active,.factory-bootstrap-400 .btn-group-vertical>.btn:focus,.factory-bootstrap-400 .btn-group-vertical>.btn:hover,.factory-bootstrap-400 .btn-group>.btn.active,.factory-bootstrap-400 .btn-group>.btn:active,.factory-bootstrap-400 .btn-group>.btn:focus,.factory-bootstrap-400 .btn-group>.btn:hover{z-index:2}.factory-bootstrap-400 .btn-group-vertical>.btn:focus,.factory-bootstrap-400 .btn-group>.btn:focus{outline:0}.factory-bootstrap-400 .btn-group .btn+.btn,.factory-bootstrap-400 .btn-group .btn+.btn-group,.factory-bootstrap-400 .btn-group .btn-group+.btn,.factory-bootstrap-400 .btn-group .btn-group+.btn-group{margin-left:-1px}.factory-bootstrap-400 .btn-toolbar:after,.factory-bootstrap-400 .btn-toolbar:before{display:table;content:" "}.factory-bootstrap-400 .btn-toolbar:after{clear:both}.factory-bootstrap-400 .btn-toolbar .btn-group{float:left}.factory-bootstrap-400 .btn-toolbar>.btn+.btn,.factory-bootstrap-400 .btn-toolbar>.btn+.btn-group,.factory-bootstrap-400 .btn-toolbar>.btn-group+.btn,.factory-bootstrap-400 .btn-toolbar>.btn-group+.btn-group{margin-left:5px}.factory-bootstrap-400 .btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.factory-bootstrap-400 .btn-group>.btn:first-child{margin-left:0}.factory-bootstrap-400 .btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.factory-bootstrap-400 .btn-group>.btn:last-child:not(:first-child),.factory-bootstrap-400 .btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.factory-bootstrap-400 .btn-group>.btn-group{float:left}.factory-bootstrap-400 .btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.factory-bootstrap-400 .btn-group>.btn-group:first-child>.btn:last-child,.factory-bootstrap-400 .btn-group>.btn-group:first-child>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.factory-bootstrap-400 .btn-group>.btn-group:last-child>.btn:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.factory-bootstrap-400 .btn-group .dropdown-toggle:active,.factory-bootstrap-400 .btn-group.open .dropdown-toggle{outline:0}.factory-bootstrap-400 .btn-group-xs>.btn{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.factory-bootstrap-400 .btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.factory-bootstrap-400 .btn-group-lg>.btn{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.factory-bootstrap-400 .btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.factory-bootstrap-400 .btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.factory-bootstrap-400 .btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.factory-bootstrap-400 .btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.factory-bootstrap-400 .btn-group{border:4px solid #f9f9f9;border-radius:4px}.factory-bootstrap-400 .btn-group .btn.active.value{text-shadow:none;color:#fff;background-color:#33aad5;-webkit-box-shadow:inset 0 1px 1px #0074a2;box-shadow:inset 0 1px 3px #0074a2;border-top:1px solid #0074a2;border-bottom:1px solid #0074a2;border-left:1px solid #0074a2}.factory-bootstrap-400 .btn .caret{margin-left:0}.factory-bootstrap-400 .btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.factory-bootstrap-400 .dropup .btn-lg .caret{border-width:0 5px 5px}.factory-bootstrap-400 .btn-group-vertical>.btn,.factory-bootstrap-400 .btn-group-vertical>.btn-group,.factory-bootstrap-400 .btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.factory-bootstrap-400 .btn-group-vertical>.btn-group:after,.factory-bootstrap-400 .btn-group-vertical>.btn-group:before{display:table;content:" "}.factory-bootstrap-400 .btn-group-vertical>.btn-group:after{clear:both}.factory-bootstrap-400 .btn-group-vertical>.btn-group>.btn{float:none}.factory-bootstrap-400 .btn-group-vertical>.btn+.btn,.factory-bootstrap-400 .btn-group-vertical>.btn+.btn-group,.factory-bootstrap-400 .btn-group-vertical>.btn-group+.btn,.factory-bootstrap-400 .btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.factory-bootstrap-400 .btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.factory-bootstrap-400 .btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.factory-bootstrap-400 .btn-group-vertical>.btn:last-child:not(:first-child){border-top-right-radius:0;border-bottom-left-radius:4px;border-top-left-radius:0}.factory-bootstrap-400 .btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.factory-bootstrap-400 .btn-group-vertical>.btn-group:first-child>.btn:last-child,.factory-bootstrap-400 .btn-group-vertical>.btn-group:first-child>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.factory-bootstrap-400 .btn-group-vertical>.btn-group:last-child>.btn:first-child{border-top-right-radius:0;border-top-left-radius:0}.factory-bootstrap-400 .btn-group-justified{display:table;width:100%;border-collapse:separate;table-layout:fixed}.factory-bootstrap-400 .btn-group-justified>.btn,.factory-bootstrap-400 .btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.factory-bootstrap-400 .btn-group-justified>.btn-group .btn{width:100%}[data-toggle=buttons]>.btn>input[type=checkbox],[data-toggle=buttons]>.btn>input[type=radio]{display:none}.factory-bootstrap-400 .input-group{position:relative;display:table;border-collapse:separate}.factory-bootstrap-400 .input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.factory-bootstrap-400 .input-group .form-control{width:100%;margin-bottom:0}.factory-bootstrap-400 .input-group-lg>.form-control,.factory-bootstrap-400 .input-group-lg>.input-group-addon,.factory-bootstrap-400 .input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.factory-bootstrap-400 select.input-group-lg>.form-control,.factory-bootstrap-400 select.input-group-lg>.input-group-addon,.factory-bootstrap-400 select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}.factory-bootstrap-400 textarea.input-group-lg>.form-control,.factory-bootstrap-400 textarea.input-group-lg>.input-group-addon,.factory-bootstrap-400 textarea.input-group-lg>.input-group-btn>.btn{height:auto}.factory-bootstrap-400 .input-group-sm>.form-control,.factory-bootstrap-400 .input-group-sm>.input-group-addon,.factory-bootstrap-400 .input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.factory-bootstrap-400 select.input-group-sm>.form-control,.factory-bootstrap-400 select.input-group-sm>.input-group-addon,.factory-bootstrap-400 select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}.factory-bootstrap-400 textarea.input-group-sm>.form-control,.factory-bootstrap-400 textarea.input-group-sm>.input-group-addon,.factory-bootstrap-400 textarea.input-group-sm>.input-group-btn>.btn{height:auto}.factory-bootstrap-400 .input-group .form-control,.factory-bootstrap-400 .input-group-addon,.factory-bootstrap-400 .input-group-btn{display:table-cell}.factory-bootstrap-400 .input-group .form-control:not(:first-child):not(:last-child),.factory-bootstrap-400 .input-group-addon:not(:first-child):not(:last-child),.factory-bootstrap-400 .input-group-btn:not(:first-child):not(:last-child){border-radius:0}.factory-bootstrap-400 .input-group-addon,.factory-bootstrap-400 .input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.factory-bootstrap-400 .input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.factory-bootstrap-400 .input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.factory-bootstrap-400 .input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.factory-bootstrap-400 .input-group-addon input[type=checkbox],.factory-bootstrap-400 .input-group-addon input[type=radio]{margin-top:0}.factory-bootstrap-400 .input-group .form-control:first-child,.factory-bootstrap-400 .input-group-addon:first-child,.factory-bootstrap-400 .input-group-btn:first-child>.btn,.factory-bootstrap-400 .input-group-btn:first-child>.dropdown-toggle,.factory-bootstrap-400 .input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.factory-bootstrap-400 .input-group-addon:first-child{border-right:0}.factory-bootstrap-400 .input-group .form-control:last-child,.factory-bootstrap-400 .input-group-addon:last-child,.factory-bootstrap-400 .input-group-btn:first-child>.btn:not(:first-child),.factory-bootstrap-400 .input-group-btn:last-child>.btn,.factory-bootstrap-400 .input-group-btn:last-child>.dropdown-toggle{border-bottom-left-radius:0;border-top-left-radius:0}.factory-bootstrap-400 .input-group-addon:last-child{border-left:0}.factory-bootstrap-400 .input-group-btn{position:relative;white-space:nowrap}.factory-bootstrap-400 .input-group-btn:first-child>.btn{margin-right:-1px}.factory-bootstrap-400 .input-group-btn:last-child>.btn{margin-left:-1px}.factory-bootstrap-400 .input-group-btn>.btn{position:relative}.factory-bootstrap-400 .input-group-btn>.btn+.btn{margin-left:-4px}.factory-bootstrap-400 .input-group-btn>.btn:active,.factory-bootstrap-400 .input-group-btn>.btn:hover{z-index:2}.factory-bootstrap-400 .nav{padding-left:0;margin-bottom:0;list-style:none}.factory-bootstrap-400 .nav:after,.factory-bootstrap-400 .nav:before{display:table;content:" "}.factory-bootstrap-400 .nav:after{clear:both}.factory-bootstrap-400 .nav>li{position:relative;display:block}.factory-bootstrap-400 .nav>li>a{position:relative;display:block;padding:10px 15px}.factory-bootstrap-400 .nav>li>a:focus,.factory-bootstrap-400 .nav>li>a:hover{text-decoration:none;background-color:#eee}.factory-bootstrap-400 .nav>li.disabled>a{color:#999}.factory-bootstrap-400 .nav>li.disabled>a:focus,.factory-bootstrap-400 .nav>li.disabled>a:hover{color:#999;text-decoration:none;cursor:not-allowed;background-color:transparent}.factory-bootstrap-400 .nav .open>a,.factory-bootstrap-400 .nav .open>a:focus,.factory-bootstrap-400 .nav .open>a:hover{background-color:#eee;border-color:#428bca}.factory-bootstrap-400 .nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.factory-bootstrap-400 .nav>li>a>img{max-width:none}.factory-bootstrap-400 .nav-tabs{border-bottom:1px solid #ddd}.factory-bootstrap-400 .nav-tabs>li{float:left;margin-bottom:-1px}.factory-bootstrap-400 .nav-tabs>li>a{margin-right:2px;line-height:1.428571429;border:1px solid transparent;border-radius:4px 4px 0 0}.factory-bootstrap-400 .nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.factory-bootstrap-400 .nav-tabs>li.active>a,.factory-bootstrap-400 .nav-tabs>li.active>a:focus,.factory-bootstrap-400 .nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.factory-bootstrap-400 .nav-tabs.nav-justified{width:100%;border-bottom:0}.factory-bootstrap-400 .nav-tabs.nav-justified>li{float:none}.factory-bootstrap-400 .nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.factory-bootstrap-400 .nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.factory-bootstrap-400 .nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.factory-bootstrap-400 .nav-tabs.nav-justified>.active>a,.factory-bootstrap-400 .nav-tabs.nav-justified>.active>a:focus,.factory-bootstrap-400 .nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.factory-bootstrap-400 .nav-pills>li{float:left}.factory-bootstrap-400 .nav-pills>li>a{border-radius:4px}.factory-bootstrap-400 .nav-pills>li+li{margin-left:2px}.factory-bootstrap-400 .nav-pills>li.active>a,.factory-bootstrap-400 .nav-pills>li.active>a:focus,.factory-bootstrap-400 .nav-pills>li.active>a:hover{color:#fff;background-color:#428bca}.factory-bootstrap-400 .nav-stacked>li{float:none}.factory-bootstrap-400 .nav-stacked>li+li{margin-top:2px;margin-left:0}.factory-bootstrap-400 .nav-justified{width:100%}.factory-bootstrap-400 .nav-justified>li{float:none}.factory-bootstrap-400 .nav-justified>li>a{margin-bottom:5px;text-align:center}.factory-bootstrap-400 .nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.factory-bootstrap-400 .nav-tabs-justified{border-bottom:0}.factory-bootstrap-400 .nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.factory-bootstrap-400 .nav-tabs-justified>.active>a,.factory-bootstrap-400 .nav-tabs-justified>.active>a:focus,.factory-bootstrap-400 .nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.factory-bootstrap-400 .tab-content>.tab-pane{display:none}.factory-bootstrap-400 .tab-content>.active{display:block}.factory-bootstrap-400 .nav-tabs .dropdown-menu{margin-top:-1px;border-top-right-radius:0;border-top-left-radius:0}.factory-bootstrap-400 .navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}.factory-bootstrap-400 .navbar:after,.factory-bootstrap-400 .navbar:before{display:table;content:" "}.factory-bootstrap-400 .navbar:after{clear:both}@media (min-width:768px){.navbar{border-radius:4px}}.factory-bootstrap-400 .navbar-header:after,.factory-bootstrap-400 .navbar-header:before{display:table;content:" "}.factory-bootstrap-400 .navbar-header:after{clear:both}@media (min-width:768px){.navbar-header{float:left}}.factory-bootstrap-400 .navbar-collapse{max-height:340px;padding-right:15px;padding-left:15px;overflow-x:visible;border-top:1px solid transparent;box-shadow:inset 0 1px 0 rgba(255,255,255,.1);-webkit-overflow-scrolling:touch}.factory-bootstrap-400 .navbar-collapse:after,.factory-bootstrap-400 .navbar-collapse:before{display:table;content:" "}.factory-bootstrap-400 .navbar-collapse:after{clear:both}.factory-bootstrap-400 .navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.factory-bootstrap-400 .container>.navbar-collapse,.factory-bootstrap-400 .container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.factory-bootstrap-400 .navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.factory-bootstrap-400 .navbar-fixed-bottom,.factory-bootstrap-400 .navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.factory-bootstrap-400 .navbar-fixed-top{top:0;border-width:0 0 1px}.factory-bootstrap-400 .navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.factory-bootstrap-400 .navbar-brand{float:left;padding:15px;font-size:18px;line-height:20px}.factory-bootstrap-400 .navbar-brand:focus,.factory-bootstrap-400 .navbar-brand:hover{text-decoration:none}@media (min-width:768px){.navbar>.container .navbar-brand{margin-left:-15px}}.factory-bootstrap-400 .navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.factory-bootstrap-400 .navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.factory-bootstrap-400 .navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.factory-bootstrap-400 .navbar-nav{margin:7.5px -15px}.factory-bootstrap-400 .navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}.navbar-nav.navbar-right:last-child{margin-right:-15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important}}.factory-bootstrap-400 .navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block}.navbar-form select.form-control{width:auto}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;padding-left:0;margin-top:0;margin-bottom:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{float:none;margin-left:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-form.navbar-right:last-child{margin-right:-15px}}.factory-bootstrap-400 .navbar-nav>li>.dropdown-menu{margin-top:0;border-top-right-radius:0;border-top-left-radius:0}.factory-bootstrap-400 .navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{border-bottom-right-radius:0;border-bottom-left-radius:0}.factory-bootstrap-400 .navbar-nav.pull-right>li>.dropdown-menu,.factory-bootstrap-400 .navbar-nav>li>.dropdown-menu.pull-right{right:0;left:auto}.factory-bootstrap-400 .navbar-btn{margin-top:8px;margin-bottom:8px}.factory-bootstrap-400 .navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.factory-bootstrap-400 .navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.factory-bootstrap-400 .navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}.navbar-text.navbar-right:last-child{margin-right:0}}.factory-bootstrap-400 .navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.factory-bootstrap-400 .navbar-default .navbar-brand{color:#777}.factory-bootstrap-400 .navbar-default .navbar-brand:focus,.factory-bootstrap-400 .navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.factory-bootstrap-400 .navbar-default .navbar-nav>li>a,.factory-bootstrap-400 .navbar-default .navbar-text{color:#777}.factory-bootstrap-400 .navbar-default .navbar-nav>li>a:focus,.factory-bootstrap-400 .navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.factory-bootstrap-400 .navbar-default .navbar-nav>.active>a,.factory-bootstrap-400 .navbar-default .navbar-nav>.active>a:focus,.factory-bootstrap-400 .navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.factory-bootstrap-400 .navbar-default .navbar-nav>.disabled>a,.factory-bootstrap-400 .navbar-default .navbar-nav>.disabled>a:focus,.factory-bootstrap-400 .navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.factory-bootstrap-400 .navbar-default .navbar-toggle{border-color:#ddd}.factory-bootstrap-400 .navbar-default .navbar-toggle:focus,.factory-bootstrap-400 .navbar-default .navbar-toggle:hover{background-color:#ddd}.factory-bootstrap-400 .navbar-default .navbar-toggle .icon-bar{background-color:#ccc}.factory-bootstrap-400 .navbar-default .navbar-collapse,.factory-bootstrap-400 .navbar-default .navbar-form{border-color:#e7e7e7}.factory-bootstrap-400 .navbar-default .navbar-nav>.open>a,.factory-bootstrap-400 .navbar-default .navbar-nav>.open>a:focus,.factory-bootstrap-400 .navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.factory-bootstrap-400 .navbar-default .navbar-link{color:#777}.factory-bootstrap-400 .navbar-default .navbar-link:hover{color:#333}.factory-bootstrap-400 .navbar-inverse{background-color:#222;border-color:#080808}.factory-bootstrap-400 .navbar-inverse .navbar-brand{color:#999}.factory-bootstrap-400 .navbar-inverse .navbar-brand:focus,.factory-bootstrap-400 .navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.factory-bootstrap-400 .navbar-inverse .navbar-nav>li>a,.factory-bootstrap-400 .navbar-inverse .navbar-text{color:#999}.factory-bootstrap-400 .navbar-inverse .navbar-nav>li>a:focus,.factory-bootstrap-400 .navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.factory-bootstrap-400 .navbar-inverse .navbar-nav>.active>a,.factory-bootstrap-400 .navbar-inverse .navbar-nav>.active>a:focus,.factory-bootstrap-400 .navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.factory-bootstrap-400 .navbar-inverse .navbar-nav>.disabled>a,.factory-bootstrap-400 .navbar-inverse .navbar-nav>.disabled>a:focus,.factory-bootstrap-400 .navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.factory-bootstrap-400 .navbar-inverse .navbar-toggle{border-color:#333}.factory-bootstrap-400 .navbar-inverse .navbar-toggle:focus,.factory-bootstrap-400 .navbar-inverse .navbar-toggle:hover{background-color:#333}.factory-bootstrap-400 .navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.factory-bootstrap-400 .navbar-inverse .navbar-collapse,.factory-bootstrap-400 .navbar-inverse .navbar-form{border-color:#101010}.factory-bootstrap-400 .navbar-inverse .navbar-nav>.open>a,.factory-bootstrap-400 .navbar-inverse .navbar-nav>.open>a:focus,.factory-bootstrap-400 .navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#999}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.factory-bootstrap-400 .navbar-inverse .navbar-link{color:#999}.factory-bootstrap-400 .navbar-inverse .navbar-link:hover{color:#fff}.factory-bootstrap-400 .breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.factory-bootstrap-400 .breadcrumb>li{display:inline-block}.factory-bootstrap-400 .breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.factory-bootstrap-400 .breadcrumb>.active{color:#999}.factory-bootstrap-400 .pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.factory-bootstrap-400 .pagination>li{display:inline}.factory-bootstrap-400 .pagination>li>a,.factory-bootstrap-400 .pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.428571429;text-decoration:none;background-color:#fff;border:1px solid #ddd}.factory-bootstrap-400 .pagination>li:first-child>a,.factory-bootstrap-400 .pagination>li:first-child>span{margin-left:0;border-bottom-left-radius:4px;border-top-left-radius:4px}.factory-bootstrap-400 .pagination>li:last-child>a,.factory-bootstrap-400 .pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.factory-bootstrap-400 .pagination>li>a:focus,.factory-bootstrap-400 .pagination>li>a:hover,.factory-bootstrap-400 .pagination>li>span:focus,.factory-bootstrap-400 .pagination>li>span:hover{background-color:#eee}.factory-bootstrap-400 .pagination>.active>a,.factory-bootstrap-400 .pagination>.active>a:focus,.factory-bootstrap-400 .pagination>.active>a:hover,.factory-bootstrap-400 .pagination>.active>span,.factory-bootstrap-400 .pagination>.active>span:focus,.factory-bootstrap-400 .pagination>.active>span:hover{z-index:2;color:#fff;cursor:default;background-color:#1e8cbe;border-color:#0074a2}.factory-bootstrap-400 .pagination>.disabled>a,.factory-bootstrap-400 .pagination>.disabled>a:focus,.factory-bootstrap-400 .pagination>.disabled>a:hover,.factory-bootstrap-400 .pagination>.disabled>span,.factory-bootstrap-400 .pagination>.disabled>span:focus,.factory-bootstrap-400 .pagination>.disabled>span:hover{color:#999;cursor:not-allowed;background-color:#fff;border-color:#ddd}.factory-bootstrap-400 .pagination-lg>li>a,.factory-bootstrap-400 .pagination-lg>li>span{padding:10px 16px;font-size:18px}.factory-bootstrap-400 .pagination-lg>li:first-child>a,.factory-bootstrap-400 .pagination-lg>li:first-child>span{border-bottom-left-radius:6px;border-top-left-radius:6px}.factory-bootstrap-400 .pagination-lg>li:last-child>a,.factory-bootstrap-400 .pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.factory-bootstrap-400 .pagination-sm>li>a,.factory-bootstrap-400 .pagination-sm>li>span{padding:5px 10px;font-size:12px}.factory-bootstrap-400 .pagination-sm>li:first-child>a,.factory-bootstrap-400 .pagination-sm>li:first-child>span{border-bottom-left-radius:3px;border-top-left-radius:3px}.factory-bootstrap-400 .pagination-sm>li:last-child>a,.factory-bootstrap-400 .pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.factory-bootstrap-400 .pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.factory-bootstrap-400 .pager:after,.factory-bootstrap-400 .pager:before{display:table;content:" "}.factory-bootstrap-400 .pager:after{clear:both}.factory-bootstrap-40
8
  */
9
 
10