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 add fields to the "quick edit" (post list inline editing)
  5  * and save data primarily to post meta.
  6  *
  7  * @package Fieldmanager_Context
  8  */
  9 class Fieldmanager_Context_QuickEdit extends Fieldmanager_Context_Storable {
 10 
 11     /**
 12      * @var string
 13      * Title of QuickEdit box; also used for the column title unless $column_title is specified.
 14      */
 15     public $title = '';
 16 
 17     /**
 18      * @var string
 19      * Override $title for the column in the list of posts
 20      */
 21     public $column_title = '';
 22 
 23     /**
 24      * @var callback
 25      * QuickEdit fields are tied to custom columns in the list of posts. This callback should return a value to
 26      * display in a custom column.
 27      */
 28     public $column_display_callback = null;
 29 
 30     /**
 31      * @var string[]
 32      * What post types to render this Quickedit form
 33      */
 34     public $post_types = array();
 35 
 36     /**
 37      * @var Fieldmanager_Group
 38      * Base field
 39      */
 40     public $fm = '';
 41 
 42     /**
 43      * Add a context to a fieldmanager
 44      * @param string $title
 45      * @param string|string[] $post_types
 46      * @param callback $column_not_empty_callback
 47      * @param callback $column_empty_callback
 48      * @param Fieldmanager_Field $fm
 49      */
 50     public function __construct( $title, $post_types, $column_display_callback, $column_title = '', $fm = Null ) {
 51 
 52         if ( !fm_match_context( 'quickedit' ) ) return; // make sure we only load up our JS if we're in a quickedit form.
 53 
 54         if ( FM_DEBUG && !is_callable( $column_display_callback ) ) {
 55             throw new FM_Developer_Exception( esc_html__( 'You must set a valid column display callback.', 'fieldmanager' ) );
 56         }
 57 
 58         // Populate the list of post types for which to add this meta box with the given settings
 59         if ( !is_array( $post_types ) ) $post_types = array( $post_types );
 60 
 61         $this->post_types = $post_types;
 62         $this->title = $title;
 63         $this->column_title = !empty( $column_title ) ? $column_title : $title;
 64         $this->column_display_callback = $column_display_callback;
 65         $this->fm = $fm;
 66 
 67         if ( is_callable( $column_display_callback ) ) {
 68             foreach ( $post_types as $post_type ) {
 69                 add_action( 'manage_' . $post_type . '_posts_columns', array( $this, 'add_custom_columns' ) );
 70             }
 71             add_action( 'manage_posts_custom_column', array( $this, 'manage_custom_columns' ), 10, 2 );
 72         }
 73 
 74         add_action( 'quick_edit_custom_box', array( $this, 'add_quickedit_box' ), 10, 2 );
 75         add_action( 'save_post', array( $this, 'save_fields_for_quickedit' ) );
 76         add_action( 'wp_ajax_fm_quickedit_render', array( $this, 'render_ajax_form' ), 10, 2 );
 77 
 78         $post_type = !isset( $_GET['post_type'] ) ? 'post' : sanitize_text_field( $_GET['post_type'] );
 79 
 80         if ( in_array( $post_type, $this->post_types ) ) {
 81             fm_add_script( 'quickedit-js', 'js/fieldmanager-quickedit.js' );
 82         }
 83     }
 84 
 85     /**
 86      * manage_{$post_type}_posts_columns callback, as QuickEdit boxes only work on custom columns.
 87      * @param array $columns
 88      * @return void
 89      */
 90     function add_custom_columns( $columns ) {
 91         $columns[$this->fm->name] = $this->column_title;
 92         return $columns;
 93     }
 94 
 95     /**
 96      * manage_posts_custom_column callback
 97      * @param string $column_name
 98      * @param int $post_id
 99      * @return void
100      */
101     public function manage_custom_columns( $column_name, $post_id ) {
102         if ( $column_name != $this->fm->name ) {
103             return;
104         }
105         $data = get_post_meta( $post_id, $this->fm->name, true );
106         $column_text = call_user_func( $this->column_display_callback, $post_id, $data );
107         echo $column_text;
108     }
109 
110     /**
111      * quick_edit_custom_box callback. Renders the QuickEdit box.
112      * Renders with blank values here since QuickEdit boxes cannot access to the WP post_id.
113      * The values will be populated by an ajax-fetched form later (see $this->render_ajax_form() ).
114      * @param string $column_name
115      * @param string $post_type
116      * @return void
117      */
118     public function add_quickedit_box( $column_name, $post_type, $values = array() ) {
119         if ( $column_name != $this->fm->name ) {
120             return;
121         }
122         ?>
123         <fieldset class="inline-edit-col-left fm-quickedit" id="fm-quickedit-<?php echo esc_attr( $column_name ); ?>" data-fm-post-type="<?php echo esc_attr( $post_type ); ?>">
124             <div class="inline-edit-col">
125                 <?php if ( ! empty( $this->title ) ) : ?>
126                     <h4><?php echo esc_html( $this->title ) ?></h4>
127                 <?php endif ?>
128                 <?php $this->render_field( array( 'data' => $values ) ); ?>
129             </div>
130         </fieldset>
131         <?php
132     }
133 
134     /**
135      * Callback for wp_ajax_fm_quickedit_render.
136      * Renders a form with pre-filled values to replace the one generated by $this->add_quickedit_box().
137      * @return string
138      */
139     public function render_ajax_form() {
140         if ( ! isset( $_GET['action'], $_GET['post_id'], $_GET['column_name'] ) ) {
141             return;
142         }
143 
144         if ( $_GET['action'] != 'fm_quickedit_render' ) {
145             return;
146         }
147 
148         $column_name = sanitize_text_field( $_GET['column_name'] );
149         $post_id = intval( $_GET['post_id'] );
150 
151         if ( ! $post_id || $column_name != $this->fm->name ) {
152             return;
153         }
154 
155         $this->fm->data_type = 'post';
156         $this->fm->data_id = $post_id;
157         $post_type = get_post_type( $post_id );
158 
159         $this->add_quickedit_box( $column_name, $post_type, $this->load() );
160         if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
161             exit;
162         }
163     }
164 
165     /**
166      * Takes $_POST data and saves it to, calling save_to_post_meta() once validation is passed
167      * When using Fieldmanager as an API, do not call this function directly, call save_to_post_meta()
168      * @param int $post_id
169      * @return void
170      */
171     public function save_fields_for_quickedit( $post_id ) {
172         // Make sure this field is attached to the post type being saved.
173         if ( !isset( $_POST['post_type'] ) || ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || $_POST['action'] != 'inline-save' ) {
174             return;
175         }
176 
177         $use_this_post_type = false;
178         foreach ( $this->post_types as $type ) {
179             if ( $type == $_POST['post_type'] ) {
180                 $use_this_post_type = true;
181                 break;
182             }
183         }
184         if ( !$use_this_post_type )  {
185             return;
186         }
187 
188         // Ensure that the nonce is set and valid
189         if ( ! $this->is_valid_nonce() ) {
190             return;
191         }
192 
193         // Make sure the current user can save this post
194         if( $_POST['post_type'] == 'post' ) {
195             if( !current_user_can( 'edit_post', $post_id ) ) {
196                 $this->fm->_unauthorized_access( __( 'User cannot edit this post', 'fieldmanager' ) );
197                 return;
198             }
199         }
200 
201         $this->save_to_post_meta( $post_id );
202     }
203 
204     /**
205      * Helper to save an array of data to post meta
206      * @param int $post_id
207      * @param array $data
208      * @return void
209      */
210     public function save_to_post_meta( $post_id, $data = null ) {
211         $this->fm->data_id = $post_id;
212         $this->fm->data_type = 'post';
213 
214         $this->save( $data );
215     }
216 
217     /**
218      * Get post meta.
219      *
220      * @see get_post_meta().
221      */
222     protected function get_data( $post_id, $meta_key, $single = false ) {
223         return get_post_meta( $post_id, $meta_key, $single );
224     }
225 
226     /**
227      * Add post meta.
228      *
229      * @see add_post_meta().
230      */
231     protected function add_data( $post_id, $meta_key, $meta_value, $unique = false ) {
232         return add_post_meta( $post_id, $meta_key, $meta_value, $unique );
233     }
234 
235     /**
236      * Update post meta.
237      *
238      * @see update_post_meta().
239      */
240     protected function update_data( $post_id, $meta_key, $meta_value, $data_prev_value = '' ) {
241         return update_post_meta( $post_id, $meta_key, $meta_value, $data_prev_value );
242     }
243 
244     /**
245      * Delete post meta.
246      *
247      * @see delete_post_meta().
248      */
249     protected function delete_data( $post_id, $meta_key, $meta_value = '' ) {
250         return delete_post_meta( $post_id, $meta_key, $meta_value );
251     }
252 
253 }
254 
Fieldmanager API documentation generated by ApiGen 2.8.0