get_compat_media_markup

The timeline below displays how wordpress function get_compat_media_markup has changed across different WordPress versions. If a version is not listed, refer to the next available version below.

WordPress Version: 6.1

/**
 * @since 3.5.0
 *
 * @param int   $attachment_id
 * @param array $args
 * @return array
 */
function get_compat_media_markup($attachment_id, $args = null)
{
    $post = get_post($attachment_id);
    $default_args = array('errors' => null, 'in_modal' => false);
    $user_can_edit = current_user_can('edit_post', $attachment_id);
    $args = wp_parse_args($args, $default_args);
    /** This filter is documented in wp-admin/includes/media.php */
    $args = apply_filters('get_media_item_args', $args);
    $form_fields = array();
    if ($args['in_modal']) {
        foreach (get_attachment_taxonomies($post) as $taxonomy) {
            $t = (array) get_taxonomy($taxonomy);
            if (!$t['public'] || !$t['show_ui']) {
                continue;
            }
            if (empty($t['label'])) {
                $t['label'] = $taxonomy;
            }
            if (empty($t['args'])) {
                $t['args'] = array();
            }
            $terms = get_object_term_cache($post->ID, $taxonomy);
            if (false === $terms) {
                $terms = wp_get_object_terms($post->ID, $taxonomy, $t['args']);
            }
            $values = array();
            foreach ($terms as $term) {
                $values[] = $term->slug;
            }
            $t['value'] = implode(', ', $values);
            $t['taxonomy'] = true;
            $form_fields[$taxonomy] = $t;
        }
    }
    /*
     * Merge default fields with their errors, so any key passed with the error
     * (e.g. 'error', 'helps', 'value') will replace the default.
     * The recursive merge is easily traversed with array casting:
     * foreach ( (array) $things as $thing )
     */
    $form_fields = array_merge_recursive($form_fields, (array) $args['errors']);
    /** This filter is documented in wp-admin/includes/media.php */
    $form_fields = apply_filters('attachment_fields_to_edit', $form_fields, $post);
    unset($form_fields['image-size'], $form_fields['align'], $form_fields['image_alt'], $form_fields['post_title'], $form_fields['post_excerpt'], $form_fields['post_content'], $form_fields['url'], $form_fields['menu_order'], $form_fields['image_url']);
    /** This filter is documented in wp-admin/includes/media.php */
    $media_meta = apply_filters('media_meta', '', $post);
    $defaults = array('input' => 'text', 'required' => false, 'value' => '', 'extra_rows' => array(), 'show_in_edit' => true, 'show_in_modal' => true);
    $hidden_fields = array();
    $item = '';
    foreach ($form_fields as $id => $field) {
        if ('_' === $id[0]) {
            continue;
        }
        $name = "attachments[{$attachment_id}][{$id}]";
        $id_attr = "attachments-{$attachment_id}-{$id}";
        if (!empty($field['tr'])) {
            $item .= $field['tr'];
            continue;
        }
        $field = array_merge($defaults, $field);
        if (!$field['show_in_edit'] && !$args['in_modal'] || !$field['show_in_modal'] && $args['in_modal']) {
            continue;
        }
        if ('hidden' === $field['input']) {
            $hidden_fields[$name] = $field['value'];
            continue;
        }
        $readonly = (!$user_can_edit && !empty($field['taxonomy'])) ? " readonly='readonly' " : '';
        $required = $field['required'] ? ' ' . wp_required_field_indicator() : '';
        $required_attr = $field['required'] ? ' required' : '';
        $class = 'compat-field-' . $id;
        $class .= $field['required'] ? ' form-required' : '';
        $item .= "\t\t<tr class='{$class}'>";
        $item .= "\t\t\t<th scope='row' class='label'><label for='{$id_attr}'><span class='alignleft'>{$field['label']}</span>{$required}<br class='clear' /></label>";
        $item .= "</th>\n\t\t\t<td class='field'>";
        if (!empty($field[$field['input']])) {
            $item .= $field[$field['input']];
        } elseif ('textarea' === $field['input']) {
            if ('post_content' === $id && user_can_richedit()) {
                // sanitize_post() skips the post_content when user_can_richedit.
                $field['value'] = htmlspecialchars($field['value'], ENT_QUOTES);
            }
            $item .= "<textarea id='{$id_attr}' name='{$name}'{$required_attr}>" . $field['value'] . '</textarea>';
        } else {
            $item .= "<input type='text' class='text' id='{$id_attr}' name='{$name}' value='" . esc_attr($field['value']) . "' {$readonly}{$required_attr} />";
        }
        if (!empty($field['helps'])) {
            $item .= "<p class='help'>" . implode("</p>\n<p class='help'>", array_unique((array) $field['helps'])) . '</p>';
        }
        $item .= "</td>\n\t\t</tr>\n";
        $extra_rows = array();
        if (!empty($field['errors'])) {
            foreach (array_unique((array) $field['errors']) as $error) {
                $extra_rows['error'][] = $error;
            }
        }
        if (!empty($field['extra_rows'])) {
            foreach ($field['extra_rows'] as $class => $rows) {
                foreach ((array) $rows as $html) {
                    $extra_rows[$class][] = $html;
                }
            }
        }
        foreach ($extra_rows as $class => $rows) {
            foreach ($rows as $html) {
                $item .= "\t\t<tr><td></td><td class='{$class}'>{$html}</td></tr>\n";
            }
        }
    }
    if (!empty($form_fields['_final'])) {
        $item .= "\t\t<tr class='final'><td colspan='2'>{$form_fields['_final']}</td></tr>\n";
    }
    if ($item) {
        $item = '<p class="media-types media-types-required-info">' . wp_required_field_message() . '</p>' . '<table class="compat-attachment-fields">' . $item . '</table>';
    }
    foreach ($hidden_fields as $hidden_field => $value) {
        $item .= '<input type="hidden" name="' . esc_attr($hidden_field) . '" value="' . esc_attr($value) . '" />' . "\n";
    }
    if ($item) {
        $item = '<input type="hidden" name="attachments[' . $attachment_id . '][menu_order]" value="' . esc_attr($post->menu_order) . '" />' . $item;
    }
    return array('item' => $item, 'meta' => $media_meta);
}

WordPress Version: 5.6

/**
 * @since 3.5.0
 *
 * @param int   $attachment_id
 * @param array $args
 * @return array
 */
