<?php
class acf_field_taxonomy extends acf_field
{
function __construct()
{
$this->name = 'taxonomy';
$this->label = __("Taxonomy", 'acf');
$this->category = __("Relational", 'acf');
$this->defaults = array(
'taxonomy' => 'category',
'field_type' => 'checkbox',
'allow_null' => 0,
'load_save_terms' => 0,
'multiple' => 0,
'return_format' => 'id'
);
parent::__construct();
}
function get_terms( $value, $taxonomy = 'category' ) {
if( count($value) > 1 ) {
$terms = get_terms($taxonomy, array(
'hide_empty' => false,
'include' => $value,
));
}
foreach( array_keys($value) as $i ) {
$value[ $i ] = get_term( $value[ $i ], $taxonomy );
}
$value = array_filter($value);
return $value;
}
function load_value( $value, $post_id, $field ) {
$value = acf_get_valid_terms($value, $field['taxonomy']);
if( $field['load_save_terms'] ) {
if( empty($value) ) {
return $value;
}
$term_ids = wp_get_object_terms($post_id, $field['taxonomy'], array('fields' => 'ids', 'orderby' => 'none'));
if( empty($term_ids) ) {
return null;
} elseif( is_array($value) ) {
$value = array_map('intval', $value);
$value = array_intersect( $value, $term_ids );
} elseif( !in_array($value, $term_ids)) {
return null;
}
}
return $value;
}
function update_value( $value, $post_id, $field ) {
if( is_array($value) ) {
$value = array_filter($value);
}
if( $field['load_save_terms'] ) {
$taxonomy = $field['taxonomy'];
$term_ids = acf_force_type_array( $value );
$term_ids = array_map('intval', $term_ids);
if( !did_action('acf/save_post') ) {
wp_set_object_terms( $post_id, $term_ids, $taxonomy, false );
return $value;
}
if( empty($this->set_terms) ) {
$this->set_terms = array();
add_action('acf/save_post', array($this, 'set_terms'), 15, 1);
}
if( empty($this->set_terms[ $taxonomy ]) ) {
$this->set_terms[ $taxonomy ] = array();
}
$this->set_terms[ $taxonomy ] = array_merge($this->set_terms[ $taxonomy ], $term_ids);
}
return $value;
}
function set_terms( $post_id ) {
if( empty($this->set_terms) ) {
return;
}
foreach( $this->set_terms as $taxonomy => $term_ids ) {
wp_set_object_terms( $post_id, $term_ids, $taxonomy, false );
}
$this->set_terms = array();
}
function format_value_for_api( $value, $post_id, $field ) {
if( empty($value) ) {
return $value;
}
$value = acf_force_type_array( $value );
$value = array_map('intval', $value);
if( $field['return_format'] == 'object' ) {
$value = $this->get_terms( $value, $field["taxonomy"] );
}
if( $field['field_type'] == 'select' || $field['field_type'] == 'radio' ) {
$value = array_shift($value);
}
return $value;
}
function create_field( $field )
{
$single_name = $field['name'];
if( $field['field_type'] == 'multi_select' )
{
$field['multiple'] = 1;
$field['field_type'] = 'select';
$field['name'] .= '[]';
}
elseif( $field['field_type'] == 'checkbox' )
{
$field['name'] .= '[]';
}
if( !is_array($field['value']) )
{
$field['value'] = array( $field['value'] );
}
$args = array(
'taxonomy' => $field['taxonomy'],
'hide_empty' => false,
'style' => 'none',
'walker' => new acf_taxonomy_field_walker( $field ),
);
$args = apply_filters('acf/fields/taxonomy/wp_list_categories', $args, $field );
?>
<div class="acf-taxonomy-field" data-load_save="<?php echo $field['load_save_terms']; ?>">
<input type="hidden" name="<?php echo $single_name; ?>" value="" />
<?php if( $field['field_type'] == 'select' ): ?>
<select id="<?php echo $field['id']; ?>" name="<?php echo $field['name']; ?>" <?php if( $field['multiple'] ): ?>multiple="multiple" size="5"<?php endif; ?>>
<?php if( $field['allow_null'] ): ?>
<option value=""><?php _e("None", 'acf'); ?></option>
<?php endif; ?>
<?php else: ?>
<div class="categorychecklist-holder">
<ul class="acf-checkbox-list">
<?php if( $field['allow_null'] ): ?>
<li>
<label class="selectit">
<input type="<?php echo $field['field_type']; ?>" name="<?php echo $field['name']; ?>" value="" /> <?php _e("None", 'acf'); ?>
</label>
</li>
<?php endif; ?>
<?php endif; ?>
<?php wp_list_categories( $args ); ?>
<?php if( $field['field_type'] == 'select' ): ?>
</select>
<?php else: ?>
</ul>
</div>
<?php endif; ?>
</div>
<?php
}
function create_options( $field )
{
$key = $field['name'];
?>
<tr class="field_option field_option_<?php echo $this->name; ?>">
<td class="label">
<label><?php _e("Taxonomy", 'acf'); ?></label>
</td>
<td>
<?php
$choices = array();
$taxonomies = get_taxonomies( array(), 'objects' );
$ignore = array( 'post_format', 'nav_menu', 'link_category' );
foreach( $taxonomies as $taxonomy )
{
if( in_array($taxonomy->name, $ignore) )
{
continue;
}
$choices[ $taxonomy->name ] = $taxonomy->name;
}
do_action('acf/create_field', array(
'type' => 'select',
'name' => 'fields['.$key.'][taxonomy]',
'value' => $field['taxonomy'],
'choices' => $choices,
));
?>
</td>
</tr>
<tr class="field_option field_option_<?php echo $this->name; ?>">
<td class="label">
<label><?php _e("Field Type", 'acf'); ?></label>
</td>
<td>
<?php
do_action('acf/create_field', array(
'type' => 'select',
'name' => 'fields['.$key.'][field_type]',
'value' => $field['field_type'],
'optgroup' => true,
'choices' => array(
__("Multiple Values", 'acf') => array(
'checkbox' => __('Checkbox', 'acf'),
'multi_select' => __('Multi Select', 'acf')
),
__("Single Value", 'acf') => array(
'radio' => __('Radio Buttons', 'acf'),
'select' => __('Select', 'acf')
)
)
));
?>
</td>
</tr>
<tr class="field_option field_option_<?php echo $this->name; ?>">
<td class="label">
<label><?php _e("Allow Null?", 'acf'); ?></label>
</td>
<td>
<?php
do_action('acf/create_field', array(
'type' => 'radio',
'name' => 'fields['.$key.'][allow_null]',
'value' => $field['allow_null'],
'choices' => array(
1 => __("Yes", 'acf'),
0 => __("No", 'acf'),
),
'layout' => 'horizontal',
));
?>
</td>
</tr>
<tr class="field_option field_option_<?php echo $this->name; ?>">
<td class="label">
<label><?php _e("Load & Save Terms to Post", 'acf'); ?></label>
</td>
<td>
<?php
do_action('acf/create_field', array(
'type' => 'true_false',
'name' => 'fields['.$key.'][load_save_terms]',
'value' => $field['load_save_terms'],
'message' => __("Load value based on the post's terms and update the post's terms on save", 'acf')
));
?>
</td>
</tr>
<tr class="field_option field_option_<?php echo $this->name; ?>">
<td class="label">
<label><?php _e("Return Value", 'acf'); ?></label>
</td>
<td>
<?php
do_action('acf/create_field', array(
'type' => 'radio',
'name' => 'fields['.$key.'][return_format]',
'value' => $field['return_format'],
'layout' => 'horizontal',
'choices' => array(
'object' => __("Term Object", 'acf'),
'id' => __("Term ID", 'acf')
)
));
?>
</td>
</tr>
<?php
}
}
new acf_field_taxonomy();
class acf_taxonomy_field_walker extends Walker
{
var $field = null,
$tree_type = 'category',
$db_fields = array ( 'parent' => 'parent', 'id' => 'term_id' );
function __construct( $field )
{
$this->field = $field;
}
function start_el( &$output, $term, $depth = 0, $args = array(), $current_object_id = 0)
{
$selected = in_array( $term->term_id, $this->field['value'] );
if( $this->field['field_type'] == 'checkbox' )
{
$output .= '<li><label class="selectit"><input type="checkbox" name="' . $this->field['name'] . '" value="' . $term->term_id . '" ' . ($selected ? 'checked="checked"' : '') . ' /> ' . $term->name . '</label>';
}
elseif( $this->field['field_type'] == 'radio' )
{
$output .= '<li><label class="selectit"><input type="radio" name="' . $this->field['name'] . '" value="' . $term->term_id . '" ' . ($selected ? 'checked="checkbox"' : '') . ' /> ' . $term->name . '</label>';
}
elseif( $this->field['field_type'] == 'select' )
{
$indent = str_repeat("— ", $depth);
$output .= '<option value="' . $term->term_id . '" ' . ($selected ? 'selected="selected"' : '') . '>' . $indent . $term->name . '</option>';
}
}
function end_el( &$output, $term, $depth = 0, $args = array() )
{
if( in_array($this->field['field_type'], array('checkbox', 'radio')) )
{
$output .= '</li>';
}
$output .= "\n";
}
function start_lvl( &$output, $depth = 0, $args = array() )
{
if( in_array($this->field['field_type'], array('checkbox', 'radio')) )
{
$output .= '<ul class="children">' . "\n";
}
}
function end_lvl( &$output, $depth = 0, $args = array() )
{
if( in_array($this->field['field_type'], array('checkbox', 'radio')) )
{
$output .= '</ul>' . "\n";
}
}
}
?>