PluginProbe
Autoptimize / trunk
Autoptimize vtrunk
3.1.16 2.2.2 2.3.0 2.3.1 2.3.2 2.3.3 2.3.4 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.5.0 2.5.1 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 All 108 releases
autoptimize / classes / autoptimizeConfig.php

autoptimizeConfig.php in Autoptimize trunk, at classes/autoptimizeConfig.php

1,117 lines 54.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Main configuration logic.
4 */
5
6 if ( ! defined( 'ABSPATH' ) ) {
7 exit;
8 }
9
10 class autoptimizeConfig
11 {
12 /**
13 * Options.
14 *
15 * @var array
16 */
17 private $config = null;
18
19 /**
20 * Singleton instance.
21 *
22 * @var self|null
23 */
24 static private $instance = null;
25
26 /**
27 * Options.
28 *
29 * @var bool
30 */
31 private $settings_screen_do_remote_http = true;
32
33 /**
34 * Singleton.
35 */
36 private function __construct()
37 {
38 if ( is_admin() ) {
39 // Add the admin page and settings.
40 if ( autoptimizeOptionWrapper::is_ao_active_for_network() ) {
41 add_action( 'network_admin_menu', array( $this, 'addmenu' ) );
42 }
43
44 add_action( 'admin_menu', array( $this, 'addmenu' ) );
45 add_action( 'admin_init', array( $this, 'registersettings' ) );
46 add_action( 'admin_init', array( 'PAnD', 'init' ) );
47
48 // Set meta info.
49 if ( function_exists( 'plugin_row_meta' ) ) {
50 // 2.8 and higher.
51 add_filter( 'plugin_row_meta', array( $this, 'setmeta' ), 10, 2 );
52 } elseif ( function_exists( 'post_class' ) ) {
53 // 2.7 and lower.
54 $plugin = plugin_basename( AUTOPTIMIZE_PLUGIN_DIR . 'autoptimize.php' );
55 add_filter( 'plugin_action_links_' . $plugin, array( $this, 'setmeta' ) );
56 }
57
58 // Clean cache?
59 if ( autoptimizeOptionWrapper::get_option( 'autoptimize_cache_clean' ) ) {
60 autoptimizeCache::clearall();
61 autoptimizeOptionWrapper::update_option( 'autoptimize_cache_clean', 0 );
62 }
63
64 $this->settings_screen_do_remote_http = apply_filters( 'autoptimize_settingsscreen_remotehttp', $this->settings_screen_do_remote_http );
65
66 if ( $this->is_ao_meta_settings_active() ) {
67 $meta_box = new autoptimizeMetabox();
68 }
69 }
70
71 // Adds the Autoptimize Toolbar to the Admin bar.
72 // (we load outside the is_admin check so it's also displayed on the frontend toolbar).
73 $toolbar = new autoptimizeToolbar();
74 }
75
76 /**
77 * Instantiates aoconfig.
78 *
79 * @return autoptimizeConfig
80 */
81 static public function instance()
82 {
83 // Only one instance.
84 if ( null === self::$instance ) {
85 self::$instance = new autoptimizeConfig();
86 }
87
88 return self::$instance;
89 }
90
91 public function show_network_message() {
92 ?>
93 <div class="wrap">
94 <h1><?php esc_html_e( 'Autoptimize Settings', 'autoptimize' ); ?></h1>
95 <?php echo $this->ao_admin_tabs(); ?>
96 <p style="font-size:120%;"><?php echo apply_filters( 'autoptimize_filter_settingsscreen_multisite_network_message', esc_html__( 'Autoptimize is enabled and configured on a WordPress network level. Please contact your network administrator if you need Autoptimize settings changed.', 'autoptimize' ) ); ?></p>
97 </div>
98 <?php
99 }
100
101 public function show_config()
102 {
103 // phpcs:disable Generic.WhiteSpace.ScopeIndent.IncorrectExact
104 // phpcs:disable Generic.WhiteSpace.ScopeIndent.Incorrect
105 $conf = self::instance();
106 ?>
107 <style>
108 /* title and button */
109 #ao_title_and_button:after {content:''; display:block; clear:both;}
110
111 /* form */
112 .itemDetail {
113 background: #fff;
114 border: 1px solid #ccc;
115 padding: 15px;
116 margin: 15px 10px 10px 0;
117 }
118 .itemTitle {
119 margin-top: 0;
120 }
121
122 .form-table th{font-weight:normal;}
123 #autoptimize_main form input:invalid {box-shadow: 0 0 1px 1px red;}
124 #autoptimize_main .cb_label {display: block; padding-left: 25px; text-indent: -25px;}
125 #autoptimize_main .form-table th {padding-top: 15px; padding-bottom: 15px;}
126 #autoptimize_main .js_aggregate td, #autoptimize_main .js_aggregate th, #autoptimize_main .js_not_aggregate td, #autoptimize_main .js_not_aggregate th{padding-top:0px;}
127
128 /* rss block */
129 #futtta_feed ul{list-style:outside;}
130 #futtta_feed {font-size:medium; margin:0px 20px;}
131
132 /* banner + unslider */
133 .autoptimize_banner {
134 margin: 0 38px;
135 padding-bottom: 5px;
136 }
137 .autoptimize_banner ul li {
138 font-size:medium;
139 text-align:center;
140 }
141 .unslider {
142 position:relative;
143 }
144 .unslider-arrow {
145 display: block;
146 left: unset;
147 margin-top: -35px;
148 margin-left: 7px;
149 margin-right: 7px;
150 border-radius: 32px;
151 background: rgba(0, 0, 0, 0.10) no-repeat 50% 50%;
152 color: rgba(255, 255, 255, 0.8);
153 font: normal 20px/1 dashicons;
154 speak: none;
155 padding: 3px 2px 3px 4px;
156 -webkit-font-smoothing: antialiased;
157 -moz-osx-font-smoothing: grayscale;
158 }
159 .unslider-arrow:hover {
160 background-color: rgba(0, 0, 0, 0.20);
161 color: #FFF;
162 }
163 .unslider-arrow.prev {
164 padding: 3px 4px 3px 2px;
165 }
166 .unslider-arrow.next {
167 right: 0px;
168 }
169 .unslider-arrow.prev::before {
170 content: "\f341";
171 }
172 .unslider-arrow.next::before {
173 content: "\f345";
174 }
175
176 /* responsive stuff: hide admin-feed on smaller screens */
177 @media (min-width: 961px) {
178 #autoptimize_main {float:left;width:69%;}
179 #autoptimize_admin_feed{float:right;width:30%;display:block !important;}
180 }
181 @media (max-width: 960px) {
182 #autoptimize_main {width:100%;}
183 #autoptimize_admin_feed {width:0%;display:none !important;}
184 }
185 @media (max-width: 782px) {
186 #autoptimize_main input[type="checkbox"] {margin-left: 10px;}
187 #autoptimize_main .cb_label {display: block; padding-left: 45px; text-indent: -45px;}
188 }
189 </style>
190
191 <div class="wrap">
192
193 <div id="autoptimize_main">
194 <h1 id="ao_title"><?php apply_filters( 'autoptimize_filter_settings_is_pro', false ) ? esc_html_e( 'Autoptimize Pro Settings', 'autoptimize' ) : esc_html_e( 'Autoptimize Settings', 'autoptimize' ); ?></h1>
195 <?php echo $this->ao_admin_tabs(); ?>
196
197 <form method="post" action="<?php echo admin_url( 'options.php' ); ?>">
198 <?php settings_fields( 'autoptimize' ); ?>
199
200 <ul>
201
202 <?php
203 // Only show enable site configuration in network site option.
204 if ( is_network_admin() && autoptimizeOptionWrapper::is_ao_active_for_network() ) {
205 ?>
206 <li class="itemDetail multiSite">
207 <h2 class="itemTitle"><?php esc_html_e( 'Multisite Options', 'autoptimize' ); ?></h2>
208 <table class="form-table">
209 <tr valign="top">
210 <th scope="row"><?php esc_html_e( 'Enable site configuration?', 'autoptimize' ); ?></th>
211 <td><label class="cb_label"><input type="checkbox" id="autoptimize_enable_site_config" name="autoptimize_enable_site_config" <?php echo autoptimizeOptionWrapper::get_option( 'autoptimize_enable_site_config' ) ? 'checked="checked" ' : ''; ?>/>
212 <?php esc_html_e( 'Enable Autoptimize configuration per site.', 'autoptimize' ); ?></label></td>
213 </tr>
214 </table>
215 </li>
216 <?php } else { ?>
217 <input type="hidden" id="autoptimize_enable_site_config" name="autoptimize_enable_site_config" value="on" />
218 <?php } ?>
219
220 <li class="itemDetail">
221 <h2 class="itemTitle"><?php esc_html_e( 'JavaScript Options', 'autoptimize' ); ?></h2>
222 <table class="form-table">
223 <tr valign="top">
224 <th scope="row"><?php esc_html_e( 'Optimize JavaScript Code?', 'autoptimize' ); ?></th>
225 <td><input type="checkbox" id="autoptimize_js" name="autoptimize_js" <?php echo $conf->get( 'autoptimize_js' ) ? 'checked="checked" ' : ''; ?>/></td>
226 </tr>
227 <tr valign="top" class="js_sub js_aggregate_master">
228 <th scope="row"><?php esc_html_e( 'Aggregate JS-files?', 'autoptimize' ); ?></th>
229 <td><label class="cb_label"><input type="checkbox" id="autoptimize_js_aggregate" name="autoptimize_js_aggregate" <?php echo $conf->get( 'autoptimize_js_aggregate' ) ? 'checked="checked" ' : ''; ?>/>
230 <?php esc_html_e( 'Aggregate all linked JS-files to have them loaded non-render blocking?', 'autoptimize' ); ?></label></td>
231 </tr>
232 <tr valign="top" class="js_sub js_aggregate hidden">
233 <th scope="row">&emsp;<?php esc_html_e( 'Also aggregate inline JS?', 'autoptimize' ); ?></th>
234 <td><label class="cb_label"><input type="checkbox" name="autoptimize_js_include_inline" <?php echo $conf->get( 'autoptimize_js_include_inline' ) ? 'checked="checked" ' : ''; ?>/>
235 <?php esc_html_e( 'Let Autoptimize also extract JS from the HTML (discouraged as it can make Autoptimize\'s cache size grow quickly)', 'autoptimize' ); ?></label></td>
236 </tr>
237 <tr valign="top" class="js_sub js_aggregate hidden">
238 <th scope="row">&emsp;<?php esc_html_e( 'Force JavaScript in &lt;head&gt;?', 'autoptimize' ); ?></th>
239 <td><label class="cb_label"><input type="checkbox" name="autoptimize_js_forcehead" <?php echo $conf->get( 'autoptimize_js_forcehead' ) ? 'checked="checked" ' : ''; ?>/>
240 <?php esc_html_e( 'Load JavaScript early (discouraged as it makes the JS render blocking)', 'autoptimize' ); ?></label></td>
241 </tr>
242 <tr valign="top" class="js_sub js_aggregate hidden">
243 <th scope="row">&emsp;<?php esc_html_e( 'Add try-catch wrapping?', 'autoptimize' ); ?></th>
244 <td><label class="cb_label"><input type="checkbox" name="autoptimize_js_trycatch" <?php echo $conf->get( 'autoptimize_js_trycatch' ) ? 'checked="checked" ' : ''; ?>/>
245 <?php esc_html_e( 'If your aggregated scripts break because of a JS-error, you might want to try this, but generally discouraged.', 'autoptimize' ); ?></label></td>
246 </tr>
247 <tr valign="top" class="js_sub js_not_aggregate_master">
248 <th scope="row"><?php esc_html_e( 'Do not aggregate but defer?', 'autoptimize' ); ?></th>
249 <td><label class="cb_label"><input type="checkbox" id="autoptimize_js_defer_not_aggregate" name="autoptimize_js_defer_not_aggregate" <?php echo $conf->get( 'autoptimize_js_defer_not_aggregate' ) ? 'checked="checked" ' : ''; ?>/>
250 <?php esc_html_e( 'Individual JS-files will be minified and deferred, making them non-render-blocking.', 'autoptimize' ); ?></label></td>
251 </tr>
252 <tr valign="top" id="js_defer_inline" class="js_sub js_not_aggregate hidden">
253 <th scope="row">&emsp;<?php esc_html_e( 'Also defer inline JS?', 'autoptimize' ); ?></th>
254 <td><label class="cb_label"><input type="checkbox" name="autoptimize_js_defer_inline" <?php echo $conf->get( 'autoptimize_js_defer_inline' ) ? 'checked="checked" ' : ''; ?>/>
255 <?php esc_html_e( 'Also defer inline JS. Generally this will allow all JS to be deferred, so you should remove default exclusions, test and only exclude specific items if still needed.', 'autoptimize' ); ?></label></td>
256 </tr>
257 <?php if ( autoptimizeOptionWrapper::get_option( 'autoptimize_js_justhead' ) ) { ?>
258 <tr valign="top" class="js_sub js_aggregate">
259 <th scope="row">
260 <?php
261 esc_html_e( 'Look for scripts only in &lt;head&gt;?', 'autoptimize' );
262 echo ' <i>' . esc_html__( '(deprecated)', 'autoptimize' ) . '</i>';
263 ?>
264 </th>
265 <td><label class="cb_label"><input type="checkbox" name="autoptimize_js_justhead" <?php echo $conf->get( 'autoptimize_js_justhead' ) ? 'checked="checked" ' : ''; ?>/>
266 <?php esc_html_e( 'Mostly useful in combination with previous option when using jQuery-based templates, but might help keeping cache size under control.', 'autoptimize' ); ?></label></td>
267 </tr>
268 <?php } ?>
269 <tr valign="top" class="js_sub">
270 <th scope="row"><?php esc_html_e( 'Exclude scripts from Autoptimize:', 'autoptimize' ); ?></th>
271 <td><label><input type="text" pattern="[^\*]*" style="width:100%;" name="autoptimize_js_exclude" value="<?php echo esc_attr( autoptimizeOptionWrapper::get_option( 'autoptimize_js_exclude', '' ) ); ?>"/><br />
272 <?php
273 echo esc_html__( 'A comma-separated list of scripts you do not want optimized, for example \'whatever.js, my_var\' (without the quotes).', 'autoptimize' ) . ' ' . esc_html__( 'Important: when "aggregate JS-files" is on, excluded non-minified files are still minified by Autoptimize unless that option under "misc" is disabled.', 'autoptimize' );
274 ?>
275 </label></td>
276 </tr>
277 <tr valign="top">
278 <th scope="row"><?php esc_html_e( 'Remove Unused JavaScript?', 'autoptimize' ); ?></th>
279 <td><?php esc_html_e( 'Autoptimize combines your theme & plugins\' JavaScript, but does not know what is used and what is not. If Google Pagespeed Insights detects unused JavaScript, consider using a plugin like "Plugin Organizer" or similar to manage what JavaScript is added where.', 'autoptimize' ); ?></td>
280 </tr>
281 </table>
282 </li>
283
284 <li class="itemDetail">
285 <h2 class="itemTitle"><?php esc_html_e( 'CSS Options', 'autoptimize' ); ?></h2>
286 <table class="form-table">
287 <tr valign="top">
288 <th scope="row"><?php esc_html_e( 'Optimize CSS Code?', 'autoptimize' ); ?></th>
289 <td><input type="checkbox" id="autoptimize_css" name="autoptimize_css" <?php echo $conf->get( 'autoptimize_css' ) ? 'checked="checked" ' : ''; ?>/></td>
290 </tr>
291 <tr class="css_sub" valign="top">
292 <th scope="row"><?php esc_html_e( 'Aggregate CSS-files?', 'autoptimize' ); ?></th>
293 <td><label class="cb_label"><input type="checkbox" id="autoptimize_css_aggregate" name="autoptimize_css_aggregate" <?php echo $conf->get( 'autoptimize_css_aggregate' ) ? 'checked="checked" ' : ''; ?>/>
294 <?php esc_html_e( 'Aggregate all linked CSS-files? If this option is off, the individual CSS-files will remain in place but will be minified.', 'autoptimize' ); ?></label></td>
295 </tr>
296 <tr valign="top" class="css_sub css_aggregate">
297 <th scope="row"><?php esc_html_e( 'Also aggregate inline CSS?', 'autoptimize' ); ?></th>
298 <td><label class="cb_label"><input type="checkbox" name="autoptimize_css_include_inline" <?php echo $conf->get( 'autoptimize_css_include_inline', '1' ) ? 'checked="checked" ' : ''; ?>/>
299 <?php esc_html_e( 'Check this option for Autoptimize to also aggregate CSS in the HTML.', 'autoptimize' ); ?></label></td>
300 </tr>
301 <tr class="css_sub css_aggregate" valign="top">
302 <th scope="row"><?php esc_html_e( 'Generate data: URIs for images?', 'autoptimize' ); ?></th>
303 <td><label class="cb_label"><input type="checkbox" name="autoptimize_css_datauris" <?php echo $conf->get( 'autoptimize_css_datauris' ) ? 'checked="checked" ' : ''; ?>/>
304 <?php esc_html_e( 'Enable this to include small background images in the CSS itself instead of as separate downloads.', 'autoptimize' ); ?></label></td>
305 </tr>
306 <?php if ( autoptimizeOptionWrapper::get_option( 'autoptimize_css_justhead' ) ) { ?>
307 <tr valign="top" class="css_sub css_aggregate">
308 <th scope="row">
309 <?php
310 esc_html_e( 'Look for styles only in &lt;head&gt;?', 'autoptimize' );
311 echo ' <i>' . esc_html__( '(deprecated)', 'autoptimize' ) . '</i>';
312 ?>
313 </th>
314 <td><label class="cb_label"><input type="checkbox" name="autoptimize_css_justhead" <?php echo $conf->get( 'autoptimize_css_justhead' ) ? 'checked="checked" ' : ''; ?>/>
315 <?php esc_html_e( 'Don\'t autoptimize CSS outside the head-section. If the cache gets big, you might want to enable this.', 'autoptimize' ); ?></label></td>
316 </tr>
317 <?php } ?>
318 <tr valign="top" class="css_sub">
319 <th scope="row"><?php esc_html_e( 'Eliminate render-blocking CSS?', 'autoptimize' ); ?></th>
320 <td><label class="cb_label"><input type="checkbox" name="autoptimize_css_defer" id="autoptimize_css_defer" <?php echo $conf->get( 'autoptimize_css_defer' ) ? 'checked="checked" ' : ''; ?>/>
321 <?php
322 _e( 'Inline "above the fold CSS" while loading the main autoptimized CSS only after page load. <a href="https://wordpress.org/plugins/autoptimize/faq/" target="_blank">Check the FAQ</a> for more info.', 'autoptimize' );
323 echo ' ';
324 $critcss_settings_url = get_admin_url( null, 'options-general.php?page=ao_critcss' );
325 // translators: links "autoptimize critical CSS" tab.
326 echo sprintf( esc_html__( 'You can manually create rules for different types of pages or have this done fully automated on the %s tab.', 'autoptimize' ), '<a href="' . $critcss_settings_url . '">CriticalCSS</a>' );
327 ?>
328 </label></td>
329 </tr>
330 <tr valign="top" class="css_sub" id="autoptimize_css_defer_inline">
331 <th scope="row"></th>
332 <td><label><textarea rows="10" cols="10" style="width:100%;" spellcheck="false" placeholder="<?php esc_html_e( 'Paste the above the fold CSS here. You can leave this empty when using the automated Critical CSS integration.', 'autoptimize' ); ?>" name="autoptimize_css_defer_inline"><?php echo autoptimizeStyles::sanitize_css( autoptimizeOptionWrapper::get_option( 'autoptimize_css_defer_inline' ) ); ?></textarea></label></td>
333 </tr>
334 <tr valign="top" class="css_sub css_aggregate">
335 <th scope="row"><?php esc_html_e( 'Inline all CSS?', 'autoptimize' ); ?></th>
336 <td><label class="cb_label"><input type="checkbox" id="autoptimize_css_inline" name="autoptimize_css_inline" <?php echo $conf->get( 'autoptimize_css_inline' ) ? 'checked="checked" ' : ''; ?>/>
337 <?php esc_html_e( 'Inlining all CSS is an easy way to stop the CSS from being render-blocking, but is generally not recommended because the size of the HTML increases significantly. Additionally, it might push meta-tags down to a position where e.g. Facebook and Whatsapp will not find them anymore, breaking thumbnails when sharing.', 'autoptimize' ); ?></label></td>
338 </tr>
339 <tr valign="top" class="css_sub">
340 <th scope="row"><?php esc_html_e( 'Exclude CSS from Autoptimize:', 'autoptimize' ); ?></th>
341 <td><label><input type="text" pattern="[^\*]*" style="width:100%;" name="autoptimize_css_exclude" value="<?php echo esc_attr( $conf->get( 'autoptimize_css_exclude', '' ) ); ?>"/><br />
342 <?php
343 echo esc_html__( 'A comma-separated list of CSS you want to exclude from being optimized.', 'autoptimize' ) . ' ' . esc_html__( 'Important: excluded non-minified files are still minified by Autoptimize unless that option under "misc" is disabled.', 'autoptimize' );
344 ?>
345 </label></td>
346 </tr>
347 <?php
348 $_availabilities = autoptimizeOptionWrapper::get_option( 'autoptimize_service_availablity' );
349 if ( empty( $_availabilities ) || ! is_array( $_availabilities ) || ! array_key_exists( 'rapidload', $_availabilities ) || ! array_key_exists( 'status', $_availabilities['rapidload'] ) ) {
350 $rapidload_true = true;
351 } else if ( $_availabilities['rapidload']['status'] === 'up' ) {
352 $rapidload_true = true;
353 } else if ( $_availabilities['rapidload']['status'] !== 'up' ) {
354 $rapidload_true = false;
355 } else {
356 $rapidload_true = false;
357 }
358 ?>
359 <?php if ( $rapidload_true && false === autoptimizeUtils::is_plugin_active( 'unusedcss/unusedcss.php' ) ) { ?>
360 <tr valign="top">
361 <th scope="row"><?php esc_html_e( 'Remove Unused CSS?', 'autoptimize' ); ?></th>
362 <?php
363 $_rapidload_link = 'https://misc.optimizingmatters.com/partners/?from=csssettings&partner=rapidload';
364 ?>
365 <td><?php
366 // translators: a link to rapidload + strong tags
367 echo sprintf( esc_html__( 'If Google Pagespeed Insights detects unused CSS, consider using %1$sthe premium Rapidload service%2$s to %3$sreduce your site\'s CSS size to up to 90&#37;%4$s, resulting in a slimmer, faster site!', 'autoptimize' ), '<a href="' . $_rapidload_link . '" target="_blank">', '</a>', '<strong>', '</strong>' ); ?></td>
368 </tr>
369 <?php } ?>
370 </table>
371 </li>
372
373 <li class="itemDetail">
374 <h2 class="itemTitle"><?php esc_html_e( 'HTML Options', 'autoptimize' ); ?></h2>
375 <table class="form-table">
376 <tr valign="top">
377 <th scope="row"><?php esc_html_e( 'Optimize HTML Code?', 'autoptimize' ); ?></th>
378 <td><input type="checkbox" id="autoptimize_html" name="autoptimize_html" <?php echo $conf->get( 'autoptimize_html' ) ? 'checked="checked" ' : ''; ?>/></td>
379 </tr>
380 <tr class="html_sub" valign="top">
381 <th scope="row"><?php esc_html_e( 'Also minify inline JS/ CSS?', 'autoptimize' ); ?></th>
382 <td><label class="cb_label"><input type="checkbox" name="autoptimize_html_minify_inline" <?php echo $conf->get( 'autoptimize_html_minify_inline' ) ? 'checked="checked" ' : ''; ?>/>
383 <?php esc_html_e( 'Enable this if you want inline JS or CSS to be minified as well.', 'autoptimize' ); ?></label></td>
384 </tr>
385 <tr class="html_sub" valign="top">
386 <th scope="row"><?php esc_html_e( 'Keep HTML comments?', 'autoptimize' ); ?></th>
387 <td><label class="cb_label"><input type="checkbox" name="autoptimize_html_keepcomments" <?php echo $conf->get( 'autoptimize_html_keepcomments' ) ? 'checked="checked" ' : ''; ?>/>
388 <?php esc_html_e( 'Enable this if you want HTML comments to remain in the page.', 'autoptimize' ); ?></label></td>
389 </tr>
390 </table>
391 </li>
392
393 <li class="itemDetail">
394 <h2 class="itemTitle"><?php esc_html_e( 'CDN Options', 'autoptimize' ); ?></h2>
395 <table class="form-table">
396 <tr valign="top">
397 <th scope="row"><?php esc_html_e( 'CDN Base URL', 'autoptimize' ); ?></th>
398 <?php
399 if ( true === autoptimizeImages::imgopt_active() && true === apply_filters( 'autoptimize_filter_cdn_set_by_imgopt', false ) ) {
400 // cdn set by imgopt, not to be changealbe in the settings.
401 $cdn_editable = 'disabled';
402 $cdn_placeholder = 'placeholder="' . esc_html__( 'The CDN has automatically been set to make use of the image optimization CDN.', 'autoptimize' ) . ' "';
403 $cdn_description = '';
404 } else {
405 $cdn_editable = '';
406 $cdn_placeholder = 'placeholder="' . esc_html__( 'example: //cdn.yoursite.com/', 'autoptimize' ) . ' "';
407 $cdn_description = esc_html__( 'Enter your CDN root URL to enable CDN for Autoptimized files. The URL can be http, https or protocol-relative. This is not needed for Cloudflare.', 'autoptimize' );
408 }
409 ?>
410 <td><label><input id="cdn_url" type="text" name="autoptimize_cdn_url" pattern="^(https?:)?\/\/([\da-z\.-]+)\.([\da-z\.]{2,6})([\/\w \.-]*)*(:\d{2,5})?\/?$" style="width:100%" <?php echo $cdn_placeholder . $cdn_editable; ?> value="<?php echo esc_url( autoptimizeOptionWrapper::get_option( 'autoptimize_cdn_url', '' ), array( 'http', 'https' ) ); ?>" /><br />
411 <?php echo $cdn_description; ?>
412 </label></td>
413 </tr>
414 </table>
415 </li>
416
417 <li class="itemDetail">
418 <h2 class="itemTitle"><?php esc_html_e( 'Cache Info', 'autoptimize' ); ?></h2>
419 <table class="form-table" >
420 <tr valign="top" >
421 <th scope="row"><?php esc_html_e( 'Cache folder', 'autoptimize' ); ?></th>
422 <td><?php echo htmlentities( AUTOPTIMIZE_CACHE_DIR ); ?></td>
423 </tr>
424 <tr valign="top" >
425 <th scope="row"><?php esc_html_e( 'Can we write?', 'autoptimize' ); ?></th>
426 <td><?php echo ( autoptimizeCache::cacheavail() ? esc_html__( 'Yes', 'autoptimize' ) : esc_html__( 'No', 'autoptimize' ) ); ?></td>
427 </tr>
428 <tr valign="top" >
429 <th scope="row"><?php esc_html_e( 'Cached styles and scripts', 'autoptimize' ); ?></th>
430 <td>
431 <?php
432 $ao_stat_arr = autoptimizeCache::stats();
433 if ( ! empty( $ao_stat_arr ) && is_array( $ao_stat_arr ) ) {
434 $ao_cache_size = size_format( $ao_stat_arr[1], 2 );
435 $details = '';
436 if ( $ao_cache_size > 0 ) {
437 $details = ', ~' . $ao_cache_size . ' total';
438 }
439 // translators: Kilobytes + timestamp shown.
440 printf( esc_html__( '%1$s files, totaling %2$s (calculated at %3$s)', 'autoptimize' ), $ao_stat_arr[0], $ao_cache_size, wp_date( 'H:i', $ao_stat_arr[2] ) ); // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
441 }
442 ?>
443 </td>
444 </tr>
445 </table>
446 </li>
447
448 <li class="itemDetail">
449 <h2 class="itemTitle"><?php esc_html_e( 'Misc Options', 'autoptimize' ); ?></h2>
450 <table class="form-table">
451 <tr valign="top">
452 <th scope="row"><?php esc_html_e( 'Save aggregated script/css as static files?', 'autoptimize' ); ?></th>
453 <td><label class="cb_label"><input type="checkbox" name="autoptimize_cache_nogzip" <?php echo $conf->get( 'autoptimize_cache_nogzip' ) ? 'checked="checked" ' : ''; ?>/>
454 <?php esc_html_e( 'By default files saved are static css/js, uncheck this option if your webserver doesn\'t properly handle the compression and expiry.', 'autoptimize' ); ?></label></td>
455 </tr>
456 <?php
457 $_min_excl_class = '';
458 if ( ! $conf->get( 'autoptimize_css_aggregate' ) && ! $conf->get( 'autoptimize_js_aggregate' ) ) {
459 $_min_excl_class = 'hidden';
460 }
461 ?>
462 <tr valign="top" id="min_excl_row" class="<?php echo $_min_excl_class; ?>">
463 <th scope="row"><?php esc_html_e( 'Minify excluded CSS and JS files?', 'autoptimize' ); ?></th>
464 <td><label class="cb_label"><input type="checkbox" name="autoptimize_minify_excluded" <?php echo $conf->get( 'autoptimize_minify_excluded' ) ? 'checked="checked" ' : ''; ?>/>
465 <?php esc_html_e( 'When aggregating JS or CSS, excluded files that are not minified (based on filename) are by default minified by Autoptimize despite being excluded. Uncheck this option if anything breaks despite excluding.', 'autoptimize' ); ?></label></td>
466 </tr>
467 <tr valign="top">
468 <th scope="row"><?php esc_html_e( 'Enable 404 fallbacks?', 'autoptimize' ); ?></th>
469 <td><label class="cb_label"><input type="checkbox" name="autoptimize_cache_fallback" <?php echo $conf->get( 'autoptimize_cache_fallback' ) ? 'checked="checked" ' : ''; ?>/>
470 <?php
471 // translators; just 2 opening and closing <code> tags.
472 printf( esc_html__( 'Sometimes Autoptimized JS/ CSS is referenced in cached HTML but is already removed, resulting in broken sites. With this option on, Autoptimize will try to redirect those not-found files to "fallback"-versions, keeping the page/ site somewhat intact. In some cases, this will require extra web-server level configuration to ensure %1$swp-content/autoptimize_404_handler.php%2$s is set to handle 404\'s in %1$swp-content/cache/autoptimize%2$s.', 'autoptimize' ), '<code>', '</code>' );
473 ?>
474 </label></td>
475 </tr>
476 <tr valign="top">
477 <th scope="row"><?php esc_html_e( 'Also optimize for logged in editors/ administrators?', 'autoptimize' ); ?></th>
478 <td><label class="cb_label"><input type="checkbox" name="autoptimize_optimize_logged" <?php echo $conf->get( 'autoptimize_optimize_logged' ) ? 'checked="checked" ' : ''; ?>/>
479 <?php esc_html_e( 'By default Autoptimize is also active for logged-on editors/ administrators, uncheck this option if you don\'t want Autoptimize to optimize when logged in e.g. to use a page builder.', 'autoptimize' ); ?></label></td>
480 </tr>
481 <?php
482 if ( function_exists( 'is_checkout' ) || function_exists( 'is_cart' ) || function_exists( 'edd_is_checkout' ) || function_exists( 'wpsc_is_cart' ) || function_exists( 'wpsc_is_checkout' ) ) {
483 ?>
484 <tr valign="top" >
485 <th scope="row"><?php esc_html_e( 'Also optimize shop cart/ checkout?', 'autoptimize' ); ?></th>
486 <td><label class="cb_label"><input type="checkbox" name="autoptimize_optimize_checkout" <?php echo $conf->get( 'autoptimize_optimize_checkout' ) ? 'checked="checked" ' : ''; ?>/>
487 <?php esc_html_e( 'By default Autoptimize is also active on your shop\'s cart/ checkout, uncheck not to optimize those.', 'autoptimize' ); ?></label>
488 </td>
489 </tr>
490 <?php } ?>
491 <?php
492 if ( true === apply_filters( 'autoptimize_filter_enable_meta_ao_settings', true ) ) {
493 ?>
494 <tr valign="top">
495 <th scope="row"><?php esc_html_e( 'Enable configuration per post/ page?', 'autoptimize' ); ?></th>
496 <td><label class="cb_label"><input type="checkbox" name="autoptimize_enable_meta_ao_settings" <?php echo $conf->get( 'autoptimize_enable_meta_ao_settings' ) ? 'checked="checked" ' : ''; ?>/>
497 <?php esc_html_e( 'Add a "meta box" to the post/ page edit screen allowing different optimizations to be turned off on a per post/ page level?', 'autoptimize' ); ?></label></td>
498 </tr>
499 <?php } ?>
500 <tr valign="top">
501 <th scope="row"><?php esc_html_e( 'Disable extra compatibility logic?', 'autoptimize' ); ?></th>
502 <td><label class="cb_label"><input type="checkbox" name="autoptimize_installed_before_compatibility" <?php echo $conf->get( 'autoptimize_installed_before_compatibility' ) ? 'checked="checked" ' : ''; ?>/>
503 <?php esc_html_e( 'Autoptimize applies extra "compatibility logic" to prevent issues with JS optimization (for e.g. Gutenberg blocks, Revolution Slider, jQuery-heavy plugins, ...) but may sometimes be a bit too careful. If you have render-blocking JS issues, you can try disabling this logic here. Make sure to test your site thoroughly though!', 'autoptimize' ); ?></label></td>
504 </tr>
505 </table>
506 </li>
507
508 </ul>
509
510 <p class="submit">
511 <input type="submit" class="button-secondary" value="<?php esc_html_e( 'Save Changes', 'autoptimize' ); ?>" />
512 <input type="submit" class="button-primary" name="autoptimize_cache_clean" value="<?php esc_html_e( 'Save Changes and Empty Cache', 'autoptimize' ); ?>" />
513 </p>
514
515 </form>
516 </div>
517 <div id="autoptimize_admin_feed">
518 <?php if ( apply_filters( 'autoptimize_filter_show_partner_tabs', true ) ) { ?>
519 <div class="autoptimize_banner hidden">
520 <ul>
521 <?php
522 if ( $this->settings_screen_do_remote_http ) {
523 $ao_banner = get_transient( 'autoptimize_banner' );
524 if ( empty( $ao_banner ) ) {
525 $banner_resp = wp_remote_get( 'https://misc.optimizingmatters.com/autoptimize_news.html?ao_ver=' . AUTOPTIMIZE_PLUGIN_VERSION );
526 if ( ! is_wp_error( $banner_resp ) ) {
527 if ( '200' == wp_remote_retrieve_response_code( $banner_resp ) ) {
528 $ao_banner = wp_kses_post( wp_remote_retrieve_body( $banner_resp ) );
529 set_transient( 'autoptimize_banner', $ao_banner, WEEK_IN_SECONDS );
530 }
531 }
532 }
533 echo $ao_banner;
534 }
535 ?>
536 <li>
537 <?php
538 // translators: link to the AO FAQ.
539 printf( esc_html__( 'Need help? %1$sCheck out the FAQ here%2$s.', 'autoptimize' ), '<a href=\'https://wordpress.org/plugins/autoptimize/faq/\'>', '</a>' );
540 ?>
541 </li>
542 <li><?php esc_html_e( 'Happy with Autoptimize?', 'autoptimize' ); ?><br /><a href="<?php echo network_admin_url(); ?>plugin-install.php?tab=search&type=author&s=optimizingmatters"><?php esc_html_e( 'Try my other plugins!', 'autoptimize' ); ?></a></li>
543 </ul>
544 </div>
545 <?php } ?>
546 <div style="margin-left:10px;margin-top:-5px;">
547 <h2>
548 <?php esc_html_e( 'Autoptimize news', 'autoptimize' ); ?>
549 </h2>
550 <div id="futtta_feed">
551 <div id="autoptimizefeed">
552 <?php $this->get_futtta_feeds( 'http://feeds.feedburner.com/futtta_autoptimize' ); ?>
553 </div>
554 </div>
555 </div>
556 <?php if ( apply_filters( 'autoptimize_filter_show_partner_tabs', true ) ) { ?>
557 <div style="float:right;margin:50px 15px;"><a href="https://blog.futtta.be/2013/10/21/do-not-donate-to-me/" target="_blank"><img width="100px" height="85px" src="<?php echo plugins_url() . '/' . plugin_basename( dirname( __FILE__ ) ) . '/external/do_not_donate_smallest.png'; ?>" title="<?php esc_html_e( 'Do not donate for this plugin!', 'autoptimize' ); ?>"></a></div>
558 <?php } ?>
559 </div>
560 <script type="text/javascript">
561 jQuery(document).ready(function() {
562 check_ini_state();
563
564 jQuery('.autoptimize_banner').unslider({autoplay:true, delay:3500, infinite: false, arrows:{prev:'<a class="unslider-arrow prev"></a>', next:'<a class="unslider-arrow next"></a>'}}).fadeTo("slow",1).show();
565
566 jQuery( "#autoptimize_html" ).change(function() {
567 if (this.checked) {
568 jQuery(".html_sub:visible").fadeTo("fast",1);
569 } else {
570 jQuery(".html_sub:visible").fadeTo("fast",.33);
571 }
572 });
573
574 jQuery( "#autoptimize_js" ).change(function() {
575 if (this.checked) {
576 jQuery(".js_sub:visible").fadeTo("fast",1);
577 } else {
578 jQuery(".js_sub:visible").fadeTo("fast",.33);
579 }
580 });
581
582 jQuery( "#autoptimize_js_aggregate" ).change(function() {
583 if (this.checked && jQuery("#autoptimize_js").prop('checked')) {
584 jQuery( "#autoptimize_js_defer_not_aggregate" ).prop( 'checked', false ); // uncheck "defer not aggregate"
585 jQuery( ".js_aggregate_master:visible" ).fadeTo( 'slow', 1 ); // ungrey self
586 jQuery( ".js_aggregate" ).show( 'slow' ); // show sub-items
587 jQuery( ".js_not_aggregate_master:visible" ).fadeTo( 'slow', .33 ); // grey out "not aggregate"
588 jQuery( ".js_not_aggregate" ).hide( 'slow' ); // hide not aggregate sub-items
589 jQuery( "#min_excl_row" ).show(); // make sure "minify excluded" is visible
590 check_exclusions( "js", "on" );
591 } else {
592 jQuery( ".js_aggregate" ).hide( 'slow' ); // hide sub-itmes
593 jQuery( ".js_not_aggregate_master:visible" ).fadeTo( 'slow', 1 ); // un-grey-out "not aggregate"
594 if ( jQuery( "#autoptimize_css_aggregate" ).prop( 'checked' ) == false ) { // hide "minify excluded"
595 jQuery( "#min_excl_row" ).hide();
596 }
597 check_exclusions( "js", "off" );
598 }
599 });
600
601 jQuery( "#autoptimize_js_defer_not_aggregate" ).change(function() {
602 if (this.checked && jQuery("#autoptimize_js").prop('checked')) {
603 jQuery( "#autoptimize_js_aggregate" ).prop( 'checked', false ); // uncheck "aggregate JS"
604 jQuery( ".js_not_aggregate_master:visible" ).fadeTo( 'slow', 1 ); // ungrey self
605 jQuery( ".js_not_aggregate" ).show( 'slow'); // show sub-items
606 jQuery( ".js_aggregate_master:visible" ).fadeTo( 'slow', .33 ); // grey out "aggregate"
607 jQuery( ".js_aggregate" ).hide( 'slow' ); // hide aggregate sub-items
608 check_exclusions( "js", "off" );
609 } else {
610 jQuery( ".js_not_aggregate" ).hide( 'slow' ); // hide sub-items
611 jQuery( ".js_aggregate_master:visible" ).fadeTo( 'slow', 1 ); // un-grey-out "aggregate"
612 }
613 });
614
615 jQuery( "#autoptimize_css" ).change(function() {
616 if (this.checked) {
617 jQuery(".css_sub:visible").fadeTo("fast",1);
618 } else {
619 jQuery(".css_sub:visible").fadeTo("fast",.33);
620 }
621 });
622
623 jQuery( "#autoptimize_css_aggregate" ).change(function() {
624 if (this.checked && jQuery("#autoptimize_css").prop('checked')) {
625 jQuery(".css_aggregate:visible").fadeTo("fast",1);
626 jQuery( "#min_excl_row" ).show();
627 check_exclusions( "css", "on" );
628 } else {
629 jQuery(".css_aggregate:visible").fadeTo("fast",.33);
630 if ( jQuery( "#autoptimize_js_aggregate" ).prop('checked') == false ) {
631 jQuery( "#min_excl_row" ).hide();
632 }
633 check_exclusions( "css", "off" );
634 }
635 });
636
637 jQuery( "#autoptimize_css_inline" ).change(function() {
638 if (this.checked) {
639 jQuery("#autoptimize_css_defer").prop("checked",false);
640 jQuery("#autoptimize_css_defer_inline").hide("slow");
641 }
642 });
643
644 jQuery( "#autoptimize_css_defer" ).change(function() {
645 if (this.checked) {
646 jQuery("#autoptimize_css_inline").prop("checked",false);
647 jQuery("#autoptimize_css_defer_inline").show("slow");
648 } else {
649 jQuery("#autoptimize_css_defer_inline").hide("slow");
650 }
651 });
652
653 jQuery( "#autoptimize_enable_site_config" ).change(function() {
654 if (this.checked) {
655 jQuery("li.itemDetail:not(.multiSite)").fadeTo("fast",.33);
656 } else {
657 jQuery("li.itemDetail:not(.multiSite)").fadeTo("fast",1);
658 }
659 });
660 })
661
662 // validate cdn_url.
663 var cdn_url=document.getElementById("cdn_url");
664 cdn_url_baseCSS=cdn_url.style.cssText;
665 if ("validity" in cdn_url) {
666 jQuery("#cdn_url").focusout(function (event) {
667 if (cdn_url.validity.valid) {
668 cdn_url.style.cssText=cdn_url_baseCSS;
669 } else {
670 cdn_url.style.cssText=cdn_url_baseCSS+"border:1px solid #f00;color:#f00;box-shadow: 0 0 2px #f00;";
671 }});
672 }
673
674 function check_ini_state() {
675 if (!jQuery("#autoptimize_css_defer").prop('checked')) {
676 jQuery("#autoptimize_css_defer_inline").hide();
677 }
678 if (!jQuery("#autoptimize_html").prop('checked')) {
679 jQuery(".html_sub:visible").fadeTo('fast',.33);
680 }
681 if (!jQuery("#autoptimize_css").prop('checked')) {
682 jQuery(".css_sub:visible").fadeTo('fast',.33);
683 }
684 if (!jQuery("#autoptimize_css_aggregate").prop('checked')) {
685 jQuery(".css_aggregate:visible").fadeTo('fast',.33);
686 }
687 if (jQuery("#autoptimize_js_aggregate").prop('checked')) {
688 jQuery( ".js_aggregate" ).show( 'fast' );
689 jQuery( ".js_not_aggregate_master:visible" ).fadeTo( 'fast', .33 );
690 }
691 if (jQuery("#autoptimize_js_defer_not_aggregate").prop('checked')) {
692 jQuery( ".js_not_aggregate" ).show( 'fast' );
693 jQuery( ".js_aggregate_master:visible" ).fadeTo( 'fast', .33 );
694 }
695 if (jQuery("#autoptimize_enable_site_config").prop('checked')) {
696 jQuery("li.itemDetail:not(.multiSite)").fadeTo('fast',.33);
697 }
698 if (!jQuery("#autoptimize_js").prop('checked')) {
699 jQuery(".js_sub:visible").fadeTo('fast',.33);
700 }
701 }
702
703 function check_exclusions( what, state ) {
704 exclusion_node = 'input[name="autoptimize_' + what + '_exclude"]';
705 current_exclusion = jQuery( exclusion_node ).val();
706
707 if ( what == "js" ) {
708 default_exclusion = ", wp-includes/js/dist/, wp-includes/js/tinymce/, js/jquery/jquery.min.js";
709 } else if ( what == "css") {
710 default_exclusion = ", admin-bar.min.css, dashicons.min.css, wp-content/cache/, wp-content/uploads/";
711 }
712
713 default_in_current = current_exclusion.indexOf(default_exclusion);
714
715 if ( state == "on" && default_in_current == -1 ) {
716 jQuery( exclusion_node ).val( current_exclusion + default_exclusion );
717 } else if ( state = "off" && current_exclusion == default_exclusion ) {
718 jQuery( exclusion_node ).val( "" );
719 } else if ( state = "off" && default_in_current != -1 ) {
720 new_exclusion = current_exclusion.substring( 0, default_in_current) + current_exclusion.substring( default_in_current + default_exclusion.length, current_exclusion.length );
721 jQuery( exclusion_node ).val( new_exclusion );
722 }
723 }
724 </script>
725 </div>
726
727 <?php
728 }
729
730 public function addmenu()
731 {
732 $_my_name = apply_filters( 'autoptimize_filter_settings_is_pro', false ) ? esc_html__( 'Autoptimize Pro', 'autoptimize' ) : esc_html__( 'Autoptimize', 'autoptimize' );
733
734 global $title;
735 if ( empty( $title ) && true === autoptimizeUtils::is_ao_settings() ) {
736 $title = $_my_name;
737 }
738
739 if ( is_multisite() && is_network_admin() && autoptimizeOptionWrapper::is_ao_active_for_network() ) {
740 // multisite, network admin, ao network activated: add normal settings page at network level.
741 $hook = add_submenu_page( 'settings.php', esc_html__( 'Autoptimize Options', 'autoptimize' ), $_my_name, 'manage_network_options', 'autoptimize', array( $this, 'show_config' ) );
742 } elseif ( is_multisite() && ! is_network_admin() && autoptimizeOptionWrapper::is_ao_active_for_network() && 'on' !== autoptimizeOptionWrapper::get_option( 'autoptimize_enable_site_config' ) ) {
743 // multisite, ao network activated, not network admin so site specific settings, but "autoptimize_enable_site_config" is off: show "sorry, ask network admin" message iso options.
744 $hook = add_options_page( esc_html__( 'Autoptimize Options', 'autoptimize' ), $_my_name, 'manage_options', 'autoptimize', array( $this, 'show_network_message' ) );
745 } else {
746 // default: show normal options page if not multisite, if multisite but not network activated, if multisite and network activated and "autoptimize_enable_site_config" is on.
747 $hook = add_options_page( esc_html__( 'Autoptimize Options', 'autoptimize' ), $_my_name, 'manage_options', 'autoptimize', array( $this, 'show_config' ) );
748 }
749
750 add_action( 'admin_print_scripts-' . $hook, array( $this, 'autoptimize_admin_scripts' ) );
751 add_action( 'admin_print_styles-' . $hook, array( $this, 'autoptimize_admin_styles' ) );
752 }
753
754 public function autoptimize_admin_scripts()
755 {
756 wp_enqueue_script( 'unslider', plugins_url( '/external/js/unslider.min.js', __FILE__ ), array( 'jquery' ), AUTOPTIMIZE_PLUGIN_VERSION, true );
757 }
758
759 public function autoptimize_admin_styles()
760 {
761 wp_enqueue_style( 'unslider', plugins_url( '/external/js/unslider.css', __FILE__ ), null, AUTOPTIMIZE_PLUGIN_VERSION );
762 wp_enqueue_style( 'unslider-dots', plugins_url( '/external/js/unslider-dots.css', __FILE__ ), null, AUTOPTIMIZE_PLUGIN_VERSION );
763 }
764
765 public function registersettings() {
766 register_setting( 'autoptimize', 'autoptimize_html' );
767 register_setting( 'autoptimize', 'autoptimize_html_keepcomments' );
768 register_setting( 'autoptimize', 'autoptimize_html_minify_inline' );
769 register_setting( 'autoptimize', 'autoptimize_enable_site_config' );
770 register_setting( 'autoptimize', 'autoptimize_js' );
771 register_setting( 'autoptimize', 'autoptimize_js_aggregate' );
772 register_setting( 'autoptimize', 'autoptimize_js_defer_not_aggregate' );
773 register_setting( 'autoptimize', 'autoptimize_js_defer_inline' );
774 register_setting( 'autoptimize', 'autoptimize_js_exclude' );
775 register_setting( 'autoptimize', 'autoptimize_js_trycatch' );
776 register_setting( 'autoptimize', 'autoptimize_js_justhead' );
777 register_setting( 'autoptimize', 'autoptimize_js_forcehead' );
778 register_setting( 'autoptimize', 'autoptimize_js_include_inline' );
779 register_setting( 'autoptimize', 'autoptimize_css' );
780 register_setting( 'autoptimize', 'autoptimize_css_aggregate' );
781 register_setting( 'autoptimize', 'autoptimize_css_exclude' );
782 register_setting( 'autoptimize', 'autoptimize_css_justhead' );
783 register_setting( 'autoptimize', 'autoptimize_css_datauris' );
784 register_setting( 'autoptimize', 'autoptimize_css_defer' );
785 register_setting( 'autoptimize', 'autoptimize_css_defer_inline' );
786 register_setting( 'autoptimize', 'autoptimize_css_inline' );
787 register_setting( 'autoptimize', 'autoptimize_css_include_inline' );
788 register_setting( 'autoptimize', 'autoptimize_cdn_url' );
789 register_setting( 'autoptimize', 'autoptimize_cache_clean' );
790 register_setting( 'autoptimize', 'autoptimize_cache_nogzip' );
791 register_setting( 'autoptimize', 'autoptimize_optimize_logged' );
792 register_setting( 'autoptimize', 'autoptimize_optimize_checkout' );
793 register_setting( 'autoptimize', 'autoptimize_minify_excluded' );
794 register_setting( 'autoptimize', 'autoptimize_cache_fallback' );
795 register_setting( 'autoptimize', 'autoptimize_enable_meta_ao_settings' );
796 register_setting( 'autoptimize', 'autoptimize_installed_before_compatibility' );
797 }
798
799 public function setmeta( $links, $file = null )
800 {
801 // Inspired on http://wpengineer.com/meta-links-for-wordpress-plugins/.
802 // Do it only once - saves time.
803 static $plugin;
804 if ( empty( $plugin ) ) {
805 $plugin = plugin_basename( AUTOPTIMIZE_PLUGIN_DIR . 'autoptimize.php' );
806 }
807
808 if ( null === $file ) {
809 // 2.7 and lower.
810 $settings_link = sprintf( '<a href="options-general.php?page=autoptimize">%s</a>', esc_html__( 'Settings' ) );
811 array_unshift( $links, $settings_link );
812 } else {
813 // 2.8 and higher.
814 // If it's us, add the link.
815 if ( $file === $plugin ) {
816 $newlink = array( sprintf( '<a href="options-general.php?page=autoptimize">%s</a>', esc_html__( 'Settings' ) ) );
817 $links = array_merge( $links, $newlink );
818 }
819 }
820
821 return $links;
822 }
823
824 /**
825 * Provides the default options.
826 *
827 * @return array
828 */
829 public static function get_defaults()
830 {
831 static $config = array(
832 'autoptimize_html' => 1,
833 'autoptimize_html_keepcomments' => 0,
834 'autoptimize_html_minify_inline' => 0,
835 'autoptimize_enable_site_config' => 1,
836 'autoptimize_js' => 1,
837 'autoptimize_js_aggregate' => 0,
838 'autoptimize_js_defer_not_aggregate' => 1,
839 'autoptimize_js_defer_inline' => 1,
840 'autoptimize_js_exclude' => '',
841 'autoptimize_js_trycatch' => 0,
842 'autoptimize_js_justhead' => 0,
843 'autoptimize_js_include_inline' => 0,
844 'autoptimize_js_forcehead' => 0,
845 'autoptimize_css' => 1,
846 'autoptimize_css_aggregate' => 0,
847 'autoptimize_css_exclude' => '',
848 'autoptimize_css_justhead' => 0,
849 'autoptimize_css_include_inline' => 0,
850 'autoptimize_css_defer' => 0,
851 'autoptimize_css_defer_inline' => '',
852 'autoptimize_css_inline' => 0,
853 'autoptimize_css_datauris' => 0,
854 'autoptimize_cdn_url' => '',
855 'autoptimize_cache_nogzip' => 1,
856 'autoptimize_optimize_logged' => 1,
857 'autoptimize_optimize_checkout' => 0,
858 'autoptimize_minify_excluded' => 1,
859 'autoptimize_cache_fallback' => 1,
860 'autoptimize_enable_meta_ao_settings' => 1,
861 'autoptimize_installed_before_compatibility' => 0,
862 );
863
864 return $config;
865 }
866
867 /**
868 * Returns default option values for autoptimizeExtra.
869 *
870 * @return array
871 */
872 public static function get_ao_extra_default_options()
873 {
874 $defaults = array(
875 'autoptimize_extra_checkbox_field_1' => '0',
876 'autoptimize_extra_checkbox_field_0' => '0',
877 'autoptimize_extra_radio_field_4' => '1',
878 'autoptimize_extra_text_field_2' => '',
879 'autoptimize_extra_text_field_3' => '',
880 'autoptimize_extra_text_field_7' => '',
881 'autoptimize_extra_checkbox_field_8' => '0',
882 );
883
884 return $defaults;
885 }
886
887 /**
888 * Returns default option values for autoptimizeExtra.
889 *
890 * @return array
891 */
892 public static function get_ao_imgopt_default_options()
893 {
894 $defaults = array(
895 'autoptimize_imgopt_checkbox_field_1' => '0', // imgopt off.
896 'autoptimize_imgopt_select_field_2' => '2', // quality glossy.
897 'autoptimize_imgopt_checkbox_field_3' => '0', // lazy load off.
898 'autoptimize_imgopt_checkbox_field_4' => '0', // avif off (might be removed).
899 'autoptimize_imgopt_text_field_5' => '', // lazy load exclusions empty.
900 'autoptimize_imgopt_text_field_6' => '', // optimization exclusions empty.
901 'autoptimize_imgopt_number_field_7' => '2', // lazy load from nth image (0 = lazyload all).
902 );
903 return $defaults;
904 }
905
906 /**
907 * Returns preload JS onload handler.
908 *
909 * @param string $media media attribute value the JS to use.
910 *
911 * @return string
912 */
913 public static function get_ao_css_preload_onload( $media = 'all' )
914 {
915 $preload_onload = apply_filters( 'autoptimize_filter_css_preload_onload', "this.onload=null;this.media='" . $media . "';" );
916 return $preload_onload;
917 }
918
919 public function get( $key )
920 {
921 if ( ! is_array( $this->config ) ) {
922 // Default config.
923 $config = self::get_defaults();
924
925 // Override with user settings.
926 foreach ( array_keys( $config ) as $name ) {
927 $conf = autoptimizeOptionWrapper::get_option( $name );
928 if ( false !== $conf ) {
929 // It was set before!
930 $config[ $name ] = $conf;
931 }
932 }
933
934 // Save for next call.
935 $this->config = apply_filters( 'autoptimize_filter_get_config', $config );
936 }
937
938 if ( isset( $this->config[ $key ] ) ) {
939 return $this->config[ $key ];
940 }
941
942 return false;
943 }
944
945 private function get_futtta_feeds( $url ) {
946 if ( $this->settings_screen_do_remote_http ) {
947 $rss = fetch_feed( $url );
948 $maxitems = 0;
949
950 if ( ! is_wp_error( $rss ) ) {
951 $maxitems = $rss->get_item_quantity( 7 );
952 $rss_items = $rss->get_items( 0, $maxitems );
953 }
954 ?>
955 <ul>
956 <?php if ( 0 == $maxitems ) : ?>
957 <li><?php esc_html_e( 'No items', 'autoptimize' ); ?></li>
958 <?php else : ?>
959 <?php foreach ( $rss_items as $item ) : ?>
960 <li>
961 <a href="<?php echo esc_url( $item->get_permalink() ); ?>"
962 <?php // translators: the variable contains a date. ?>
963 title="<?php printf( esc_html__( 'Posted %s', 'autoptimize' ), $item->get_date( 'j F Y | g:i a' ) ); ?>">
964 <?php echo esc_html( $item->get_title() ); ?>
965 </a>
966 </li>
967 <?php endforeach; ?>
968 <?php endif; ?>
969 </ul>
970 <?php
971 }
972 }
973
974 static function ao_admin_tabs()
975 {
976 // based on http://wordpress.stackexchange.com/a/58826 .
977 $tabs = apply_filters( 'autoptimize_filter_settingsscreen_tabs', array( 'autoptimize' => esc_html__( 'JS, CSS &amp; HTML', 'autoptimize' ) ) );
978 $tab_content = '';
979 $tabs_count = count( $tabs );
980 if ( $tabs_count > 1 ) {
981 if ( isset( $_GET['page'] ) ) {
982 $current_id = $_GET['page'];
983 } else {
984 $current_id = 'autoptimize';
985 }
986 $tab_content .= '<h2 class="nav-tab-wrapper">';
987 foreach ( $tabs as $tab_id => $tab_name ) {
988 if ( $current_id == $tab_id ) {
989 $class = ' nav-tab-active';
990 } else {
991 $class = '';
992 }
993 $tab_content .= '<a class="nav-tab' . $class . '" href="?page=' . $tab_id . '">' . $tab_name . '</a>';
994 }
995 $tab_content .= '</h2>';
996 } else {
997 $tab_content = '<hr/>';
998 }
999
1000 return $tab_content;
1001 }
1002
1003 /**
1004 * Returns true if in admin (and not in admin-ajax.php!)
1005 *
1006 * @return bool
1007 */
1008 public static function is_admin_and_not_ajax()
1009 {
1010 return ( is_admin() && ! self::doing_ajax() );
1011 }
1012
1013 /**
1014 * Returns true if doing ajax.
1015 *
1016 * @return bool
1017 */
1018 protected static function doing_ajax()
1019 {
1020 if ( function_exists( 'wp_doing_ajax' ) ) {
1021 return wp_doing_ajax();
1022 }
1023 return ( defined( 'DOING_AJAX' ) && DOING_AJAX );
1024 }
1025
1026 /**
1027 * Returns true menu or tab is to be shown.
1028 *
1029 * @return bool
1030 */
1031 public static function should_show_menu_tabs() {
1032 if ( ! is_multisite() || is_network_admin() || 'on' === autoptimizeOptionWrapper::get_option( 'autoptimize_enable_site_config' ) || false === autoptimizeOptionWrapper::is_ao_active_for_network() ) {
1033 return true;
1034 } else {
1035 return false;
1036 }
1037 }
1038
1039 /**
1040 * Returns the post meta AO settings for reuse in different optimizers.
1041 *
1042 * @param string $optim What optimization we need meta setting for.
1043 *
1044 * @return bool
1045 */
1046 public static function get_post_meta_ao_settings( $optim ) {
1047 if ( ! autoptimizeConfig::is_ao_meta_settings_active() ) {
1048 // Per page/post settings not active, so always return true (as in; can be optimized).
1049 if ( in_array( $optim, apply_filters( 'autoptimize_filter_meta_inactive_return_false_for', array( 'ao_post_preload' ) ) ) ) {
1050 // but make sure to return false for text input.
1051 return false;
1052 }
1053 return true;
1054 }
1055
1056 static $_meta_value = null;
1057 if ( null === $_meta_value ) {
1058 global $wp_query;
1059 if ( isset( $wp_query ) ) {
1060 $_meta_value = get_post_meta( get_the_ID(), 'ao_post_optimize', true );
1061 } else {
1062 $_meta_value = false;
1063 }
1064 }
1065
1066 // If autoptimize_post_optimize !== 'on' (except for ao_post_preload, which can have other values) then always return false as all is off.
1067 // fixme: need unit tests to ensure below logic is sane!
1068 if ( empty( $_meta_value ) || ! is_array( $_meta_value ) ) {
1069 // no metabox values so all optimizations are a go.
1070 if ( in_array( $optim, apply_filters( 'autoptimize_filter_meta_optim_nonbool', array( 'ao_post_preload' ) ) ) ) {
1071 // but make sure to return false for text input.
1072 return false;
1073 }
1074 return true;
1075 } else if ( array_key_exists( 'ao_post_optimize', $_meta_value ) && 'on' !== $_meta_value['ao_post_optimize'] ) {
1076 // ao entirely off for this page.
1077 return false;
1078 } else if ( in_array( $optim, apply_filters( 'autoptimize_filter_meta_optim_with_filters', array() ) ) ) {
1079 // if an $optim is registered as having a filter, apply filter and return that (default false).
1080 return apply_filters( 'autoptimize_filter_meta_filtered_optim', false, $optim, $_meta_value );
1081 } else if ( array_key_exists( $optim, $_meta_value ) && empty( $_meta_value[ $optim ] ) ) {
1082 // sub-optimization off for this page.
1083 return false;
1084 } else if ( array_key_exists( $optim, $_meta_value ) && 'on' === $_meta_value[ $optim ] ) {
1085 // sub-optimization is explictly on.
1086 return true;
1087 } else if ( array_key_exists( $optim, $_meta_value ) && in_array( $optim, array( 'ao_post_preload' ) ) && ! empty( $_meta_value[ $optim ] ) ) {
1088 // a non-bool metabox optimization (currently only preload field), return value instead of bool.
1089 return $_meta_value[ $optim ];
1090 } else if ( in_array( $optim, array( 'ao_post_preload' ) ) && ( ! array_key_exists( $optim, $_meta_value ) || empty( $_meta_value[ $optim ] ) ) ) {
1091 // a non-bool metabox optimization not found or empty, so returning false.
1092 return false;
1093 } else {
1094 // when in doubt "go" for optimization, but this should never happen?
1095 if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
1096 error_log( 'AO meta box logic fallback; well, how did I get here? Maybe this helps: looking for ' . $optim . ' in ' . json_encode( $_meta_value ) );
1097 }
1098 return true;
1099 }
1100 }
1101
1102 /**
1103 * Are the post meta AO settings active (default: no)?
1104 *
1105 * @return bool
1106 */
1107 public static function is_ao_meta_settings_active() {
1108 static $_meta_settings_active = null;
1109
1110 if ( null === $_meta_settings_active ) {
1111 $_meta_settings_active = apply_filters( 'autoptimize_filter_enable_meta_ao_settings', autoptimizeOptionWrapper::get_option( 'autoptimize_enable_meta_ao_settings', '1' ) );
1112 }
1113
1114 return $_meta_settings_active;
1115 }
1116 }
1117