function get_compat_media_markup($attachment_id, $args = null)
{
    $post = get_post($attachment_id);
    $default_args = array('errors' => null, 'in_modal' => false);
    $user_can_edit = current_user_can('edit_post', $attachment_id);
    $args = wp_parse_args($args, $default_args);
    /** This filter is documented in wp-admin/includes/media.php */
    $args = apply_filters('get_media_item_args', $args);
    $form_fields = array();
    if ($args['in_modal']) {
        foreach (get_attachment_taxonomies($post) as $taxonomy) {
            $t = (array) get_taxonomy($taxonomy);
            if (!$t['public'] || !$t['show_ui']) {
                continue;
            }
            if (empty($t['label'])) {
                $t['label'] = $taxonomy;
            }
            if (empty($t['args'])) {
                $t['args'] = array();
            }
            $terms = get_object_term_cache($post->ID, $taxonomy);
            if (false === $terms) {
                $terms = wp_get_object_terms($post->ID, $taxonomy, $t['args']);
            }
            $values = array();
            foreach ($terms as $term) {
                $values[] = $term->slug;
            }
            $t['value'] = implode(', ', $values);
            $t['taxonomy'] = true;
            $form_fields[$taxonomy] = $t;
        }
    }
    /*
     * Merge default fields with their errors, so any key passed with the error
     * (e.g. 'error', 'helps', 'value') will replace the default.
     * The recursive merge is easily traversed with array casting:
     * foreach ( (array) $things as $thing )
     */
    $form_fields = array_merge_recursive($form_fields, (array) $args['errors']);
    /** This filter is documented in wp-admin/includes/media.php */
    $form_fields = apply_filters('attachment_fields_to_edit', $form_fields, $post);
    unset($form_fields['image-size'], $form_fields['align'], $form_fields['image_alt'], $form_fields['post_title'], $form_fields['post_excerpt'], $form_fields['post_content'], $form_fields['url'], $form_fields['menu_order'], $form_fields['image_url']);
    /** This filter is documented in wp-admin/includes/media.php */
    $media_meta = apply_filters('media_meta', '', $post);
    $defaults = array('input' => 'text', 'required' => false, 'value' => '', 'extra_rows' => array(), 'show_in_edit' => true, 'show_in_modal' => true);
    $hidden_fields = array();
    $item = '';
    foreach ($form_fields as $id => $field) {
        if ('_' === $id[0]) {
            continue;
        }
        $name = "attachments[{$attachment_id}][{$id}]";
        $id_attr = "attachments-{$attachment_id}-{$id}";
        if (!empty($field['tr'])) {
            $item .= $field['tr'];
            continue;
        }
        $field = array_merge($defaults, $field);
        if (!$field['show_in_edit'] && !$args['in_modal'] || !$field['show_in_modal'] && $args['in_modal']) {
            continue;
        }
        if ('hidden' === $field['input']) {
            $hidden_fields[$name] = $field['value'];
            continue;
        }
        $readonly = (!$user_can_edit && !empty($field['taxonomy'])) ? " readonly='readonly' " : '';
        $required = $field['required'] ? '<span class="required">*</span>' : '';
        $required_attr = $field['required'] ? ' required' : '';
        $class = 'compat-field-' . $id;
        $class .= $field['required'] ? ' form-required' : '';
        $item .= "\t\t<tr class='{$class}'>";
        $item .= "\t\t\t<th scope='row' class='label'><label for='{$id_attr}'><span class='alignleft'>{$field['label']}</span>{$required}<br class='clear' /></label>";
        $item .= "</th>\n\t\t\t<td class='field'>";
        if (!empty($field[$field['input']])) {
            $item .= $field[$field['input']];
        } elseif ('textarea' === $field['input']) {
            if ('post_content' === $id && user_can_richedit()) {
                // sanitize_post() skips the post_content when user_can_richedit.
                $field['value'] = htmlspecialchars($field['value'], ENT_QUOTES);
            }
            $item .= "<textarea id='{$id_attr}' name='{$name}'{$required_attr}>" . $field['value'] . '</textarea>';
        } else {
            $item .= "<input type='text' class='text' id='{$id_attr}' name='{$name}' value='" . esc_attr($field['value']) . "' {$readonly}{$required_attr} />";
        }
        if (!empty($field['helps'])) {
            $item .= "<p class='help'>" . implode("</p>\n<p class='help'>", array_unique((array) $field['helps'])) . '</p>';
        }
        $item .= "</td>\n\t\t</tr>\n";
        $extra_rows = array();
        if (!empty($field['errors'])) {
            foreach (array_unique((array) $field['errors']) as $error) {
                $extra_rows['error'][] = $error;
            }
        }
        if (!empty($field['extra_rows'])) {
            foreach ($field['extra_rows'] as $class => $rows) {
                foreach ((array) $rows as $html) {
                    $extra_rows[$class][] = $html;
                }
            }
        }
        foreach ($extra_rows as $class => $rows) {
            foreach ($rows as $html) {
                $item .= "\t\t<tr><td></td><td class='{$class}'>{$html}</td></tr>\n";
            }
        }
    }
    if (!empty($form_fields['_final'])) {
        $item .= "\t\t<tr class='final'><td colspan='2'>{$form_fields['_final']}</td></tr>\n";
    }
    if ($item) {
        $item = '<p class="media-types media-types-required-info">' . sprintf(__('Required fields are marked %s'), '<span class="required">*</span>') . '</p>' . '<table class="compat-attachment-fields">' . $item . '</table>';
    }
    foreach ($hidden_fields as $hidden_field => $value) {
        $item .= '<input type="hidden" name="' . esc_attr($hidden_field) . '" value="' . esc_attr($value) . '" />' . "\n";
    }
    if ($item) {
        $item = '<input type="hidden" name="attachments[' . $attachment_id . '][menu_order]" value="' . esc_attr($post->menu_order) . '" />' . $item;
    }
    return array('item' => $item, 'meta' => $media_meta);
}

WordPress Version: 5.5

/**
 * @since 3.5.0
 *
 * @param int   $attachment_id
 * @param array $args
 * @return array
 */
function get_compat_media_markup($attachment_id, $args = null)
{
    $post = get_post($attachment_id);
    $default_args = array('errors' => null, 'in_modal' => false);
    $user_can_edit = current_user_can('edit_post', $attachment_id);
    $args = wp_parse_args($args, $default_args);
    /** This filter is documented in wp-admin/includes/media.php */
    $args = apply_filters('get_media_item_args', $args);
    $form_fields = array();
    if ($args['in_modal']) {
        foreach (get_attachment_taxonomies($post) as $taxonomy) {
            $t = (array) get_taxonomy($taxonomy);
            if (!$t['public'] || !$t['show_ui']) {
                continue;
            }
            if (empty($t['label'])) {
                $t['label'] = $taxonomy;
            }
            if (empty($t['args'])) {
                $t['args'] = array();
            }
            $terms = get_object_term_cache($post->ID, $taxonomy);
            if (false === $terms) {
                $terms = wp_get_object_terms($post->ID, $taxonomy, $t['args']);
            }
            $values = array();
            foreach ($terms as $term) {
                $values[] = $term->slug;
            }
            $t['value'] = join(', ', $values);
            $t['taxonomy'] = true;
            $form_fields[$taxonomy] = $t;
        }
    }
    /*
     * Merge default fields with their errors, so any key passed with the error
     * (e.g. 'error', 'helps', 'value') will replace the default.
     * The recursive merge is easily traversed with array casting:
     * foreach ( (array) $things as $thing )
     */
    $form_fields = array_merge_recursive($form_fields, (array) $args['errors']);
    /** This filter is documented in wp-admin/includes/media.php */
    $form_fields = apply_filters('attachment_fields_to_edit', $form_fields, $post);
    unset($form_fields['image-size'], $form_fields['align'], $form_fields['image_alt'], $form_fields['post_title'], $form_fields['post_excerpt'], $form_fields['post_content'], $form_fields['url'], $form_fields['menu_order'], $form_fields['image_url']);
    /** This filter is documented in wp-admin/includes/media.php */
    $media_meta = apply_filters('media_meta', '', $post);
    $defaults = array('input' => 'text', 'required' => false, 'value' => '', 'extra_rows' => array(), 'show_in_edit' => true, 'show_in_modal' => true);
    $hidden_fields = array();
    $item = '';
    foreach ($form_fields as $id => $field) {
        if ('_' === $id[0]) {
            continue;
        }
        $name = "attachments[{$attachment_id}][{$id}]";
        $id_attr = "attachments-{$attachment_id}-{$id}";
        if (!empty($field['tr'])) {
            $item .= $field['tr'];
            continue;
        }
        $field = array_merge($defaults, $field);
        if (!$field['show_in_edit'] && !$args['in_modal'] || !$field['show_in_modal'] && $args['in_modal']) {
            continue;
        }
        if ('hidden' === $field['input']) {
            $hidden_fields[$name] = $field['value'];
            continue;
        }
        $readonly = (!$user_can_edit && !empty($field['taxonomy'])) ? " readonly='readonly' " : '';
        $required = $field['required'] ? '<span class="required">*</span>' : '';
        $required_attr = $field['required'] ? ' required' : '';
        $class = 'compat-field-' . $id;
        $class .= $field['required'] ? ' form-required' : '';
        $item .= "\t\t<tr class='{$class}'>";
        $item .= "\t\t\t<th scope='row' class='label'><label for='{$id_attr}'><span class='alignleft'>{$field['label']}</span>{$required}<br class='clear' /></label>";
        $item .= "</th>\n\t\t\t<td class='field'>";
        if (!empty($field[$field['input']])) {
            $item .= $field[$field['input']];
        } elseif ('textarea' === $field['input']) {
            if ('post_content' === $id && user_can_richedit()) {
                // sanitize_post() skips the post_content when user_can_richedit.
                $field['value'] = htmlspecialchars($field['value'], ENT_QUOTES);
            }
            $item .= "<textarea id='{$id_attr}' name='{$name}'{$required_attr}>" . $field['value'] . '</textarea>';
        } else {
            $item .= "<input type='text' class='text' id='{$id_attr}' name='{$name}' value='" . esc_attr($field['value']) . "' {$readonly}{$required_attr} />";
        }
        if (!empty($field['helps'])) {
            $item .= "<p class='help'>" . join("</p>\n<p class='help'>", array_unique((array) $field['helps'])) . '</p>';
        }
        $item .= "</td>\n\t\t</tr>\n";
        $extra_rows = array();
        if (!empty($field['errors'])) {
            foreach (array_unique((array) $field['errors']) as $error) {
                $extra_rows['error'][] = $error;
            }
        }
        if (!empty($field['extra_rows'])) {
            foreach ($field['extra_rows'] as $class => $rows) {
                foreach ((array) $rows as $html) {
                    $extra_rows[$class][] = $html;
                }
            }
        }
        foreach ($extra_rows as $class => $rows) {
            foreach ($rows as $html) {
                $item .= "\t\t<tr><td></td><td class='{$class}'>{$html}</td></tr>\n";
            }
        }
    }
    if (!empty($form_fields['_final'])) {
        $item .= "\t\t<tr class='final'><td colspan='2'>{$form_fields['_final']}</td></tr>\n";
    }
    if ($item) {
        $item = '<p class="media-types media-types-required-info">' . sprintf(__('Required fields are marked %s'), '<span class="required">*</span>') . '</p>' . '<table class="compat-attachment-fields">' . $item . '</table>';
    }
    foreach ($hidden_fields as $hidden_field => $value) {
        $item .= '<input type="hidden" name="' . esc_attr($hidden_field) . '" value="' . esc_attr($value) . '" />' . "\n";
    }
    if ($item) {
        $item = '<input type="hidden" name="attachments[' . $attachment_id . '][menu_order]" value="' . esc_attr($post->menu_order) . '" />' . $item;
    }
    return array('item' => $item, 'meta' => $media_meta);
}

