PluginProbe
Module Control for Jetpack / 1.6
Module Control for Jetpack v1.6
1.7.4 1.7.3 trunk 0.4 1.0 1.2 1.3 1.4 1.4.1 1.4.2 1.5 1.6 1.7 1.7.1 1.7.2
jetpack-module-control / jetpack-module-control.php

jetpack-module-control.php in Module Control for Jetpack 1.6, at jetpack-module-control.php

880 lines 28.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 * Plugin Name: Module Control for Jetpack
4 * Plugin URI: https://status301.net/wordpress-plugins/jetpack-module-control/
5 * Description: This plugin brings additional control over Jetpack modules. You can blacklist / remove individual modules, prevent auto-activation or allow activation without a WordPress.com account.
6 * Author: RavanH
7 * Author URI: https://status301.net/
8 * Network: true
9 * Text Domain: jetpack-module-control
10 * License: GPL2+
11 * Version: 1.6
12 */
13
14 /*
15 * ROADMAP
16 *
17 * version 2.0
18 * Replace "Prevent the Jetpack plugin from auto-activating (new) modules" with
19 * finer grained "Select which modules to auto-activate"
20 * see http://jeremy.hu/customize-the-list-of-modules-available-in-jetpack/
21 * function jeherve_auto_activate_stats() {
22 return array( 'stats' );
23 }
24 add_filter( 'jetpack_get_default_modules', 'jeherve_auto_activate_stats' );
25 *
26 * TO CONSIDER
27 *
28 * Make blacklist or whitelist optional
29 *
30 * Option to disable JUMPSTART with "Jetpack_Options::update_option( 'jumpstart', 'jumpstart_dismissed' );" ??
31 * or do we need to go through apply_filters( 'jetpack_module_feature' ...
32 * If we want to be able to select which modules should appear in Jumpstart later!
33 *
34 * Can we disable Debug link in the footer menu? No...
35 *
36 * Option to "force_deactivate" (same as blacklist?) as described on https://github.com/Automattic/jetpack/issues/1452
37 *
38 */
39
40
41 /**
42 * Jetpack Module Control Class
43 *
44 * since 0.1
45 */
46 class Jetpack_Module_Control {
47
48 /**
49 * The single instance.
50 * @var object
51 * @access private
52 * @since 0.1
53 */
54 private static $instance = null;
55
56 /**
57 * The plugins basename.
58 * @var string
59 * @access private
60 * @since 0.1
61 */
62 private static $plugin_basename = null;
63
64 /**
65 * Current plugin version.
66 * @since 0.1
67 * @var string
68 */
69 public $version = '1.6';
70
71 /**
72 * Available modules array
73 * @since 0.1
74 * @access private
75 * @var array
76 */
77 private static $modules = null;
78
79 /**
80 * Know modules array with names
81 * @since 0.2
82 * @access private
83 * @var array
84 */
85 private static $known_modules = array(
86 'wordads' => array( 'name' => 'Ads',
87 'requires_connection' => true ),
88 // 'after-the-deadline' => array( 'name' => 'Spelling and Grammar',
89 // 'requires_connection' => true ),
90 'carousel' => array( 'name' => 'Carousel',
91 'requires_connection' => false ),
92 'comments' => array( 'name' => 'Comments',
93 'requires_connection' => true ),
94 'comment-likes' => array( 'name' => 'Comment Likes',
95 'requires_connection' => true ),
96 'contact-form' => array( 'name' => 'Contact Form',
97 'requires_connection' => false ),
98 'copy-post' => array( 'name' => 'Copy Post',
99 'requires_connection' => false ),
100 'custom-content-types' => array( 'name' => 'Custom content types',
101 'requires_connection' => false ),
102 'custom-css' => array( 'name' => 'Custom CSS',
103 'requires_connection' => false ),
104 'enhanced-distribution' => array( 'name' => 'Enhanced Distribution',
105 'requires_connection' => true ),
106 'google-analytics' => array( 'name' => 'Google Analytics',
107 'requires_connection' => true ),
108 'gravatar-hovercards' => array( 'name' => 'Gravatar Hovercards',
109 'requires_connection' => false ),
110 'infinite-scroll' => array( 'name' => 'Infinite Scroll',
111 'requires_connection' => false ),
112 'json-api' => array( 'name' => 'JSON API',
113 'requires_connection' => true ),
114 'latex' => array( 'name' => 'Beautiful Math',
115 'requires_connection' => false ),
116 'lazy-images' => array( 'name' => 'Lazy Images',
117 'requires_connection' => false ),
118 'likes' => array( 'name' => 'Likes',
119 'requires_connection' => true ),
120 // 'manage' => array( 'name' => 'Manage',
121 // 'requires_connection' => true ),
122 'markdown' => array( 'name' => 'Markdown',
123 'requires_connection' => false ),
124 // 'minileven' => array( 'name' => 'Mobile Theme',
125 // 'requires_connection' => false ),
126 'monitor' => array( 'name' => 'Monitor',
127 'requires_connection' => true ),
128 'notes' => array( 'name' => 'Notifications',
129 'requires_connection' => true ),
130 // 'omnisearch' => array( 'name' => 'Omnisearch',
131 // 'requires_connection' => false ),
132 'photon' => array( 'name' => 'Image CDN',
133 'requires_connection' => true ),
134 'photon-cdn' => array( 'name' => 'Asset CDN',
135 'requires_connection' => true ),
136 'post-by-email' => array( 'name' => 'Post by Email',
137 'requires_connection' => true ),
138 'protect' => array( 'name' => 'Protect',
139 'requires_connection' => true ),
140 'publicize' => array( 'name' => 'Publicize',
141 'requires_connection' => true ),
142 'related-posts' => array( 'name' => 'Related Posts',
143 'requires_connection' => true ),
144 'search' => array( 'name' => 'Search',
145 'requires_connection' => true ),
146 'seo-tools' => array( 'name' => 'SEO Tools',
147 'requires_connection' => true ),
148 'sharedaddy' => array( 'name' => 'Sharing',
149 'requires_connection' => false ),
150 'shortcodes' => array( 'name' => 'Shortcode Embeds',
151 'requires_connection' => false ),
152 'shortlinks' => array( 'name' => 'WP.me Shortlinks',
153 'requires_connection' => true ),
154 // 'site-icon' => array( 'name' => 'Site Icon',
155 // 'requires_connection' => false ),
156 'sitemaps' => array( 'name' => 'Sitemaps',
157 'requires_connection' => false ),
158 'sso' => array( 'name' => 'Secure Sign On',
159 'requires_connection' => true ),
160 'stats' => array( 'name' => 'Site Stats',
161 'requires_connection' => true ),
162 'subscriptions' => array( 'name' => 'Subscriptions',
163 'requires_connection' => true ),
164 'tiled-gallery' => array( 'name' => 'Tiled Galleries',
165 'requires_connection' => false ),
166 'vaultpress' => array( 'name' => 'Backups and Scanning',
167 'requires_connection' => false ),
168 'verification-tools' => array( 'name' => 'Site Verification',
169 'requires_connection' => false ),
170 'videopress' => array( 'name' => 'VideoPress',
171 'requires_connection' => true ),
172 'widget-visibility' => array( 'name' => 'Widget Visibility',
173 'requires_connection' => false ),
174 'widgets' => array( 'name' => 'Extra Sidebar Widgets',
175 'requires_connection' => false ),
176 'woocommerce-analytics' => array( 'name' => 'WooCommerce Analytics',
177 'requires_connection' => true ),
178 'masterbar' => array( 'name' => 'WordPress.com Toolbar',
179 'requires_connection' => true )
180 );
181
182 /**
183 * Know modules array with dashicons
184 * https://developer.wordpress.org/resource/dashicons/
185 *
186 * @since 0.3
187 * @access private
188 * @var array
189 */
190 private static $known_modules_icons = array(
191 'wordads' => 'megaphone',
192 'after-the-deadline' => 'edit',
193 'carousel' => 'camera',
194 'comments' => 'format-chat',
195 'comment-likes' => 'star-filled',
196 'contact-form' => 'feedback',
197 'copy-post' => 'admin-page',
198 'custom-content-types' => 'media-default',
199 'custom-css' => 'admin-appearance',
200 'enhanced-distribution' => 'share',
201 'google-analytics' => 'chart-line',
202 'gravatar-hovercards' => 'id', // not available
203 'infinite-scroll' => 'star-filled',
204 'json-api' => 'share-alt',
205 'latex' => 'star-filled',
206 'likes' => 'star-filled',
207 'lazy-images' => 'images-alt',
208 'manage' => 'wordpress-alt',
209 'markdown' => 'editor-code',
210 'minileven' => 'smartphone',
211 'monitor' => 'flag',
212 'notes' => 'admin-comments',
213 'omnisearch' => 'search',
214 'photon' => 'visibility',
215 'photon-cdn' => 'visibility',
216 'post-by-email' => 'email',
217 'protect' => 'lock',
218 'publicize' => 'share',
219 'related-posts' => 'update',
220 'search' => 'search',
221 'seo-tools' => 'chart-bar',
222 'sharedaddy' => 'share-alt',
223 'shortcodes' => 'text',
224 'shortlinks' => 'admin-links',
225 'site-icon' => 'admin-site',
226 'sitemaps' => 'networking',
227 'sso' => 'wordpress-alt',
228 'stats' => 'chart-area',
229 'subscriptions' => 'email',
230 'tiled-gallery' => 'layout',
231 'vaultpress' => 'shield-alt', // not availabe
232 'verification-tools' => 'clipboard', // maybe yes
233 'videopress' => 'embed-video',
234 'widget-visibility' => 'welcome-widgets-menus',
235 'widgets' => 'welcome-widgets-menus',
236 'woocommerce-analytics' => 'cart',
237 'masterbar' => 'wordpress',
238 );
239
240 /**
241 * Default dashicon
242 * @since 1.0
243 * @access private
244 * @var string
245 */
246 private static $default_icon = 'star-empty';
247
248 /**
249 * Return Jetpack available modules
250 * @since 0.1
251 * @return array
252 */
253 private function get_available_modules() {
254 if ( null === self::$modules ) {
255 if ( class_exists('Jetpack') ) {
256 remove_filter( 'jetpack_get_available_modules', array($this, 'blacklist') );
257 $modules = array();
258 foreach ( Jetpack::get_available_modules() as $slug ) {
259 $module = Jetpack::get_module( $slug );
260 if ( $module )
261 $modules[$slug] = $module;
262 }
263 self::$modules = $modules;
264 add_filter( 'jetpack_get_available_modules', array($this, 'blacklist') );
265 } else {
266 self::$modules = self::$known_modules;
267 }
268 }
269 return self::$modules;
270 }
271
272 /**
273 * Return plugin basename
274 *
275 * @since 0.1
276 *
277 * @return string Plugin basename
278 */
279 private function plugin_basename() {
280 if ( null === self::$plugin_basename ) {
281 self::$plugin_basename = plugin_basename( __FILE__ );
282 }
283 return self::$plugin_basename;
284 }
285
286 /**
287 * Sub-site override
288 */
289
290 /**
291 * Adds the sub-site override option
292 *
293 * @see get_site_option(), checked(), disabled()
294 * @uses jetpack_mc_subsite_override network option
295 * @echo Html Checkbox input field for jetpack_mc_subsite_override option
296 * @return void
297 */
298 public function subsite_override_settings() {
299
300 if( is_network_admin() ) {
301 $option = get_site_option('jetpack_mc_subsite_override');
302 }
303 $disabled = false;
304 ?>
305 <label>
306 <input type='checkbox' name='jetpack_mc_subsite_override' value='1'
307 <?php checked( $option, '1' ); ?>
308 <?php disabled( $disabled ); ?>>
309 <?php _e('Allow individual site administrators to manage their own settings for Jetpack Module Control','jetpack-module-control'); ?>
310 </label>
311
312 <?php
313 } // END subsite_override_settings()
314
315 /**
316 * Checks if subsite override is allowed on multisite.
317 *
318 * @uses get_site_option()
319 * @return bool jetpack_mc_subsite_override network option. Always true if single site installation
320 */
321 public function subsite_override() {
322
323 if ( is_multisite() ) {
324 $option = get_site_option('jetpack_mc_subsite_override');
325 } else {
326 //Always return true if not multisite
327 $option = true;
328 }
329
330 return $option;
331
332 } // END subsite_override()
333
334
335 /**
336 * MANUAL CONTROL
337 */
338
339 /**
340 * Adds the Manual Control option
341 *
342 * @since 0.1
343 * @see get_site_option(), checked(), disabled()
344 *
345 * @uses jetpack_mc_manual_control network option
346 * @echo Html Checkbox input field for jetpack_mc_manual_control option
347 * @return void
348 */
349 public function manual_control_settings() {
350
351 if ( is_network_admin() ) {
352 // we're in network admin: retrieve network settings
353 $disabled = is_plugin_active_for_network('manual-control/manual-control.php');
354 $option = $disabled ? '1' : get_site_option('jetpack_mc_manual_control');
355 } else {
356 // we're in site admin
357 if ( is_plugin_active('manual-control/manual-control.php') ) {
358 $option = '1';
359 $disabled = true;
360 } else {
361 // check if subsite override allowed
362 if( $this->subsite_override() ) {
363 // retrieve site setting
364 $option = get_option('jetpack_mc_manual_control');
365 } else {
366 $option = false;
367 }
368 // fall back on network settings
369 if ( $option === false && is_multisite() ) $option = get_site_option('jetpack_mc_manual_control');
370 $disabled = defined('JETPACK_MC_LOCKDOWN') && JETPACK_MC_LOCKDOWN ? true : false;
371 }
372 }
373
374 ?>
375 <label>
376 <input type='checkbox' name='jetpack_mc_manual_control' value='1'
377 <?php checked( $option, '1' ); ?>
378 <?php disabled( $disabled ); ?>>
379 <?php _e('Prevent Jetpack from auto-activating (new) modules','jetpack-module-control'); ?>
380 </label>
381 <p class="description"><?php echo sprintf( __('Note: The module %s is excepted from this rule.','jetpack-module-control'), translate_with_gettext_context('Protect','Module Name','jetpack') ); ?></p>
382 <?php
383
384 } // END manual_control_settings()
385
386 /**
387 * Activates Manual Control by returning an empty array on module auto-activation.
388 * First modelled after Manual Control for Jetpack by Mark Jaquith http://coveredwebservices.com/
389 * To be converted to allow selected modules instead of all or none.
390 *
391 * @since 0.1
392 * @see add_filter()
393 */
394 public function manual_control( $modules ) {
395
396 // check if subsite override allowed
397 if( $this->subsite_override() ) {
398 $option = get_option('jetpack_mc_manual_control');
399 } else {
400 $option = false;
401 }
402 // if false, fall back on network settings
403 if ( $option === false && is_multisite() ) $option = get_site_option('jetpack_mc_manual_control');
404
405 return !empty($option) ? array() : $modules;
406
407 } // END manual_control()
408
409 /**
410 * DEVELOPMENT MODE
411 */
412
413 /**
414 * Get the Jetpack Without WordPress.com option
415 *
416 * @since 1.6
417 *
418 * @return bool|string
419 */
420 private function get_development_mode() {
421
422 if ( is_network_admin() ) {
423 // we're in network admin
424 if ( is_plugin_active_for_network('slimjetpack/slimjetpack.php') || is_plugin_active_for_network('unplug-jetpack/unplug-jetpack.php') ) {
425 $option = '1';
426 } else {
427 // retrieve network settings
428 $option = get_site_option('jetpack_mc_development_mode');
429 }
430 } else {
431 // we're in site admin
432 if ( is_plugin_active('slimjetpack/slimjetpack.php') || is_plugin_active('unplug-jetpack/unplug-jetpack.php') ) {
433 $option = '1';
434 } else {
435 // check if subsite override allowed
436 if( $this->subsite_override() ) {
437 //retrieve site setting
438 $option = get_option('jetpack_mc_development_mode');
439 } else {
440 $option = false;
441 }
442 // fall back on network settings
443 if ( $option === false && is_multisite() ) $option = get_site_option('jetpack_mc_development_mode');
444 }
445 }
446
447 return $option;
448 }
449
450 /**
451 * Adds the Jetpack Without WordPress.com option
452 *
453 * @since 1.0
454 * @see get_site_option(), checked(), disabled()
455 *
456 * @echo Html Checkbox input field for jetpack_mc_development_mode option
457 * @return void
458 */
459 public function development_mode_settings() {
460
461 $option = $this->get_development_mode();
462 $disabled = ! is_network_admin() && defined('JETPACK_MC_LOCKDOWN') && JETPACK_MC_LOCKDOWN ? true : false;
463
464 if ( is_network_admin() && ( is_plugin_active_for_network('slimjetpack/slimjetpack.php') || is_plugin_active_for_network('unplug-jetpack/unplug-jetpack.php') ) || is_plugin_active('slimjetpack/slimjetpack.php') || is_plugin_active('unplug-jetpack/unplug-jetpack.php') ) {
465 $disabled = true;
466 }
467
468 ?>
469 <label>
470 <input type='checkbox' name='jetpack_mc_development_mode' value='1'
471 <?php checked( $option, '1' ); ?>
472 <?php disabled( $disabled ); ?>>
473 <?php _e('Use Jetpack modules without a WordPress.com connection','jetpack-module-control'); ?>
474 </label>
475 <p class="description"><?php _e('By forcing Jetpack into development mode, modules are used without a WordPress.com account. All modules that require a WordPress.com connection will be unavailable. These modules are marked with an asterisk (*) below. The admin message about Jetpack running in development mode will be hidden.','jetpack-module-control'); ?></p>
476 <?php
477
478 } // END development_mode_settings()
479
480 /**
481 * Activates Development Mode by returning true on jetpack_development_mode filter.
482 * Based on http://jeremy.hu/customize-the-list-of-modules-available-in-jetpack/
483 *
484 * @since 1.0
485 * @see add_filter()
486 */
487 public function development_mode() {
488 // check if subsite override allowed
489 if( $this->subsite_override() ) {
490 $option = get_option('jetpack_mc_development_mode');
491 } else {
492 $option = false;
493 }
494
495 // if false, fall back on network settings
496 if ( $option === false && is_multisite() ) {
497 $option = get_site_option('jetpack_mc_development_mode');
498 }
499
500 return !empty($option) ? true : false;
501 }
502
503 /**
504 * ADMIN NOTICES
505 */
506
507 /**
508 * Disables Centralized Site Management banner by returning false on can_display_jetpack_manage_notice filter.
509 *
510 * @since 0.1
511 * @see add_filter()
512 */
513 private function no_manage_notice() {
514 // check if subsite override allowed
515 if( $this->subsite_override() ) {
516 $blacklist = get_option('jetpack_mc_blacklist');
517 } else {
518 $blacklist = false;
519 }
520
521 // fall back on network setting
522 if ( $blacklist === false && is_multisite() ) $blacklist = get_site_option('jetpack_mc_blacklist');
523
524 if ( is_array( $blacklist ) && in_array( 'manage', $blacklist ) ) {
525 add_filter( 'can_display_jetpack_manage_notice', '__return_false' );
526 }
527 }
528
529 /**
530 * Disables Centralized Site Management banner by removing show_development_mode_notice from jetpack_notices actions.
531 *
532 * @since 0.1
533 * @see add_filter()
534 */
535 private function no_dev_notice() {
536 if ( class_exists('Jetpack') && ( get_option('jetpack_mc_development_mode') || get_site_option('jetpack_mc_development_mode') ) ) {
537 remove_action( 'jetpack_notices', array( Jetpack::init(), 'show_development_mode_notice' ) );
538 }
539 }
540
541 /**
542 * BLACKLIST
543 */
544
545 /**
546 * Adds a checkmark list of modules to blacklist
547 *
548 * @since 0.1
549 * @see get_site_option(), checked()
550 *
551 * @uses jetpack_mc_blacklist network option
552 * @echo Html Checkbox input field table for jetpack_mc_blacklist option
553 */
554 public function blacklist_settings() {
555
556 if ( is_network_admin() ) {
557 // in network admin retrieve network settings
558 $blacklist = get_site_option( 'jetpack_mc_blacklist', array() );
559 $disabled = false;
560 } else {
561 // check if subsite override allowed
562 if( $this->subsite_override() ) {
563 // in site admin retrieve site settings
564 $blacklist = get_option( 'jetpack_mc_blacklist' );
565 } else {
566 $blacklist = false;
567 }
568
569 // fall back on network setting
570 if ( $blacklist === false && is_multisite() ) $blacklist = get_site_option('jetpack_mc_blacklist');
571 $disabled = defined('JETPACK_MC_LOCKDOWN') && JETPACK_MC_LOCKDOWN ? true : false;
572 }
573
574 $devmode = $this->get_development_mode();
575
576 // blacklist must be an array, if anything else then just make it an empty array
577 if ( !is_array($blacklist) ) $blacklist = array();
578
579 $modules = $this->get_available_modules();
580 asort($modules);
581
582 ?>
583 <fieldset><legend class="screen-reader-text"><span><?php _e('Blacklist Modules','jetpack-module-control'); ?></span></legend>
584 <?php
585 foreach ( $modules as $slug => $module ) {
586 $icon = isset(self::$known_modules_icons[$slug]) ? self::$known_modules_icons[$slug] : self::$default_icon;
587 $reqconn = !empty($module['requires_connection']) && true === $module['requires_connection'];
588 if ( $devmode && $reqconn ) continue;
589 ?>
590 <label>
591 <input type='checkbox' name='jetpack_mc_blacklist[]' value='<?php echo $slug; ?>'
592 <?php checked( in_array( $slug, $blacklist ) ); ?>
593 <?php disabled( $disabled ); ?>>
594 <span class="dashicons dashicons-<?php echo $icon; ?>"></span> <?php echo translate_with_gettext_context( $module['name'], 'Module Name', 'jetpack' ) ?>
595 </label><?php echo $reqconn ? ' <a href="#jmc-note-1" style="text-decoration:none" title="' . __('Requires a WordPress.com connection','jetpack-module-control') . '">*</a>' : ''; ?><br>
596 <?php
597 }
598 if ( ! $devmode ) echo '<aside role="note" id="jmc-note-1"><p class="description">' . __('*) Modules marked with an asterisk require a WordPress.com connection. They will be unavailable if Jetpack is forced into offline mode.','jetpack-module-control') . '</p></aside>';
599 ?>
600 </fieldset>
601 <?php
602
603 } // END blacklist_settings()
604
605 /**
606 * Blacklist Jetpack modules
607 * Modelled after ParhamG's blacklist_jetpack_modules.php https://gist.github.com/ParhamG/6494979
608 *
609 * @since 0.1
610 * @param $modules
611 *
612 * @return Array Allowed modules after unsetting blacklisted modules from all modules array
613 */
614 public function blacklist ( $modules ) {
615
616 // check if subsite override allowed
617 if( $this->subsite_override() ) {
618 $blacklist = get_option('jetpack_mc_blacklist');
619 } else {
620 $blacklist = false;
621 }
622
623 // fall back on network setting
624 if ( $blacklist === false && is_multisite() ) $blacklist = get_site_option('jetpack_mc_blacklist');
625
626 foreach ( (array)$blacklist as $mod )
627 if ( isset( $modules[$mod] ) )
628 unset( $modules[$mod] );
629
630 return $modules;
631
632 }
633
634 /**
635 * ADMIN
636 */
637
638 /**
639 * Initiate plugins admin stuff
640 *
641 * @since 0.1
642 */
643 public function admin_init(){
644
645 $this->no_manage_notice();
646
647 $this->no_dev_notice();
648
649 if ( is_plugin_active_for_network( $this->plugin_basename() ) ) {
650 // Check for network activation, else these will also take effect when
651 // plugin is activated on the primary site alone.
652 // TODO : see if you can actually use this scenario where plugin is activatied on site 1 and
653 // network options can be set to serve as default settings for other site activations !
654
655 // Add settings to Network Settings
656 // thanks to http://zao.is/2013/07/adding-settings-to-network-settings-for-wordpress-multisite/
657 add_filter( 'wpmu_options', array( $this, 'show_network_settings' ) );
658 add_action( 'update_wpmu_options', array( $this, 'save_network_settings' ) );
659
660 // Plugin action links
661 add_filter( 'network_admin_plugin_action_links_' . $this->plugin_basename(), array($this, 'add_action_link') );
662 }
663
664 // check if subsite override allowed
665 if($this->subsite_override()) {
666 // Plugin action links
667 add_filter( 'plugin_action_links_' . $this->plugin_basename(), array($this, 'add_action_link') );
668
669 // Do regular register/add_settings stuff in 'general' settings on options-general.php
670 $settings = 'general';
671
672 add_settings_section('jetpack-module-control', '<a name="jetpack-mc"></a>' . __('Jetpack Module Control','jetpack-module-control'), array($this, 'add_settings_section'), $settings);
673
674 // register settings
675 if ( defined('JETPACK_MC_LOCKDOWN') && JETPACK_MC_LOCKDOWN ) {
676 // do not register site settings to prevent them being updated
677 } else {
678 register_setting( $settings, 'jetpack_mc_manual_control' ); // sanitize_callback 'boolval' ?
679 register_setting( $settings, 'jetpack_mc_development_mode' ); // sanitize_callback 'boolval' ?
680 register_setting( $settings, 'jetpack_mc_blacklist', array($this, 'sanitize_blacklist') );
681 }
682
683 // add settings fields
684 add_settings_field( 'jetpack_mc_manual_control', __('Manual Control','jetpack-module-control'), array($this, 'manual_control_settings'), $settings, 'jetpack-module-control' ); // array('label_for' => 'elementid')
685 add_settings_field( 'jetpack_mc_development_mode', __('Offline Mode','jetpack-module-control'), array($this, 'development_mode_settings'), $settings, 'jetpack-module-control' ); // array('label_for' => 'elementid')
686 add_settings_field( 'jetpack_mc_blacklist', __('Blacklist Modules','jetpack-module-control'), array($this, 'blacklist_settings'), $settings, 'jetpack-module-control' );
687 }
688
689 }
690
691 /**
692 * Sanitizes blacklist array
693 *
694 * @since 1.6
695 */
696 public function sanitize_blacklist( $options ) {
697 return is_array($options) ? array_values($options) : $options;
698 }
699
700 /**
701 * Saves the network settings
702 *
703 * @since 0.2
704 */
705 public function save_network_settings() {
706
707 $posted_settings = array(
708 'jetpack_mc_manual_control' => '',
709 'jetpack_mc_development_mode' => '',
710 'jetpack_mc_blacklist' => '',
711 'jetpack_mc_subsite_override' => ''
712 );
713
714 isset( $_POST['jetpack_mc_subsite_override'] ) && $posted_settings['jetpack_mc_subsite_override'] = '1';
715
716 isset( $_POST['jetpack_mc_manual_control'] ) && $posted_settings['jetpack_mc_manual_control'] = '1';
717
718 isset( $_POST['jetpack_mc_development_mode'] ) && $posted_settings['jetpack_mc_development_mode'] = '1';
719
720 isset( $_POST['jetpack_mc_blacklist'] ) && $posted_settings['jetpack_mc_blacklist'] = $this->sanitize_blacklist( $_POST['jetpack_mc_blacklist'] );
721
722 foreach( $posted_settings as $name => $value ) {
723 update_site_option( $name, $value );
724 }
725
726 }
727
728 /**
729 * Prints the network settings
730 *
731 * @since 0.2
732 */
733 public function show_network_settings() {
734 ?>
735 <h3><a name="jetpack-mc"></a><?php _e('Jetpack Module Control','jetpack-module-control'); ?></h3>
736 <?php
737 $this->add_settings_section('');
738 ?>
739 <table class="form-table">
740 <tbody>
741 <tr>
742 <th scope="row"><?php _e('Sub-site Override','jetpack-module-control'); ?></th>
743 <td>
744 <?php
745 $this->subsite_override_settings();
746 ?>
747 </td>
748 </tr>
749
750 <tr>
751 <th scope="row"><?php _e('Manual Control','jetpack-module-control'); ?></th>
752 <td>
753 <?php
754 $this->manual_control_settings();
755 ?>
756 </td>
757 </tr>
758 <tr>
759 <th scope="row"><?php _e('Development Mode','jetpack-module-control'); ?></th>
760 <td>
761 <?php
762 $this->development_mode_settings();
763 ?>
764 </td>
765 </tr>
766 <tr>
767 <th scope="row"><?php _e('Blacklist Modules','jetpack-module-control'); ?></th>
768 <td>
769 <?php
770 $this->blacklist_settings();
771 ?>
772 </td>
773 </tr>
774 </tbody>
775 </table>
776 <?php
777 }
778
779 /**
780 * Echos a settings section header
781 *
782 * @since 0.1
783 *
784 * @param $option (unused)
785 * @echo Html
786 */
787 public function add_settings_section( $option ) {
788 echo '<p><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=ravanhagen%40gmail%2ecom&item_name=Jetpack%20Module%20Control&item_number='
789 . $this->version
790 . '&no_shipping=0&tax=0&charset=UTF%2d8&currency_code=EUR" title="'
791 . __('Donate to keep plugin development going!','jetpack-module-control')
792 . '" target="_blank"><img src="https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif" style="border:none;float:right;margin:5px 0 0 10px" alt="'
793 . __('Donate to keep plugin development going!','jetpack-module-control') . '" width="92" height="26" /></a>'
794 . sprintf(__('The options in this section are provided by %s.','jetpack-module-control'),'<strong><a href="http://status301.net/wordpress-plugins/jetpack-module-control/">'
795 . __('Jetpack Module Control','jetpack-module-control') . ' ' . $this->version . '</a></strong>') . ' '
796 . __('This plugin brings additional control over Jetpack modules. You can blacklist / remove individual modules, prevent auto-activation or allow activation without a WordPress.com account.','jetpack-module-control') . ' ';
797
798 if ( !is_multisite() )
799 echo sprintf(__('These settings can be locked down by adding %s to your wp-config.php file.','jetpack-module-control'),'<code>define(\'JETPACK_MC_LOCKDOWN\', true);</code>');
800 else if ( is_network_admin() )
801 echo '<br><em>' . __('These settings are only visible to you as Super Admin and these settings affect all sites on the network.','jetpack-module-control') . '</em>';
802
803 echo '</p>';
804 }
805
806 /**
807 * Adds an action link on the Plugins page
808 *
809 * @since 0.1
810 * @see is_plugin_active_for_network(), admin_url(), network_admin_url()
811 *
812 * @param array $links Plugin de/activation and deletion links
813 * @return array Plugin links plus Settings link
814 */
815 public function add_action_link( $links ) {
816 $settings_link = is_plugin_active_for_network( $this->plugin_basename() ) ?
817 '<a href="' . network_admin_url('settings.php#jetpack-mc') . '">' . translate('Network Settings') . '</a>' :
818 '<a href="' . admin_url('options-general.php#jetpack-mc') . '">' . translate('Settings') . '</a>';
819 return array_merge(
820 array( 'settings' => $settings_link ),
821 $links
822 );
823 return $links;
824 }
825
826 /**
827 * Routines to execute on plugins_loaded
828 *
829 * https://github.com/Automattic/jetpack/pull/2027 >> request accepted and fixed
830 *
831 * @since 0.1
832 */
833 public function plugins_loaded() {
834 global $pagenow;
835
836 // only need translations on admin page
837 if ( is_admin() ) {
838 load_plugin_textdomain( 'jetpack-module-control' );
839 }
840
841 add_filter( 'jetpack_get_default_modules', array( $this, 'manual_control' ), 99 );
842 add_filter( 'jetpack_offline_mode', array( $this, 'development_mode' ) );
843 add_filter( 'jetpack_get_available_modules', array( $this, 'blacklist' ) );
844 }
845
846 /**
847 * Getter method for retrieving single object instance.
848 *
849 * @since 0.1
850 *
851 * @return Jetpack_Module_Control|null instance object
852 */
853 public static function instance() {
854 if(is_null(self::$instance)) {
855 self::$instance = new self();
856 }
857 return self::$instance;
858 }
859
860 /**
861 * Constructor
862 *
863 * @since 0.1
864 */
865 private function __construct() {
866 add_action( 'plugins_loaded', array( $this, 'plugins_loaded' ), 0 );
867 add_action( 'admin_init', array($this,'admin_init'), 11 );
868 }
869
870 /**
871 * Cloning
872 *
873 * @since 0.1
874 */
875 private function __clone() { }
876
877 }
878
879 Jetpack_Module_Control::instance();
880