Jetpack_Core_API_Module_Data_Endpoint

The WordPress Core Jetpack Core API Module Data Endpoint class.

Defined (1)

The class is defined in the following location(s).

/_inc/lib/core-api/class.jetpack-core-api-module-endpoints.php  
  1. class Jetpack_Core_API_Module_Data_Endpoint { 
  2.  
  3. public function process( $request ) { 
  4. switch( $request['slug'] ) { 
  5. case 'protect': 
  6. return $this->get_protect_data(); 
  7. case 'stats': 
  8. return $this->get_stats_data( $request ); 
  9. case 'akismet': 
  10. return $this->get_akismet_data(); 
  11. case 'monitor': 
  12. return $this->get_monitor_data(); 
  13. case 'verification-tools': 
  14. return $this->get_verification_tools_data(); 
  15. case 'vaultpress': 
  16. return $this->get_vaultpress_data(); 
  17.  
  18. /** 
  19. * Decide against which service to check the key. 
  20. * @since 4.8.0 
  21. * @param WP_REST_Request $request 
  22. * @return bool 
  23. */ 
  24. public function key_check( $request ) { 
  25. switch( $request['service'] ) { 
  26. case 'akismet': 
  27. $params = $request->get_json_params(); 
  28. if ( isset( $params['api_key'] ) && ! empty( $params['api_key'] ) ) { 
  29. return $this->check_akismet_key( $params['api_key'] ); 
  30. return $this->check_akismet_key(); 
  31. return false; 
  32.  
  33. /** 
  34. * Get number of blocked intrusion attempts. 
  35. * @since 4.3.0 
  36. * @return mixed|WP_Error Number of blocked attempts if protection is enabled. Otherwise, a WP_Error instance with the corresponding error. 
  37. */ 
  38. public function get_protect_data() { 
  39. if ( Jetpack::is_module_active( 'protect' ) ) { 
  40. return get_site_option( 'jetpack_protect_blocked_attempts' ); 
  41.  
  42. return new WP_Error( 
  43. 'not_active',  
  44. esc_html__( 'The requested Jetpack module is not active.', 'jetpack' ),  
  45. array( 'status' => 404 ) 
  46. ); 
  47.  
  48. /** 
  49. * Get number of spam messages blocked by Akismet. 
  50. * @since 4.3.0 
  51. * @return int|string Number of spam blocked by Akismet. Otherwise, an error message. 
  52. */ 
  53. public function get_akismet_data() { 
  54. if ( ! is_wp_error( $status = $this->akismet_is_active_and_registered() ) ) { 
  55. return rest_ensure_response( Akismet_Admin::get_stats( Akismet::get_api_key() ) ); 
  56. } else { 
  57. return $status->get_error_code(); 
  58.  
  59. /** 
  60. * Verify the Akismet API key. 
  61. * @since 4.8.0 
  62. * @param string $api_key Optional API key to check. 
  63. * @return array Information about the key. 'validKey' is true if key is valid, false otherwise. 
  64. */ 
  65. public function check_akismet_key( $api_key = '' ) { 
  66. $akismet_status = $this->akismet_class_exists(); 
  67. if ( is_wp_error( $akismet_status ) ) { 
  68. return rest_ensure_response( array( 
  69. 'validKey' => false,  
  70. 'invalidKeyCode' => $akismet_status->get_error_code(),  
  71. 'invalidKeyMessage' => $akismet_status->get_error_message(),  
  72. ) ); 
  73.  
  74. $key_status = Akismet::check_key_status( empty( $api_key ) ? Akismet::get_api_key() : $api_key ); 
  75.  
  76. if ( ! $key_status || 'invalid' === $key_status || 'failed' === $key_status ) { 
  77. return rest_ensure_response( array( 
  78. 'validKey' => false,  
  79. 'invalidKeyCode' => 'invalid_key',  
  80. 'invalidKeyMessage' => esc_html__( 'Invalid Akismet key. Please contact support.', 'jetpack' ),  
  81. ) ); 
  82.  
  83. return rest_ensure_response( array( 
  84. 'validKey' => isset( $key_status[1] ) && 'valid' === $key_status[1] 
  85. ) ); 
  86.  
  87. /** 
  88. * Check if Akismet class file exists and if class is loaded. 
  89. * @since 4.8.0 
  90. * @return bool|WP_Error Returns true if class file exists and class is loaded, WP_Error otherwise. 
  91. */ 
  92. private function akismet_class_exists() { 
  93. if ( ! file_exists( WP_PLUGIN_DIR . '/akismet/class.akismet.php' ) ) { 
  94. return new WP_Error( 'not_installed', esc_html__( 'Please install Akismet.', 'jetpack' ), array( 'status' => 400 ) ); 
  95.  
  96. if ( ! class_exists( 'Akismet' ) ) { 
  97. return new WP_Error( 'not_active', esc_html__( 'Please activate Akismet.', 'jetpack' ), array( 'status' => 400 ) ); 
  98.  
  99. return true; 
  100.  
  101. /** 
  102. * Is Akismet registered and active? 
  103. * @since 4.3.0 
  104. * @return bool|WP_Error True if Akismet is active and registered. Otherwise, a WP_Error instance with the corresponding error. 
  105. */ 
  106. private function akismet_is_active_and_registered() { 
  107. if ( is_wp_error( $akismet_exists = $this->akismet_class_exists() ) ) { 
  108. return $akismet_exists; 
  109.  
  110. // What about if Akismet is put in a sub-directory or maybe in mu-plugins? 
  111. require_once WP_PLUGIN_DIR . '/akismet/class.akismet.php'; 
  112. require_once WP_PLUGIN_DIR . '/akismet/class.akismet-admin.php'; 
  113. $akismet_key = Akismet::verify_key( Akismet::get_api_key() ); 
  114.  
  115. if ( ! $akismet_key || 'invalid' === $akismet_key || 'failed' === $akismet_key ) { 
  116. return new WP_Error( 'invalid_key', esc_html__( 'Invalid Akismet key. Please contact support.', 'jetpack' ), array( 'status' => 400 ) ); 
  117.  
  118. return true; 
  119.  
  120. /** 
  121. * Get stats data for this site 
  122. * @since 4.1.0 
  123. * @param WP_REST_Request $request { 
  124. * Array of parameters received by request. 
  125. * @type string $date Date range to restrict results to. 
  126. * } 
  127. * @return int|string Number of spam blocked by Akismet. Otherwise, an error message. 
  128. */ 
  129. public function get_stats_data( WP_REST_Request $request ) { 
  130. // Get parameters to fetch Stats data. 
  131. $range = $request->get_param( 'range' ); 
  132.  
  133. // If no parameters were passed. 
  134. if ( 
  135. empty ( $range ) 
  136. || ! in_array( $range, array( 'day', 'week', 'month' ), true ) 
  137. ) { 
  138. $range = 'day'; 
  139.  
  140. if ( ! function_exists( 'stats_get_from_restapi' ) ) { 
  141. require_once( JETPACK__PLUGIN_DIR . 'modules/stats.php' ); 
  142.  
  143. switch ( $range ) { 
  144.  
  145. // This is always called first on page load 
  146. case 'day': 
  147. $initial_stats = stats_get_from_restapi(); 
  148. return rest_ensure_response( array( 
  149. 'general' => $initial_stats,  
  150.  
  151. // Build data for 'day' as if it was stats_get_from_restapi( array(), 'visits?unit=day&quantity=30' ); 
  152. 'day' => isset( $initial_stats->visits ) 
  153. ? $initial_stats->visits 
  154. : array(),  
  155. ) ); 
  156. case 'week': 
  157. return rest_ensure_response( array( 
  158. 'week' => stats_get_from_restapi( array(), 'visits?unit=week&quantity=14' ),  
  159. ) ); 
  160. case 'month': 
  161. return rest_ensure_response( array( 
  162. 'month' => stats_get_from_restapi( array(), 'visits?unit=month&quantity=12&' ),  
  163. ) ); 
  164.  
  165. /** 
  166. * Get date of last downtime. 
  167. * @since 4.3.0 
  168. * @return mixed|WP_Error Number of days since last downtime. Otherwise, a WP_Error instance with the corresponding error. 
  169. */ 
  170. public function get_monitor_data() { 
  171. if ( ! Jetpack::is_module_active( 'monitor' ) ) { 
  172. return new WP_Error( 
  173. 'not_active',  
  174. esc_html__( 'The requested Jetpack module is not active.', 'jetpack' ),  
  175. array( 'status' => 404 ) 
  176. ); 
  177.  
  178. $monitor = new Jetpack_Monitor(); 
  179. $last_downtime = $monitor->monitor_get_last_downtime(); 
  180. if ( is_wp_error( $last_downtime ) ) { 
  181. return $last_downtime; 
  182. } else if ( false === strtotime( $last_downtime ) ) { 
  183. return rest_ensure_response( array( 
  184. 'code' => 'success',  
  185. 'date' => null,  
  186. ) ); 
  187. } else { 
  188. return rest_ensure_response( array( 
  189. 'code' => 'success',  
  190. 'date' => human_time_diff( strtotime( $last_downtime ), strtotime( 'now' ) ),  
  191. ) ); 
  192.  
  193. /** 
  194. * Get services that this site is verified with. 
  195. * @since 4.3.0 
  196. * @return mixed|WP_Error List of services that verified this site. Otherwise, a WP_Error instance with the corresponding error. 
  197. */ 
  198. public function get_verification_tools_data() { 
  199. if ( ! Jetpack::is_module_active( 'verification-tools' ) ) { 
  200. return new WP_Error( 
  201. 'not_active',  
  202. esc_html__( 'The requested Jetpack module is not active.', 'jetpack' ),  
  203. array( 'status' => 404 ) 
  204. ); 
  205.  
  206. $verification_services_codes = get_option( 'verification_services_codes' ); 
  207. if ( 
  208. ! is_array( $verification_services_codes ) 
  209. || empty( $verification_services_codes ) 
  210. ) { 
  211. return new WP_Error( 
  212. 'empty',  
  213. esc_html__( 'Site not verified with any service.', 'jetpack' ),  
  214. array( 'status' => 404 ) 
  215. ); 
  216.  
  217. $services = array(); 
  218. foreach ( jetpack_verification_services() as $name => $service ) { 
  219. if ( is_array( $service ) && ! empty( $verification_services_codes[ $name ] ) ) { 
  220. switch ( $name ) { 
  221. case 'google': 
  222. $services[] = 'Google'; 
  223. break; 
  224. case 'bing': 
  225. $services[] = 'Bing'; 
  226. break; 
  227. case 'pinterest': 
  228. $services[] = 'Pinterest'; 
  229. break; 
  230. case 'yandex': 
  231. $services[] = 'Yandex'; 
  232. break; 
  233.  
  234. if ( empty( $services ) ) { 
  235. return new WP_Error( 
  236. 'empty',  
  237. esc_html__( 'Site not verified with any service.', 'jetpack' ),  
  238. array( 'status' => 404 ) 
  239. ); 
  240.  
  241. if ( 2 > count( $services ) ) { 
  242. $message = esc_html( 
  243. sprintf( 
  244. /** translators: %s is a service name like Google, Bing, Pinterest, etc. */ 
  245. __( 'Your site is verified with %s.', 'jetpack' ),  
  246. $services[0] 
  247. ); 
  248. } else { 
  249. $copy_services = $services; 
  250. $last = count( $copy_services ) - 1; 
  251. $last_service = $copy_services[ $last ]; 
  252. unset( $copy_services[ $last ] ); 
  253. $message = esc_html( 
  254. sprintf( 
  255. /** translators: %1$s is a comma separated list of services, and %2$s is a single service name like Google, Bing, Pinterest, etc. */ 
  256. __( 'Your site is verified with %1$s and %2$s.', 'jetpack' ),  
  257. join( ', ', $copy_services ),  
  258. $last_service 
  259. ); 
  260.  
  261. return rest_ensure_response( array( 
  262. 'code' => 'success',  
  263. 'message' => $message,  
  264. 'services' => $services,  
  265. ) ); 
  266.  
  267. /** 
  268. * Get VaultPress site data including, among other things, the date of the last backup if it was completed. 
  269. * @since 4.3.0 
  270. * @return mixed|WP_Error VaultPress site data. Otherwise, a WP_Error instance with the corresponding error. 
  271. */ 
  272. public function get_vaultpress_data() { 
  273. if ( ! class_exists( 'VaultPress' ) ) { 
  274. return new WP_Error( 
  275. 'not_active',  
  276. esc_html__( 'The requested Jetpack module is not active.', 'jetpack' ),  
  277. array( 'status' => 404 ) 
  278. ); 
  279.  
  280. $vaultpress = new VaultPress(); 
  281. if ( ! $vaultpress->is_registered() ) { 
  282. return rest_ensure_response( array( 
  283. 'code' => 'not_registered',  
  284. 'message' => esc_html__( 'You need to register for VaultPress.', 'jetpack' ) 
  285. ) ); 
  286.  
  287. $data = json_decode( base64_decode( $vaultpress->contact_service( 'plugin_data' ) ) ); 
  288. if ( is_wp_error( $data ) || ! isset( $data->backups->last_backup ) ) { 
  289. return $data; 
  290. } else if ( empty( $data->backups->last_backup ) ) { 
  291. return rest_ensure_response( array( 
  292. 'code' => 'success',  
  293. 'message' => esc_html__( 'VaultPress is active and will back up your site soon.', 'jetpack' ),  
  294. 'data' => $data,  
  295. ) ); 
  296. } else { 
  297. return rest_ensure_response( array( 
  298. 'code' => 'success',  
  299. 'message' => esc_html( 
  300. sprintf( 
  301. __( 'Your site was successfully backed-up %s ago.', 'jetpack' ),  
  302. human_time_diff( 
  303. $data->backups->last_backup,  
  304. current_time( 'timestamp' ) 
  305. ),  
  306. 'data' => $data,  
  307. ) ); 
  308.  
  309. /** 
  310. * A WordPress REST API permission callback method that accepts a request object and 
  311. * decides if the current user has enough privileges to act. 
  312. * @since 4.3.0 
  313. * @return bool does a current user have enough privileges. 
  314. */ 
  315. public function can_request() { 
  316. return current_user_can( 'jetpack_admin_page' );