Fieldmanager
  • Package
  • Class
  • Tree
  • Todo

Packages

  • Fieldmanager
    • Context
    • Datasource
    • Field
    • Util
  • None

Classes

  • Fieldmanager_Context
  • Fieldmanager_Context_Page
  • Fieldmanager_Context_Post
  • Fieldmanager_Context_QuickEdit
  • Fieldmanager_Context_Storable
  • Fieldmanager_Context_Submenu
  • Fieldmanager_Context_Term
  • Fieldmanager_Context_User
  1 <?php
  2 
  3 /**
  4  * Use fieldmanager to create meta boxes on the new/edit post screen and save
  5  * data primarily to post meta.
  6  *
  7  * @package Fieldmanager_Context
  8  */
  9 class Fieldmanager_Context_Post extends Fieldmanager_Context_Storable {
 10 
 11     /**
 12      * @var string
 13      * Title of meta box
 14      */
 15     public $title = '';
 16 
 17     /**
 18      * @var string[]
 19      * What post types to render this meta box
 20      */
 21     public $post_types = array();
 22 
 23     /**
 24      * @var string
 25      * Context (normal, advanced, or side)
 26      */
 27     public $context = 'normal';
 28 
 29     /**
 30      * @var priority
 31      * Priority (high, core, default, or low)
 32      */
 33     public $priority = 'default';
 34 
 35     /**
 36      * @var Fieldmanager_Group
 37      * Base field
 38      */
 39     public $fm = null;
 40 
 41     /*
 42      * @var boolean
 43      */
 44     private static $doing_internal_update = false;
 45 
 46     /**
 47      * Add a context to a fieldmanager
 48      * @param string $title
 49      * @param string|string[] $post_types
 50      * @param string $context (normal, advanced, or side)
 51      * @param string $priority (high, core, default, or low)
 52      * @param Fieldmanager_Field $fm
 53      */
 54     public function __construct( $title, $post_types, $context = 'normal', $priority = 'default', $fm = Null ) {
 55 
 56         // Populate the list of post types for which to add this meta box with the given settings
 57         if ( !is_array( $post_types ) ) $post_types = array( $post_types );
 58 
 59         $this->post_types = $post_types;
 60         $this->title = $title;
 61         $this->context = $context;
 62         $this->priority = $priority;
 63         $this->fm = $fm;
 64 
 65         add_action( 'admin_init', array( $this, 'meta_box_render_callback' ) );
 66         // If this meta box is on an attachment page, add the appropriate filter hook to save the data
 67         if ( isset( $this->fm->is_attachment ) && $this->fm->is_attachment ) {
 68             add_filter( 'attachment_fields_to_save', array( $this, 'save_fields_for_attachment' ), 10, 2 );
 69         }
 70         add_action( 'save_post', array( $this, 'delegate_save_post' ) );
 71         // Check if any meta boxes need to be removed
 72         if ( $this->fm && !empty( $this->fm->meta_boxes_to_remove ) ) {
 73             add_action( 'add_meta_boxes', array( $this, 'remove_meta_boxes' ), 100 );
 74         }
 75     }
 76 
 77     /**
 78      * admin_init callback to add meta boxes to content types
 79      * Registers render_meta_box()
 80      * @return void
 81      */
 82     public function meta_box_render_callback() {
 83         foreach ( $this->post_types as $type ) {
 84             add_meta_box(
 85                 'fm_meta_box_' . $this->fm->name,
 86                 $this->title,
 87                 array( $this, 'render_meta_box' ),
 88                 $type,
 89                 $this->context,
 90                 $this->priority
 91             );
 92         }
 93     }
 94 
 95     /**
 96      * Helper to attach element_markup() to add_meta_box(). Prints markup for post editor.
 97      * @see http://codex.wordpress.org/Function_Reference/add_meta_box
 98      * @param $post the post object.
 99      * @param $form_struct the structure of the form itself. Unused.
100      * @return void.
101      */
102     public function render_meta_box( $post, $form_struct = null ) {
103         $this->fm->data_type = 'post';
104         $this->fm->data_id = $post->ID;
105 
106         $this->render_field();
107 
108         // Check if any validation is required
109         $fm_validation = Fieldmanager_Util_Validation( 'post', 'post' );
110         $fm_validation->add_field( $this->fm );
111     }
112 
113     /**
114      * Helper to remove all built-in meta boxes for all specified taxonomies on a post type
115      * @param $post_type the post type
116      * @param $taxonomies the taxonomies for which to remove default meta boxes
117      * @return void.
118      */
119     public function remove_meta_boxes() {
120         foreach( $this->post_types as $type ) {
121             foreach( $this->fm->meta_boxes_to_remove as $meta_box ) {
122                 remove_meta_box( $meta_box['id'], $type, $meta_box['context'] );
123             }
124         }
125     }
126 
127     /**
128      * Handles saving Fieldmanager data when the custom meta boxes are used on an attachment.
129      * Calls save_fields_for_post with the post ID.
130      * @param array $post The post fields
131      * @param array $attachment The attachment fields
132      * @return void
133      */
134     public function save_fields_for_attachment( $post, $attachment ) {
135         // Use save_fields_for_post to handle saving any Fieldmanager meta data
136         $this->save_fields_for_post( $post['ID'] );
137 
138         // Return the post data for the attachment unmodified
139         return $post;
140     }
141 
142     /**
143      * Action handler to delegate to appropriate methods when a post is saved.
144      * @param int $post_id
145      * @return void
146      */
147     public function delegate_save_post( $post_id ) {
148         if ( self::$doing_internal_update ) {
149             return;
150         }
151         if( defined( 'DOING_CRON' ) && DOING_CRON ) {
152             $this->save_fields_for_cron( $post_id );
153         } else {
154             $this->save_fields_for_post( $post_id );
155         }
156     }
157 
158     /**
159      * Takes $_POST data and saves it to, calling save_to_post_meta() once validation is passed
160      * When using Fieldmanager as an API, do not call this function directly, call save_to_post_meta()
161      * @param int $post_id
162      * @return void
163      */
164     public function save_fields_for_post( $post_id ) {
165         // Make sure this field is attached to the post type being saved.
166         if ( empty( $_POST['post_ID'] ) || ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || $_POST['action'] != 'editpost' ) {
167             return;
168         }
169 
170         // Make sure this hook fired on the post being saved, not a side-effect post for which the $_POST context is invalid.
171         if ( $post_id !== absint( $_POST['post_ID'] ) ) {
172             return;
173         }
174 
175         // Prevent saving the same post twice; FM does not yet use revisions.
176         if ( get_post_type( $post_id ) == 'revision' ) {
177             return;
178         }
179 
180         // Make sure this post type is intended for handling by this FM context.
181         if ( ! in_array( get_post_type( $post_id ), $this->post_types ) ) {
182             return;
183         }
184 
185         // Do not handle quickedit in this context.
186         if ( $_POST['action'] == 'inline-save' ) {
187             return;
188         }
189 
190         // Verify nonce is present and valid. If present but not valid, this
191         // throws an exception, but if it's absent we can assume our data is
192         // not present.
193         if ( ! $this->is_valid_nonce() ) {
194             return;
195         }
196 
197         // Make sure the current user is authorized to save this post.
198         if ( $_POST['post_type'] == 'post' ) {
199             if ( ! current_user_can( 'edit_post', $post_id ) ) {
200                 $this->fm->_unauthorized_access( __( 'User cannot edit this post', 'fieldmanager' ) );
201                 return;
202             }
203         }
204 
205         $this->save_to_post_meta( $post_id );
206     }
207 
208     /**
209      * Process fields during a cron request, without saving data since the data isn't changing.
210      * @param int $post_id
211      * @return void
212      */
213     public function save_fields_for_cron( $post_id ) {
214         if ( ! in_array( get_post_type( $post_id ), $this->post_types ) ) {
215             return;
216         }
217         // don't save values since we aren't provided with any; just trigger presave so that subclass handlers can process as necessary
218         $this->fm->skip_save = true;
219         $current = get_post_meta( $post_id, $this->fm->name, true );
220         $this->save_to_post_meta( $post_id, $current );
221     }
222 
223     /**
224      * Helper to save an array of data to post meta
225      * @param int $post_id
226      * @param array $data
227      * @return void
228      */
229     public function save_to_post_meta( $post_id, $data = null ) {
230         if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
231             return;
232         }
233         $this->fm->data_id = $post_id;
234         $this->fm->data_type = 'post';
235 
236         $this->save( $data );
237     }
238 
239     /**
240      * Helper for fieldmanager internals to save a post without worrying about infinite loops
241      */
242     public static function safe_update_post( $args ) {
243         self::$doing_internal_update = true;
244         $ret = wp_update_post( $args );
245         self::$doing_internal_update = false;
246         return $ret;
247     }
248 
249     /**
250      * Get post meta.
251      *
252      * @see get_post_meta().
253      */
254     protected function get_data( $post_id, $meta_key, $single = false ) {
255         return get_post_meta( $post_id, $meta_key, $single );
256     }
257 
258     /**
259      * Add post meta.
260      *
261      * @see add_post_meta().
262      */
263     protected function add_data( $post_id, $meta_key, $meta_value, $unique = false ) {
264         return add_post_meta( $post_id, $meta_key, $meta_value, $unique );
265     }
266 
267     /**
268      * Update post meta.
269      *
270      * @see update_post_meta().
271      */
272     protected function update_data( $post_id, $meta_key, $meta_value, $data_prev_value = '' ) {
273         return update_post_meta( $post_id, $meta_key, $meta_value, $data_prev_value );
274     }
275 
276     /**
277      * Delete post meta.
278      *
279      * @see delete_post_meta().
280      */
281     protected function delete_data( $post_id, $meta_key, $meta_value = '' ) {
282         return delete_post_meta( $post_id, $meta_key, $meta_value );
283     }
284 
285 }
286 
Fieldmanager API documentation generated by ApiGen 2.8.0