WordPress Version: 5.4

/**
 * @since 3.5.0
 *
 * @param int   $attachment_id
 * @param array $args
 * @return array
 */
function get_compat_media_markup($attachment_id, $args = null)
{
    $post = get_post($attachment_id);
    $default_args = array('errors' => null, 'in_modal' => false);
    $user_can_edit = current_user_can('edit_post', $attachment_id);
    $args = wp_parse_args($args, $default_args);
    /** This filter is documented in wp-admin/includes/media.php */
    $args = apply_filters('get_media_item_args', $args);
    $form_fields = array();
    if ($args['in_modal']) {
        foreach (get_attachment_taxonomies($post) as $taxonomy) {
            $t = (array) get_taxonomy($taxonomy);
            if (!$t['public'] || !$t['show_ui']) {
                continue;
            }
            if (empty($t['label'])) {
                $t['label'] = $taxonomy;
            }
            if (empty($t['args'])) {
                $t['args'] = array();
            }
            $terms = get_object_term_cache($post->ID, $taxonomy);
            if (false === $terms) {
                $terms = wp_get_object_terms($post->ID, $taxonomy, $t['args']);
            }
            $values = array();
            foreach ($terms as $term) {
                $values[] = $term->slug;
            }
            $t['value'] = join(', ', $values);
            $t['taxonomy'] = true;
            $form_fields[$taxonomy] = $t;
        }
    }
    /*
     * Merge default fields with their errors, so any key passed with the error
     * (e.g. 'error', 'helps', 'value') will replace the default.
     * The recursive merge is easily traversed with array casting:
     * foreach ( (array) $things as $thing )
     */
    $form_fields = array_merge_recursive($form_fields, (array) $args['errors']);
    /** This filter is documented in wp-admin/includes/media.php */
    $form_fields = apply_filters('attachment_fields_to_edit', $form_fields, $post);
    unset($form_fields['image-size'], $form_fields['align'], $form_fields['image_alt'], $form_fields['post_title'], $form_fields['post_excerpt'], $form_fields['post_content'], $form_fields['url'], $form_fields['menu_order'], $form_fields['image_url']);
    /** This filter is documented in wp-admin/includes/media.php */
    $media_meta = apply_filters('media_meta', '', $post);
    $defaults = array('input' => 'text', 'required' => false, 'value' => '', 'extra_rows' => array(), 'show_in_edit' => true, 'show_in_modal' => true);
    $hidden_fields = array();
    $item = '';
    foreach ($form_fields as $id => $field) {
        if ('_' === $id[0]) {
            continue;
        }
        $name = "attachments[{$attachment_id}][{$id}]";
        $id_attr = "attachments-{$attachment_id}-{$id}";
        if (!empty($field['tr'])) {
            $item .= $field['tr'];
            continue;
        }
        $field = array_merge($defaults, $field);
        if (!$field['show_in_edit'] && !$args['in_modal'] || !$field['show_in_modal'] && $args['in_modal']) {
            continue;
        }
        if ('hidden' === $field['input']) {
            $hidden_fields[$name] = $field['value'];
            continue;
        }
        $readonly = (!$user_can_edit && !empty($field['taxonomy'])) ? " readonly='readonly' " : '';
        $required = $field['required'] ? '<span class="required">*</span>' : '';
        $required_attr = $field['required'] ? ' required' : '';
        $class = 'compat-field-' . $id;
        $class .= $field['required'] ? ' form-required' : '';
        $item .= "\t\t<tr class='{$class}'>";
        $item .= "\t\t\t<th scope='row' class='label'><label for='{$id_attr}'><span class='alignleft'>{$field['label']}</span>{$required}<br class='clear' /></label>";
        $item .= "</th>\n\t\t\t<td class='field'>";
        if (!empty($field[$field['input']])) {
            $item .= $field[$field['input']];
        } elseif ('textarea' === $field['input']) {
            if ('post_content' == $id && user_can_richedit()) {
                // sanitize_post() skips the post_content when user_can_richedit.
                $field['value'] = htmlspecialchars($field['value'], ENT_QUOTES);
            }
            $item .= "<textarea id='{$id_attr}' name='{$name}'{$required_attr}>" . $field['value'] . '</textarea>';
        } else {
            $item .= "<input type='text' class='text' id='{$id_attr}' name='{$name}' value='" . esc_attr($field['value']) . "' {$readonly}{$required_attr} />";
        }
        if (!empty($field['helps'])) {
            $item .= "<p class='help'>" . join("</p>\n<p class='help'>", array_unique((array) $field['helps'])) . '</p>';
        }
        $item .= "</td>\n\t\t</tr>\n";
        $extra_rows = array();
        if (!empty($field['errors'])) {
            foreach (array_unique((array) $field['errors']) as $error) {
                $extra_rows['error'][] = $error;
            }
        }
        if (!empty($field['extra_rows'])) {
            foreach ($field['extra_rows'] as $class => $rows) {
                foreach ((array) $rows as $html) {
                    $extra_rows[$class][] = $html;
                }
            }
        }
        foreach ($extra_rows as $class => $rows) {
            foreach ($rows as $html) {
                $item .= "\t\t<tr><td></td><td class='{$class}'>{$html}</td></tr>\n";
            }
        }
    }
    if (!empty($form_fields['_final'])) {
        $item .= "\t\t<tr class='final'><td colspan='2'>{$form_fields['_final']}</td></tr>\n";
    }
    if ($item) {
        $item = '<p class="media-types media-types-required-info">' . sprintf(__('Required fields are marked %s'), '<span class="required">*</span>') . '</p>' . '<table class="compat-attachment-fields">' . $item . '</table>';
    }
    foreach ($hidden_fields as $hidden_field => $value) {
        $item .= '<input type="hidden" name="' . esc_attr($hidden_field) . '" value="' . esc_attr($value) . '" />' . "\n";
    }
    if ($item) {
        $item = '<input type="hidden" name="attachments[' . $attachment_id . '][menu_order]" value="' . esc_attr($post->menu_order) . '" />' . $item;
    }
    return array('item' => $item, 'meta' => $media_meta);
}

WordPress Version: 5.3

/**
 * @since 3.5.0
 *
 * @param int   $attachment_id
 * @param array $args
 * @return array
 */
