<?php
add_filter( 'get_terms', __NAMESPACE__ . '\add_descriptions_to_tag_search', 10, 4 );
add_filter( 'get_terms_args', __NAMESPACE__ . '\get_terms_args', 10, 2 );
add_action( 'pre_post_tax_input', __NAMESPACE__ . '\pre_post_tax_input', 10, 2 );

/**
 * Change the tags from being just the tag name to id + name + description.
 * Must be used with the get_terms_args filter.
 *
 * @param $terms
 * @param $taxonomies
 * @param $args
 * @param $term_query
 *
 * @return array of strings for dropdown.
 */
function add_descriptions_to_tag_search( $terms, $taxonomies, $args, $term_query) {
    if ( ! ( is_tag_search() && 'post_tag' === $taxonomies[0] ) ) {
        return $terms;
    }

    $term_strings = array();
    foreach( $terms as $term ) {
        $term_string = "<span style='display:none;'>$term->term_id:</span><strong>$term->name </strong>";
        if ( $term->description ) {
             $term_string .= "<br /><em>$term->description</em>";
        }

        $term_strings[] = $term_string;
    }
}

/**
 * For a tag search post_tag get_terms call, override the behaviour from $args['fields'] = 'name' to 'all',
 * must be combined with @see add_descriptions_to_tag_search() above to work correctly.
 * @param $args
 * @param $taxonomies
 *
 * @return mixed
 */
function get_terms_args( $args, $taxonomies ) {
    if ( ! ( is_tag_search() && 'post_tag' === $taxonomies[0] ) ) {
        return $args;
    }
    $args['fields'] = 'all';
    return $args;
}

function pre_post_tax_input( $tax_input ) {
    if ( defined( 'DOING_CRON' ) || ( defined('WP_CLI') && WP_CLI ) ) {
        return;
    }


    if ( isset( $tax_input['post_tag'] ) ) {
        $incoming_terms = $tax_input['post_tag'];

        foreach ( $incoming_terms as $term ) {
            // If the term already exists, WP sends just the ID. If it is new, the term name is passed.
            if ( ! is_int( $term ) ) {
                $tag_id = absint( strtok( $term, ':') );
                if ( 0 !== $tag_id ) {
                    $updated_terms[] = $tag_id; // We just use the ID from the tag dropdown
                } else {
                    $updated_terms[] = $term; // For anywhere we haven't overriddent the default behaviour.
                }
            } else {
                $updated_terms[] = $term;
            }
        }

        $tax_input['post_tag'] = $updated_terms;
    }

    return $tax_input;
}
