Jetpack by WordPress.com - Version 3.6.2

Version Description

Release Date: May 26, 2016

  • Important security update. Please upgrade immediately.
Download this release

Release Info

Developer samhotchkiss
Plugin Icon 128x128 Jetpack by WordPress.com
Version 3.6.2
Comparing to
See all releases

Code changes from version 3.5.4 to 3.6.2

Files changed (210) hide show
  1. CONTRIBUTING.md +38 -0
  2. _inc/footer.php +4 -17
  3. _inc/gallery-settings.js +2 -2
  4. _inc/header.php +13 -9
  5. _inc/jetpack-modules.js +11 -2
  6. _inc/jp-my-jetpack.js +86 -0
  7. _inc/jp.js +3 -3
  8. _inc/lib/admin-pages/class.jetpack-landing-page.php +9 -1
  9. _inc/lib/admin-pages/class.jetpack-my-jetpack-page.php +187 -0
  10. _inc/lib/markdown/extra.php +3 -3
  11. _inc/lib/markdown/gfm.php +2 -1
  12. _inc/lib/markdown/test.php +0 -33
  13. class.jetpack-admin.php +11 -2
  14. class.jetpack-cli.php +432 -17
  15. class.jetpack-client-server.php +48 -6
  16. class.jetpack-client.php +63 -0
  17. class.jetpack-data.php +83 -0
  18. class.jetpack-heartbeat.php +2 -0
  19. class.jetpack-ixr-client.php +3 -3
  20. class.jetpack-modules-list-table.php +43 -6
  21. class.jetpack-network-sites-list-table.php +10 -10
  22. class.jetpack-network.php +45 -6
  23. class.jetpack-options.php +13 -1
  24. class.jetpack-signature.php +1 -1
  25. class.jetpack-sync.php +5 -0
  26. class.jetpack-twitter-cards.php +7 -33
  27. class.jetpack-user-agent.php +1 -1
  28. class.jetpack-xmlrpc-server.php +22 -0
  29. class.jetpack.php +351 -35
  30. class.json-api-endpoints.php +60 -166
  31. class.media-summary.php +1 -0
  32. css/dashboard-widget-rtl.css +0 -1
  33. css/dashboard-widget.css +0 -2
  34. css/dashboard-widget.css.map +1 -1
  35. css/jetpack-admin-rtl.css +281 -8
  36. css/jetpack-admin-rtl.min.css +32 -1
  37. css/jetpack-admin.css +249 -8
  38. css/jetpack-admin.css.map +1 -1
  39. css/jetpack-admin.min.css +32 -1
  40. css/jetpack-admin.min.css.map +1 -1
  41. css/jetpack-banners-rtl.css +59 -20
  42. css/jetpack-banners-rtl.min.css +4 -1
  43. css/jetpack-banners.css +54 -19
  44. css/jetpack-banners.css.map +1 -1
  45. css/jetpack-banners.min.css +4 -1
  46. css/jetpack-banners.min.css.map +1 -1
  47. css/jetpack-icons.css +0 -2
  48. css/jetpack-icons.css.map +1 -1
  49. css/jetpack-rtl.css +1 -1
  50. css/jetpack.css +1 -1
  51. functions.gallery.php +0 -12
  52. functions.opengraph.php +53 -24
  53. images/the-footcloud.svg +4 -4
  54. jetpack.php +4 -4
  55. json-api-config.php +1 -0
  56. json-endpoints.php +145 -1603
  57. json-endpoints/class.wpcom-json-api-get-post-counts-v1-1-endpoint.php +40 -0
  58. json-endpoints/class.wpcom-json-api-get-site-endpoint.php +2 -2
  59. json-endpoints/class.wpcom-json-api-list-comments-endpoint.php +6 -2
  60. json-endpoints/class.wpcom-json-api-list-posts-v1-1-endpoint.php +20 -8
  61. json-endpoints/class.wpcom-json-api-site-settings-endpoint.php +28 -1
  62. json-endpoints/class.wpcom-json-api-update-post-endpoint.php +31 -15
  63. json-endpoints/class.wpcom-json-api-update-post-v1-1-endpoint.php +31 -15
  64. json-endpoints/class.wpcom-json-api-update-post-v1-2-endpoint.php +31 -15
  65. languages/jetpack-af.mo +0 -0
  66. languages/jetpack-ar.mo +0 -0
  67. languages/jetpack-az.mo +0 -0
  68. languages/jetpack-bg_BG.mo +0 -0
  69. languages/jetpack-bs_BA.mo +0 -0
  70. languages/jetpack-ca.mo +0 -0
  71. languages/jetpack-ckb.mo +0 -0
  72. languages/jetpack-cs_CZ.mo +0 -0
  73. languages/jetpack-cy.mo +0 -0
  74. languages/jetpack-da_DK.mo +0 -0
  75. languages/jetpack-de_DE.mo +0 -0
  76. languages/jetpack-el.mo +0 -0
  77. languages/jetpack-es_ES.mo +0 -0
  78. languages/jetpack-fa_IR.mo +0 -0
  79. languages/jetpack-fi.mo +0 -0
  80. languages/jetpack-fr_FR.mo +0 -0
  81. languages/jetpack-gd.mo +0 -0
  82. languages/jetpack-gl_ES.mo +0 -0
  83. languages/jetpack-he_IL.mo +0 -0
  84. languages/jetpack-hr.mo +0 -0
  85. languages/jetpack-hu_HU.mo +0 -0
  86. languages/jetpack-id_ID.mo +0 -0
  87. languages/jetpack-is_IS.mo +0 -0
  88. languages/jetpack-it_IT.mo +0 -0
  89. languages/jetpack-ja.mo +0 -0
  90. languages/jetpack-ka_GE.mo +0 -0
  91. languages/jetpack-ko_KR.mo +0 -0
  92. languages/jetpack-lt_LT.mo +0 -0
  93. languages/jetpack-mk_MK.mo +0 -0
  94. languages/jetpack-ms_MY.mo +0 -0
  95. languages/jetpack-my_MM.mo +0 -0
  96. languages/jetpack-nb_NO.mo +0 -0
  97. languages/jetpack-nl_NL.mo +0 -0
  98. languages/jetpack-nn_NO.mo +0 -0
  99. languages/jetpack-pl_PL.mo +0 -0
  100. languages/jetpack-pt_BR.mo +0 -0
  101. languages/jetpack-pt_PT.mo +0 -0
  102. languages/jetpack-ro_RO.mo +0 -0
  103. languages/jetpack-ru_RU.mo +0 -0
  104. languages/jetpack-sa_IN.mo +0 -0
  105. languages/jetpack-si_LK.mo +0 -0
  106. languages/jetpack-sk_SK.mo +0 -0
  107. languages/jetpack-sl_SI.mo +0 -0
  108. languages/jetpack-sq.mo +0 -0
  109. languages/jetpack-sr_RS.mo +0 -0
  110. languages/jetpack-sv_SE.mo +0 -0
  111. languages/jetpack-te.mo +0 -0
  112. languages/jetpack-th.mo +0 -0
  113. languages/jetpack-tr_TR.mo +0 -0
  114. languages/jetpack-uk.mo +0 -0
  115. languages/jetpack-ur.mo +0 -0
  116. languages/jetpack-vi.mo +0 -0
  117. languages/jetpack-zh_CN.mo +0 -0
  118. languages/jetpack-zh_TW.mo +0 -0
  119. locales.php +117 -36
  120. modules/after-the-deadline.php +1 -1
  121. modules/after-the-deadline/atd.core.js +66 -2
  122. modules/carousel/jetpack-carousel.css +15 -0
  123. modules/carousel/jetpack-carousel.js +1 -1
  124. modules/carousel/jetpack-carousel.php +15 -1
  125. modules/carousel/rtl/jetpack-carousel-rtl.css +15 -15
  126. modules/contact-form/admin.php +1 -1
  127. modules/contact-form/css/menu-alter-rtl.css +1 -1
  128. modules/contact-form/css/menu-alter-rtl.min.css +1 -1
  129. modules/contact-form/css/menu-alter.css +1 -1
  130. modules/contact-form/css/menu-alter.min.css +1 -1
  131. modules/contact-form/grunion-form-view.php +1 -1
  132. modules/custom-css/csstidy/data.inc.php +9 -0
  133. modules/custom-css/custom-css.php +2 -2
  134. modules/custom-css/custom-css/css/blank.css +1 -0
  135. modules/custom-css/custom-css/preprocessors/lessc.inc.php +149 -56
  136. modules/custom-post-types/comics.php +6 -5
  137. modules/custom-post-types/css/nova-font.css +3 -2
  138. modules/custom-post-types/css/testimonial-shortcode.css +1 -0
  139. modules/custom-post-types/nova.php +7 -7
  140. modules/custom-post-types/testimonial.php +163 -76
  141. modules/infinite-scroll/infinity.js +1 -1
  142. modules/infinite-scroll/infinity.php +7 -5
  143. modules/likes.php +13 -16
  144. modules/manage.php +11 -1
  145. modules/minileven/minileven.php +1 -1
  146. modules/minileven/theme/pub/minileven/content-gallery.php +5 -0
  147. modules/minileven/theme/pub/minileven/footer.php +8 -0
  148. modules/minileven/theme/pub/minileven/page.php +5 -0
  149. modules/module-info.php +2 -1
  150. modules/notes.php +2 -2
  151. modules/omnisearch/omnisearch-posts.php +4 -2
  152. modules/protect.php +170 -54
  153. modules/protect/config-ui.php +18 -5
  154. modules/protect/math-fallback.php +19 -5
  155. modules/protect/shared-functions.php +158 -36
  156. modules/publicize/publicize.php +10 -6
  157. modules/related-posts/jetpack-related-posts.php +1 -1
  158. modules/related-posts/related-posts.css +37 -39
  159. modules/related-posts/related-posts.js +1 -1
  160. modules/sharedaddy/recaptcha.php +179 -0
  161. modules/sharedaddy/recaptchalib.php +0 -277
  162. modules/sharedaddy/sharedaddy.php +18 -8
  163. modules/sharedaddy/sharing-service.php +16 -13
  164. modules/sharedaddy/sharing-sources.php +107 -74
  165. modules/sharedaddy/sharing.js +27 -54
  166. modules/sharedaddy/sharing.php +3 -11
  167. modules/shortcodes/css/rtl/slideshow-shortcode-rtl.css +35 -17
  168. modules/shortcodes/css/slideshow-shortcode.css +36 -18
  169. modules/shortcodes/dailymotion.php +70 -0
  170. modules/shortcodes/facebook.php +6 -15
  171. modules/shortcodes/instagram.php +20 -25
  172. modules/shortcodes/js/facebook.js +29 -0
  173. modules/shortcodes/js/instagram.js +19 -0
  174. modules/shortcodes/js/slideshow-shortcode.js +14 -33
  175. modules/shortcodes/mesh.php +16 -0
  176. modules/shortcodes/mixcloud.php +1 -1
  177. modules/shortcodes/slideshare.php +63 -22
  178. modules/shortcodes/slideshow.php +21 -39
  179. modules/shortcodes/wufoo.php +80 -0
  180. modules/site-icon/jetpack-site-icon.php +18 -8
  181. modules/site-icon/upload-site-icon.php +1 -1
  182. modules/sso.php +16 -4
  183. modules/stats.php +115 -9
  184. modules/subscriptions.php +41 -26
  185. modules/theme-tools/compat/twentyfifteen-rtl.css +1 -17
  186. modules/theme-tools/compat/twentyfifteen.css +1 -17
  187. modules/theme-tools/featured-content.php +13 -0
  188. modules/theme-tools/responsive-videos.php +4 -0
  189. modules/theme-tools/responsive-videos/responsive-videos.css +10 -0
  190. modules/verification-tools/blog-verification-tools.php +48 -13
  191. modules/widgets/facebook-likebox.php +31 -77
  192. modules/widgets/facebook-likebox/style.css +3 -0
  193. modules/widgets/gallery.php +8 -4
  194. modules/widgets/gallery/js/admin.js +3 -4
  195. modules/widgets/goodreads.php +2 -7
  196. modules/widgets/rsslinks-widget.php +28 -10
  197. modules/widgets/social-media-icons.php +207 -0
  198. modules/widgets/social-media-icons/style.css +49 -0
  199. modules/widgets/top-posts.php +134 -24
  200. modules/widgets/twitter-timeline.php +14 -4
  201. modules/widgets/wordpress-post-widget.php +51 -13
  202. readme.txt +65 -7
  203. scss/jetpack-admin.scss +1 -0
  204. scss/organisms/_banners.scss +62 -10
  205. scss/pages/_connection.scss +160 -0
  206. scss/templates/_main.scss +50 -3
  207. scss/templates/_settings.scss +61 -3
  208. views/admin/landing-page-templates.php +1 -1
  209. views/admin/my-jetpack-page.php +157 -0
  210. views/admin/network-settings.php +17 -10
