Jetpack_Sync_Module_Posts

The WordPress Core Jetpack Sync Module Posts class.

Defined (1)

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

/sync/class.jetpack-sync-module-posts.php  
  1. class Jetpack_Sync_Module_Posts extends Jetpack_Sync_Module { 
  2.  
  3. private $just_published = array(); 
  4. private $just_trashed = array(); 
  5. private $action_handler; 
  6.  
  7. public function name() { 
  8. return 'posts'; 
  9.  
  10. public function get_object_by_id( $object_type, $id ) { 
  11. if ( $object_type === 'post' && $post = get_post( intval( $id ) ) ) { 
  12. return $this->filter_post_content_and_add_links( $post ); 
  13.  
  14. return false; 
  15.  
  16. public function set_defaults() { 
  17.  
  18. public function init_listeners( $callable ) { 
  19. $this->action_handler = $callable; 
  20.  
  21. // Core < 4.7 doesn't deal with nested wp_insert_post calls very well 
  22. global $wp_version; 
  23. $priority = version_compare( $wp_version, '4.7-alpha', '<' ) ? 0 : 11; 
  24.  
  25. add_action( 'wp_insert_post', array( $this, 'wp_insert_post' ), $priority, 3 ); 
  26.  
  27. add_action( 'deleted_post', $callable, 10 ); 
  28. add_action( 'jetpack_published_post', $callable, 10, 2 ); 
  29. add_action( 'jetpack_trashed_post', $callable, 10, 2 ); 
  30.  
  31. add_action( 'transition_post_status', array( $this, 'save_published' ), 10, 3 ); 
  32. add_filter( 'jetpack_sync_before_enqueue_wp_insert_post', array( $this, 'filter_blacklisted_post_types' ) ); 
  33.  
  34. // listen for meta changes 
  35. $this->init_listeners_for_meta_type( 'post', $callable ); 
  36. $this->init_meta_whitelist_handler( 'post', array( $this, 'filter_meta' ) ); 
  37.  
  38. public function init_full_sync_listeners( $callable ) { 
  39. add_action( 'jetpack_full_sync_posts', $callable ); // also sends post meta 
  40.  
  41. public function init_before_send() { 
  42. add_filter( 'jetpack_sync_before_send_wp_insert_post', array( $this, 'expand_wp_insert_post' ) ); 
  43.  
  44. // full sync 
  45. add_filter( 'jetpack_sync_before_send_jetpack_full_sync_posts', array( $this, 'expand_post_ids' ) ); 
  46.  
  47. public function enqueue_full_sync_actions( $config, $max_items_to_enqueue, $state ) { 
  48. global $wpdb; 
  49.  
  50. return $this->enqueue_all_ids_as_action( 'jetpack_full_sync_posts', $wpdb->posts, 'ID', $this->get_where_sql( $config ), $max_items_to_enqueue, $state ); 
  51.  
  52. public function estimate_full_sync_actions( $config ) { 
  53. global $wpdb; 
  54.  
  55. $query = "SELECT count(*) FROM $wpdb->posts WHERE " . $this->get_where_sql( $config ); 
  56. $count = $wpdb->get_var( $query ); 
  57.  
  58. return (int) ceil( $count / self::ARRAY_CHUNK_SIZE ); 
  59.  
  60. private function get_where_sql( $config ) { 
  61. $where_sql = Jetpack_Sync_Settings::get_blacklisted_post_types_sql(); 
  62.  
  63. // config is a list of post IDs to sync 
  64. if ( is_array( $config ) ) { 
  65. $where_sql .= ' AND ID IN (' . implode( ', ', array_map( 'intval', $config ) ) . ')'; 
  66.  
  67. return $where_sql; 
  68.  
  69. function get_full_sync_actions() { 
  70. return array( 'jetpack_full_sync_posts' ); 
  71.  
  72. /** 
  73. * Process content before send 
  74. * @param array $args wp_insert_post arguments 
  75. * @return array 
  76. */ 
  77. function expand_wp_insert_post( $args ) { 
  78. return array( $args[0], $this->filter_post_content_and_add_links( $args[1] ), $args[2] ); 
  79.  
  80. function filter_blacklisted_post_types( $args ) { 
  81. $post = $args[1]; 
  82.  
  83. if ( in_array( $post->post_type, Jetpack_Sync_Settings::get_setting( 'post_types_blacklist' ) ) ) { 
  84. return false; 
  85.  
  86. return $args; 
  87.  
  88. // Meta 
  89. function filter_meta( $args ) { 
  90. if ( $this->is_post_type_allowed( $args[1] ) && $this->is_whitelisted_post_meta( $args[2] ) ) { 
  91. return $args; 
  92.  
  93. return false; 
  94.  
  95. function is_whitelisted_post_meta( $meta_key ) { 
  96. // _wpas_skip_ is used by publicize 
  97. return in_array( $meta_key, Jetpack_Sync_Settings::get_setting( 'post_meta_whitelist' ) ) || wp_startswith( $meta_key, '_wpas_skip_' ); 
  98.  
  99. function is_post_type_allowed( $post_id ) { 
  100. $post = get_post( $post_id ); 
  101.  
  102. return ! in_array( $post->post_type, Jetpack_Sync_Settings::get_setting( 'post_types_blacklist' ) ); 
  103.  
  104. function remove_embed() { 
  105. global $wp_embed; 
  106. remove_filter( 'the_content', array( $wp_embed, 'run_shortcode' ), 8 ); 
  107. // remove the embed shortcode since we would do the part later. 
  108. remove_shortcode( 'embed' ); 
  109. // Attempts to embed all URLs in a post 
  110. remove_filter( 'the_content', array( $wp_embed, 'autoembed' ), 8 ); 
  111.  
  112. function add_embed() { 
  113. global $wp_embed; 
  114. add_filter( 'the_content', array( $wp_embed, 'run_shortcode' ), 8 ); 
  115. // Shortcode placeholder for strip_shortcodes() 
  116. add_shortcode( 'embed', '__return_false' ); 
  117. // Attempts to embed all URLs in a post 
  118. add_filter( 'the_content', array( $wp_embed, 'autoembed' ), 8 ); 
  119.  
  120. // Expands wp_insert_post to include filtered content 
  121. function filter_post_content_and_add_links( $post_object ) { 
  122. global $post; 
  123. $post = $post_object; 
  124.  
  125. // return non existant post  
  126. $post_type = get_post_type_object( $post->post_type ); 
  127. if ( empty( $post_type ) || ! is_object( $post_type ) ) { 
  128. $non_existant_post = new stdClass(); 
  129. $non_existant_post->ID = $post->ID; 
  130. $non_existant_post->post_modified = $post->post_modified; 
  131. $non_existant_post->post_modified_gmt = $post->post_modified_gmt; 
  132. $non_existant_post->post_status = 'jetpack_sync_non_registered_post_type'; 
  133.  
  134. return $non_existant_post; 
  135. /** 
  136. * Filters whether to prevent sending post data to .com 
  137. * Passing true to the filter will prevent the post data from being sent 
  138. * to the WordPress.com. 
  139. * Instead we pass data that will still enable us to do a checksum against the 
  140. * Jetpacks data but will prevent us from displaying the data on in the API as well as 
  141. * other services. 
  142. * @since 4.2.0 
  143. * @param boolean false prevent post data from being synced to WordPress.com 
  144. * @param mixed $post WP_POST object 
  145. */ 
  146. if ( apply_filters( 'jetpack_sync_prevent_sending_post_data', false, $post ) ) { 
  147. // We only send the bare necessary object to be able to create a checksum. 
  148. $blocked_post = new stdClass(); 
  149. $blocked_post->ID = $post->ID; 
  150. $blocked_post->post_modified = $post->post_modified; 
  151. $blocked_post->post_modified_gmt = $post->post_modified_gmt; 
  152. $blocked_post->post_status = 'jetpack_sync_blocked'; 
  153.  
  154. return $blocked_post; 
  155.  
  156. // lets not do oembed just yet. 
  157. $this->remove_embed(); 
  158.  
  159. if ( 0 < strlen( $post->post_password ) ) { 
  160. $post->post_password = 'auto-' . wp_generate_password( 10, false ); 
  161.  
  162. /** This filter is already documented in core. wp-includes/post-template.php */ 
  163. if ( Jetpack_Sync_Settings::get_setting( 'render_filtered_content' ) && $post_type->public ) { 
  164. global $shortcode_tags; 
  165. /** 
  166. * Filter prevents some shortcodes from expanding. 
  167. * Since we can can expand some type of shortcode better on the .com side and make the 
  168. * expansion more relevant to contexts. For example [galleries] and subscription emails 
  169. * @since 4.5.0 
  170. * @param array of shortcode tags to remove. 
  171. */ 
  172. $shortcodes_to_remove = apply_filters( 'jetpack_sync_do_not_expand_shortcodes', array( 
  173. 'gallery',  
  174. 'slideshow' 
  175. ) ); 
  176. $removed_shortcode_callbacks = array(); 
  177. foreach ( $shortcodes_to_remove as $shortcode ) { 
  178. if ( isset ( $shortcode_tags[ $shortcode ] ) ) { 
  179. $removed_shortcode_callbacks[ $shortcode ] = $shortcode_tags[ $shortcode ]; 
  180.  
  181. array_map( 'remove_shortcode', array_keys( $removed_shortcode_callbacks ) ); 
  182.  
  183. $post->post_content_filtered = apply_filters( 'the_content', $post->post_content ); 
  184. $post->post_excerpt_filtered = apply_filters( 'the_excerpt', $post->post_excerpt ); 
  185.  
  186. foreach ( $removed_shortcode_callbacks as $shortcode => $callback ) { 
  187. add_shortcode( $shortcode, $callback ); 
  188.  
  189. $this->add_embed(); 
  190.  
  191. if ( has_post_thumbnail( $post->ID ) ) { 
  192. $image_attributes = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'full' ); 
  193. if ( is_array( $image_attributes ) && isset( $image_attributes[0] ) ) { 
  194. $post->featured_image = $image_attributes[0]; 
  195.  
  196. $post->permalink = get_permalink( $post->ID ); 
  197. $post->shortlink = wp_get_shortlink( $post->ID ); 
  198.  
  199. return $post; 
  200.  
  201. public function save_published( $new_status, $old_status, $post ) { 
  202. if ( 'publish' === $new_status && 'publish' !== $old_status ) { 
  203. $this->just_published[] = $post->ID; 
  204.  
  205. if ( 'trash' === $new_status && 'trash' !== $old_status ) { 
  206. $this->just_trashed[] = $post->ID; 
  207.  
  208. public function wp_insert_post( $post_ID, $post, $update ) { 
  209. call_user_func( $this->action_handler, $post_ID, $post, $update ); 
  210. $this->send_published( $post_ID, $post ); 
  211. $this->send_trashed( $post_ID, $post ); 
  212.  
  213. public function send_published( $post_ID, $post ) { 
  214. if ( ! in_array( $post_ID, $this->just_published ) ) { 
  215. return; 
  216.  
  217. // Post revisions cause race conditions where this send_published add the action before the actual post gets synced 
  218. if ( wp_is_post_autosave( $post ) || wp_is_post_revision( $post ) ) { 
  219. return; 
  220.  
  221. /** 
  222. * Filter that is used to add to the post flags ( meta data ) when a post gets published 
  223. * @since 4.4.0 
  224. * @param mixed array post flags that are added to the post 
  225. * @param mixed $post WP_POST object 
  226. */ 
  227. $flags = apply_filters( 'jetpack_published_post_flags', array(), $post ); 
  228.  
  229. /** 
  230. * Action that gets synced when a post type gets published. 
  231. * @since 4.4.0 
  232. * @param int $post_ID 
  233. * @param mixed array $flags post flags that are added to the post 
  234. */ 
  235. do_action( 'jetpack_published_post', $post_ID, $flags ); 
  236.  
  237. $this->just_published = array_diff( $this->just_published, array( $post_ID ) ); 
  238.  
  239. public function send_trashed( $post_ID, $post ) { 
  240. if ( ! in_array( $post_ID, $this->just_trashed ) ) { 
  241. return; 
  242.  
  243. // Post revisions cause race conditions where this send_published add the action before the actual post gets synced 
  244. if ( wp_is_post_autosave( $post ) || wp_is_post_revision( $post ) ) { 
  245. return; 
  246.  
  247. /** 
  248. * Action that gets synced when a post type gets trashed. 
  249. * @since 4.9.0 
  250. * @param int $post_ID 
  251. */ 
  252. do_action( 'jetpack_trashed_post', $post_ID ); 
  253.  
  254. $this->just_trashed = array_diff( $this->just_trashed, array( $post_ID ) ); 
  255.  
  256. public function expand_post_ids( $args ) { 
  257. $post_ids = $args[0]; 
  258.  
  259. $posts = array_filter( array_map( array( 'WP_Post', 'get_instance' ), $post_ids ) ); 
  260. $posts = array_map( array( $this, 'filter_post_content_and_add_links' ), $posts ); 
  261. $posts = array_values( $posts ); // reindex in case posts were deleted 
  262.  
  263. return array( 
  264. $posts,  
  265. $this->get_metadata( $post_ids, 'post', Jetpack_Sync_Settings::get_setting( 'post_meta_whitelist' ) ),  
  266. $this->get_term_relationships( $post_ids ),  
  267. );