function get_compat_media_markup($attachment_id, $args = null)
{
    $post = get_post($attachment_id);
    $default_args = array('errors' => null, 'in_modal' => false);
    $user_can_edit = current_user_can('edit_post', $attachment_id);
    $args = wp_parse_args($args, $default_args);
    /** This filter is documented in wp-admin/includes/media.php */
    $args = apply_filters('get_media_item_args', $args);
    $form_fields = array();
    if ($args['in_modal']) {
        foreach (get_attachment_taxonomies($post) as $taxonomy) {
            $t = (array) get_taxonomy($taxonomy);
            if (!$t['public'] || !$t['show_ui']) {
                continue;
            }
            if (empty($t['label'])) {
                $t['label'] = $taxonomy;
            }
            if (empty($t['args'])) {
                $t['args'] = array();
            }
            $terms = get_object_term_cache($post->ID, $taxonomy);
            if (false === $terms) {
                $terms = wp_get_object_terms($post->ID, $taxonomy, $t['args']);
            }
            $values = array();
            foreach ($terms as $term) {
                $values[] = $term->slug;
            }
            $t['value'] = join(', ', $values);
            $t['taxonomy'] = true;
            $form_fields[$taxonomy] = $t;
        }
    }
    // Merge default fields with their errors, so any key passed with the error (e.g. 'error', 'helps', 'value') will replace the default
    // The recursive merge is easily traversed with array casting: foreach ( (array) $things as $thing )
    $form_fields = array_merge_recursive($form_fields, (array) $args['errors']);
    /** This filter is documented in wp-admin/includes/media.php */
    $form_fields = apply_filters('attachment_fields_to_edit', $form_fields, $post);
    unset($form_fields['image-size'], $form_fields['align'], $form_fields['image_alt'], $form_fields['post_title'], $form_fields['post_excerpt'], $form_fields['post_content'], $form_fields['url'], $form_fields['menu_order'], $form_fields['image_url']);
    /** This filter is documented in wp-admin/includes/media.php */
    $media_meta = apply_filters('media_meta', '', $post);
    $defaults = array('input' => 'text', 'required' => false, 'value' => '', 'extra_rows' => array(), 'show_in_edit' => true, 'show_in_modal' => true);
    $hidden_fields = array();
    $item = '';
    foreach ($form_fields as $id => $field) {
        if ($id[0] == '_') {
            continue;
        }
        $name = "attachments[{$attachment_id}][{$id}]";
        $id_attr = "attachments-{$attachment_id}-{$id}";
        if (!empty($field['tr'])) {
            $item .= $field['tr'];
            continue;
        }
        $field = array_merge($defaults, $field);
        if (!$field['show_in_edit'] && !$args['in_modal'] || !$field['show_in_modal'] && $args['in_modal']) {
            continue;
        }
        if ($field['input'] == 'hidden') {
            $hidden_fields[$name] = $field['value'];
            continue;
        }
        $readonly = (!$user_can_edit && !empty($field['taxonomy'])) ? " readonly='readonly' " : '';
        $required = $field['required'] ? '<span class="required">*</span>' : '';
        $required_attr = $field['required'] ? ' required' : '';
        $class = 'compat-field-' . $id;
        $class .= $field['required'] ? ' form-required' : '';
        $item .= "\t\t<tr class='{$class}'>";
        $item .= "\t\t\t<th scope='row' class='label'><label for='{$id_attr}'><span class='alignleft'>{$field['label']}</span>{$required}<br class='clear' /></label>";
        $item .= "</th>\n\t\t\t<td class='field'>";
        if (!empty($field[$field['input']])) {
            $item .= $field[$field['input']];
        } elseif ($field['input'] == 'textarea') {
            if ('post_content' == $id && user_can_richedit()) {
                // sanitize_post() skips the post_content when user_can_richedit.
                $field['value'] = htmlspecialchars($field['value'], ENT_QUOTES);
            }
            $item .= "<textarea id='{$id_attr}' name='{$name}'{$required_attr}>" . $field['value'] . '</textarea>';
        } else {
            $item .= "<input type='text' class='text' id='{$id_attr}' name='{$name}' value='" . esc_attr($field['value']) . "' {$readonly}{$required_attr} />";
        }
        if (!empty($field['helps'])) {
            $item .= "<p class='help'>" . join("</p>\n<p class='help'>", array_unique((array) $field['helps'])) . '</p>';
        }
        $item .= "</td>\n\t\t</tr>\n";
        $extra_rows = array();
        if (!empty($field['errors'])) {
            foreach (array_unique((array) $field['errors']) as $error) {
                $extra_rows['error'][] = $error;
            }
        }
        if (!empty($field['extra_rows'])) {
            foreach ($field['extra_rows'] as $class => $rows) {
                foreach ((array) $rows as $html) {
                    $extra_rows[$class][] = $html;
                }
            }
        }
        foreach ($extra_rows as $class => $rows) {
            foreach ($rows as $html) {
                $item .= "\t\t<tr><td></td><td class='{$class}'>{$html}</td></tr>\n";
            }
        }
    }
    if (!empty($form_fields['_final'])) {
        $item .= "\t\t<tr class='final'><td colspan='2'>{$form_fields['_final']}</td></tr>\n";
    }
    if ($item) {
        $item = '<p class="media-types media-types-required-info">' . sprintf(__('Required fields are marked %s'), '<span class="required">*</span>') . '</p>' . '<table class="compat-attachment-fields">' . $item . '</table>';
    }
    foreach ($hidden_fields as $hidden_field => $value) {
        $item .= '<input type="hidden" name="' . esc_attr($hidden_field) . '" value="' . esc_attr($value) . '" />' . "\n";
    }
    if ($item) {
        $item = '<input type="hidden" name="attachments[' . $attachment_id . '][menu_order]" value="' . esc_attr($post->menu_order) . '" />' . $item;
    }
    return array('item' => $item, 'meta' => $media_meta);
}

WordPress Version: 5.1

/**
 * @since 3.5.0
 *
 * @param int   $attachment_id
 * @param array $args
 * @return array
 */
function get_compat_media_markup($attachment_id, $args = null)
{
    $post = get_post($attachment_id);
    $default_args = array('errors' => null, 'in_modal' => false);
    $user_can_edit = current_user_can('edit_post', $attachment_id);
    $args = wp_parse_args($args, $default_args);
    /** This filter is documented in wp-admin/includes/media.php */
    $args = apply_filters('get_media_item_args', $args);
    $form_fields = array();
    if ($args['in_modal']) {
        foreach (get_attachment_taxonomies($post) as $taxonomy) {
            $t = (array) get_taxonomy($taxonomy);
            if (!$t['public'] || !$t['show_ui']) {
                continue;
            }
            if (empty($t['label'])) {
                $t['label'] = $taxonomy;
            }
            if (empty($t['args'])) {
                $t['args'] = array();
            }
            $terms = get_object_term_cache($post->ID, $taxonomy);
            if (false === $terms) {
                $terms = wp_get_object_terms($post->ID, $taxonomy, $t['args']);
            }
            $values = array();
            foreach ($terms as $term) {
                $values[] = $term->slug;
            }
            $t['value'] = join(', ', $values);
            $t['taxonomy'] = true;
            $form_fields[$taxonomy] = $t;
        }
    }
    // Merge default fields with their errors, so any key passed with the error (e.g. 'error', 'helps', 'value') will replace the default
    // The recursive merge is easily traversed with array casting: foreach ( (array) $things as $thing )
    $form_fields = array_merge_recursive($form_fields, (array) $args['errors']);
    /** This filter is documented in wp-admin/includes/media.php */
    $form_fields = apply_filters('attachment_fields_to_edit', $form_fields, $post);
    unset($form_fields['image-size'], $form_fields['align'], $form_fields['image_alt'], $form_fields['post_title'], $form_fields['post_excerpt'], $form_fields['post_content'], $form_fields['url'], $form_fields['menu_order'], $form_fields['image_url']);
    /** This filter is documented in wp-admin/includes/media.php */
    $media_meta = apply_filters('media_meta', '', $post);
    $defaults = array('input' => 'text', 'required' => false, 'value' => '', 'extra_rows' => array(), 'show_in_edit' => true, 'show_in_modal' => true);
    $hidden_fields = array();
    $item = '';
    foreach ($form_fields as $id => $field) {
        if ($id[0] == '_') {
            continue;
        }
        $name = "attachments[{$attachment_id}][{$id}]";
        $id_attr = "attachments-{$attachment_id}-{$id}";
        if (!empty($field['tr'])) {
            $item .= $field['tr'];
            continue;
        }
        $field = array_merge($defaults, $field);
        if (!$field['show_in_edit'] && !$args['in_modal'] || !$field['show_in_modal'] && $args['in_modal']) {
            continue;
        }
        if ($field['input'] == 'hidden') {
            $hidden_fields[$name] = $field['value'];
            continue;
        }
        $readonly = (!$user_can_edit && !empty($field['taxonomy'])) ? " readonly='readonly' " : '';
        $required = $field['required'] ? '<span class="required">*</span>' : '';
        $required_attr = $field['required'] ? ' required' : '';
        $class = 'compat-field-' . $id;
        $class .= $field['required'] ? ' form-required' : '';
        $item .= "\t\t<tr class='{$class}'>";
        $item .= "\t\t\t<th scope='row' class='label'><label for='{$id_attr}'><span class='alignleft'>{$field['label']}</span>{$required}<br class='clear' /></label>";
        $item .= "</th>\n\t\t\t<td class='field'>";
        if (!empty($field[$field['input']])) {
            $item .= $field[$field['input']];
        } elseif ($field['input'] == 'textarea') {
            if ('post_content' == $id && user_can_richedit()) {
                // sanitize_post() skips the post_content when user_can_richedit.
                $field['value'] = htmlspecialchars($field['value'], ENT_QUOTES);
            }
            $item .= "<textarea id='{$id_attr}' name='{$name}'{$required_attr}>" . $field['value'] . '</textarea>';
        } else {
            $item .= "<input type='text' class='text' id='{$id_attr}' name='{$name}' value='" . esc_attr($field['value']) . "' {$readonly}{$required_attr} />";
        }
        if (!empty($field['helps'])) {
            $item .= "<p class='help'>" . join("</p>\n<p class='help'>", array_unique((array) $field['helps'])) . '</p>';
        }
        $item .= "</td>\n\t\t</tr>\n";
        $extra_rows = array();
        if (!empty($field['errors'])) {
            foreach (array_unique((array) $field['errors']) as $error) {
                $extra_rows['error'][] = $error;
            }
        }
        if (!empty($field['extra_rows'])) {
            foreach ($field['extra_rows'] as $class => $rows) {
                foreach ((array) $rows as $html) {
                    $extra_rows[$class][] = $html;
                }
            }
        }
        foreach ($extra_rows as $class => $rows) {
            foreach ($rows as $html) {
                $item .= "\t\t<tr><td></td><td class='{$class}'>{$html}</td></tr>\n";
            }
        }
    }
    if (!empty($form_fields['_final'])) {
        $item .= "\t\t<tr class='final'><td colspan='2'>{$form_fields['_final']}</td></tr>\n";
    }
    if ($item) {
        $item = '<p class="media-types media-types-required-info">' . sprintf(__('Required fields are marked %s'), '<span class="required">*</span>') . '</p>
			<table class="compat-attachment-fields">' . $item . '</table>';
    }
    foreach ($hidden_fields as $hidden_field => $value) {
        $item .= '<input type="hidden" name="' . esc_attr($hidden_field) . '" value="' . esc_attr($value) . '" />' . "\n";
    }
    if ($item) {
        $item = '<input type="hidden" name="attachments[' . $attachment_id . '][menu_order]" value="' . esc_attr($post->menu_order) . '" />' . $item;
    }
    return array('item' => $item, 'meta' => $media_meta);
}

