class.jetpack-admin-page.php 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. <?php
  2. // Shared logic between Jetpack admin pages
  3. abstract class Jetpack_Admin_Page {
  4. // Add page specific actions given the page hook
  5. abstract function add_page_actions( $hook );
  6. // Create a menu item for the page and returns the hook
  7. abstract function get_page_hook();
  8. // Enqueue and localize page specific scripts
  9. abstract function page_admin_scripts();
  10. // Render page specific HTML
  11. abstract function page_render();
  12. /**
  13. * Should we block the page rendering because the site is in IDC?
  14. * @var bool
  15. */
  16. static $block_page_rendering_for_idc;
  17. /**
  18. * Function called after admin_styles to load any additional needed styles.
  19. *
  20. * @since 4.3.0
  21. */
  22. function additional_styles() {}
  23. function __construct() {
  24. $this->jetpack = Jetpack::init();
  25. self::$block_page_rendering_for_idc = (
  26. Jetpack::validate_sync_error_idc_option() && ! Jetpack_Options::get_option( 'safe_mode_confirmed' )
  27. );
  28. }
  29. function add_actions() {
  30. // If user is not an admin and site is in Dev Mode, don't do anything
  31. if ( ! current_user_can( 'manage_options' ) && Jetpack::is_development_mode() ) {
  32. return;
  33. }
  34. // Don't add in the modules page unless modules are available!
  35. if ( $this->dont_show_if_not_active && ! Jetpack::is_active() && ! Jetpack::is_development_mode() ) {
  36. return;
  37. }
  38. // Initialize menu item for the page in the admin
  39. $hook = $this->get_page_hook();
  40. // Attach hooks common to all Jetpack admin pages based on the created
  41. // hook
  42. add_action( "load-$hook", array( $this, 'admin_help' ) );
  43. add_action( "load-$hook", array( $this, 'admin_page_load' ) );
  44. add_action( "admin_head-$hook", array( $this, 'admin_head' ) );
  45. add_action( "admin_print_styles-$hook", array( $this, 'admin_styles' ) );
  46. add_action( "admin_print_scripts-$hook", array( $this, 'admin_scripts' ) );
  47. if ( ! self::$block_page_rendering_for_idc ) {
  48. add_action( "admin_print_styles-$hook", array( $this, 'additional_styles' ) );
  49. }
  50. // Check if the site plan changed and deactivate modules accordingly.
  51. add_action( 'current_screen', array( $this, 'check_plan_deactivate_modules' ) );
  52. // Attach page specific actions in addition to the above
  53. $this->add_page_actions( $hook );
  54. }
  55. function admin_head() {
  56. if ( isset( $_GET['configure'] ) && Jetpack::is_module( $_GET['configure'] ) && current_user_can( 'manage_options' ) ) {
  57. /**
  58. * Fires in the <head> of a particular Jetpack configuation page.
  59. *
  60. * The dynamic portion of the hook name, `$_GET['configure']`,
  61. * refers to the slug of module, such as 'stats', 'sso', etc.
  62. * A complete hook for the latter would be
  63. * 'jetpack_module_configuation_head_sso'.
  64. *
  65. * @since 3.0.0
  66. */
  67. do_action( 'jetpack_module_configuration_head_' . $_GET['configure'] );
  68. }
  69. }
  70. // Render the page with a common top and bottom part, and page specific content
  71. function render() {
  72. // We're in an IDC: we need a decision made before we show the UI again.
  73. if ( self::$block_page_rendering_for_idc ) {
  74. return;
  75. }
  76. $this->page_render();
  77. }
  78. function admin_help() {
  79. $this->jetpack->admin_help();
  80. }
  81. function admin_page_load() {
  82. // This is big. For the moment, just call the existing one.
  83. $this->jetpack->admin_page_load();
  84. }
  85. function admin_page_top() {
  86. include_once( JETPACK__PLUGIN_DIR . '_inc/header.php' );
  87. }
  88. function admin_page_bottom() {
  89. include_once( JETPACK__PLUGIN_DIR . '_inc/footer.php' );
  90. }
  91. // Add page specific scripts and jetpack stats for all menu pages
  92. function admin_scripts() {
  93. $this->page_admin_scripts(); // Delegate to inheriting class
  94. add_action( 'admin_footer', array( $this->jetpack, 'do_stats' ) );
  95. }
  96. // Enqueue the Jetpack admin stylesheet
  97. function admin_styles() {
  98. $min = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
  99. wp_enqueue_style( 'jetpack-admin', plugins_url( "css/jetpack-admin{$min}.css", JETPACK__PLUGIN_FILE ), array( 'genericons' ), JETPACK__VERSION . '-20121016' );
  100. wp_style_add_data( 'jetpack-admin', 'rtl', 'replace' );
  101. wp_style_add_data( 'jetpack-admin', 'suffix', $min );
  102. }
  103. /**
  104. * Checks if WordPress version is too old to have REST API.
  105. *
  106. * @since 4.3
  107. *
  108. * @return bool
  109. */
  110. function is_wp_version_too_old() {
  111. global $wp_version;
  112. return ( ! function_exists( 'rest_api_init' ) || version_compare( $wp_version, '4.4-z', '<=' ) );
  113. }
  114. /**
  115. * Checks if REST API is enabled.
  116. *
  117. * @since 4.4.2
  118. *
  119. * @return bool
  120. */
  121. function is_rest_api_enabled() {
  122. return
  123. /** This filter is documented in wp-includes/rest-api/class-wp-rest-server.php */
  124. apply_filters( 'rest_enabled', true ) &&
  125. /** This filter is documented in wp-includes/rest-api/class-wp-rest-server.php */
  126. apply_filters( 'rest_jsonp_enabled', true ) &&
  127. /** This filter is documented in wp-includes/rest-api/class-wp-rest-server.php */
  128. apply_filters( 'rest_authentication_errors', true );
  129. }
  130. /**
  131. * Checks the site plan and deactivates modules that were active but are no longer included in the plan.
  132. *
  133. * @since 4.4.0
  134. *
  135. * @param $page
  136. *
  137. * @return array
  138. */
  139. function check_plan_deactivate_modules( $page ) {
  140. if (
  141. Jetpack::is_development_mode()
  142. || ! in_array(
  143. $page->base,
  144. array(
  145. 'toplevel_page_jetpack',
  146. 'admin_page_jetpack_modules',
  147. 'jetpack_page_vaultpress',
  148. 'jetpack_page_stats',
  149. 'jetpack_page_akismet-key-config'
  150. )
  151. )
  152. ) {
  153. return false;
  154. }
  155. $current = Jetpack::get_active_plan();
  156. $to_deactivate = array();
  157. if ( isset( $current['product_slug'] ) ) {
  158. $active = Jetpack::get_active_modules();
  159. switch ( $current['product_slug'] ) {
  160. case 'jetpack_free':
  161. $to_deactivate = array( 'seo-tools', 'videopress', 'google-analytics', 'wordads', 'search' );
  162. break;
  163. case 'jetpack_personal':
  164. case 'jetpack_personal_monthly':
  165. $to_deactivate = array( 'seo-tools', 'videopress', 'google-analytics', 'wordads', 'search' );
  166. break;
  167. case 'jetpack_premium':
  168. case 'jetpack_premium_monthly':
  169. $to_deactivate = array( 'seo-tools', 'google-analytics', 'search' );
  170. break;
  171. }
  172. $to_deactivate = array_intersect( $active, $to_deactivate );
  173. $to_leave_enabled = array();
  174. foreach ( $to_deactivate as $feature ) {
  175. if ( Jetpack::active_plan_supports( $feature ) ) {
  176. $to_leave_enabled []= $feature;
  177. }
  178. }
  179. $to_deactivate = array_diff( $to_deactivate, $to_leave_enabled );
  180. if ( ! empty( $to_deactivate ) ) {
  181. Jetpack::update_active_modules( array_filter( array_diff( $active, $to_deactivate ) ) );
  182. }
  183. }
  184. return array(
  185. 'current' => $current,
  186. 'deactivate' => $to_deactivate
  187. );
  188. }
  189. }