Guest User

Untitled

a guest
Dec 17th, 2018
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.86 KB | None | 0 0
  1. <?php
  2. /**
  3. * Example class implementation to perform actions, such as sending a Post
  4. * to a third party API or service, when the Post is published or updated through:
  5. * - Classic Editor
  6. * - Gutenberg
  7. * - REST API
  8. *
  9. * @package Post_To_Social
  10. * @author Tim Carr
  11. * @version 1.0.0
  12. */
  13. class Post_To_Social {
  14.  
  15. /**
  16. * Constructor
  17. *
  18. * @since 1.0.0
  19. */
  20. public function __construct() {
  21.  
  22. // Actions
  23. add_action( 'wp_loaded', array( $this, 'register_publish_hooks' ), 1 );
  24.  
  25. }
  26.  
  27. /**
  28. * Registers publish hooks against all public Post Types,
  29. *
  30. * @since 1.0.0
  31. */
  32. public function register_publish_hooks() {
  33.  
  34. add_action( 'transition_post_status', array( $this, 'transition_post_status' ), 10, 3 );
  35.  
  36. }
  37.  
  38. /**
  39. * Fired when a Post's status transitions.
  40. *
  41. * Called by WordPress when wp_insert_post() is called.
  42. *
  43. * As wp_insert_post() is called by WordPress and the REST API whenever creating or updating a Post,
  44. * we can safely rely on this hook.
  45. *
  46. * @since 1.0.0
  47. *
  48. * @param string $new_status New Status
  49. * @param string $old_status Old Status
  50. * @param WP_Post $post Post
  51. */
  52. public function transition_post_status( $new_status, $old_status, $post ) {
  53.  
  54. // Bail if the Post Type isn't public
  55. // This prevents the rest of this routine running on e.g. ACF Free, when saving Fields (which results in Field loss)
  56. $post_types = array( 'post', 'page' );
  57. if ( ! in_array( $post->post_type, $post_types ) ) {
  58. return;
  59. }
  60.  
  61. // Bail if we're working on a draft or trashed item
  62. if ( $new_status == 'auto-draft' || $new_status == 'draft' || $new_status == 'inherit' || $new_status == 'trash' ) {
  63. return;
  64. }
  65.  
  66. /**
  67. * = REST API =
  68. * If this is a REST API Request, we can't use the wp_insert_post action, because any metadata
  69. * included in the REST API request is *not* included in the call to wp_insert_post().
  70. *
  71. * Instead, we must use a late REST API action that gives the REST API time to save metadata.
  72. *
  73. * Thankfully, the REST API supplies an action to do this: rest_after_insert_posttype, where posttype
  74. * is the Post Type in question.
  75. *
  76. * Note that any meta being supplied in the REST API Request MUST be registered with WordPress using
  77. * register_meta(). If you're using a third party plugin to register custom fields, you'll need to
  78. * confirm it uses register_meta() as part of its process.
  79. *
  80. * = Gutenberg =
  81. * If Gutenberg is being used on the given Post Type, two requests are sent:
  82. * - a REST API request, comprising of Post Data and Metadata registered *in* Gutenberg,
  83. * - a standard request, comprising of Post Metadata registered *outside* of Gutenberg (i.e. add_meta_box() data)
  84. *
  85. * If we're publishing a Post, the second request will be seen by transition_post_status() as an update, which
  86. * isn't strictly true.
  87. *
  88. * Therefore, we set a meta flag on the first Gutenberg REST API request to defer acting on the Post until
  89. * the second, standard request - at which point, all Post metadata will be available to the Plugin.
  90. *
  91. * = Classic Editor =
  92. * Metadata is included in the call to wp_insert_post(), meaning that it's saved to the Post before we use it.
  93. */
  94.  
  95. // Flag to determine if the current Post is a Gutenberg Post
  96. $is_gutenberg_post = $this->is_gutenberg_post( $post );
  97.  
  98. // If a previous request flagged that an 'update' request should be treated as a publish request (i.e.
  99. // we're using Gutenberg and request to post.php was made after the REST API), do this now.
  100. $needs_publishing = get_post_meta( $post->ID, '_needs_publishing', true );
  101. if ( $needs_publishing ) {
  102. // Run Publish Status Action now
  103. delete_post_meta( $post->ID, '_needs_publishing' );
  104. add_action( 'wp_insert_post', array( $this, 'wp_insert_post_publish' ), 999 );
  105.  
  106. // Don't need to do anything else, so exit
  107. return;
  108. }
  109.  
  110. // If a previous request flagged that an update request be deferred (i.e.
  111. // we're using Gutenberg and request to post.php was made after the REST API), do this now.
  112. $needs_updating = get_post_meta( $post->ID, '_needs_updating', true );
  113. if ( $needs_updating ) {
  114. // Run Publish Status Action now
  115. delete_post_meta( $post->ID, '_needs_updating' );
  116. add_action( 'wp_insert_post', array( $this, 'wp_insert_post_update' ), 999 );
  117.  
  118. // Don't need to do anything else, so exit
  119. return;
  120. }
  121.  
  122. // Publish
  123. if ( $new_status == 'publish' && $new_status != $old_status ) {
  124. /**
  125. * Classic Editor
  126. */
  127. if ( ! defined( 'REST_REQUEST' ) || ( defined( 'REST_REQUEST' ) && ! REST_REQUEST ) ) {
  128. add_action( 'wp_insert_post', array( $this, 'wp_insert_post_publish' ), 999 );
  129.  
  130. // Don't need to do anything else, so exit
  131. return;
  132. }
  133.  
  134. /**
  135. * Gutenberg Editor
  136. * - Non-Gutenberg metaboxes are POSTed via a second, separate request to post.php, which appears
  137. * as an 'update'. Define a meta key that we'll check on the separate request later.
  138. */
  139. if ( $is_gutenberg_post ) {
  140. update_post_meta( $post->ID, '_needs_publishing', 1 );
  141.  
  142. // Don't need to do anything else, so exit
  143. return;
  144. }
  145.  
  146. /**
  147. * REST API
  148. */
  149. add_action( 'rest_after_insert_' . $post->post_type, array( $this, 'rest_api_post_publish' ), 10, 2 );
  150.  
  151. // Don't need to do anything else, so exit
  152. return;
  153. }
  154.  
  155. // Update
  156. if ( $new_status == 'publish' && $old_status == 'publish' ) {
  157. /**
  158. * Classic Editor
  159. */
  160. if ( ! defined( 'REST_REQUEST' ) || ( defined( 'REST_REQUEST' ) && ! REST_REQUEST ) ) {
  161. add_action( 'wp_insert_post', array( $this, 'wp_insert_post_update' ), 999 );
  162.  
  163. // Don't need to do anything else, so exit
  164. return;
  165. }
  166.  
  167. /**
  168. * Gutenberg Editor
  169. * - Non-Gutenberg metaboxes are POSTed via a second, separate request to post.php, which appears
  170. * as an 'update'. Define a meta key that we'll check on the separate request later.
  171. */
  172. if ( $is_gutenberg_post ) {
  173. update_post_meta( $post->ID, '_needs_updating', 1 );
  174.  
  175. // Don't need to do anything else, so exit
  176. return;
  177. }
  178.  
  179. /**
  180. * REST API
  181. */
  182. add_action( 'rest_after_insert_' . $post->post_type, array( $this, 'rest_api_post_update' ), 10, 2 );
  183.  
  184. // Don't need to do anything else, so exit
  185. return;
  186. }
  187.  
  188. }
  189.  
  190. /**
  191. * Helper function to determine if the Post is using the Gutenberg Editor.
  192. *
  193. * @since 1.0.0
  194. *
  195. * @param WP_Post $post Post
  196. * @return bool Post uses Gutenberg Editor
  197. */
  198. private function is_gutenberg_post( $post ) {
  199.  
  200. // This will fail if a Post is created or updated with no content and only a title.
  201. if ( strpos( $post->post_content, '<!-- wp:' ) === false ) {
  202. return false;
  203. }
  204.  
  205. return true;
  206.  
  207. }
  208.  
  209. /**
  210. * Called when a Post has been Published via the REST API
  211. *
  212. * @since 1.0.0
  213. *
  214. * @param WP_Post $post Post
  215. * @param WP_REST_Request $request Request Object
  216. */
  217. public function rest_api_post_publish( $post, $request ) {
  218.  
  219. $this->wp_insert_post_publish( $post->ID );
  220.  
  221. }
  222.  
  223. /**
  224. * Called when a Post has been Published via the REST API
  225. *
  226. * @since 1.0.0
  227. *
  228. * @param WP_Post $post Post
  229. * @param WP_REST_Request $request Request Object
  230. */
  231. public function rest_api_post_update( $post, $request ) {
  232.  
  233. $this->wp_insert_post_update( $post->ID );
  234.  
  235. }
  236.  
  237. /**
  238. * Called when a Post has been Published
  239. *
  240. * @since 1.0.0
  241. *
  242. * @param int $post_id Post ID
  243. */
  244. public function wp_insert_post_publish( $post_id ) {
  245.  
  246. // Call main function
  247. $this->send( $post_id, 'publish' );
  248.  
  249. }
  250.  
  251. /**
  252. * Called when a Post has been Updated
  253. *
  254. * @since 1.0.0
  255. *
  256. * @param int $post_id Post ID
  257. */
  258. public function wp_insert_post_update( $post_id ) {
  259.  
  260. // Call main function
  261. $this->send( $post_id, 'update' );
  262.  
  263. }
  264.  
  265. /**
  266. * Main function. Called when any Page, Post or CPT is published or updated
  267. *
  268. * @since 1.0.0
  269. *
  270. * @param int $post_id Post ID
  271. * @param string $action Action (publish|update)
  272. * @return mixed WP_Error | API Results array
  273. */
  274. public function send( $post_id, $action ) {
  275.  
  276. // Get Post
  277. global $post;
  278. $post = get_post( $post_id );
  279. if ( ! $post ) {
  280. return new WP_Error( 'no_post', sprintf( __( 'No WordPress Post could be found for Post ID %s' ), $post_id ) );
  281. }
  282.  
  283. // @TODO Save any metadata that your Plugin expects now - such as post-specific settings your Plugin may offer via add_meta_box() calls
  284. update_post_meta( $post_id, 'your-key', sanitize_text_field( $_POST['your-key'] ) );
  285.  
  286. // @TODO Add your code here to send your Post to whichever API / third party service
  287.  
  288.  
  289. }
  290.  
  291. }
Add Comment
Please, Sign In to add comment