WordPress Version: 4.5

/**
 * @since 3.5.0
 *
 * @param int   $attachment_id
 * @param array $args
 * @return array
 */
function get_compat_media_markup($attachment_id, $args = null)
{
    $post = get_post($attachment_id);
    $default_args = array('errors' => null, 'in_modal' => false);
    $user_can_edit = current_user_can('edit_post', $attachment_id);
    $args = wp_parse_args($args, $default_args);
    /** This filter is documented in wp-admin/includes/media.php */
    $args = apply_filters('get_media_item_args', $args);
    $form_fields = array();
    if ($args['in_modal']) {
        foreach (get_attachment_taxonomies($post) as $taxonomy) {
            $t = (array) get_taxonomy($taxonomy);
            if (!$t['public'] || !$t['show_ui']) {
                continue;
            }
            if (empty($t['label'])) {
                $t['label'] = $taxonomy;
            }
            if (empty($t['args'])) {
                $t['args'] = array();
            }
            $terms = get_object_term_cache($post->ID, $taxonomy);
            if (false === $terms) {
                $terms = wp_get_object_terms($post->ID, $taxonomy, $t['args']);
            }
            $values = array();
            foreach ($terms as $term) {
                $values[] = $term->slug;
            }
            $t['value'] = join(', ', $values);
            $t['taxonomy'] = true;
            $form_fields[$taxonomy] = $t;
        }
    }
    // Merge default fields with their errors, so any key passed with the error (e.g. 'error', 'helps', 'value') will replace the default
    // The recursive merge is easily traversed with array casting: foreach ( (array) $things as $thing )
    $form_fields = array_merge_recursive($form_fields, (array) $args['errors']);
    /** This filter is documented in wp-admin/includes/media.php */
    $form_fields = apply_filters('attachment_fields_to_edit', $form_fields, $post);
    unset($form_fields['image-size'], $form_fields['align'], $form_fields['image_alt'], $form_fields['post_title'], $form_fields['post_excerpt'], $form_fields['post_content'], $form_fields['url'], $form_fields['menu_order'], $form_fields['image_url']);
    /** This filter is documented in wp-admin/includes/media.php */
    $media_meta = apply_filters('media_meta', '', $post);
    $defaults = array('input' => 'text', 'required' => false, 'value' => '', 'extra_rows' => array(), 'show_in_edit' => true, 'show_in_modal' => true);
    $hidden_fields = array();
    $item = '';
    foreach ($form_fields as $id => $field) {
        if ($id[0] == '_') {
            continue;
        }
        $name = "attachments[{$attachment_id}][{$id}]";
        $id_attr = "attachments-{$attachment_id}-{$id}";
        if (!empty($field['tr'])) {
            $item .= $field['tr'];
            continue;
        }
        $field = array_merge($defaults, $field);
        if (!$field['show_in_edit'] && !$args['in_modal'] || !$field['show_in_modal'] && $args['in_modal']) {
            continue;
        }
        if ($field['input'] == 'hidden') {
            $hidden_fields[$name] = $field['value'];
            continue;
        }
        $readonly = (!$user_can_edit && !empty($field['taxonomy'])) ? " readonly='readonly' " : '';
        $required = $field['required'] ? '<span class="required">*</span>' : '';
        $required_attr = $field['required'] ? ' required' : '';
        $aria_required = $field['required'] ? " aria-required='true'" : '';
        $class = 'compat-field-' . $id;
        $class .= $field['required'] ? ' form-required' : '';
        $item .= "\t\t<tr class='{$class}'>";
        $item .= "\t\t\t<th scope='row' class='label'><label for='{$id_attr}'><span class='alignleft'>{$field['label']}</span>{$required}<br class='clear' /></label>";
        $item .= "</th>\n\t\t\t<td class='field'>";
        if (!empty($field[$field['input']])) {
            $item .= $field[$field['input']];
        } elseif ($field['input'] == 'textarea') {
            if ('post_content' == $id && user_can_richedit()) {
                // sanitize_post() skips the post_content when user_can_richedit.
                $field['value'] = htmlspecialchars($field['value'], ENT_QUOTES);
            }
            $item .= "<textarea id='{$id_attr}' name='{$name}'{$required_attr}{$aria_required}>" . $field['value'] . '</textarea>';
        } else {
            $item .= "<input type='text' class='text' id='{$id_attr}' name='{$name}' value='" . esc_attr($field['value']) . "' {$readonly}{$required_attr}{$aria_required} />";
        }
        if (!empty($field['helps'])) {
            $item .= "<p class='help'>" . join("</p>\n<p class='help'>", array_unique((array) $field['helps'])) . '</p>';
        }
        $item .= "</td>\n\t\t</tr>\n";
        $extra_rows = array();
        if (!empty($field['errors'])) {
            foreach (array_unique((array) $field['errors']) as $error) {
                $extra_rows['error'][] = $error;
            }
        }
        if (!empty($field['extra_rows'])) {
            foreach ($field['extra_rows'] as $class => $rows) {
                foreach ((array) $rows as $html) {
                    $extra_rows[$class][] = $html;
                }
            }
        }
        foreach ($extra_rows as $class => $rows) {
            foreach ($rows as $html) {
                $item .= "\t\t<tr><td></td><td class='{$class}'>{$html}</td></tr>\n";
            }
        }
    }
    if (!empty($form_fields['_final'])) {
        $item .= "\t\t<tr class='final'><td colspan='2'>{$form_fields['_final']}</td></tr>\n";
    }
    if ($item) {
        $item = '<p class="media-types media-types-required-info">' . sprintf(__('Required fields are marked %s'), '<span class="required">*</span>') . '</p>
			<table class="compat-attachment-fields">' . $item . '</table>';
    }
    foreach ($hidden_fields as $hidden_field => $value) {
        $item .= '<input type="hidden" name="' . esc_attr($hidden_field) . '" value="' . esc_attr($value) . '" />' . "\n";
    }
    if ($item) {
        $item = '<input type="hidden" name="attachments[' . $attachment_id . '][menu_order]" value="' . esc_attr($post->menu_order) . '" />' . $item;
    }
    return array('item' => $item, 'meta' => $media_meta);
}

WordPress Version: 4.4

/**
 * @since 3.5.0
 *
 * @param int   $attachment_id
 * @param array $args
 * @return array
 */