CONTRIBUTING.md ADDED
@@ -0,0 +1,38 @@
1
+ # Want to contribute?
2
+
3
+ Did you know that you could be instrumental in making Jetpack more robust and secure? If you use and love Jetpack, why not contribute to the project?
4
+
5
+ ## Contributing for Everyone!
6
+
7
+ Whether you can barely recognize a filter (or don’t know what that means) or you’ve already authored your own plugins, there are ways for you to pitch in.
8
+
9
+ ### Beta Testing
10
+
11
+ Beta testers give updates, fixes, and new modules a test run before they’re publicly released, so they’re an important part of the development process. If you'd like to join our Beta group, [contact us](http://jetpack.me/contact-support/)!
12
+
13
+ ### Create Bug Reports
14
+
15
+ If you find a bug, let us know by creating a new issue [here](https://github.com/Automattic/jetpack/issues/new). You can [check our recommendations to create great bug reports here](http://jetpack.me/contribute/#bugs).
16
+
17
+ ### Write and submit a patch
18
+
19
+ If you'd like to fix a bug, you can submit a Pull Request. [Follow these detailed steps to find out how](http://jetpack.me/contribute/#patch).
20
+
21
+ When creating Pull Requests, remember:
22
+
23
+ - [Check In Early, Check In Often](http://blog.codinghorror.com/check-in-early-check-in-often/).
24
+ - Write [good commit messages](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html).
25
+ - Respect the [Best practices for WordPress development](http://jetpack.me/contribute/#practices).
26
+
27
+ There are a few bonuses that can increase the chances that your Pull Request is accepted:
28
+
29
+ - If you've created a new action or filter, [add inline documentation](https://make.wordpress.org/core/handbook/inline-documentation-standards/php-documentation-standards/#4-hooks-actions-and-filters) to help others understand how to use the action or the filter.
30
+ - Create [unit tests](https://github.com/Automattic/jetpack/tree/master/tests) if you can. If you're not familiar with Unit Testing, you can check [this tutorial](https://pippinsplugins.com/series/unit-tests-wordpress-plugins/).
31
+ - If [Grunt](http://gruntjs.com/) is installed on your testing environmenent, run it after committing your changes. It will allow you to [detect errors in Javascript files](http://jshint.com/about/), compile Sass to CSS, and [a few other things](https://github.com/Automattic/jetpack/blob/master/Gruntfile.js).
32
+
33
+ #### Where to get started?
34
+
35
+ If you'd like to contribute but don't know where to get started, you can take a look at existing issues:
36
+
37
+ - ["Good First Bug"](https://github.com/Automattic/Jetpack/issues?q=is%3Aopen+is%3Aissue+label%3A%22Good+First+Bug%22) issues are a good entry point to get familiar with Jetpack's codebase.
38
+ - ["Whisky"](https://github.com/Automattic/jetpack/labels/Whisky%20Ticket) issues are important bugs or enhancements. Take a crack at it if you feel adventurous! :)
_inc/footer.php CHANGED
@@ -1,12 +1,4 @@
1
- <?php
2
- global $current_user;
3
- $is_active = Jetpack::is_active();
4
- $user_token = Jetpack_Data::get_access_token( $current_user->ID );
5
- $is_user_connected = $user_token && ! is_wp_error( $user_token );
6
- $is_master_user = $current_user->ID == Jetpack_Options::get_option( 'master_user' );
7
- ?>
8
-
9
- </div><!-- .wrapper -->
10
<div class="footer">
11
12
<nav class="primary nav-horizontal">
@@ -24,17 +16,12 @@ $is_master_user = $current_user->ID == Jetpack_Options::get_option( 'master_u
24
<a href="http://jetpack.me">Jetpack <?php echo JETPACK__VERSION; ?></a>
25
<a href="http://wordpress.com/tos/"><?php esc_html_e( 'Terms', 'jetpack' ); ?></a>
26
<a href="http://automattic.com/privacy/"><?php esc_html_e( 'Privacy', 'jetpack' ); ?></a>
27
- <a href="<?php echo esc_url( Jetpack::admin_url( 'page=jetpack-debugger' ) ); ?>" title="<?php esc_attr_e( 'Test your site&#8217;s compatibility with Jetpack.', 'jetpack' ); ?>"><?php _e( 'Debug', 'jetpack' ); ?></a>
28
<a href="http://jetpack.me/contact-support/" title="<?php esc_attr_e( 'Contact the Jetpack Happiness Squad.', 'jetpack' ); ?>"><?php _e( 'Support', 'jetpack' ); ?></a>
29
<a href="http://jetpack.me/survey/?rel=<?php echo JETPACK__VERSION; ?>" title="<?php esc_attr_e( 'Take a survey. Tell us how we&#8217;re doing.', 'jetpack' ); ?>"><?php _e( 'Give Us Feedback', 'jetpack' ); ?></a>
30
-
31
- <?php if ( $is_active && current_user_can( 'jetpack_disconnect' ) ) : ?>
32
- <a href="<?php echo wp_nonce_url( Jetpack::admin_url( 'action=disconnect' ), 'jetpack-disconnect' ); ?>" onclick="return confirm('<?php echo htmlspecialchars( __('Are you sure you want to disconnect from WordPress.com?', 'jetpack'), ENT_QUOTES ); ?>');"><?php esc_html_e( 'Disconnect from WordPress.com', 'jetpack' ); ?></a>
33
<?php endif; ?>
34
- <?php if ( $is_active && $is_user_connected && ! $is_master_user ) : ?>
35
- <a href="<?php echo wp_nonce_url( Jetpack::admin_url( 'action=unlink' ), 'jetpack-unlink' ); ?>"><?php esc_html_e( 'Unlink your user account', 'jetpack' ); ?></a>
36
- <?php endif; ?>
37
-
38
</div>
39
</nav><!-- .secondary -->
40
</div><!-- .footer -->
1
+ </div><!-- .wrapper -->
2
<div class="footer">
3
4
<nav class="primary nav-horizontal">
16
<a href="http://jetpack.me">Jetpack <?php echo JETPACK__VERSION; ?></a>
17
<a href="http://wordpress.com/tos/"><?php esc_html_e( 'Terms', 'jetpack' ); ?></a>
18
<a href="http://automattic.com/privacy/"><?php esc_html_e( 'Privacy', 'jetpack' ); ?></a>
19
+ <?php if ( current_user_can( 'jetpack_manage_modules' ) ) : ?><a href="<?php echo esc_url( Jetpack::admin_url( 'page=jetpack-debugger' ) ); ?>" title="<?php esc_attr_e( 'Test your site&#8217;s compatibility with Jetpack.', 'jetpack' ); ?>"><?php _e( 'Debug', 'jetpack' ); ?><?php endif; ?></a>
20
<a href="http://jetpack.me/contact-support/" title="<?php esc_attr_e( 'Contact the Jetpack Happiness Squad.', 'jetpack' ); ?>"><?php _e( 'Support', 'jetpack' ); ?></a>
21
<a href="http://jetpack.me/survey/?rel=<?php echo JETPACK__VERSION; ?>" title="<?php esc_attr_e( 'Take a survey. Tell us how we&#8217;re doing.', 'jetpack' ); ?>"><?php _e( 'Give Us Feedback', 'jetpack' ); ?></a>
22
+ <?php if ( current_user_can( 'jetpack_disconnect' ) ) : ?>
23
+ <a href="<?php echo esc_url( Jetpack::admin_url( 'page=my_jetpack#disconnect' ) ); ?>"><?php esc_html_e( 'Disconnect Jetpack', 'jetpack' ); ?></a>
24
<?php endif; ?>
25
</div>
26
</nav><!-- .secondary -->
27
</div><!-- .footer -->
_inc/gallery-settings.js CHANGED
@@ -20,7 +20,7 @@
20
$el.find( 'select[name=type]' ).on( 'change', function () {
21
var columnSetting = $el.find( 'select[name=columns]' ).closest( 'label.setting' );
22
23
- if ( 'default' === $( this ).val() ) {
24
columnSetting.show();
25
} else {
26
columnSetting.hide();
@@ -30,4 +30,4 @@
30
return this;
31
}
32
});
33
- })(jQuery);
20
$el.find( 'select[name=type]' ).on( 'change', function () {
21
var columnSetting = $el.find( 'select[name=columns]' ).closest( 'label.setting' );
22
23
+ if ( 'default' === $( this ).val() || 'thumbnails' === $( this ).val() ) {
24
columnSetting.show();
25
} else {
26
columnSetting.hide();
30
return this;
31
}
32
});
33
+ })(jQuery);
_inc/header.php CHANGED
@@ -6,15 +6,19 @@
6
7
<ul class="main-nav">
8
<li class="jetpack-logo"><a href="<?php echo Jetpack::admin_url(); ?>" title="<?php esc_attr_e( 'Jetpack', 'jetpack' ); ?>" <?php if ( 'jetpack' == $current ) { echo 'class="current"'; } ?>><span><?php esc_html_e( 'Jetpack', 'jetpack' ); ?></span></a></li>
9
- <?php if ( ( Jetpack::is_active() || Jetpack::is_development_mode() )
10
- && current_user_can( 'jetpack_manage_modules' )
11
- ) : ?>
12
- <li class="jetpack-modules">
13
- <a href="<?php echo Jetpack::admin_url( 'page=jetpack_modules' ); ?>" class="jp-button--settings <?php if ( 'jetpack_modules' == $current ) { echo 'current'; } ?>"><?php esc_html_e( 'Settings', 'jetpack' ); ?></a>
14
- </li>
15
- <li class="jetpack-modules">
16
- <a href="http://jetpack.me/survey/?rel=<?php echo JETPACK__VERSION; ?>" class="jp-button--settings"><?php esc_html_e( 'Feedback', 'jetpack' ); ?></a>
17
- </li>
18
<?php endif; ?>
19
</ul>
20
6
7
<ul class="main-nav">
8
<li class="jetpack-logo"><a href="<?php echo Jetpack::admin_url(); ?>" title="<?php esc_attr_e( 'Jetpack', 'jetpack' ); ?>" <?php if ( 'jetpack' == $current ) { echo 'class="current"'; } ?>><span><?php esc_html_e( 'Jetpack', 'jetpack' ); ?></span></a></li>
9
+ <?php if ( ( Jetpack::is_active() || Jetpack::is_development_mode() ) && current_user_can( 'jetpack_manage_modules' ) ) : ?>
10
+ <li class="jetpack-modules">
11
+ <a href="<?php echo Jetpack::admin_url( 'page=jetpack_modules' ); ?>" class="jp-button--settings <?php if ( 'jetpack_modules' == $current ) { echo 'current'; } ?>"><?php esc_html_e( 'Settings', 'jetpack' ); ?></a>
12
+ </li>
13
+ <li class="jetpack-modules">
14
+ <a href="http://jetpack.me/survey/?rel=<?php echo JETPACK__VERSION; ?>" class="jp-button--settings"><?php esc_html_e( 'Feedback', 'jetpack' ); ?></a>
15
+ </li>
16
+ <?php endif; // End if connected or dev mode and is admin ?>
17
+
18
+ <?php if ( Jetpack::is_active() && ! Jetpack::is_development_mode() ) : ?>
19
+ <li class="jetpack-modules">
20
+ <a href="<?php echo Jetpack::admin_url( 'page=my_jetpack' ); ?>" class="jp-button--settings <?php if ( 'my_jetpack' == $current ) { echo 'current'; } ?>"><?php esc_html_e( 'My Jetpack', 'jetpack' ); ?></a>
21
+ </li>
22
<?php endif; ?>
23
</ul>
24
_inc/jetpack-modules.js CHANGED
@@ -1,5 +1,5 @@
1
2
- ( function( window, $, items, models, views, i18n, nonces ) {
3
'use strict';
4
5
var modules, list_table, handle_module_tag_click, $the_table, $the_filters, $the_search, $jp_frame, $bulk_button, show_modal, hide_modal, set_modal_tab, originPoint;
@@ -59,6 +59,15 @@
59
$( '.modal' ).focus();
60
};
61
62
hide_modal = function() {
63
$jp_frame.children( '.modal, .shade' ).hide();
64
$jp_frame.children( '.modal' ).data( 'current-module', '' );
@@ -138,4 +147,4 @@
138
event.preventDefault();
139
} );
140
141
- } ) ( this, jQuery, window.jetpackModulesData.modules, this.jetpackModules.models, this.jetpackModules.views, window.jetpackModulesData.i18n, window.jetpackModulesData.nonces );
1
2
+ ( function( window, $, items, models, views, i18n, modalinfo, nonces ) {
3
'use strict';
4
5
var modules, list_table, handle_module_tag_click, $the_table, $the_filters, $the_search, $jp_frame, $bulk_button, show_modal, hide_modal, set_modal_tab, originPoint;
59
$( '.modal' ).focus();
60
};
61
62
+ /**
63
+ * If modalinfo is defined, auto popup the modal
64
+ */
65
+ $( document ).ready(function() {
66
+ if ( modalinfo ) {
67
+ show_modal( modalinfo );
68
+ }
69
+ });
70
+
71
hide_modal = function() {
72
$jp_frame.children( '.modal, .shade' ).hide();
73
$jp_frame.children( '.modal' ).data( 'current-module', '' );
147
event.preventDefault();
148
} );
149
150
+ } ) ( this, jQuery, window.jetpackModulesData.modules, this.jetpackModules.models, this.jetpackModules.views, window.jetpackModulesData.i18n, window.jetpackModulesData.modalinfo, window.jetpackModulesData.nonces );
_inc/jp-my-jetpack.js ADDED
@@ -0,0 +1,86 @@
1
+ /* global jpConnection, jQuery */
2
+
3
+ (function( $, jpConnection ) {
4
+
5
+ ///////////////////////////////////////
6
+ // INIT
7
+ ///////////////////////////////////////
8
+
9
+ var data = {
10
+ 'jetpackIsActive' : jpConnection.jetpackIsActive,
11
+ 'isAdmin' : jpConnection.isAdmin,
12
+ 'otherAdminsLinked' : jpConnection.otherAdminsLinked,
13
+ 'stats_urls' : jpConnection.my_jetpack_stats_urls,
14
+ 'masterUser' : jpConnection.masterUser,
15
+ 'masterUserLink' : jpConnection.masterUser.masterUserLink,
16
+ 'currentUser' : jpConnection.currentUser
17
+ };
18
+
19
+ $( document ).ready(function () {
20
+ renderPageTemplate( data );
21
+
22
+ // Set someone as master.
23
+ $( '#change-primary-btn' ).click( function() {
24
+ $( '#change-primary-btn' ).hide();
25
+ $( '#user-list' ).show();
26
+ $( '#save-primary-btn' ).show();
27
+
28
+ //Log My Jetpack event "change primary" in MC Stats
29
+ new Image().src = data.stats_urls.change_primary;
30
+ });
31
+
32
+ // Hide the success message after a little bit
33
+ setTimeout( function(){
34
+ jQuery( '.jetpack-message:not( .stay-visible, .jetpack-err )' ).hide( 600 );
35
+ }, 6000);
36
+
37
+ });
38
+
39
+ function renderPageTemplate( data ) {
40
+ $( '#my-jetpack-page-template' ).html( wp.template( 'connection-page' )( data ) );
41
+ // Save the focused element, then shift focus to the modal window.
42
+ confirmJetpackDisconnect();
43
+ }
44
+
45
+ /*
46
+ The function used to display the disconnect confirmation and support buttons
47
+ */
48
+ function confirmJetpackDisconnect() {
49
+ if ( window.location.hash.substr( '#disconnect' ) ) {
50
+ $( '#jetpack-disconnect-content' ).show();
51
+ $( '#my-jetpack-content, .my-jetpack-actions' ).hide();
52
+
53
+ //Log My Jetpack event "wants to disconnect Jetpack" in MC Stats
54
+ new Image().src = data.stats_urls.disconnect_site;
55
+ }
56
+
57
+ $( '#jetpack-disconnect' ).click( function() {
58
+ $( '#jetpack-disconnect-content' ).show();
59
+ $( '#my-jetpack-content, .my-jetpack-actions' ).hide();
60
+
61
+ //Log My Jetpack event "wants to disconnect Jetpack" in MC Stats
62
+ new Image().src = data.stats_urls.disconnect_site;
63
+ });
64
+
65
+ $( '#cancel-disconnect' ).click( function() {
66
+ event.preventDefault();
67
+
68
+ $( '#jetpack-disconnect-content' ).hide();
69
+ $( '#my-jetpack-content, .my-jetpack-actions' ).show();
70
+
71
+ //Log My Jetpack event "decided not to disconnect Jetpack" in MC Stats
72
+ new Image().src = data.stats_urls.cancel_disconnect;
73
+ });
74
+
75
+ $( '#jetpack-disconnect-content #support-no-disconnect' ).click( function() {
76
+ //Log My Jetpack event "get support instead of disconnecting site" in MC Stats
77
+ new Image().src = data.stats_urls.support_no_disconnect;
78
+ });
79
+
80
+ $( '#jetpack-disconnect-content #confirm-disconnect' ).click( function() {
81
+ //Log My Jetpack event "confirm the disconnecting of a the site" in MC Stats
82
+ new Image().src = data.stats_urls.confirm_disconnect;
83
+ });
84
+ }
85
+
86
+ })( jQuery, jpConnection );
_inc/jp.js CHANGED
@@ -65,7 +65,7 @@
65
66
// Hide the successful connection message after a little bit
67
setTimeout( function(){
68
- jQuery( '.jetpack-message:not(.stay-visible)' ).hide( 600 );
69
}, 6000);
70
71
// Modal events
@@ -200,8 +200,8 @@
200
}
201
});
202
203
- // Apply new height
204
- module.css( 'height', tallest + 'px' );
205
}
206
207
/*
65
66
// Hide the successful connection message after a little bit
67
setTimeout( function(){
68
+ jQuery( '.jetpack-message:not( .stay-visible, .jetpack-err )' ).hide( 600 );
69
}, 6000);
70
71
// Modal events
200
}
201
});
202
203
+ // Apply new height plus 20 pixels
204
+ module.css( 'height', ( parseInt( tallest, 10 ) + 5 ) + 'px' );
205
}
206
207
/*
_inc/lib/admin-pages/class.jetpack-landing-page.php CHANGED
@@ -38,7 +38,15 @@ class Jetpack_Landing_Page extends Jetpack_Admin_Page {
38
39
function add_page_actions( $hook ) {
40
// Add landing page specific underscore templates
41
- add_action( "admin_footer-$hook", array( $this, 'js_templates' ) );
42
/** This action is documented in class.jetpack.php */
43
do_action( 'jetpack_admin_menu', $hook );
44
38
39
function add_page_actions( $hook ) {
40
// Add landing page specific underscore templates
41
+ /**
42
+ * Filters the js_templates callback value
43
+ *
44
+ * @since 3.6.0
45
+ *
46
+ * @param array array( $this, 'js_templates' ) js_templates callback.
47
+ * @param string $hook Specific admin page.
48
+ */
49
+ add_action( "admin_footer-$hook", apply_filters( 'jetpack_landing_page_js_templates_callback', array( $this, 'js_templates' ), $hook ) );
50
/** This action is documented in class.jetpack.php */
51
do_action( 'jetpack_admin_menu', $hook );
52
_inc/lib/admin-pages/class.jetpack-my-jetpack-page.php ADDED
@@ -0,0 +1,187 @@
1
+ <?php
2
+ include_once( 'class.jetpack-admin-page.php' );
3
+ include_once( JETPACK__PLUGIN_DIR . 'class.jetpack-modules-list-table.php' );
4
+
5
+ // Builds the My Jetpack page
6
+ class Jetpack_My_Jetpack_Page extends Jetpack_Admin_Page {
7
+ // Show the settings page only when Jetpack is connected or in dev mode
8
+ protected $dont_show_if_not_active = true;
9
+ function add_page_actions( $hook ) {} // There are no page specific actions to attach to the menu
10
+
11
+ // Adds the My Jetpack page, but hides it from the submenu
12
+ function get_page_hook() {
13
+ return add_submenu_page( null, __( 'My Jetpack', 'jetpack' ), __( 'My Jetpack', 'jetpack' ), 'jetpack_connect_user', 'my_jetpack', array( $this, 'render' ) );
14
+ }
15
+
16
+ // Renders the view file
17
+ function page_render() {
18
+ Jetpack::init()->load_view( 'admin/my-jetpack-page.php' );
19
+
20
+ //My Jetpack view tracking, send to MC Stats
21
+ Jetpack::init()->stat( 'admin', 'my-jetpack' );
22
+ Jetpack::init()->do_stats( 'server_side' );
23
+
24
+ }
25
+
26
+ /*
27
+ * Handle the change in master user
28
+ */
29
+ function jetpack_my_jetpack_change_user() {
30
+ if ( ! isset( $_POST['_my_jetpack_nonce'] ) || ! wp_verify_nonce( $_POST['_my_jetpack_nonce'], 'jetpack_change_primary_user' ) ) {
31
+ wp_die( __( 'Failed permissions, please try again.', 'jetpack' ) );
32
+ exit;
33
+ }
34
+
35
+ if ( isset( $_POST['jetpack-new-master'] ) ) {
36
+ $old_master_user = Jetpack_Options::get_option( 'master_user' );
37
+ $new_master_user = $_POST['jetpack-new-master'];
38
+ $user_token = Jetpack_Data::get_access_token( $new_master_user );
39
+ $is_user_connected = $user_token && ! is_wp_error( $user_token );
40
+ if ( current_user_can( 'manage_options' ) && $is_user_connected ) {
41
+ Jetpack::log( 'switch_master_user', array( 'old_master' => $old_master_user, 'new_master' => $new_master_user ) );
42
+ Jetpack_Options::update_option( 'master_user', $new_master_user );
43
+ Jetpack::state( 'message', 'switch_master' );
44
+
45
+ //My Jetpack primary user successfully changed, send to MC Stats
46
+ Jetpack::init()->stat( 'admin', 'change-primary-successful' );
47
+ Jetpack::init()->do_stats( 'server_side' );
48
+
49
+ // Change the blog owner dotcom side
50
+ $this->wpcom_switch_blog_owner( $new_master_user );
51
+ }
52
+ }
53
+ }
54
+
55
+ /*
56
+ * Tell wpcom that the master user has switched
57
+ * so we can update the 'wpcom_blog_owner'
58
+ */
59
+ function wpcom_switch_blog_owner( $new_master ) {
60
+ $request = array(
61
+ 'new_blog_owner' => $new_master
62
+ );
63
+
64
+ // Tell wpcom about the change
65
+ Jetpack::load_xml_rpc_client();
66
+ $xml = new Jetpack_IXR_Client( array(
67
+ 'user_id' => get_current_user_id(),
68
+ ) );
69
+
70
+ $xml->query( 'jetpack.switchBlogOwner', $request );
71
+ }
72
+
73
+ /*
74
+ * Checks to see if there are any other users available to become primary
75
+ * Users must both:
76
+ * - Be linked to wpcom
77
+ * - Be an admin
78
+ *
79
+ * @return bool
80
+ */
81
+ function jetpack_are_other_users_linked_and_admin() {
82
+ // If only one admin
83
+ $all_users = count_users();
84
+ if ( 2 > $all_users['avail_roles']['administrator'] ) {
85
+ return false;
86
+ }
87
+
88
+ $users = get_users();
89
+ $available = array();
90
+ // If no one else is linked to dotcom
91
+ foreach ( $users as $user ) {
92
+ if ( isset( $user->caps['administrator'] ) && Jetpack::is_user_connected( $user->ID ) ) {
93
+ $available[] = $user->ID;
94
+ }
95
+ }
96
+
97
+ if ( 2 > count( $available ) ) {
98
+ return false;
99
+ }
100
+
101
+ return true;
102
+ }
103
+
104
+ /*
105
+ * All the data we'll need about the Master User
106
+ * for the My Jetpack page template
107
+ *
108
+ * @return array
109
+ */
110
+ function jetpack_master_user_data() {
111
+ // If the master user has disappeared, none of this is useful.
112
+ // @todo throw up a warning and offer a solution
113
+ $master = Jetpack_Options::get_option( 'master_user' );
114
+ if ( ! get_user_by( 'id', $master ) ) {
115
+ return false;
116
+ }
117
+
118
+ $master_user = get_userdata( $master );
119
+ $master_user_data_com = Jetpack::get_connected_user_data( $master_user->ID );
120
+ $gravatar = sprintf( '<a href="%s">%s</a>', get_edit_user_link( $master_user->ID ), get_avatar( $master_user->ID, 40 ) );
121
+
122
+ $master_user_data = array(
123
+ 'masterUser' => $master_user,
124
+ 'masterDataCom' => $master_user_data_com,
125
+ 'gravatar' => $gravatar,
126
+ );
127
+
128
+ return $master_user_data;
129
+ }
130
+
131
+ /*
132
+ * All the data we'll need about the Current User
133
+ *
134
+ * @return array
135
+ */
136
+ function jetpack_current_user_data() {
137
+ global $current_user;
138
+ $is_master_user = $current_user->ID == Jetpack_Options::get_option( 'master_user' );
139
+ $dotcom_data = Jetpack::get_connected_user_data();
140
+
141
+ $current_user_data = array(
142
+ 'isUserConnected' => Jetpack::is_user_connected( $current_user->ID ),
143
+ 'isMasterUser' => $is_master_user,
144
+ 'adminUsername' => $current_user->user_login,
145
+ 'userComData' => $dotcom_data,
146
+ 'gravatar' => sprintf( '<a href="%s">%s</a>', get_edit_user_link( $current_user->ID ), get_avatar( $current_user->ID, 40 ) ),
147
+ );
148
+
149
+ return $current_user_data;
150
+ }
151
+
152
+
153
+ /*
154
+ * Build an array of My Jetpack stats urls.
155
+ * requires the build URL args passed as an array
156
+ *
157
+ * @param array $my_jetpack_stats
158
+ * @return (array) of built stats urls
159
+ */
160
+ function build_my_jetpack_stats_urls( $my_jetpack_stats ) {
161
+ $my_jetpack_urls = array();
162
+
163
+ foreach ( $my_jetpack_stats as $value ) {
164
+ $my_jetpack_urls[ $value ] = Jetpack::build_stats_url( array( 'x_jetpack-admin' => $value ) );
165
+ }
166
+
167
+ return $my_jetpack_urls;
168
+
169
+ }
170
+
171
+ // Load up admin scripts
172
+ function page_admin_scripts() {
173
+ wp_enqueue_script( 'jp-connection-js', plugins_url( '_inc/jp-my-jetpack.js', JETPACK__PLUGIN_FILE ), array( 'jquery', 'wp-util' ), JETPACK__VERSION . 'yep' );
174
+
175
+ wp_localize_script( 'jp-connection-js', 'jpConnection',
176
+ array(
177
+ 'jetpackIsActive' => Jetpack::is_active(),
178
+ 'isAdmin' => current_user_can( 'jetpack_manage_modules' ),
179
+ 'otherAdminsLinked' => $this->jetpack_are_other_users_linked_and_admin(),
180
+ 'masterUser' => $this->jetpack_master_user_data(),
181
+ 'currentUser' => $this->jetpack_current_user_data(),
182
+ 'my_jetpack_stats_urls' => $this->build_my_jetpack_stats_urls( array( 'change_primary', 'disconnect_site', 'confirm_disconnect', 'support_no_disconnect', 'cancel_disconnect' ) ),
183
+ 'alertText' => __( 'You must link another admin account before switching primary account holders.', 'jetpack' ),
184
+ )
185
+ );
186
+ }
187
+ }
_inc/lib/markdown/extra.php CHANGED
@@ -99,7 +99,7 @@ class Markdown_Parser {
99
var $escape_chars_re;
100
101
102
- function Markdown_Parser() {
103
#
104
# Constructor function. Initialize appropriate member variables.
105
#
@@ -1574,7 +1574,7 @@ class MarkdownExtra_Parser extends Markdown_Parser {
1574
1575
### Parser Implementation ###
1576
1577
- function MarkdownExtra_Parser() {
1578
#
1579
# Constructor function. Initialize the parser object.
1580
#
@@ -1600,7 +1600,7 @@ class MarkdownExtra_Parser extends Markdown_Parser {
1600
"doAbbreviations" => 70,
1601
);
1602
1603
- parent::Markdown_Parser();
1604
}
1605
1606
99
var $escape_chars_re;
100
101
102
+ function __construct() {
103
#
104
# Constructor function. Initialize appropriate member variables.
105
#
1574
1575
### Parser Implementation ###
1576
1577
+ function __construct() {
1578
#
1579
# Constructor function. Initialize the parser object.
1580
#
1600
"doAbbreviations" => 70,
1601
);
1602
1603
+ parent::__construct();
1604
}
1605
1606
_inc/lib/markdown/gfm.php CHANGED
@@ -64,7 +64,7 @@ class WPCom_GHF_Markdown_Parser extends MarkdownExtra_Parser {
64
$this->preserve_latex = function_exists( 'latex_markup' );
65
$this->strip_paras = function_exists( 'wpautop' );
66
67
- parent::MarkdownExtra_Parser();
68
}
69
70
/**
@@ -148,6 +148,7 @@ class WPCom_GHF_Markdown_Parser extends MarkdownExtra_Parser {
148
public function do_codeblock_preserve( $matches ) {
149
$block = stripslashes( $matches[3] );
150
$block = esc_html( $block );
151
$open = $matches[1] . $matches[2] . "\n";
152
return $open . $block . $matches[4];
153
}
64
$this->preserve_latex = function_exists( 'latex_markup' );
65
$this->strip_paras = function_exists( 'wpautop' );
66
67
+ parent::__construct();
68
}
69
70
/**
148
public function do_codeblock_preserve( $matches ) {
149
$block = stripslashes( $matches[3] );
150
$block = esc_html( $block );
151
+ $block = str_replace( '\\', '\\\\', $block );
152
$open = $matches[1] . $matches[2] . "\n";
153
return $open . $block . $matches[4];
154
}
_inc/lib/markdown/test.php DELETED
@@ -1,33 +0,0 @@
1
- <?php
2
-
3
- require 'extra.php';
4
- require 'gfm.php';
5
- $parser = new WPCom_GHF_Markdown_Parser;
6
-
7
- $text1 = <<<EOD
8
- I am just back\slashing up a *storm* \*mofo*.
9
-
10
- EOD;
11
-
12
- $text = 'Just rockin in the *free* world
13
-
14
- ```html
15
- <html lang="en">
16
- </html>
17
- ```
18
- ';
19
- #echo $text;
20
- echo $parser->transform( $text );
21
- echo "\n\n\n";
22
- #echo $parser->hashBlock( '<pre>foobar</pre>' );
23
-
24
-
25
- $foo = <<<EOD
26
- Here is a *list* with things:
27
-
28
- * some `code` is better than others
29
- * **my** code is better than *yours*
30
- * the best code is that which need not be written
31
-
32
- Selah.
33
- EOD;
class.jetpack-admin.php CHANGED
@@ -30,10 +30,19 @@ class Jetpack_Admin {
30
jetpack_require_lib( 'admin-pages/class.jetpack-settings-page' );
31
$this->settings_page = new Jetpack_Settings_Page;
32
33
// Add hooks for admin menus
34
add_action( 'admin_menu', array( $this->landing_page, 'add_actions' ), 998 );
35
add_action( 'jetpack_admin_menu', array( $this, 'admin_menu_debugger' ) );
36
add_action( 'jetpack_admin_menu', array( $this->settings_page, 'add_actions' ) );
37
38
// Add redirect to current page for activation/deactivation of modules
39
add_action( 'jetpack_pre_activate_module', array( $this, 'fix_redirect' ), 10, 2 );
@@ -146,14 +155,14 @@ class Jetpack_Admin {
146
return false;
147
148
/**
149
- * We never want to show VaultPress as activate-able through Jetpack.
150
*/
151
if ( 'vaultpress' === $module['module'] ) {
152
return false;
153
}
154
155
if ( Jetpack::is_development_mode() ) {
156
- return ! ( $module['requires_connection'] && ! Jetpack::is_active() );
157
} else {
158
return Jetpack::is_active();
159
}
30
jetpack_require_lib( 'admin-pages/class.jetpack-settings-page' );
31
$this->settings_page = new Jetpack_Settings_Page;
32
33
+ jetpack_require_lib( 'admin-pages/class.jetpack-my-jetpack-page' );
34
+ $this->my_jetpack_page = new Jetpack_My_Jetpack_Page;
35
+
36
+ if ( isset( $_POST['jetpack-set-master-user'] ) ) {
37
+ add_action( 'init', array( $this->my_jetpack_page, 'jetpack_my_jetpack_change_user' ) );
38
+ }
39
+
40
// Add hooks for admin menus
41
add_action( 'admin_menu', array( $this->landing_page, 'add_actions' ), 998 );
42
add_action( 'jetpack_admin_menu', array( $this, 'admin_menu_debugger' ) );
43
add_action( 'jetpack_admin_menu', array( $this->settings_page, 'add_actions' ) );
44
+ add_action( 'jetpack_admin_menu', array( $this->my_jetpack_page, 'add_actions' ) );
45
+
46
47
// Add redirect to current page for activation/deactivation of modules
48
add_action( 'jetpack_pre_activate_module', array( $this, 'fix_redirect' ), 10, 2 );
155
return false;
156
157
/**
158
+ * We never want to show VaultPress as activatable through Jetpack.
159
*/
160
if ( 'vaultpress' === $module['module'] ) {
161
return false;
162
}
163
164
if ( Jetpack::is_development_mode() ) {
165
+ return ! ( $module['requires_connection'] );
166
} else {
167
return Jetpack::is_active();
168
}
class.jetpack-cli.php CHANGED
@@ -7,26 +7,82 @@ WP_CLI::add_command( 'jetpack', 'Jetpack_CLI' );
7
*/
8
class Jetpack_CLI extends WP_CLI_Command {
9
10
/**
11
* Get Jetpack Details
12
*
13
* ## OPTIONS
14
*
15
- * None. Simply returns details about whether or not your blog
16
- * is connected, its Jetpack version, and WordPress.com blog_id.
17
*
18
* ## EXAMPLES
19
*
20
* wp jetpack status
21
*
22
*/
23
public function status( $args, $assoc_args ) {
24
- if ( Jetpack::is_active() ) {
25
WP_CLI::success( __( 'Jetpack is currently connected to WordPress.com', 'jetpack' ) );
26
WP_CLI::line( sprintf( __( 'The Jetpack Version is %s', 'jetpack' ), JETPACK__VERSION ) );
27
WP_CLI::line( sprintf( __( 'The WordPress.com blog_id is %d', 'jetpack' ), Jetpack_Options::get_option( 'id' ) ) );
28
- } else {
29
- WP_CLI::line( __( 'Jetpack is not currently connected to WordPress.com', 'jetpack' ) );
30
}
31
}
32
@@ -50,7 +106,7 @@ class Jetpack_CLI extends WP_CLI_Command {
50
* wp jetpack disconnect user username
51
* wp jetpack disconnect user email@domain.com
52
*
53
- * @synopsis blog|[user <user_id>]
54
*/
55
public function disconnect( $args, $assoc_args ) {
56
if ( ! Jetpack::is_active() ) {
@@ -79,7 +135,7 @@ class Jetpack_CLI extends WP_CLI_Command {
79
WP_CLI::error( __( 'Please specify a valid user.', 'jetpack' ) );
80
}
81
} else {
82
- WP_CLI::error( __( 'Please specify a user.', 'jetpack' ) );
83
}
84
}
85
@@ -104,17 +160,91 @@ class Jetpack_CLI extends WP_CLI_Command {
104
}
105
106
/**
107
- * Manage Jetpack Modules
108
*
109
* ## OPTIONS
110
*
111
- * list: View all available modules, and their status.
112
*
113
- * activate <module_slug>: Activate a module.
114
*
115
- * deactivate <module_slug>: Deactivate a module.
116
*
117
- * toggle <module_slug>: Toggle a module on or off.
118
*
119
* ## EXAMPLES
120
*
@@ -123,35 +253,47 @@ class Jetpack_CLI extends WP_CLI_Command {
123
* wp jetpack module deactivate stats
124
* wp jetpack module toggle stats
125
*
126
- * @synopsis [list|activate|deactivate|toggle [<module_name>]]
127
*/
128
public function module( $args, $assoc_args ) {
129
$action = isset( $args[0] ) ? $args[0] : 'list';
130
if ( ! in_array( $action, array( 'list', 'activate', 'deactivate', 'toggle' ) ) ) {
131
WP_CLI::error( sprintf( __( '%s is not a valid command.', 'jetpack' ), $action ) );
132
}
133
-
134
if ( in_array( $action, array( 'activate', 'deactivate', 'toggle' ) ) ) {
135
if ( isset( $args[1] ) ) {
136
$module_slug = $args[1];
137
- if ( ! Jetpack::is_module( $module_slug ) ) {
138
WP_CLI::error( sprintf( __( '%s is not a valid module.', 'jetpack' ), $module_slug ) );
139
}
140
if ( 'toggle' == $action ) {
141
$action = Jetpack::is_module_active( $module_slug ) ? 'deactivate' : 'activate';
142
}
143
} else {
144
WP_CLI::line( __( 'Please specify a valid module.', 'jetpack' ) );
145
$action = 'list';
146
}
147
}
148
-
149
switch ( $action ) {
150
case 'list':
151
WP_CLI::line( __( 'Available Modules:', 'jetpack' ) );
152
$modules = Jetpack::get_available_modules();
153
sort( $modules );
154
foreach( $modules as $module_slug ) {
155
$active = Jetpack::is_module_active( $module_slug ) ? __( 'Active', 'jetpack' ) : __( 'Inactive', 'jetpack' );
156
WP_CLI::line( "\t" . str_pad( $module_slug, 24 ) . $active );
157
}
@@ -159,19 +301,292 @@ class Jetpack_CLI extends WP_CLI_Command {
159
case 'activate':
160
$module = Jetpack::get_module( $module_slug );
161
Jetpack::log( 'activate', $module_slug );
162
- Jetpack::activate_module( $module_slug, false );
163
WP_CLI::success( sprintf( __( '%s has been activated.', 'jetpack' ), $module['name'] ) );
164
break;
165
case 'deactivate':
166
$module = Jetpack::get_module( $module_slug );
167
Jetpack::log( 'deactivate', $module_slug );
168
Jetpack::deactivate_module( $module_slug );
169
WP_CLI::success( sprintf( __( '%s has been deactivated.', 'jetpack' ), $module['name'] ) );
170
break;
171
case 'toggle':
172
// Will never happen, should have been handled above and changed to activate or deactivate.
173
break;
174
}
175
}
176
177
}
7
*/
8
class Jetpack_CLI extends WP_CLI_Command {
9
10
+ // Aesthetics
11
+ public $green_open = "\033[32m";
12
+ public $red_open = "\033[31m";
13
+ public $yellow_open = "\033[33m";
14
+ public $color_close = "\033[0m";
15
+
16
/**
17
* Get Jetpack Details
18
*
19
* ## OPTIONS
20
*
21
+ * empty: Leave it empty for basic stats
22
+ *
23
+ * full: View full stats. It's the data from the heartbeat
24
*
25
* ## EXAMPLES
26
*
27
* wp jetpack status
28
+ * wp jetpack status full
29
*
30
*/
31
public function status( $args, $assoc_args ) {
32
+ if ( ! Jetpack::is_active() ) {
33
+ WP_CLI::error( __( 'Jetpack is not currently connected to WordPress.com', 'jetpack' ) );
34
+ }
35
+
36
+ if ( isset( $args[0] ) && 'full' !== $args[0] ) {
37
+ WP_CLI::error( sprintf( __( '%s is not a valid command.', 'jetpack' ), $args[0] ) );
38
+ }
39
+
40
+ /*
41
+ * Are they asking for all data?
42
+ *
43
+ * Loop through heartbeat data and organize by priority.
44
+ */
45
+ $all_data = ( isset( $args[0] ) && 'full' == $args[0] ) ? 'full' : false;
46
+ if ( $all_data ) {
47
+ WP_CLI::success( __( 'Jetpack is currently connected to WordPress.com', 'jetpack' ) );
48
+ WP_CLI::line( sprintf( __( "The Jetpack Version is %s", 'jetpack' ), JETPACK__VERSION ) );
49
+ WP_CLI::line( sprintf( __( "The WordPress.com blog_id is %d", 'jetpack' ), Jetpack_Options::get_option( 'id' ) ) );
50
+
51
+ // Heartbeat data
52
+ WP_CLI::line( "\n" . __( 'Additional data: ', 'jetpack' ) );
53
+
54
+ // Get the filtered heartbeat data.
55
+ // Filtered so we can color/list by severity
56
+ $stats = Jetpack::jetpack_check_heartbeat_data();
57
+
58
+ // Display red flags first
59
+ foreach ( $stats['bad'] as $stat => $value ) {
60
+ printf( "$this->red_open%-'.16s %s $this->color_close\n", $stat, $value );
61
+ }
62
+
63
+ // Display caution warnings next
64
+ foreach ( $stats['caution'] as $stat => $value ) {
65
+ printf( "$this->yellow_open%-'.16s %s $this->color_close\n", $stat, $value );
66
+ }
67
+
68
+ // The rest of the results are good!
69
+ foreach ( $stats['good'] as $stat => $value ) {
70
+
71
+ // Modules should get special spacing for aestetics
72
+ if ( strpos( $stat, 'odule-' ) ) {
73
+ printf( "%-'.30s %s\n", $stat, $value );
74
+ usleep( 4000 ); // For dramatic effect lolz
75
+ continue;
76
+ }
77
+ printf( "%-'.16s %s\n", $stat, $value );
78
+ usleep( 4000 ); // For dramatic effect lolz
79
+ }
80
+ } else {
81
+ // Just the basics
82
WP_CLI::success( __( 'Jetpack is currently connected to WordPress.com', 'jetpack' ) );
83
WP_CLI::line( sprintf( __( 'The Jetpack Version is %s', 'jetpack' ), JETPACK__VERSION ) );
84
WP_CLI::line( sprintf( __( 'The WordPress.com blog_id is %d', 'jetpack' ), Jetpack_Options::get_option( 'id' ) ) );
85
+ WP_CLI::line( "\n" . _x( "View full status with 'wp jetpack status full'", '"wp jetpack status full" is a command - do not translate', 'jetpack' ) );
86
}
87
}
88
106
* wp jetpack disconnect user username
107
* wp jetpack disconnect user email@domain.com
108
*
109
+ * @synopsis <blog|user> [<user_identifier>]
110
*/
111
public function disconnect( $args, $assoc_args ) {
112
if ( ! Jetpack::is_active() ) {
135
WP_CLI::error( __( 'Please specify a valid user.', 'jetpack' ) );
136
}
137
} else {
138
+ WP_CLI::error( __( 'Please specify a user by either ID, username, or email.', 'jetpack' ) );
139
}
140
}
141
160
}
161
162
/**
163
+ * Reset Jetpack options and settings to default
164
*
165
* ## OPTIONS
166
*
167
+ * modules: Resets modules to default state ( get_default_modules() )
168
*
169
+ * options: Resets all Jetpack options except:
170
+ * - All private options (Blog token, user token, etc...)
171
+ * - id (The Client ID/WP.com Blog ID of this site)
172
+ * - master_user
173
+ * - version
174
+ * - activated
175
*
176
+ * ## EXAMPLES
177
*
178
+ * wp jetpack reset options
179
+ * wp jetpack reset modules
180
+ *
181
+ * @synopsis <modules|options>
182
+ */
183
+ public function reset( $args, $assoc_args ) {
184
+ $action = isset( $args[0] ) ? $args[0] : 'prompt';
185
+ if ( ! in_array( $action, array( 'options', 'modules' ) ) ) {
186
+ WP_CLI::error( sprintf( __( '%s is not a valid command.', 'jetpack' ), $action ) );
187
+ }
188
+
189
+ // Are you sure?
190
+ jetpack_cli_are_you_sure();
191
+
192
+ switch ( $action ) {
193
+ case 'options':
194
+ $options_to_reset = Jetpack::get_jetapck_options_for_reset();
195
+
196
+ // Reset the Jetpack options
197
+ _e( "Resetting Jetpack Options...\n", "jetpack" );
198
+ sleep(1); // Take a breath
199
+ foreach ( $options_to_reset['jp_options'] as $option_to_reset ) {
200
+ Jetpack_Options::delete_option( $option_to_reset );
201
+ usleep( 100000 );
202
+ WP_CLI::success( sprintf( __( '%s option reset', 'jetpack' ), $option_to_reset ) );
203
+ }
204
+
205
+ // Reset the WP options
206
+ _e( "Resetting the jetpack options stored in wp_options...\n", "jetpack" );
207
+ usleep( 500000 ); // Take a breath
208
+ foreach ( $options_to_reset['wp_options'] as $option_to_reset ) {
209
+ delete_option( $option_to_reset );
210
+ usleep( 100000 );
211
+ WP_CLI::success( sprintf( __( '%s option reset', 'jetpack' ), $option_to_reset ) );
212
+ }
213
+
214
+ // Reset to default modules
215
+ _e( "Resetting default modules...\n", "jetpack" );
216
+ usleep( 500000 ); // Take a breath
217
+ $default_modules = Jetpack::get_default_modules();
218
+ Jetpack_Options::update_option( 'active_modules', $default_modules );
219
+ WP_CLI::success( __( 'Modules reset to default.', 'jetpack' ) );
220
+
221
+ // Jumpstart option is special
222
+ Jetpack_Options::update_option( 'jumpstart', 'new_connection' );
223
+ WP_CLI::success( __( 'jumpstart option reset', 'jetpack' ) );
224
+ break;
225
+ case 'modules':
226
+ $default_modules = Jetpack::get_default_modules();
227
+ Jetpack_Options::update_option( 'active_modules', $default_modules );
228
+ WP_CLI::success( __( 'Modules reset to default.', 'jetpack' ) );
229
+ break;
230
+ case 'prompt':
231
+ WP_CLI::error( __( 'Please specify if you would like to reset your options, or modules', 'jetpack' ) );
232
+ break;
233
+ }
234
+ }
235
+
236
+ /**
237
+ * Manage Jetpack Modules
238
+ *
239
+ * ## OPTIONS
240
+ *
241
+ * list : View all available modules, and their status.
242
+ * activate all : Activate all modules
243
+ * deactivate all: Deactivate all modules
244
+ *
245
+ * activate <module_slug> : Activate a module.
246
+ * deactivate <module_slug> : Deactivate a module.
247
+ * toggle <module_slug> : Toggle a module on or off.
248
*
249
* ## EXAMPLES
250
*
253
* wp jetpack module deactivate stats
254
* wp jetpack module toggle stats
255
*
256
+ * wp jetpack module activate all
257
+ * wp jetpack module deactivate all
258
+ *
259
+ * @synopsis <list|activate|deactivate|toggle> [<module_name>]
260
*/
261
public function module( $args, $assoc_args ) {
262
$action = isset( $args[0] ) ? $args[0] : 'list';
263
if ( ! in_array( $action, array( 'list', 'activate', 'deactivate', 'toggle' ) ) ) {
264
WP_CLI::error( sprintf( __( '%s is not a valid command.', 'jetpack' ), $action ) );
265
}
266
if ( in_array( $action, array( 'activate', 'deactivate', 'toggle' ) ) ) {
267
if ( isset( $args[1] ) ) {
268
$module_slug = $args[1];
269
+ if ( 'all' !== $module_slug && ! Jetpack::is_module( $module_slug ) ) {
270
WP_CLI::error( sprintf( __( '%s is not a valid module.', 'jetpack' ), $module_slug ) );
271
}
272
if ( 'toggle' == $action ) {
273
$action = Jetpack::is_module_active( $module_slug ) ? 'deactivate' : 'activate';
274
}
275
+ // Bulk actions
276
+ if ( 'all' == $args[1] ) {
277
+ $action = ( 'deactivate' == $action ) ? 'deactivate_all' : 'activate_all';
278
+ }
279
+ // VaultPress needs to be handled elsewhere.
280
+ if ( in_array( $action, array( 'activate', 'deactivate', 'toggle' ) ) && 'vaultpress' == $args[1] ) {
281
+ WP_CLI::error( sprintf( _x( 'Please visit %s to configure your VaultPress subscription.', '%s is a website', 'jetpack' ), esc_url( 'https://vaultpress.com/jetpack/' ) ) );
282
+ }
283
} else {
284
WP_CLI::line( __( 'Please specify a valid module.', 'jetpack' ) );
285
$action = 'list';
286
}
287
}
288
switch ( $action ) {
289
case 'list':
290
WP_CLI::line( __( 'Available Modules:', 'jetpack' ) );
291
$modules = Jetpack::get_available_modules();
292
sort( $modules );
293
foreach( $modules as $module_slug ) {
294
+ if ( 'vaultpress' == $module_slug ) {
295
+ continue;
296
+ }
297
$active = Jetpack::is_module_active( $module_slug ) ? __( 'Active', 'jetpack' ) : __( 'Inactive', 'jetpack' );
298
WP_CLI::line( "\t" . str_pad( $module_slug, 24 ) . $active );
299
}
301
case 'activate':
302
$module = Jetpack::get_module( $module_slug );
303
Jetpack::log( 'activate', $module_slug );
304
+ Jetpack::activate_module( $module_slug, false, false );
305
WP_CLI::success( sprintf( __( '%s has been activated.', 'jetpack' ), $module['name'] ) );
306
break;
307
+ case 'activate_all':
308
+ $modules = Jetpack::get_available_modules();
309
+ Jetpack_Options::update_option( 'active_modules', $modules );
310
+ WP_CLI::success( __( 'All modules activated!', 'jetpack' ) );
311
+ break;
312
case 'deactivate':
313
$module = Jetpack::get_module( $module_slug );
314
Jetpack::log( 'deactivate', $module_slug );
315
Jetpack::deactivate_module( $module_slug );
316
WP_CLI::success( sprintf( __( '%s has been deactivated.', 'jetpack' ), $module['name'] ) );
317
break;
318
+ case 'deactivate_all':
319
+ Jetpack_Options::update_option( 'active_modules', '' );
320
+ WP_CLI::success( __( 'All modules deactivated!', 'jetpack' ) );
321
+ break;
322
case 'toggle':
323
// Will never happen, should have been handled above and changed to activate or deactivate.
324
break;
325
}
326
}
327
328
+ /**
329
+ * Manage Jetpack Protect Settings
330
+ *
331
+ * ## OPTIONS
332
+ *
333
+ * whitelist: Whitelist an IP address. You can also read or clear the whitelist.
334
+ *
335
+ *
336
+ * ## EXAMPLES
337
+ *
338
+ * wp jetpack protect whitelist <ip address>
339
+ * wp jetpack protect whitelist list
340
+ * wp jetpack protect whitelist clear
341
+ *
342
+ * @synopsis <whitelist> [<ip|ip_low-ip_high|list|clear>]
343
+ */
344
+ public function protect( $args, $assoc_args ) {
345
+ $action = isset( $args[0] ) ? $args[0] : 'prompt';
346
+ if ( ! in_array( $action, array( 'whitelist' ) ) ) {
347
+ WP_CLI::error( sprintf( __( '%s is not a valid command.', 'jetpack' ), $action ) );
348
+ }
349
+ // Check if module is active
350
+ if ( ! Jetpack::is_module_active( __FUNCTION__ ) ) {
351
+ WP_CLI::error( sprintf( _x( '%s is not active. You can activate it with "wp jetpack module activate %s"', '"wp jetpack module activate" is a command - do not translate', 'jetpack' ), __FUNCTION__, __FUNCTION__ ) );
352
+ }
353
+ if ( in_array( $action, array( 'whitelist' ) ) ) {
354
+ if ( isset( $args[1] ) ) {
355
+ $action = 'whitelist';
356
+ } else {
357
+ $action = 'prompt';
358
+ }
359
+ }
360
+ switch ( $action ) {
361
+ case 'whitelist':
362
+ $whitelist = array();
363
+ $new_ip = $args[1];
364
+ $current_whitelist = get_site_option( 'jetpack_protect_whitelist' );
365
+
366
+ // Build array of IPs that are already whitelisted.
367
+ // Re-build manually instead of using jetpack_protect_format_whitelist() so we can easily get
368
+ // low & high range params for jetpack_protect_ip_address_is_in_range();
369
+ foreach( $current_whitelist as $whitelisted ) {
370
+
371
+ // IP ranges
372
+ if ( $whitelisted->range ) {
373
+
374
+ // Is it already whitelisted?
375
+ if ( jetpack_protect_ip_address_is_in_range( $new_ip, $whitelisted->range_low, $whitelisted->range_high ) ) {
376
+ WP_CLI::error( sprintf( __( "%s has already been whitelisted", 'jetpack' ), $new_ip ) );
377
+ break;
378
+ }
379
+ $whitelist[] = $whitelisted->range_low . " - " . $whitelisted->range_high;
380
+
381
+ } else { // Individual IPs
382
+
383
+ // Check if the IP is already whitelisted (single IP only)
384
+ if ( $new_ip == $whitelisted->ip_address ) {
385
+ WP_CLI::error( sprintf( __( "%s has already been whitelisted", 'jetpack' ), $new_ip ) );
386
+ break;
387
+ }
388
+ $whitelist[] = $whitelisted->ip_address;
389
+
390
+ }
391
+ }
392
+
393
+ /*
394
+ * List the whitelist
395
+ * Done here because it's easier to read the $whitelist array after it's been rebuilt
396
+ */
397
+ if ( isset( $args[1] ) && 'list' == $args[1] ) {
398
+ if ( ! empty( $whitelist ) ) {
399
+ WP_CLI::success( __( 'Here are your whitelisted IPs:', 'jetpack' ) );
400
+ foreach ( $whitelist as $ip ) {
401
+ WP_CLI::line( "\t" . str_pad( $ip, 24 ) ) ;
402
+ }
403
+ } else {
404
+ WP_CLI::line( __( 'Whitelist is empty.', "jetpack" ) ) ;
405
+ }
406
+ break;
407
+ }
408
+
409
+ /*
410
+ * Clear the whitelist
411
+ */
412
+ if ( isset( $args[1] ) && 'clear' == $args[1] ) {
413
+ if ( ! empty( $whitelist ) ) {
414
+ $whitelist = array();
415
+ jetpack_protect_save_whitelist( $whitelist );
416
+ WP_CLI::success( __( 'Cleared all whitelisted IPs', 'jetpack' ) );
417
+ } else {
418
+ WP_CLI::line( __( 'Whitelist is empty.', "jetpack" ) ) ;
419
+ }
420
+ break;
421
+ }
422
+
423
+ // Append new IP to whitelist array
424
+ array_push( $whitelist, $new_ip );
425
+
426
+ // Save whitelist if there are no errors
427
+ $result = jetpack_protect_save_whitelist( $whitelist );
428
+ if ( is_wp_error( $result ) ) {
429
+ WP_CLI::error( __( $result, 'jetpack' ) );
430
+ }
431
+
432
+ WP_CLI::success( sprintf( __( '%s has been whitelisted.', 'jetpack' ), $new_ip ) );
433
+ break;
434
+ case 'prompt':
435
+ WP_CLI::error(
436
+ __( 'No command found.', 'jetpack' ) . "\n" .
437
+ __( 'Please enter the IP address you want to whitelist.', 'jetpack' ) . "\n" .
438
+ _x( 'You can save a range of IPs {low_range}-{high_range}. No spaces allowed. (example: 1.1.1.1-2.2.2.2)', 'Instructions on how to whitelist IP ranges - low_range/high_range should be translated.', 'jetpack' ) . "\n" .
439
+ _x( "You can also 'list' or 'clear' the whitelist.", "'list' and 'clear' are commands and should not be translated", 'jetpack' ) . "\n"
440
+ );
441
+ break;
442
+ }
443
+ }
444
+
445
+ /**
446
+ * Manage Jetpack Options
447
+ *
448
+ * ## OPTIONS
449
+ *
450
+ * list : List all jetpack options and their values
451
+ * delete : Delete an option
452
+ * - can only delete options that are white listed.
453
+ * update : update an option
454
+ * - can only update option strings
455
+ * get : get the value of an option
456
+ *
457
+ * ## EXAMPLES
458
+ *
459
+ * wp jetpack options list
460
+ * wp jetpack options get <option_name>
461
+ * wp jetpack options delete <option_name>
462
+ * wp jetpack options update <option_name> [<option_value>]
463
+ *
464
+ * @synopsis <list|get|delete|update> [<option_name>] [<option_value>]
465
+ */
466
+ public function options( $args, $assoc_args ) {
467
+ $action = isset( $args[0] ) ? $args[0] : 'list';
468
+ $safe_to_modify = Jetpack::get_jetapck_options_for_reset();
469
+
470
+ // Jumpstart is special
471
+ array_push( $safe_to_modify, 'jumpstart' );
472
+
473
+ if ( ! in_array( $action, array( 'list', 'get', 'delete', 'update' ) ) ) {
474
+ WP_CLI::error( sprintf( __( '%s is not a valid command.', 'jetpack' ), $action ) );
475
+ }
476
+
477
+ if ( isset( $args[0] ) ) {
478
+ if ( 'get' == $args[0] && isset( $args[1] ) ) {
479
+ $action = 'get';
480
+ } else if ( 'delete' == $args[0] && isset( $args[1] ) ) {
481
+ $action = 'delete';
482
+ } else if ( 'update' == $args[0] && isset( $args[1] ) ) {
483
+ $action = 'update';
484
+ } else {
485
+ $action = 'list';
486
+ }
487
+ }
488
+
489
+ // Bail if the option isn't found
490
+ $option = isset( $args[1] ) ? Jetpack_Options::get_option( $args[1] ) : false;
491
+ if ( isset( $args[1] ) && ! $option && 'update' !== $args[0] ) {
492
+ WP_CLI::error( __( 'Option not found or is empty. Use "list" to list option names', 'jetpack' ) );
493
+ }
494
+
495
+ // Let's print_r the option if it's an array
496
+ // Used in the 'get' and 'list' actions
497
+ $option = is_array( $option ) ? print_r( $option ) : $option;
498
+
499
+ switch ( $action ) {
500
+ case 'get':
501
+ WP_CLI::success( "\t" . $option );
502
+ break;
503
+ case 'delete':
504
+ // Check if it's safe to modify
505
+ if ( ! in_array( $args[1], $safe_to_modify ) ) {
506
+ WP_CLI::error( __( 'It is not recommended to delete this option.', 'jetpack' ) );
507
+ }
508
+
509
+ // Are you sure?
510
+ jetpack_cli_are_you_sure();
511
+
512
+ Jetpack_Options::delete_option( $args[1] );
513
+ WP_CLI::success( sprintf( __( 'Deleted option: %s', 'jetpack' ), $args[1] ) );
514
+ break;
515
+ case 'update':
516
+ // Check if it's safe to modify
517
+ if ( ! in_array( $args[1], $safe_to_modify ) ) {
518
+ WP_CLI::error( __( 'It is not recommended to change this option.', 'jetpack' ) );
519
+ }
520
+
521
+ // Updating arrays would get pretty tricky...
522
+ $value = Jetpack_Options::get_option( $args[1] );
523
+ if ( $value && is_array( $value ) ) {
524
+ WP_CLI::error( __( 'Sorry, no updating arrays at this time', 'jetpack' ) );
525
+ }
526
+
527
+ Jetpack_Options::update_option( $args[1], $args[2] );
528
+ WP_CLI::success( sprintf( _x( 'Updated option: %s to "%s"', 'Updating an option from "this" to "that".', 'jetpack' ), $args[1], $args[2] ) );
529
+ break;
530
+ case 'list':
531
+ $options_compact = Jetpack_Options::get_option_names();
532
+ $options_non_compact = Jetpack_Options::get_option_names( 'non_compact' );
533
+ $options_private = Jetpack_Options::get_option_names( 'private' );
534
+ $options = array_merge( $options_compact, $options_non_compact, $options_private );
535
+
536
+ // Table headers
537
+ WP_CLI::line( "\t" . str_pad( __( 'Option', 'jetpack' ), 30 ) . __( 'Value', 'jetpack' ) );
538
+
539
+ // List out the options and their values
540
+ // Tell them if the value is empty or not
541
+ // Tell them if it's an array
542
+ foreach ( $options as $option ) {
543
+ $value = Jetpack_Options::get_option( $option );
544
+ if ( ! $value ) {
545
+ WP_CLI::line( "\t" . str_pad( $option, 30 ) . 'Empty' );
546
+ continue;
547
+ }
548
+
549
+ if ( ! is_array( $value ) ) {
550
+ WP_CLI::line( "\t" . str_pad( $option, 30 ) . $value );
551
+ } else if ( is_array( $value ) ) {
552
+ WP_CLI::line( "\t" . str_pad( $option, 30 ) . 'Array - Use "get <option>" to read option array.' );
553
+ }
554
+ }
555
+ $option_text = '{' . _x( 'option', 'a variable command that a user can write, provided in the printed instructions', 'jetpack' ) . '}';
556
+ $value_text = '{' . _x( 'value', 'the value that they want to update the option to', 'jetpack' ) . '}';
557
+
558
+ WP_CLI::success(
559
+ _x( "Above are your options. You may 'get', 'delete', and 'update' them.", "'get', 'delete', and 'update' are commands - do not translate.", 'jetpack' ) . "\n" .
560
+ str_pad( 'wp jetpack options get', 26 ) . $option_text . "\n" .
561
+ str_pad( 'wp jetpack options delete', 26 ) . $option_text . "\n" .
562
+ str_pad( 'wp jetpack options update', 26 ) . "$option_text $value_text" . "\n" .
563
+ _x( "Type 'wp jetpack options' for more info.", "'wp jetpack options' is a command - do not translate.", 'jetpack' ) . "\n"
564
+ );
565
+ break;
566
+ }
567
+ }
568
}
569
+
570
+ /*
571
+ * Standard "ask for permission to continue" function.
572
+ * If action cancelled, ask if they need help.
573
+ *
574
+ * Written outside of the class so it's not listed as an executable command w/ 'wp jetpack'
575
+ *
576
+ * @param $error_msg string (optional)
577
+ */
578
+ function jetpack_cli_are_you_sure( $error_msg = false ) {
579
+ $cli = new Jetpack_CLI();
580
+
581
+ // Default cancellation message
582
+ if ( ! $error_msg ) {
583
+ $error_msg = sprintf( __( 'Action cancelled. Have a question? %sjetpack.me/support%s', 'jetpack' ), $cli->green_open, $cli->color_close );
584
+ }
585
+
586
+ WP_CLI::line( _x( 'Are you sure? This cannot be undone. Type "yes" to continue:', '"yes" is a command. Do not translate that.', 'jetpack' ) );
587
+ $handle = fopen( "php://stdin", "r" );
588
+ $line = fgets( $handle );
589
+ if ( 'yes' != trim( $line ) ){
590
+ WP_CLI::error( $error_msg );
591
+ }
592
+ }
class.jetpack-client-server.php CHANGED
@@ -5,14 +5,39 @@
5
* Client Server = API Methods the Plugin must respond to
6
*/
7
class Jetpack_Client_Server {
8
function authorize() {
9
$data = stripslashes_deep( $_GET );
10
$args = array();
11
$redirect = isset( $data['redirect'] ) ? esc_url_raw( (string) $data['redirect'] ) : '';
12
13
- do {
14
$jetpack = Jetpack::init();
15
$role = $jetpack->translate_current_user_to_role();
16
if ( !$role ) {
17
Jetpack::state( 'error', 'no_role' );
18
break;
@@ -24,7 +49,7 @@ class Jetpack_Client_Server {
24
break;
25
}
26
27
- check_admin_referer( "jetpack-authorize_{$role}_{$redirect}" );
28
29
if ( !empty( $data['error'] ) ) {
30
Jetpack::state( 'error', $data['error'] );
@@ -100,12 +125,12 @@ class Jetpack_Client_Server {
100
} while ( false );
101
102
if ( wp_validate_redirect( $redirect ) ) {
103
- wp_safe_redirect( $redirect );
104
} else {
105
- wp_safe_redirect( Jetpack::admin_url() );
106
}
107
108
- exit;
109
}
110
111
public static function deactivate_plugin( $probable_file, $probable_title ) {
@@ -132,7 +157,7 @@ class Jetpack_Client_Server {
132
* @return object|WP_Error
133
*/
134
function get_token( $data ) {
135
- $jetpack = Jetpack::init();
136
$role = $jetpack->translate_current_user_to_role();
137
138
if ( !$role ) {
@@ -214,4 +239,21 @@ class Jetpack_Client_Server {
214
215
return (string) $json->access_token;
216
}
217
}
5
* Client Server = API Methods the Plugin must respond to
6
*/
7
class Jetpack_Client_Server {
8
+
9
function authorize() {
10
$data = stripslashes_deep( $_GET );
11
$args = array();
12
$redirect = isset( $data['redirect'] ) ? esc_url_raw( (string) $data['redirect'] ) : '';
13
14
+ $jetpack_unique_connection = Jetpack_Options::get_option( 'unique_connection' );
15
+ // Checking if site has been active/connected previously before recording unique connection
16
+ if ( ! $jetpack_unique_connection ) {
17
+ // jetpack_unique_connection option has never been set
18
+ $jetpack_unique_connection = array(
19
+ 'connected' => 0,
20
+ 'disconnected' => 0,
21
+ 'version' => '3.6.1'
22
+ );
23
+
24
+ update_option( 'jetpack_unique_connection', $jetpack_unique_connection );
25
+
26
+ //track unique connection
27
$jetpack = Jetpack::init();
28
+
29
+ $jetpack->stat( 'connections', 'unique-connection' );
30
+ $jetpack->do_stats( 'server_side' );
31
+ }
32
+
33
+ // increment number of times connected
34
+ $jetpack_unique_connection['connected'] += 1;
35
+ Jetpack_Options::update_option( 'unique_connection', $jetpack_unique_connection );
36
+
37
+ do {
38
+ $jetpack = $this->get_jetpack();
39
$role = $jetpack->translate_current_user_to_role();
40
+
41
if ( !$role ) {
42
Jetpack::state( 'error', 'no_role' );
43
break;
49
break;
50
}
51
52
+ $this->check_admin_referer( "jetpack-authorize_{$role}_{$redirect}" );
53
54
if ( !empty( $data['error'] ) ) {
55
Jetpack::state( 'error', $data['error'] );
125
} while ( false );
126
127
if ( wp_validate_redirect( $redirect ) ) {
128
+ $this->wp_safe_redirect( $redirect );
129
} else {
130
+ $this->wp_safe_redirect( Jetpack::admin_url() );
131
}
132
133
+ $this->do_exit();
134
}
135
136
public static function deactivate_plugin( $probable_file, $probable_title ) {
157
* @return object|WP_Error
158
*/
159
function get_token( $data ) {
160
+ $jetpack = $this->get_jetpack();
161
$role = $jetpack->translate_current_user_to_role();
162
163
if ( !$role ) {
239
240
return (string) $json->access_token;
241
}
242
+
243
+ public function get_jetpack() {
244
+ return Jetpack::init();
245
+ }
246
+
247
+ public function check_admin_referer( $action ) {
248
+ return check_admin_referer( $action );
249
+ }
250
+
251
+ public function wp_safe_redirect( $redirect ) {
252
+ return wp_safe_redirect( $redirect );
253
+ }
254
+
255
+ public function do_exit() {
256
+ exit;
257
+ }
258
+
259
}
class.jetpack-client.php CHANGED
@@ -1,6 +1,9 @@
1
<?php
2
3
class Jetpack_Client {
4
/**
5
* Makes an authorized remote request using Jetpack_Signature
6
*
@@ -131,6 +134,21 @@ class Jetpack_Client {
131
* @return array|WP_Error WP HTTP response on success
132
*/
133
public static function _wp_remote_request( $url, $args, $set_fallback = false ) {
134
$fallback = Jetpack_Options::get_option( 'fallback_no_verify_ssl_certs' );
135
if ( false === $fallback ) {
136
Jetpack_Options::update_option( 'fallback_no_verify_ssl_certs', 0 );
@@ -216,4 +234,49 @@ class Jetpack_Client {
216
}
217
}
218
}
219
}
1
<?php
2
3
class Jetpack_Client {
4
+ const WPCOM_JSON_API_HOST = 'public-api.wordpress.com';
5
+ const WPCOM_JSON_API_VERSION = '1.1';
6
+
7
/**
8
* Makes an authorized remote request using Jetpack_Signature
9
*
134
* @return array|WP_Error WP HTTP response on success
135
*/
136
public static function _wp_remote_request( $url, $args, $set_fallback = false ) {
137
+ /**
138
+ * SSL verification (`sslverify`) for the JetpackClient remote request
139
+ * defaults to off, use this filter to force it on.
140
+ *
141
+ * Return `true` to ENABLE SSL verification, return `false`
142
+ * to DISABLE SSL verification.
143
+ *
144
+ * @since 3.6
145
+ *
146
+ * @param bool Whether to force `sslverify` or not.
147
+ */
148
+ if ( apply_filters( 'jetpack_client_verify_ssl_certs', false ) ) {
149
+ return wp_remote_request( $url, $args );
150
+ }
151
+
152
$fallback = Jetpack_Options::get_option( 'fallback_no_verify_ssl_certs' );
153
if ( false === $fallback ) {
154
Jetpack_Options::update_option( 'fallback_no_verify_ssl_certs', 0 );
234
}
235
}
236
}
237
+
238
+ /**
239
+ * Query the WordPress.com REST API using the blog token
240
+ *
241
+ * @param string $path
242
+ * @param string $version
243
+ * @param array $args
244
+ * @param string $body
245
+ * @return array|WP_Error $response Data.
246
+ */
247
+ static function wpcom_json_api_request_as_blog( $path, $version = self::WPCOM_JSON_API_VERSION, $args = array(), $body = null ) {
248
+ $filtered_args = array_intersect_key( $args, array(
249
+ 'method' => 'string',
250
+ 'timeout' => 'int',
251
+ 'redirection' => 'int',
252
+ ) );
253
+
254
+ /**
255
+ * Determines whether Jetpack can send outbound https requests to the WPCOM api.
256
+ *
257
+ * @since 3.6.0
258
+ *
259
+ * @param bool $proto Defaults to true.
260
+ */
261
+ $proto = apply_filters( 'jetpack_can_make_outbound_https', true ) ? 'https' : 'http';
262
+
263
+ // unprecedingslashit
264
+ $_path = preg_replace( '/^\//', '', $path );
265
+
266
+ // Use GET by default whereas `remote_request` uses POST
267
+ if ( isset( $filtered_args['method'] ) && strtoupper( $filtered_args['method'] === 'POST' ) ) {
268
+ $request_method = 'POST';
269
+ } else {
270
+ $request_method = 'GET';
271
+ }
272
+
273
+ $validated_args = array_merge( $filtered_args, array(
274
+ 'url' => sprintf( '%s://%s/rest/v%s/%s', $proto, self::WPCOM_JSON_API_HOST, $version, $_path ),
275
+ 'blog_id' => (int) Jetpack_Options::get_option( 'id' ),
276
+ 'method' => $request_method,
277
+ ) );
278
+
279
+ return Jetpack_Client::remote_request( $validated_args, $body );
280
+ }
281
+
282
}
class.jetpack-data.php CHANGED
@@ -39,4 +39,87 @@ class Jetpack_Data {
39
'external_user_id' => (int) $user_id,
40
);
41
}
42
}
39
'external_user_id' => (int) $user_id,
40
);
41
}
42
+
43
+ /**
44
+ * This function mirrors Jetpack_Data::is_usable_domain() in the WPCOM codebase.
45
+ *
46
+ * @param $domain
47
+ * @param array $extra
48
+ *
49
+ * @return bool|WP_Error
50
+ */
51
+ public static function is_usable_domain( $domain, $extra = array() ) {
52
+
53
+ // If it's empty, just fail out.
54
+ if ( ! $domain ) {
55
+ return new WP_Error( 'fail_domain_empty', sprintf( __( 'Domain `%1$s` just failed is_usable_domain check as it is empty.', 'jetpack' ), $domain ) );
56
+ }
57
+
58
+ // None of the explicit localhosts.
59
+ $forbidden_domains = array(
60
+ 'wordpress.com',
61
+ 'localhost',
62
+ 'localhost.localdomain',
63
+ '127.0.0.1',
64
+ 'local.wordpress.dev', // VVV
65
+ 'local.wordpress-trunk.dev', // VVV
66
+ 'src.wordpress-develop.dev', // VVV
67
+ 'build.wordpress-develop.dev', // VVV
68
+ );
69
+ if ( in_array( $domain, $forbidden_domains ) ) {
70
+ return new WP_Error( 'fail_domain_forbidden', sprintf( __( 'Domain `%1$s` just failed is_usable_domain check as it is in the forbidden array.', 'jetpack' ), $domain ) );
71
+ }
72
+
73
+ // No .dev or .local domains
74
+ if ( preg_match( '#\.(dev|local)$#i', $domain ) ) {
75
+ return new WP_Error( 'fail_domain_tld', sprintf( __( 'Domain `%1$s` just failed is_usable_domain check as it uses an invalid top level domain.', 'jetpack' ), $domain ) );
76
+ }
77
+
78
+ // No WPCOM subdomains
79
+ if ( preg_match( '#\.wordpress\.com$#i', $domain ) ) {
80
+ return new WP_Error( 'fail_subdomain_wpcom', sprintf( __( 'Domain `%1$s` just failed is_usable_domain check as it is a subdomain of WordPress.com.', 'jetpack' ), $domain ) );
81
+ }
82
+
83
+ // If PHP was compiled without support for the Filter module (very edge case)
84
+ if ( ! function_exists( 'filter_var' ) ) {
85
+ // Just pass back true for now, and let wpcom sort it out.
86
+ return true;
87
+ }
88
+
89
+ // Check the IP to make sure it's pingable.
90
+ $ip = gethostbyname( $domain );
91
+
92
+ // Doing this again as I was getting some false positives when gethostbyname() flaked out and returned the domain.
93
+ $ip = filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) ? $ip : gethostbyname( $ip );
94
+
95
+ if ( ! filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE | FILTER_FLAG_IPV4 ) && ! self::php_bug_66229_check( $ip ) ) {
96
+ return new WP_Error( 'fail_domain_bad_ip_range', sprintf( __( 'Domain `%1$s` just failed is_usable_domain check as its IP `%2$s` is either invalid, or in a reserved or private range.', 'jetpack' ), $domain, $ip ) );
97
+ }
98
+
99
+ return true;
100
+ }
101
+
102
+ /**
103
+ * Returns true if the IP address passed in should not be in a reserved range, even if PHP says that it is.
104
+ * See: https://bugs.php.net/bug.php?id=66229 and https://github.com/php/php-src/commit/d1314893fd1325ca6aa0831101896e31135a2658
105
+ *
106
+ * This function mirrors Jetpack_Data::php_bug_66229_check() in the WPCOM codebase.
107
+ */
108
+ public static function php_bug_66229_check( $ip ) {
109
+ if ( ! filter_var( $ip, FILTER_VALIDATE_IP ) ) {
110
+ return false;
111
+ }
112
+
113
+ $ip_arr = array_map( 'intval', explode( '.', $ip ) );
114
+
115
+ if ( 128 == $ip_arr[0] && 0 == $ip_arr[1] ) {
116
+ return true;
117
+ }
118
+
119
+ if ( 191 == $ip_arr[0] && 255 == $ip_arr[1] ) {
120
+ return true;
121
+ }
122
+
123
+ return false;
124
+ }
125
}
class.jetpack-heartbeat.php CHANGED
@@ -111,6 +111,8 @@ class Jetpack_Heartbeat {
111
$return["{$prefix}identitycrisis"] = Jetpack::check_identity_crisis( 1 ) ? 'yes' : 'no';
112
$return["{$prefix}plugins"] = implode( ',', Jetpack::get_active_plugins() );
113
114
$return["{$prefix}manage-enabled"] = Jetpack::is_module_active( 'manage' );
115
116
// is-multi-network can have three values, `single-site`, `single-network`, and `multi-network`
111
$return["{$prefix}identitycrisis"] = Jetpack::check_identity_crisis( 1 ) ? 'yes' : 'no';
112
$return["{$prefix}plugins"] = implode( ',', Jetpack::get_active_plugins() );
113
114
+ $return["{$prefix}single-user-site"]= Jetpack::is_single_user_site();
115
+
116
$return["{$prefix}manage-enabled"] = Jetpack::is_module_active( 'manage' );
117
118
// is-multi-network can have three values, `single-site`, `single-network`, and `multi-network`
class.jetpack-ixr-client.php CHANGED
@@ -10,7 +10,7 @@
10
class Jetpack_IXR_Client extends IXR_Client {
11
var $jetpack_args = null;
12
13
- function Jetpack_IXR_Client( $args = array(), $path = false, $port = 80, $timeout = 15 ) {
14
$defaults = array(
15
'url' => Jetpack::xmlrpc_api_url(),
16
'user_id' => 0,
@@ -99,8 +99,8 @@ class Jetpack_IXR_Client extends IXR_Client {
99
class Jetpack_IXR_ClientMulticall extends Jetpack_IXR_Client {
100
var $calls = array();
101
102
- function Jetpack_IXR_ClientMulticall( $args = array(), $path = false, $port = 80, $timeout = 15 ) {
103
- parent::Jetpack_IXR_Client( $args, $path, $port, $timeout );
104
}
105
106
function addCall() {
10
class Jetpack_IXR_Client extends IXR_Client {
11
var $jetpack_args = null;
12
13
+ function __construct( $args = array(), $path = false, $port = 80, $timeout = 15 ) {
14
$defaults = array(
15
'url' => Jetpack::xmlrpc_api_url(),
16
'user_id' => 0,
99
class Jetpack_IXR_ClientMulticall extends Jetpack_IXR_Client {
100
var $calls = array();
101
102
+ function __construct( $args = array(), $path = false, $port = 80, $timeout = 15 ) {
103
+ parent::__construct( $args, $path, $port, $timeout );
104
}
105
106
function addCall() {
class.jetpack-modules-list-table.php CHANGED
@@ -19,7 +19,8 @@ class Jetpack_Modules_List_Table extends WP_List_Table {
19
$this->items = $this->all_items = Jetpack_Admin::init()->get_modules();
20
$this->items = $this->filter_displayed_table_items( $this->items );
21
$this->items = apply_filters( 'jetpack_modules_list_table_items', $this->items );
22
- $this->_column_headers = array( $this->get_columns(), array(), array() );
23
24
wp_register_script(
25
'models.jetpack-modules',
@@ -50,13 +51,23 @@ class Jetpack_Modules_List_Table extends WP_List_Table {
50
'i18n' => array(
51
'search_placeholder' => __( 'Search Modules…', 'jetpack' ),
52
),
53
'nonces' => array(
54
'bulk' => wp_create_nonce( 'bulk-jetpack_page_jetpack_modules' ),
55
),
56
) );
57
58
wp_enqueue_script( 'jetpack-modules-list-table' );
59
- add_action( 'admin_footer', array( $this, 'js_templates' ), 9 );
60
}
61
62
function js_templates() {
@@ -66,7 +77,20 @@ class Jetpack_Modules_List_Table extends WP_List_Table {
66
if ( data.items.length ) {
67
_.each( data.items, function( item, key, list ) {
68
if ( item === undefined ) return;
69
- #>
70
<tr class="jetpack-module <# if ( ++i % 2 ) { #> alternate<# } #><# if ( item.activated ) { #> active<# } #><# if ( ! item.available ) { #> unavailable<# } #>" id="{{{ item.module }}}">
71
<th scope="row" class="check-column">
72
<input type="checkbox" name="modules[]" value="{{{ item.module }}}" />
@@ -77,7 +101,7 @@ class Jetpack_Modules_List_Table extends WP_List_Table {
77
<# if ( item.configurable ) { #>
78
<span class='configure'>{{{ item.configurable }}}</span>
79
<# } #>
80
- <# if ( item.activated && 'vaultpress' !== item.module ) { #>
81
<span class='delete'><a href="<?php echo admin_url( 'admin.php' ); ?>?page=jetpack&#038;action=deactivate&#038;module={{{ item.module }}}&#038;_wpnonce={{{ item.deactivate_nonce }}}"><?php _e( 'Deactivate', 'jetpack' ); ?></a></span>
82
<# } else if ( item.available ) { #>
83
<span class='activate'><a href="<?php echo admin_url( 'admin.php' ); ?>?page=jetpack&#038;action=activate&#038;module={{{ item.module }}}&#038;_wpnonce={{{ item.activate_nonce }}}"><?php _e( 'Activate', 'jetpack' ); ?></a></span>
@@ -115,7 +139,7 @@ class Jetpack_Modules_List_Table extends WP_List_Table {
115
'all' => sprintf( $format, $title, $count, $url, $current ),
116
);
117
foreach ( $module_tags_unique as $title => $count ) {
118
- if( 'Jumpstart' == $title ) {
119
continue;
120
}
121
$key = sanitize_title( $title );
@@ -148,7 +172,11 @@ class Jetpack_Modules_List_Table extends WP_List_Table {
148
if ( ! is_array( $module ) || empty( $module ) )
149
return false;
150
151
- return ! ( $module['requires_connection'] && ! Jetpack::is_active() );
152
}
153
154
static function is_module_displayed( $module ) {
@@ -297,6 +325,15 @@ class Jetpack_Modules_List_Table extends WP_List_Table {
297
}
298
}
299
300
/**
301
* Core switched their `display_tablenav()` method to protected, so we can't access it directly.
302
* Instead, let's include an access function to make it doable without errors!
19
$this->items = $this->all_items = Jetpack_Admin::init()->get_modules();
20
$this->items = $this->filter_displayed_table_items( $this->items );
21
$this->items = apply_filters( 'jetpack_modules_list_table_items', $this->items );
22
+ $this->_column_headers = array( $this->get_columns(), array(), array(), 'name' );
23
+ $modal_info = isset( $_GET['info'] ) ? $_GET['info'] : false;
24
25
wp_register_script(
26
'models.jetpack-modules',
51
'i18n' => array(
52
'search_placeholder' => __( 'Search Modules…', 'jetpack' ),
53
),
54
+ 'modalinfo' => $this->module_info_check( $modal_info, $this->all_items ),
55
'nonces' => array(
56
'bulk' => wp_create_nonce( 'bulk-jetpack_page_jetpack_modules' ),
57
),
58
+ 'coreIconAvailable' => Jetpack::jetpack_site_icon_available_in_core(),
59
) );
60
61
wp_enqueue_script( 'jetpack-modules-list-table' );
62
+
63
+ /**
64
+ * Filters the js_templates callback value
65
+ *
66
+ * @since 3.6.0
67
+ *
68
+ * @param array array( $this, 'js_templates' ) js_templates callback.
69
+ */
70
+ add_action( 'admin_footer', apply_filters( 'jetpack_modules_list_table_js_template_callback', array( $this, 'js_templates' ) ), 9 );
71
}
72
73
function js_templates() {
77
if ( data.items.length ) {
78
_.each( data.items, function( item, key, list ) {
79
if ( item === undefined ) return;
80
+ if ( jetpackModulesData.coreIconAvailable && 'site-icon' == item.module ) { #>
81
+ <tr class="jetpack-module deprecated <# if ( ++i % 2 ) { #> alternate<# } #>" id="site-icon-deprecated">
82
+ <th scope="row" class="check-column">
83
+ <input type="checkbox" name="modules[]" value="{{{ item.module }}}" disabled />
84
+ </th>
85
+ <td class='name column-name'>
86
+ <span class='info'>{{{ item.name }}}</span>
87
+ <div class="row-actions">
88
+ <span class="dep-msg"><?php _ex( 'WordPress now has Site Icon built in!', '"Site Icon" is the feature name.', 'jetpack' ); ?></span>
89
+ <span class='configure'><a href="<?php esc_html_e( admin_url( 'options-general.php' ), 'jetpack' ); ?>"><?php _e( 'configure' , 'jetpack' ); ?></a></span>
90
+ </div>
91
+ </td>
92
+ </tr>
93
+ <# return; } #>
94
<tr class="jetpack-module <# if ( ++i % 2 ) { #> alternate<# } #><# if ( item.activated ) { #> active<# } #><# if ( ! item.available ) { #> unavailable<# } #>" id="{{{ item.module }}}">
95
<th scope="row" class="check-column">
96
<input type="checkbox" name="modules[]" value="{{{ item.module }}}" />
101
<# if ( item.configurable ) { #>
102
<span class='configure'>{{{ item.configurable }}}</span>
103
<# } #>
104
+ <# if ( item.activated && 'vaultpress' !== item.module && item.available ) { #>
105
<span class='delete'><a href="<?php echo admin_url( 'admin.php' ); ?>?page=jetpack&#038;action=deactivate&#038;module={{{ item.module }}}&#038;_wpnonce={{{ item.deactivate_nonce }}}"><?php _e( 'Deactivate', 'jetpack' ); ?></a></span>
106
<# } else if ( item.available ) { #>
107
<span class='activate'><a href="<?php echo admin_url( 'admin.php' ); ?>?page=jetpack&#038;action=activate&#038;module={{{ item.module }}}&#038;_wpnonce={{{ item.activate_nonce }}}"><?php _e( 'Activate', 'jetpack' ); ?></a></span>
139
'all' => sprintf( $format, $title, $count, $url, $current ),
140
);
141
foreach ( $module_tags_unique as $title => $count ) {
142
+ if ( 'Jumpstart' == $title ) {
143
continue;
144
}
145
$key = sanitize_title( $title );
172
if ( ! is_array( $module ) || empty( $module ) )
173
return false;
174
175
+ if ( Jetpack::is_development_mode() ) {
176
+ return ! ( $module['requires_connection'] );
177
+ } else {
178
+ return Jetpack::is_active();
179
+ }
180
}
181
182
static function is_module_displayed( $module ) {
325
}
326
}
327
328
+ //Check if the info parameter provided in the URL corresponds to an actual module
329
+ function module_info_check( $info = false, $modules ) {
330
+ if ( false == $info ) {
331
+ return false;
332
+ } else if ( array_key_exists( $info, $modules ) ) {
333
+ return $info;
334
+ }
335
+ }
336
+
337
/**
338
* Core switched their `display_tablenav()` method to protected, so we can't access it directly.
339
* Instead, let's include an access function to make it doable without errors!
class.jetpack-network-sites-list-table.php CHANGED
@@ -6,7 +6,7 @@ if( ! class_exists( 'WP_List_Table' ) ) {
6
7
class Jetpack_Network_Sites_List_Table extends WP_List_Table {
8
9
-
10
public function get_columns() {
11
// site name, status, username connected under
12
$columns = array(
@@ -27,9 +27,9 @@ class Jetpack_Network_Sites_List_Table extends WP_List_Table {
27
28
// Get sites
29
$sites = $jpms->wp_get_sites( array( 'exclude_blogs' => array( 1 ) ) );
30
-
31
// Setup pagination
32
- $per_page = 40;
33
$current_page = $this->get_pagenum();
34
$total_items = count( $sites );
35
$sites = array_slice( $sites, ( ( $current_page-1 ) * $per_page ), $per_page );
@@ -55,15 +55,15 @@ class Jetpack_Network_Sites_List_Table extends WP_List_Table {
55
'edit' => '<a href="' . network_admin_url( 'site-info.php?id=' . $item->blog_id ) . '">' . __( 'Edit', 'jetpack' ) . '</a>',
56
'dashboard' => '<a href="' . get_admin_url( $item->blog_id, '', 'admin' ) . '">Dashboard</a>',
57
'view' => '<a href="' . get_site_url( $item->blog_id, '', 'admin' ) . '">View</a>',
58
- 'jetpack-' . $item->blog_id => '<a href="' . $jp_url . '">Jetpack</a>',
59
);
60
61
return sprintf('%1$s %2$s', '<strong>' . get_blog_option( $item->blog_id, 'blogname' ) . '</strong>', $this->row_actions($actions) );
62
}
63
64
public function column_blog_path( $item ) {
65
- return
66
- '<a href="' .
67
get_site_url( $item->blog_id, '', 'admin' ) .
68
'">' .
69
str_replace( array( 'http://', 'https://' ), '', get_site_url( $item->blog_id, '', 'admin' ) ) .
@@ -76,7 +76,7 @@ class Jetpack_Network_Sites_List_Table extends WP_List_Table {
76
77
switch_to_blog( $item->blog_id );
78
if( $jp->is_active() ) {
79
- // Build url for disconnecting
80
$url = $jpms->get_url( array(
81
'name' => 'subsitedisconnect',
82
'site_id' => $item->blog_id,
@@ -86,7 +86,7 @@ class Jetpack_Network_Sites_List_Table extends WP_List_Table {
86
return '<a href="' . $url . '">Disconnect</a>';
87
}
88
restore_current_blog();
89
-
90
// Build URL for connecting
91
$url = $jpms->get_url( array(
92
'name' => 'subsiteregister',
@@ -107,7 +107,7 @@ class Jetpack_Network_Sites_List_Table extends WP_List_Table {
107
function column_cb($item) {
108
return sprintf(
109
'<input type="checkbox" name="bulk[]" value="%s" />', $item->blog_id
110
- );
111
}
112
113
public function process_bulk_action() {
@@ -123,7 +123,7 @@ class Jetpack_Network_Sites_List_Table extends WP_List_Table {
123
case 'connect':
124
foreach( $_POST['bulk'] as $k => $site ) {
125
$jpms->do_subsiteregister( $site );
126
- }
127
break;
128
case 'disconnect':
129
foreach( $_POST['bulk'] as $k => $site ) {
6
7
class Jetpack_Network_Sites_List_Table extends WP_List_Table {
8
9
+
10
public function get_columns() {
11
// site name, status, username connected under
12
$columns = array(
27
28
// Get sites
29
$sites = $jpms->wp_get_sites( array( 'exclude_blogs' => array( 1 ) ) );
30
+
31
// Setup pagination
32
+ $per_page = 25;
33
$current_page = $this->get_pagenum();
34
$total_items = count( $sites );
35
$sites = array_slice( $sites, ( ( $current_page-1 ) * $per_page ), $per_page );
55
'edit' => '<a href="' . network_admin_url( 'site-info.php?id=' . $item->blog_id ) . '">' . __( 'Edit', 'jetpack' ) . '</a>',
56
'dashboard' => '<a href="' . get_admin_url( $item->blog_id, '', 'admin' ) . '">Dashboard</a>',
57
'view' => '<a href="' . get_site_url( $item->blog_id, '', 'admin' ) . '">View</a>',
58
+ 'jetpack-' . $item->blog_id => '<a href="' . $jp_url . '">Jetpack</a>',
59
);
60
61
return sprintf('%1$s %2$s', '<strong>' . get_blog_option( $item->blog_id, 'blogname' ) . '</strong>', $this->row_actions($actions) );
62
}
63
64
public function column_blog_path( $item ) {
65
+ return
66
+ '<a href="' .
67
get_site_url( $item->blog_id, '', 'admin' ) .
68
'">' .
69
str_replace( array( 'http://', 'https://' ), '', get_site_url( $item->blog_id, '', 'admin' ) ) .
76
77
switch_to_blog( $item->blog_id );
78
if( $jp->is_active() ) {
79
+ // Build url for disconnecting
80
$url = $jpms->get_url( array(
81
'name' => 'subsitedisconnect',
82
'site_id' => $item->blog_id,
86
return '<a href="' . $url . '">Disconnect</a>';
87
}
88
restore_current_blog();
89
+
90
// Build URL for connecting
91
$url = $jpms->get_url( array(
92
'name' => 'subsiteregister',
107
function column_cb($item) {
108
return sprintf(
109
'<input type="checkbox" name="bulk[]" value="%s" />', $item->blog_id
110
+ );
111
}
112
113
public function process_bulk_action() {
123
case 'connect':
124
foreach( $_POST['bulk'] as $k => $site ) {
125
$jpms->do_subsiteregister( $site );
126
+ }
127
break;
128
case 'disconnect':
129
foreach( $_POST['bulk'] as $k => $site ) {
class.jetpack-network.php CHANGED
@@ -45,7 +45,8 @@ class Jetpack_Network {
45
* @since 2.9
46
*/
47
private function __construct() {
48
- require_once( ABSPATH . '/wp-admin/includes/plugin.php' ); // For the is_plugin... check