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 (165) 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 -25
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