function get_compat_media_markup($attachment_id, $args = null)
{
    $post = get_post($attachment_id);
    $default_args = array('errors' => null, 'in_modal' => false);
    $user_can_edit = current_user_can('edit_post', $attachment_id);
    $args = wp_parse_args($args, $default_args);
    /** This filter is documented in wp-admin/includes/media.php */
    $args = apply_filters('get_media_item_args', $args);
    $form_fields = array();
    if ($args['in_modal']) {
        foreach (get_attachment_taxonomies($post) as $taxonomy) {
            $t = (array) get_taxonomy($taxonomy);
            if (!$t['public'] || !$t['show_ui']) {
                continue;
            }
            if (empty($t['label'])) {
                $t['label'] = $taxonomy;
            }
            if (empty($t['args'])) {
                $t['args'] = array();
            }
            $terms = get_object_term_cache($post->ID, $taxonomy);
            if (false === $terms) {
                $terms = wp_get_object_terms($post->ID, $taxonomy, $t['args']);
            }
            $values = array();
            foreach ($terms as $term) {
                $values[] = $term->slug;
            }
            $t['value'] = join(', ', $values);
            $t['taxonomy'] = true;
            $form_fields[$taxonomy] = $t;
        }
    }
    // Merge default fields with their errors, so any key passed with the error (e.g. 'error', 'helps', 'value') will replace the default
    // The recursive merge is easily traversed with array casting: foreach ( (array) $things as $thing )
    $form_fields = array_merge_recursive($form_fields, (array) $args['errors']);
    /** This filter is documented in wp-admin/includes/media.php */
    $form_fields = apply_filters('attachment_fields_to_edit', $form_fields, $post);
    unset($form_fields['image-size'], $form_fields['align'], $form_fields['image_alt'], $form_fields['post_title'], $form_fields['post_excerpt'], $form_fields['post_content'], $form_fields['url'], $form_fields['menu_order'], $form_fields['image_url']);
    /** This filter is documented in wp-admin/includes/media.php */
    $media_meta = apply_filters('media_meta', '', $post);
    $defaults = array('input' => 'text', 'required' => false, 'value' => '', 'extra_rows' => array(), 'show_in_edit' => true, 'show_in_modal' => true);
    $hidden_fields = array();
    $item = '';
    foreach ($form_fields as $id => $field) {
        if ($id[0] == '_') {
            continue;
        }
        $name = "attachments[{$attachment_id}][{$id}]";
        $id_attr = "attachments-{$attachment_id}-{$id}";
        if (!empty($field['tr'])) {
            $item .= $field['tr'];
            continue;
        }
        $field = array_merge($defaults, $field);
        if (!$field['show_in_edit'] && !$args['in_modal'] || !$field['show_in_modal'] && $args['in_modal']) {
            continue;
        }
        if ($field['input'] == 'hidden') {
            $hidden_fields[$name] = $field['value'];
            continue;
        }
        $readonly = (!$user_can_edit && !empty($field['taxonomy'])) ? " readonly='readonly' " : '';
        $required = $field['required'] ? '<span class="alignright"><abbr title="required" class="required">*</abbr></span>' : '';
        $aria_required = $field['required'] ? " aria-required='true' " : '';
        $class = 'compat-field-' . $id;
        $class .= $field['required'] ? ' form-required' : '';
        $item .= "\t\t<tr class='{$class}'>";
        $item .= "\t\t\t<th scope='row' class='label'><label for='{$id_attr}'><span class='alignleft'>{$field['label']}</span>{$required}<br class='clear' /></label>";
        $item .= "</th>\n\t\t\t<td class='field'>";
        if (!empty($field[$field['input']])) {
            $item .= $field[$field['input']];
        } elseif ($field['input'] == 'textarea') {
            if ('post_content' == $id && user_can_richedit()) {
                // sanitize_post() skips the post_content when user_can_richedit.
                $field['value'] = htmlspecialchars($field['value'], ENT_QUOTES);
            }
            $item .= "<textarea id='{$id_attr}' name='{$name}' {$aria_required}>" . $field['value'] . '</textarea>';
        } else {
            $item .= "<input type='text' class='text' id='{$id_attr}' name='{$name}' value='" . esc_attr($field['value']) . "' {$readonly} {$aria_required} />";
        }
        if (!empty($field['helps'])) {
            $item .= "<p class='help'>" . join("</p>\n<p class='help'>", array_unique((array) $field['helps'])) . '</p>';
        }
        $item .= "</td>\n\t\t</tr>\n";
        $extra_rows = array();
        if (!empty($field['errors'])) {
            foreach (array_unique((array) $field['errors']) as $error) {
                $extra_rows['error'][] = $error;
            }
        }
        if (!empty($field['extra_rows'])) {
            foreach ($field['extra_rows'] as $class => $rows) {
                foreach ((array) $rows as $html) {
                    $extra_rows[$class][] = $html;
                }
            }
        }
        foreach ($extra_rows as $class => $rows) {
            foreach ($rows as $html) {
                $item .= "\t\t<tr><td></td><td class='{$class}'>{$html}</td></tr>\n";
            }
        }
    }
    if (!empty($form_fields['_final'])) {
        $item .= "\t\t<tr class='final'><td colspan='2'>{$form_fields['_final']}</td></tr>\n";
    }
    if ($item) {
        $item = '<table class="compat-attachment-fields">' . $item . '</table>';
    }
    foreach ($hidden_fields as $hidden_field => $value) {
        $item .= '<input type="hidden" name="' . esc_attr($hidden_field) . '" value="' . esc_attr($value) . '" />' . "\n";
    }
    if ($item) {
        $item = '<input type="hidden" name="attachments[' . $attachment_id . '][menu_order]" value="' . esc_attr($post->menu_order) . '" />' . $item;
    }
    return array('item' => $item, 'meta' => $media_meta);
}

WordPress Version: 4.3

/**
 * @since 3.5.0
 *
 * @param int   $attachment_id
 * @param array $args
 * @return array
 */
function get_compat_media_markup($attachment_id, $args = null)
{
    $post = get_post($attachment_id);
    $default_args = array('errors' => null, 'in_modal' => false);
    $user_can_edit = current_user_can('edit_post', $attachment_id);
    $args = wp_parse_args($args, $default_args);
    /** This filter is documented in wp-admin/includes/media.php */
    $args = apply_filters('get_media_item_args', $args);
    $form_fields = array();
    if ($args['in_modal']) {
        foreach (get_attachment_taxonomies($post) as $taxonomy) {
            $t = (array) get_taxonomy($taxonomy);
            if (!$t['public'] || !$t['show_ui']) {
                continue;
            }
            if (empty($t['label'])) {
                $t['label'] = $taxonomy;
            }
            if (empty($t['args'])) {
                $t['args'] = array();
            }
            $terms = get_object_term_cache($post->ID, $taxonomy);
            if (false === $terms) {
                $terms = wp_get_object_terms($post->ID, $taxonomy, $t['args']);
            }
            $values = array();
            foreach ($terms as $term) {
                $values[] = $term->slug;
            }
            $t['value'] = join(', ', $values);
            $t['taxonomy'] = true;
            $form_fields[$taxonomy] = $t;
        }
    }
    // Merge default fields with their errors, so any key passed with the error (e.g. 'error', 'helps', 'value') will replace the default
    // The recursive merge is easily traversed with array casting: foreach( (array) $things as $thing )
    $form_fields = array_merge_recursive($form_fields, (array) $args['errors']);
    /** This filter is documented in wp-admin/includes/media.php */
    $form_fields = apply_filters('attachment_fields_to_edit', $form_fields, $post);
    unset($form_fields['image-size'], $form_fields['align'], $form_fields['image_alt'], $form_fields['post_title'], $form_fields['post_excerpt'], $form_fields['post_content'], $form_fields['url'], $form_fields['menu_order'], $form_fields['image_url']);
    /** This filter is documented in wp-admin/includes/media.php */
    $media_meta = apply_filters('media_meta', '', $post);
    $defaults = array('input' => 'text', 'required' => false, 'value' => '', 'extra_rows' => array(), 'show_in_edit' => true, 'show_in_modal' => true);
    $hidden_fields = array();
    $item = '';
    foreach ($form_fields as $id => $field) {
        if ($id[0] == '_') {
            continue;
        }
        $name = "attachments[{$attachment_id}][{$id}]";
        $id_attr = "attachments-{$attachment_id}-{$id}";
        if (!empty($field['tr'])) {
            $item .= $field['tr'];
            continue;
        }
        $field = array_merge($defaults, $field);
        if (!$field['show_in_edit'] && !$args['in_modal'] || !$field['show_in_modal'] && $args['in_modal']) {
            continue;
        }
        if ($field['input'] == 'hidden') {
            $hidden_fields[$name] = $field['value'];
            continue;
        }
        $readonly = (!$user_can_edit && !empty($field['taxonomy'])) ? " readonly='readonly' " : '';
        $required = $field['required'] ? '<span class="alignright"><abbr title="required" class="required">*</abbr></span>' : '';
        $aria_required = $field['required'] ? " aria-required='true' " : '';
        $class = 'compat-field-' . $id;
        $class .= $field['required'] ? ' form-required' : '';
        $item .= "\t\t<tr class='{$class}'>";
        $item .= "\t\t\t<th scope='row' class='label'><label for='{$id_attr}'><span class='alignleft'>{$field['label']}</span>{$required}<br class='clear' /></label>";
        $item .= "</th>\n\t\t\t<td class='field'>";
        if (!empty($field[$field['input']])) {
            $item .= $field[$field['input']];
        } elseif ($field['input'] == 'textarea') {
            if ('post_content' == $id && user_can_richedit()) {
                // sanitize_post() skips the post_content when user_can_richedit.
                $field['value'] = htmlspecialchars($field['value'], ENT_QUOTES);
            }
            $item .= "<textarea id='{$id_attr}' name='{$name}' {$aria_required}>" . $field['value'] . '</textarea>';
        } else {
            $item .= "<input type='text' class='text' id='{$id_attr}' name='{$name}' value='" . esc_attr($field['value']) . "' {$readonly} {$aria_required} />";
        }
        if (!empty($field['helps'])) {
            $item .= "<p class='help'>" . join("</p>\n<p class='help'>", array_unique((array) $field['helps'])) . '</p>';
        }
        $item .= "</td>\n\t\t</tr>\n";
        $extra_rows = array();
        if (!empty($field['errors'])) {
            foreach (array_unique((array) $field['errors']) as $error) {
                $extra_rows['error'][] = $error;
            }
        }
        if (!empty($field['extra_rows'])) {
            foreach ($field['extra_rows'] as $class => $rows) {
                foreach ((array) $rows as $html) {
                    $extra_rows[$class][] = $html;
                }
            }
        }
        foreach ($extra_rows as $class => $rows) {
            foreach ($rows as $html) {
                $item .= "\t\t<tr><td></td><td class='{$class}'>{$html}</td></tr>\n";
            }
        }
    }
    if (!empty($form_fields['_final'])) {
        $item .= "\t\t<tr class='final'><td colspan='2'>{$form_fields['_final']}</td></tr>\n";
    }
    if ($item) {
        $item = '<table class="compat-attachment-fields">' . $item . '</table>';
    }
    foreach ($hidden_fields as $hidden_field => $value) {
        $item .= '<input type="hidden" name="' . esc_attr($hidden_field) . '" value="' . esc_attr($value) . '" />' . "\n";
    }
    if ($item) {
        $item = '<input type="hidden" name="attachments[' . $attachment_id . '][menu_order]" value="' . esc_attr($post->menu_order) . '" />' . $item;
    }
    return array('item' => $item, 'meta' => $media_meta);
}

