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 term screens and save
  5  * data primarily to term meta.
  6  *
  7  * @package Fieldmanager_Context
  8  */
  9 class Fieldmanager_Context_Term extends Fieldmanager_Context_Storable {
 10     /**
 11      * @var string
 12      * Title of field to display in standard term form field location
 13      */
 14     public $title = '';
 15 
 16     /**
 17      * @var string[]
 18      * What taxonomies to render these fields
 19      */
 20     public $taxonomies = array();
 21 
 22     /**
 23      * @var boolean
 24      * Whether or not to show the fields on the term add form
 25      */
 26     public $show_on_add = true;
 27 
 28     /**
 29      * @var boolean
 30      * Whether or not to show the fields on the term edit form
 31      */
 32     public $show_on_edit = true;
 33 
 34     /**
 35      * @var int
 36      * Only show this field on child terms of this parent
 37      */
 38     public $parent = '';
 39 
 40     /**
 41      * @var array
 42      * Field names reserved for WordPress on the term add/edit forms
 43      */
 44     public $reserved_fields = array( 'name', 'slug', 'description' );
 45 
 46     /**
 47      * Use FM term meta or WordPres core term meta. The default is a bit
 48      * confusing: technically, it's to use core's term meta, but if the class is
 49      * instantiated using the now-deprecated separated arguments, this gets set
 50      * to true for backwards-compatibility purposes.
 51      *
 52      * This should be false whenever possible to instead use core's built-in
 53      * term meta (introduced in WordPress 4.4).
 54      *
 55      * @var boolean
 56      */
 57     public $use_fm_meta = false;
 58 
 59     /**
 60      * Base field
 61      *
 62      * @var Fieldmanager_Field
 63      */
 64     public $fm = '';
 65 
 66     /**
 67      * The current taxonomy. Used when saving data.
 68      * @var string
 69      */
 70     private $current_taxonomy;
 71 
 72 
 73     /**
 74      * Instantiate this context. You can either pass an array of all args
 75      * (preferred), or pass them individually (deprecated).
 76      *
 77      * @param array|string $args {
 78      *     Array of arguments.
 79      *
 80      *     If a string (deprecated), this will be used as the $title.
 81      *
 82      *     @type string $title The context/meta box title.
 83      *     @type string|array $taxonomies The taxonomy/taxonomies to which to
 84      *                                    add this field.
 85      *     @type bool $show_on_add Optional. Should this field show on the "Add
 86      *                             Term" screen? Defaults to yes (true).
 87      *     @type bool $show_on_edit Optional. Should this field show on the
 88      *                              "Edit Term" screen? Defaults to yes (true).
 89      *     @type int $parent Optional. Should this field only show if its parent
 90      *                       matches this term ID?
 91      *     @type bool $use_fm_meta Optional. Should this context store its data
 92      *                             using FM term meta (true, deprecated) or
 93      *                             WordPress core term meta (false). Defaults to
 94      *                             false.
 95      *     @type Fieldmanager_Field $field Optional. The field to which to
 96      *                                     attach this context.
 97      * }
 98      * @param string|array $taxonomies Optional. Deprecated. Required if $args
 99      *                                 is a string.
100      * @param boolean $show_on_add Optional. Deprecated.
101      * @param boolean $show_on_edit Optional. Deprecated.
102      * @param string $parent Optional. Deprecated.
103      * @param Fieldmanager_Field $fm Optional. Deprecated.
104      */
105     public function __construct( $args, $taxonomies = array(), $show_on_add = true, $show_on_edit = true, $parent = '', $fm = null ) {
106         if ( is_array( $args ) ) {
107             $args = wp_parse_args( $args, array(
108                 'show_on_add'  => true,
109                 'show_on_edit' => true,
110                 'parent'       => '',
111                 'use_fm_meta'  => false,
112                 'field'        => null,
113             ) );
114             if ( ! isset( $args['title'], $args['taxonomies'] ) ) {
115                 throw new FM_Developer_Exception( esc_html__( '"title" and "taxonomies" are required values for Fieldmanager_Context_Term', 'fieldmanager' ) );
116             }
117 
118             $this->title        = $args['title'];
119             $this->taxonomies   = (array) $args['taxonomies'];
120             $this->show_on_add  = $args['show_on_add'];
121             $this->show_on_edit = $args['show_on_edit'];
122             $this->parent       = $args['parent'];
123             $this->use_fm_meta  = $args['use_fm_meta'];
124             $this->fm           = $args['field'];
125         } elseif ( empty( $taxonomies ) ) {
126             throw new FM_Developer_Exception( esc_html__( '"title" and "taxonomies" are required values for Fieldmanager_Context_Term', 'fieldmanager' ) );
127         } else {
128             // Instantiating Fieldmanager_Context_Term using individual
129             // arguments is deprecated as of Fieldmanager-1.0.0-beta.3; you
130             // should pass an array of arguments instead.
131 
132             // Set the class variables
133             $this->title        = $args;
134             $this->taxonomies   = (array) $taxonomies;
135             $this->show_on_add  = $show_on_add;
136             $this->show_on_edit = $show_on_edit;
137             $this->parent       = $parent;
138             $this->use_fm_meta  = true;
139             $this->fm           = $fm;
140         }
141 
142         // Iterate through the taxonomies and add the fields to the requested forms
143         // Also add handlers for saving the fields and which forms to validate (if enabled)
144         foreach ( $this->taxonomies as $taxonomy ) {
145             if ( $this->show_on_add ) {
146                 add_action( $taxonomy . '_add_form_fields', array( $this, 'add_term_fields' ), 10, 1 );
147                 add_action( 'created_term', array( $this, 'save_term_fields'), 10, 3 );
148             }
149 
150             if ( $this->show_on_edit ) {
151                 add_action( $taxonomy . '_edit_form_fields', array( $this, 'edit_term_fields' ), 10, 2 );
152                 add_action( 'edited_term', array( $this, 'save_term_fields'), 10, 3 );
153             }
154 
155             if ( $this->use_fm_meta ) {
156                 // Handle removing FM term meta when a term is deleted
157                 add_action( 'delete_term', array( $this, 'delete_term_fields'), 10, 4 );
158             }
159         }
160     }
161 
162     /**
163      * Creates the HTML template for wrapping fields on the add term form and prints the field
164      * @access public
165      * @param string $taxonomy
166      * @return void
167      */
168     public function add_term_fields( $taxonomy ) {
169         // If the parent is set, do nothing because we don't know what the parent term is yet
170         if ( ! empty( $this->parent ) ) {
171             return;
172         }
173 
174         // Create the HTML template for output
175         $html_template = '<div class="form-field">%s%s</div>';
176 
177         // Check if any validation is required
178         $fm_validation = Fieldmanager_Util_Validation( 'addtag', 'term' );
179         $fm_validation->add_field( $this->fm );
180 
181         // Display the field
182         echo $this->term_fields( $html_template, $taxonomy );
183     }
184 
185     /**
186      * Creates the HTML template for wrapping fields on the edit term form and prints the field
187      * @access public
188      * @param WP_Term $tag
189      * @param string $taxonomy
190      * @return void
191      */
192     public function edit_term_fields( $term, $taxonomy ) {
193         // Check if this term's parent matches the specified term if it is set
194         if ( ! empty( $this->parent ) && $this->parent != $term->parent ) {
195             return;
196         }
197 
198         // Create the HTML template for output
199         $html_template = '<tr class="form-field"><th scope="row" valign="top">%s</th><td>%s</td></tr>';
200 
201         // Check if any validation is required
202         $fm_validation = Fieldmanager_Util_Validation( 'edittag', 'term' );
203         $fm_validation->add_field( $this->fm );
204 
205         // Display the field
206         echo $this->term_fields( $html_template, $taxonomy, $term );
207     }
208 
209     /**
210      * Generates HTML for the term field
211      * @access public
212      * @param string $html_template THe HTML used to wrap the field
213      * @param string $taxonomy
214      * @param WP_Term $term
215      * @return string The element markup
216      */
217     public function term_fields( $html_template, $taxonomy, $term = null ) {
218         // Make sure the user hasn't specified a field name we can't use
219         if ( in_array( $this->fm->name, $this->reserved_fields ) ) {
220             $this->fm->_invalid_definition( sprintf( __( 'The field name "%s" is reserved for WordPress on the term form.', 'fieldmanager' ), $this->fm->name ) );
221         }
222 
223         // Set the data type and ID
224         $this->fm->data_type = 'term';
225         $this->fm->data_id = is_object( $term ) ? $term->term_id : null;
226         $this->current_taxonomy = $taxonomy;
227 
228         // Create the display label if one is set
229         if ( ! empty( $this->title ) ) {
230             $label = sprintf(
231                 '<label for="%s">%s</label>',
232                 esc_attr( $this->fm->name ),
233                 esc_html( $this->title )
234             );
235         } else {
236             $label = '';
237         }
238 
239         $field = $this->render_field( array( 'echo' => false ) );
240 
241         // Create the markup and return it
242         return sprintf(
243             $html_template,
244             $label,
245             $field
246         );
247     }
248 
249     /**
250      * Saves custom term fields
251      * @access public
252      * @param int $term_id
253      * @param int $tt_id
254      * @param string $taxonomy
255      * @return void
256      */
257     public function save_term_fields( $term_id, $tt_id, $taxonomy ) {
258         // Make sure this field is attached to the taxonomy being saved and this is the appropriate action
259         if ( ! in_array( $taxonomy, $this->taxonomies ) ) {
260             return;
261         }
262 
263         // Make sure that our nonce field arrived intact
264         if ( ! $this->is_valid_nonce() ) {
265             return;
266         }
267 
268         // Make sure the current user can save this post
269         $tax_obj = get_taxonomy( $taxonomy );
270         if ( ! current_user_can( $tax_obj->cap->manage_terms ) ) {
271             $this->fm->_unauthorized_access( __( 'User cannot edit this term', 'fieldmanager' ) );
272             return;
273         }
274 
275         // Save the data
276         $this->save_to_term_meta( $term_id, $taxonomy );
277     }
278 
279     /**
280      * Helper to save an array of data to term meta
281      * @param int $term_id
282      * @param array $data
283      * @return void
284      */
285     public function save_to_term_meta( $term_id, $taxonomy, $data = null ) {
286         // Set the data ID and type
287         $this->fm->data_id = $term_id;
288         $this->fm->data_type = 'term';
289         $this->current_taxonomy = $taxonomy;
290 
291         $this->save( $data );
292     }
293 
294     /**
295      * Saves custom fields for the sport taxonomy.
296      *
297      * @deprecated Fieldmanager-1.0.0-beta.3 This is not necessary if you're
298      *                                       using core's term meta.
299      *
300      * @access public
301      *
302      * @param int $term_id
303      * @param int $tt_id
304      * @param string $taxonomy
305      * @param WP_term $deleted_term
306      */
307     public function delete_term_fields( $term_id, $tt_id, $taxonomy, $deleted_term ) {
308         // Get an instance of the term meta class
309         $term_meta = Fieldmanager_Util_Term_Meta();
310 
311         // Delete any instance of this field for the term that was deleted
312         $term_meta->delete_term_meta( $term_id, $taxonomy, $this->fm->name );
313     }
314 
315     /**
316      * Callback to get term meta for the given term ID and current taxonomy.
317      *
318      * @see get_term_meta().
319      * @see Fieldmanager_Util_Term_Meta::get_term_meta() (Deprecated).
320      */
321     protected function get_data( $term_id, $meta_key, $single = false ) {
322         if ( $this->use_fm_meta ) {
323             return fm_get_term_meta( $term_id, $this->current_taxonomy, $meta_key, $single );
324         } else {
325             return get_term_meta( $term_id, $meta_key, $single );
326         }
327     }
328 
329     /**
330      * Callback to add term meta for the given term ID and current taxonomy.
331      *
332      * @see add_term_meta().
333      * @see Fieldmanager_Util_Term_Meta::add_term_meta() (Deprecated).
334      */
335     protected function add_data( $term_id, $meta_key, $meta_value, $unique = false ) {
336         if ( $this->use_fm_meta ) {
337             return fm_add_term_meta( $term_id, $this->current_taxonomy, $meta_key, $meta_value, $unique );
338         } else {
339             return add_term_meta( $term_id, $meta_key, $meta_value, $unique );
340         }
341     }
342 
343     /**
344      * Callback to update term meta for the given term ID and current taxonomy.
345      *
346      * @see update_term_meta().
347      * @see Fieldmanager_Util_Term_Meta::update_term_meta() (Deprecated).
348      */
349     protected function update_data( $term_id, $meta_key, $meta_value, $meta_prev_value = '' ) {
350         if ( $this->use_fm_meta ) {
351             return fm_update_term_meta( $term_id, $this->current_taxonomy, $meta_key, $meta_value, $meta_prev_value );
352         } else {
353             return update_term_meta( $term_id, $meta_key, $meta_value, $meta_prev_value );
354         }
355     }
356 
357     /**
358      * Callback to delete term meta for the given term ID and current taxonomy.
359      *
360      * @see delete_term_meta().
361      * @see Fieldmanager_Util_Term_Meta::delete_term_meta() (Deprecated).
362      */
363     protected function delete_data( $term_id, $meta_key, $meta_value = '' ) {
364         if ( $this->use_fm_meta ) {
365             return fm_delete_term_meta( $term_id, $this->current_taxonomy, $meta_key, $meta_value );
366         } else {
367             return delete_term_meta( $term_id, $meta_key, $meta_value );
368         }
369     }
370 
371 }
372 
Fieldmanager API documentation generated by ApiGen 2.8.0