/core/controllers/revisions.php

  1. <?php  
  2.  
  3. /** 
  4. * Revisions 
  5. * 
  6. * This Class contains all the functionality for adding ACF fields to the WP revisions interface 
  7. * 
  8. * @type class 
  9. * @date 11/08/13 
  10. */ 
  11.  
  12. class acf_revisions 
  13.  
  14. /** 
  15. * __construct 
  16. * 
  17. * A good place to add actions / filters 
  18. * 
  19. * @type function 
  20. * @date 11/08/13 
  21. * 
  22. * @param N/A 
  23. * @return N/A 
  24. */ 
  25.  
  26. function __construct() 
  27. // actions  
  28. add_action('wp_restore_post_revision', array($this, 'wp_restore_post_revision'), 10, 2 ); 
  29.  
  30.  
  31. // filters 
  32. add_filter('_wp_post_revision_fields', array($this, 'wp_post_revision_fields') ); 
  33. add_filter('wp_save_post_revision_check_for_changes', array($this, 'force_save_revision'), 10, 3); 
  34.  
  35.  
  36. /** 
  37. * force_save_revision 
  38. * 
  39. * This filter will return false and force WP to save a revision. This is required due to 
  40. * WP checking only post_title, post_excerpt and post_content values, not custom fields. 
  41. * 
  42. * @type filter 
  43. * @date 19/09/13 
  44. * 
  45. * @param $return (boolean) defaults to true 
  46. * @param $last_revision (object) the last revision that WP will compare against 
  47. * @param $post (object) the $post that WP will compare against 
  48. * @return $return (boolean) 
  49. */ 
  50.  
  51. function force_save_revision( $return, $last_revision, $post ) 
  52. // preview hack 
  53. if( isset($_POST['acf_has_changed']) && $_POST['acf_has_changed'] == '1' ) 
  54. $return = false; 
  55.  
  56.  
  57. // return 
  58. return $return; 
  59.  
  60.  
  61. /** 
  62. * wp_post_revision_fields 
  63. * 
  64. * This filter will add the ACF fields to the returned array 
  65. * Versions 3.5 and 3.6 of WP feature different uses of the revisions filters, so there are 
  66. * some hacks to allow both versions to work correctly 
  67. * 
  68. * @type filter 
  69. * @date 11/08/13 
  70. * 
  71. * @param $post_id (int) 
  72. * @return $post_id (int) 
  73. */ 
  74.  
  75. function wp_post_revision_fields( $return ) { 
  76.  
  77.  
  78. //globals 
  79. global $post, $pagenow; 
  80.  
  81.  
  82. // validate 
  83. $allowed = false; 
  84.  
  85.  
  86. // Normal revisions page 
  87. if( $pagenow == 'revision.php' ) 
  88. $allowed = true; 
  89.  
  90.  
  91. // WP 3.6 AJAX revision 
  92. if( $pagenow == 'admin-ajax.php' && isset($_POST['action']) && $_POST['action'] == 'get-revision-diffs' ) 
  93. $allowed = true; 
  94.  
  95.  
  96. // bail 
  97. if( !$allowed )  
  98. return $return; 
  99.  
  100.  
  101. // vars 
  102. $post_id = 0; 
  103.  
  104.  
  105. // determine $post_id 
  106. if( isset($_POST['post_id']) ) 
  107. $post_id = $_POST['post_id']; 
  108. elseif( isset($post->ID) ) 
  109. $post_id = $post->ID; 
  110. else 
  111. return $return; 
  112.  
  113.  
  114. // get field objects 
  115. $fields = get_field_objects( $post_id, array('format_value' => false ) ); 
  116.  
  117.  
  118. if( $fields ) 
  119. foreach( $fields as $field ) 
  120. // dud field? 
  121. if( !$field || !isset($field['name']) || !$field['name'] ) 
  122. continue; 
  123.  
  124.  
  125. // Add field key / label 
  126. $return[ $field['name'] ] = $field['label']; 
  127.  
  128.  
  129. // load value 
  130. add_filter('_wp_post_revision_field_' . $field['name'], array($this, 'wp_post_revision_field'), 10, 4); 
  131.  
  132.  
  133. // WP 3.5: left vs right 
  134. // Add a value of the revision ID (as there is no way to determine this within the '_wp_post_revision_field_' filter!) 
  135. if( isset($_GET['action'], $_GET['left'], $_GET['right']) && $_GET['action'] == 'diff' ) 
  136. global $left_revision, $right_revision; 
  137.  
  138. $left_revision->$field['name'] = 'revision_id=' . $_GET['left']; 
  139. $right_revision->$field['name'] = 'revision_id=' . $_GET['right']; 
  140.  
  141.  
  142.  
  143. return $return; 
  144.  
  145.  
  146.  
  147. /** 
  148. * wp_post_revision_field 
  149. * 
  150. * This filter will load the value for the given field and return it for rendering 
  151. * 
  152. * @type filter 
  153. * @date 11/08/13 
  154. * 
  155. * @param $value (mixed) should be false as it has not yet been loaded 
  156. * @param $field_name (string) The name of the field 
  157. * @param $post (mixed) Holds the $post object to load from - in WP 3.5, this is not passed! 
  158. * @param $direction (string) to / from - not used 
  159. * @return $value (string) 
  160. */ 
  161.  
  162. function wp_post_revision_field( $value, $field_name, $post = null, $direction = false) 
  163. // vars 
  164. $post_id = 0; 
  165.  
  166.  
  167. // determine $post_id 
  168. if( isset($post->ID) ) 
  169. // WP 3.6 
  170. $post_id = $post->ID; 
  171. elseif( isset($_GET['revision']) ) 
  172. // WP 3.5 
  173. $post_id = (int) $_GET['revision']; 
  174. elseif( strpos($value, 'revision_id=') !== false ) 
  175. // WP 3.5 (left vs right) 
  176. $post_id = (int) str_replace('revision_id=', '', $value); 
  177.  
  178.  
  179. // load field 
  180. $field = get_field_object($field_name, $post_id, array('format_value' => false )); 
  181. $value = $field['value']; 
  182.  
  183.  
  184. // default formatting 
  185. if( is_array($value) ) 
  186. $value = implode(', ', $value); 
  187.  
  188.  
  189. // format 
  190. if( $value ) 
  191. // image? 
  192. if( $field['type'] == 'image' || $field['type'] == 'file' ) 
  193. $url = wp_get_attachment_url($value); 
  194. $value = $value . ' (' . $url . ')'; 
  195.  
  196.  
  197. // return 
  198. return $value; 
  199.  
  200.  
  201. /** 
  202. * wp_restore_post_revision 
  203. * 
  204. * This action will copy and paste the metadata from a revision to the post 
  205. * 
  206. * @type action 
  207. * @date 11/08/13 
  208. * 
  209. * @param $parent_id (int) the destination post 
  210. * @return $revision_id (int) the source post 
  211. */ 
  212.  
  213. function wp_restore_post_revision( $post_id, $revision_id ) { 
  214.  
  215. // global 
  216. global $wpdb; 
  217.  
  218.  
  219. // vars 
  220. $fields = array(); 
  221.  
  222.  
  223. // get field from postmeta 
  224. $rows = $wpdb->get_results( $wpdb->prepare( 
  225. "SELECT * FROM $wpdb->postmeta WHERE post_id=%d",  
  226. $revision_id 
  227. ), ARRAY_A); 
  228.  
  229.  
  230. // populate $fields 
  231. if( $rows ) 
  232. foreach( $rows as $row ) 
  233. // meta_key must start with '_' 
  234. if( substr($row['meta_key'], 0, 1) !== '_' ) 
  235. continue; 
  236.  
  237.  
  238. // meta_value must start with 'field_' 
  239. if( substr($row['meta_value'], 0, 6) !== 'field_' ) 
  240. continue; 
  241.  
  242.  
  243. // this is an ACF field, append to $fields 
  244. $fields[] = substr($row['meta_key'], 1); 
  245.  
  246.  
  247.  
  248. // save data 
  249. if( $rows ) 
  250. foreach( $rows as $row ) 
  251. if( in_array($row['meta_key'], $fields) ) 
  252. update_post_meta( $post_id, $row['meta_key'], $row['meta_value'] ); 
  253.  
  254.  
  255.  
  256.  
  257. new acf_revisions(); 
  258.  
  259. ?> 
.