WordPress Version: 4.0

function get_compat_media_markup($attachment_id, $args = null)
{
    $post = get_post($attachment_id);
    $default_args = array('errors' => null, 'in_modal' => false);
    $user_can_edit = current_user_can('edit_post', $attachment_id);
    $args = wp_parse_args($args, $default_args);
    /** This filter is documented in wp-admin/includes/media.php */
    $args = apply_filters('get_media_item_args', $args);
    $form_fields = array();
    if ($args['in_modal']) {
        foreach (get_attachment_taxonomies($post) as $taxonomy) {
            $t = (array) get_taxonomy($taxonomy);
            if (!$t['public'] || !$t['show_ui']) {
                continue;
            }
            if (empty($t['label'])) {
                $t['label'] = $taxonomy;
            }
            if (empty($t['args'])) {
                $t['args'] = array();
            }
            $terms = get_object_term_cache($post->ID, $taxonomy);
            if (false === $terms) {
                $terms = wp_get_object_terms($post->ID, $taxonomy, $t['args']);
            }
            $values = array();
            foreach ($terms as $term) {
                $values[] = $term->slug;
            }
            $t['value'] = join(', ', $values);
            $t['taxonomy'] = true;
            $form_fields[$taxonomy] = $t;
        }
    }
    // Merge default fields with their errors, so any key passed with the error (e.g. 'error', 'helps', 'value') will replace the default
    // The recursive merge is easily traversed with array casting: foreach( (array) $things as $thing )
    $form_fields = array_merge_recursive($form_fields, (array) $args['errors']);
    /** This filter is documented in wp-admin/includes/media.php */
    $form_fields = apply_filters('attachment_fields_to_edit', $form_fields, $post);
    unset($form_fields['image-size'], $form_fields['align'], $form_fields['image_alt'], $form_fields['post_title'], $form_fields['post_excerpt'], $form_fields['post_content'], $form_fields['url'], $form_fields['menu_order'], $form_fields['image_url']);
    /** This filter is documented in wp-admin/includes/media.php */
    $media_meta = apply_filters('media_meta', '', $post);
    $defaults = array('input' => 'text', 'required' => false, 'value' => '', 'extra_rows' => array(), 'show_in_edit' => true, 'show_in_modal' => true);
    $hidden_fields = array();
    $item = '';
    foreach ($form_fields as $id => $field) {
        if ($id[0] == '_') {
            continue;
        }
        $name = "attachments[{$attachment_id}][{$id}]";
        $id_attr = "attachments-{$attachment_id}-{$id}";
        if (!empty($field['tr'])) {
            $item .= $field['tr'];
            continue;
        }
        $field = array_merge($defaults, $field);
        if (!$field['show_in_edit'] && !$args['in_modal'] || !$field['show_in_modal'] && $args['in_modal']) {
            continue;
        }
        if ($field['input'] == 'hidden') {
            $hidden_fields[$name] = $field['value'];
            continue;
        }
        $readonly = (!$user_can_edit && !empty($field['taxonomy'])) ? " readonly='readonly' " : '';
        $required = $field['required'] ? '<span class="alignright"><abbr title="required" class="required">*</abbr></span>' : '';
        $aria_required = $field['required'] ? " aria-required='true' " : '';
        $class = 'compat-field-' . $id;
        $class .= $field['required'] ? ' form-required' : '';
        $item .= "\t\t<tr class='{$class}'>";
        $item .= "\t\t\t<th scope='row' class='label'><label for='{$id_attr}'><span class='alignleft'>{$field['label']}</span>{$required}<br class='clear' /></label>";
        $item .= "</th>\n\t\t\t<td class='field'>";
        if (!empty($field[$field['input']])) {
            $item .= $field[$field['input']];
        } elseif ($field['input'] == 'textarea') {
            if ('post_content' == $id && user_can_richedit()) {
                // sanitize_post() skips the post_content when user_can_richedit.
                $field['value'] = htmlspecialchars($field['value'], ENT_QUOTES);
            }
            $item .= "<textarea id='{$id_attr}' name='{$name}' {$aria_required}>" . $field['value'] . '</textarea>';
        } else {
            $item .= "<input type='text' class='text' id='{$id_attr}' name='{$name}' value='" . esc_attr($field['value']) . "' {$readonly} {$aria_required} />";
        }
        if (!empty($field['helps'])) {
            $item .= "<p class='help'>" . join("</p>\n<p class='help'>", array_unique((array) $field['helps'])) . '</p>';
        }
        $item .= "</td>\n\t\t</tr>\n";
        $extra_rows = array();
        if (!empty($field['errors'])) {
            foreach (array_unique((array) $field['errors']) as $error) {
                $extra_rows['error'][] = $error;
            }
        }
        if (!empty($field['extra_rows'])) {
            foreach ($field['extra_rows'] as $class => $rows) {
                foreach ((array) $rows as $html) {
                    $extra_rows[$class][] = $html;
                }
            }
        }
        foreach ($extra_rows as $class => $rows) {
            foreach ($rows as $html) {
                $item .= "\t\t<tr><td></td><td class='{$class}'>{$html}</td></tr>\n";
            }
        }
    }
    if (!empty($form_fields['_final'])) {
        $item .= "\t\t<tr class='final'><td colspan='2'>{$form_fields['_final']}</td></tr>\n";
    }
    if ($item) {
        $item = '<table class="compat-attachment-fields">' . $item . '</table>';
    }
    foreach ($hidden_fields as $hidden_field => $value) {
        $item .= '<input type="hidden" name="' . esc_attr($hidden_field) . '" value="' . esc_attr($value) . '" />' . "\n";
    }
    if ($item) {
        $item = '<input type="hidden" name="attachments[' . $attachment_id . '][menu_order]" value="' . esc_attr($post->menu_order) . '" />' . $item;
    }
    return array('item' => $item, 'meta' => $media_meta);
}

WordPress Version: 3.9

function get_compat_media_markup($attachment_id, $args = null)
{
    $post = get_post($attachment_id);
    $default_args = array('errors' => null, 'in_modal' => false);
    $user_can_edit = current_user_can('edit_post', $attachment_id);
    $args = wp_parse_args($args, $default_args);
    /** This filter is documented in wp-admin/includes/media.php */
    $args = apply_filters('get_media_item_args', $args);
    $form_fields = array();
    if ($args['in_modal']) {
        foreach (get_attachment_taxonomies($post) as $taxonomy) {
            $t = (array) get_taxonomy($taxonomy);
            if (!$t['public'] || !$t['show_ui']) {
                continue;
            }
            if (empty($t['label'])) {
                $t['label'] = $taxonomy;
            }
            if (empty($t['args'])) {
                $t['args'] = array();
            }
            $terms = get_object_term_cache($post->ID, $taxonomy);
            if (false === $terms) {
                $terms = wp_get_object_terms($post->ID, $taxonomy, $t['args']);
            }
            $values = array();
            foreach ($terms as $term) {
                $values[] = $term->slug;
            }
            $t['value'] = join(', ', $values);
            $t['taxonomy'] = true;
            $form_fields[$taxonomy] = $t;
        }
    }
    // Merge default fields with their errors, so any key passed with the error (e.g. 'error', 'helps', 'value') will replace the default
    // The recursive merge is easily traversed with array casting: foreach( (array) $things as $thing )
    $form_fields = array_merge_recursive($form_fields, (array) $args['errors']);
    /** This filter is documented in wp-admin/includes/media.php */
    $form_fields = apply_filters('attachment_fields_to_edit', $form_fields, $post);
    unset($form_fields['image-size'], $form_fields['align'], $form_fields['image_alt'], $form_fields['post_title'], $form_fields['post_excerpt'], $form_fields['post_content'], $form_fields['url'], $form_fields['menu_order'], $form_fields['image_url']);
    /** This filter is documented in wp-admin/includes/media.php */
    $media_meta = apply_filters('media_meta', '', $post);
    $defaults = array('input' => 'text', 'required' => false, 'value' => '', 'extra_rows' => array(), 'show_in_edit' => true, 'show_in_modal' => true);
    $hidden_fields = array();
    $item = '';
    foreach ($form_fields as $id => $field) {
        if ($id[0] == '_') {
            continue;
        }
        $name = "attachments[{$attachment_id}][{$id}]";
        $id_attr = "attachments-{$attachment_id}-{$id}";
        if (!empty($field['tr'])) {
            $item .= $field['tr'];
            continue;
        }
        $field = array_merge($defaults, $field);
        if (!$field['show_in_edit'] && !$args['in_modal'] || !$field['show_in_modal'] && $args['in_modal']) {
            continue;
        }
        if ($field['input'] == 'hidden') {
            $hidden_fields[$name] = $field['value'];
            continue;
        }
        $readonly = (!$user_can_edit && !empty($field['taxonomy'])) ? " readonly='readonly' " : '';
        $required = $field['required'] ? '<span class="alignright"><abbr title="required" class="required">*</abbr></span>' : '';
        $aria_required = $field['required'] ? " aria-required='true' " : '';
        $class = 'compat-field-' . $id;
        $class .= $field['required'] ? ' form-required' : '';
        $item .= "\t\t<tr class='{$class}'>";
        $item .= "\t\t\t<th scope='row' class='label'><label for='{$id_attr}'><span class='alignleft'>{$field['label']}</span>{$required}<br class='clear' /></label>";
        $item .= "</th>\n\t\t\t<td class='field'>";
        if (!empty($field[$field['input']])) {
            $item .= $field[$field['input']];
        } elseif ($field['input'] == 'textarea') {
            if ('post_content' == $id && user_can_richedit()) {
                // sanitize_post() skips the post_content when user_can_richedit
                $field['value'] = htmlspecialchars($field['value'], ENT_QUOTES);
            }
            $item .= "<textarea id='{$id_attr}' name='{$name}' {$aria_required}>" . $field['value'] . '</textarea>';
        } else {
            $item .= "<input type='text' class='text' id='{$id_attr}' name='{$name}' value='" . esc_attr($field['value']) . "' {$readonly} {$aria_required} />";
        }
        if (!empty($field['helps'])) {
            $item .= "<p class='help'>" . join("</p>\n<p class='help'>", array_unique((array) $field['helps'])) . '</p>';
        }
        $item .= "</td>\n\t\t</tr>\n";
        $extra_rows = array();
        if (!empty($field['errors'])) {
            foreach (array_unique((array) $field['errors']) as $error) {
                $extra_rows['error'][] = $error;
            }
        }
        if (!empty($field['extra_rows'])) {
            foreach ($field['extra_rows'] as $class => $rows) {
                foreach ((array) $rows as $html) {
                    $extra_rows[$class][] = $html;
                }
            }
        }
        foreach ($extra_rows as $class => $rows) {
            foreach ($rows as $html) {
                $item .= "\t\t<tr><td></td><td class='{$class}'>{$html}</td></tr>\n";
            }
        }
    }
    if (!empty($form_fields['_final'])) {
        $item .= "\t\t<tr class='final'><td colspan='2'>{$form_fields['_final']}</td></tr>\n";
    }
    if ($item) {
        $item = '<table class="compat-attachment-fields">' . $item . '</table>';
    }
    foreach ($hidden_fields as $hidden_field => $value) {
        $item .= '<input type="hidden" name="' . esc_attr($hidden_field) . '" value="' . esc_attr($value) . '" />' . "\n";
    }
    if ($item) {
        $item = '<input type="hidden" name="attachments[' . $attachment_id . '][menu_order]" value="' . esc_attr($post->menu_order) . '" />' . $item;
    }
    return array('item' => $item, 'meta' => $media_meta);
}

WordPress Version: 3.7

function get_compat_media_markup($attachment_id, $args = null)
{
    $post = get_post($attachment_id);
    $default_args = array('errors' => null, 'in_modal' => false);
    $user_can_edit = current_user_can('edit_post', $attachment_id);
    $args = wp_parse_args($args, $default_args);
    $args = apply_filters('get_media_item_args', $args);
    $form_fields = array();
    if ($args['in_modal']) {
        foreach (get_attachment_taxonomies($post) as $taxonomy) {
            $t = (array) get_taxonomy($taxonomy);
            if (!$t['public'] || !$t['show_ui']) {
                continue;
            }
            if (empty($t['label'])) {
                $t['label'] = $taxonomy;
            }
            if (empty($t['args'])) {
                $t['args'] = array();
            }
            $terms = get_object_term_cache($post->ID, $taxonomy);
            if (false === $terms) {
                $terms = wp_get_object_terms($post->ID, $taxonomy, $t['args']);
            }
            $values = array();
            foreach ($terms as $term) {
                $values[] = $term->slug;
            }
            $t['value'] = join(', ', $values);
            $t['taxonomy'] = true;
            $form_fields[$taxonomy] = $t;
        }
    }
    // Merge default fields with their errors, so any key passed with the error (e.g. 'error', 'helps', 'value') will replace the default
    // The recursive merge is easily traversed with array casting: foreach( (array) $things as $thing )
    $form_fields = array_merge_recursive($form_fields, (array) $args['errors']);
    $form_fields = apply_filters('attachment_fields_to_edit', $form_fields, $post);
    unset($form_fields['image-size'], $form_fields['align'], $form_fields['image_alt'], $form_fields['post_title'], $form_fields['post_excerpt'], $form_fields['post_content'], $form_fields['url'], $form_fields['menu_order'], $form_fields['image_url']);
    $media_meta = apply_filters('media_meta', '', $post);
    $defaults = array('input' => 'text', 'required' => false, 'value' => '', 'extra_rows' => array(), 'show_in_edit' => true, 'show_in_modal' => true);
    $hidden_fields = array();
    $item = '';
    foreach ($form_fields as $id => $field) {
        if ($id[0] == '_') {
            continue;
        }
        $name = "attachments[{$attachment_id}][{$id}]";
        $id_attr = "attachments-{$attachment_id}-{$id}";
        if (!empty($field['tr'])) {
            $item .= $field['tr'];
            continue;
        }
        $field = array_merge($defaults, $field);
        if (!$field['show_in_edit'] && !$args['in_modal'] || !$field['show_in_modal'] && $args['in_modal']) {
            continue;
        }
        if ($field['input'] == 'hidden') {
            $hidden_fields[$name] = $field['value'];
            continue;
        }
        $readonly = (!$user_can_edit && !empty($field['taxonomy'])) ? " readonly='readonly' " : '';
        $required = $field['required'] ? '<span class="alignright"><abbr title="required" class="required">*</abbr></span>' : '';
        $aria_required = $field['required'] ? " aria-required='true' " : '';
        $class = 'compat-field-' . $id;
        $class .= $field['required'] ? ' form-required' : '';
        $item .= "\t\t<tr class='{$class}'>";
        $item .= "\t\t\t<th valign='top' scope='row' class='label'><label for='{$id_attr}'><span class='alignleft'>{$field['label']}</span>{$required}<br class='clear' /></label>";
        $item .= "</th>\n\t\t\t<td class='field'>";
        if (!empty($field[$field['input']])) {
            $item .= $field[$field['input']];
        } elseif ($field['input'] == 'textarea') {
            if ('post_content' == $id && user_can_richedit()) {
                // sanitize_post() skips the post_content when user_can_richedit
                $field['value'] = htmlspecialchars($field['value'], ENT_QUOTES);
            }
            $item .= "<textarea id='{$id_attr}' name='{$name}' {$aria_required}>" . $field['value'] . '</textarea>';
        } else {
            $item .= "<input type='text' class='text' id='{$id_attr}' name='{$name}' value='" . esc_attr($field['value']) . "' {$readonly} {$aria_required} />";
        }
        if (!empty($field['helps'])) {
            $item .= "<p class='help'>" . join("</p>\n<p class='help'>", array_unique((array) $field['helps'])) . '</p>';
        }
        $item .= "</td>\n\t\t</tr>\n";
        $extra_rows = array();
        if (!empty($field['errors'])) {
            foreach (array_unique((array) $field['errors']) as $error) {
                $extra_rows['error'][] = $error;
            }
        }
        if (!empty($field['extra_rows'])) {
            foreach ($field['extra_rows'] as $class => $rows) {
                foreach ((array) $rows as $html) {
                    $extra_rows[$class][] = $html;
                }
            }
        }
        foreach ($extra_rows as $class => $rows) {
            foreach ($rows as $html) {
                $item .= "\t\t<tr><td></td><td class='{$class}'>{$html}</td></tr>\n";
            }
        }
    }
    if (!empty($form_fields['_final'])) {
        $item .= "\t\t<tr class='final'><td colspan='2'>{$form_fields['_final']}</td></tr>\n";
    }
    if ($item) {
        $item = '<table class="compat-attachment-fields">' . $item . '</table>';
    }
    foreach ($hidden_fields as $hidden_field => $value) {
        $item .= '<input type="hidden" name="' . esc_attr($hidden_field) . '" value="' . esc_attr($value) . '" />' . "\n";
    }
    if ($item) {
        $item = '<input type="hidden" name="attachments[' . $attachment_id . '][menu_order]" value="' . esc_attr($post->menu_order) . '" />' . $item;
    }
    return array('item' => $item, 'meta' => $media_meta);
}