На заказ метабокс с загрузкой галереи изображений, который не привязывает изображения к посту.

Вопрос или проблема

Я создал пользовательский метабокс с загрузчиком изображений, который загружает несколько изображений в галерею, которую я затем могу запрашивать. Все работает, кроме того факта, что изображения не отображаются как прикрепленные к записи в медиатеке. Они отображаются как не прикрепленные. Есть идеи, народ?

<?php
// Добавить метабокс
function agch_properties_add_custom_meta_box() {
    add_meta_box(
        'custom_meta_box', // $id
        'Фото недвижимости', // $title
        'agch_properties_show_custom_meta_box', // $callback
        'properties', // $page
        'normal', // $context
        'high'); // $priority
}
add_action('add_meta_boxes', 'agch_properties_add_custom_meta_box');

// Массив полей
$prefix = 'agch_properties_';
$custom_meta_fields = array(
    array(
        'label'=> 'Загрузить изображения',
        'desc'  => 'Это галерея изображений на странице отдельного элемента.',
        'id'    => $prefix.'gallery',
        'type'  => 'gallery'
    ),
);

// Обработчик обратного вызова
function agch_properties_show_custom_meta_box($object) {
        global $custom_meta_fields, $post;
        // Используйте nonce для проверки
        echo '<input type="hidden" name="custom_meta_box_nonce" value="'.wp_create_nonce(basename(__FILE__)).'" />';

        // Начало таблицы полей и цикла
        echo '<table class="form-table">';
        foreach ($custom_meta_fields as $field) {
                // получить значение этого поля, если оно существует для этой записи
                $meta = get_post_meta($post->ID, $field['id'], true);
                // начать строку таблицы
                echo '<tr>
                <th><label for="'.$field['id'].'">'.$field['label'].'</label></th>
                <td>';
                switch($field['type']) {
                        case 'gallery':
                        $meta_html = null;
                        if ($meta) {
                                $meta_html .= '<ul class="agch_properties_gallery_list">';
                                $meta_array = explode(',', $meta);
                                foreach ($meta_array as $meta_gall_item) {
                                        $meta_html .= '<li><div class="agch_properties_gallery_container"><span class="agch_properties_gallery_close"><img id="' . esc_attr($meta_gall_item) . '" src="' . wp_get_attachment_thumb_url($meta_gall_item) . '"></span></div></li>';
                                }
                                $meta_html .= '</ul>';
                        }
                        echo '<input id="agch_properties_gallery" type="hidden" name="agch_properties_gallery" value="' . esc_attr($meta) . '" />
                        <span id="agch_properties_gallery_src">' . $meta_html . '</span>
                        <div class="agch_gallery_button_container"><input id="agch_properties_gallery_button" type="button" value="Добавить изображения" /></div>';
                        break;
                } //конец switch
                echo '</td></tr>';
        } // конец foreach
        echo '</table>'; // конец таблицы
}

// Сохранить данные
function agch_properties_save_custom_meta($post_id) {
        global $custom_meta_fields;
        // Проверка nonce
        if ($_POST && !wp_verify_nonce($_POST['custom_meta_box_nonce'], basename(__FILE__)))
                return $post_id;
        // Проверка автосохранения
        if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
                return $post_id;
        // Проверка прав
        if ('properties' == get_post_type()) {
                if (!current_user_can('edit_page', $post_id))
                        return $post_id;
        } elseif (!current_user_can('edit_post', $post_id)) {
                return $post_id;
        }
        // Цикл по метаполям
        foreach ($custom_meta_fields as $field) {
                $new_meta_value = esc_attr($_POST[$field['id']]);
        $meta_key = $field['id'];
                $meta_value = get_post_meta( $post_id, $meta_key, true );
                // Если есть новое мета значение и существующее мета значение пустое
                if ( $new_meta_value && $meta_value == null ) {
                        add_post_meta( $post_id, $meta_key, $new_meta_value, true );
                // Если есть новое мета значение и существующее мета значение отличается
                } elseif ( $new_meta_value && $new_meta_value != $meta_value ) {
                        update_post_meta( $post_id, $meta_key, $new_meta_value );
                } elseif ( $new_meta_value == null && $meta_value ) {
                        delete_post_meta( $post_id, $meta_key, $meta_value );
                }
        }
}
add_action('save_post', 'agch_properties_save_custom_meta');

function AGCH_properties_load_wp_admin_style() {
        wp_enqueue_media();
        wp_enqueue_script('media-upload');
        wp_enqueue_style( 'AGCH_properties_admin_css', get_template_directory_uri() . '/library/css/properties_gallery_admin.css' );
        wp_enqueue_script( 'AGCH_properties_admin_script', get_template_directory_uri() . '/library/js/properties_gallery_admin.js' );
}
add_action( 'admin_enqueue_scripts', 'AGCH_properties_load_wp_admin_style' );
?>

Вот моя функция для сохранения вложения в поле с использованием плагина acf. Это может помочь

    $filename = $wp_upload_dir['path']."https://wordpress.stackexchange.com/".$img;

    // Проверка типа файла. Мы используем это как 'post_mime_type'.
    $filetype = wp_check_filetype( basename( $filename ), null );

    // Подготовка массива данных поста для вложения.
    $attachment = array(
      'guid'           => $wp_upload_dir['url'] . "https://wordpress.stackexchange.com/" . basename( $filename ),
      'post_mime_type' => $filetype['type'],
      'post_title'     => preg_replace( '/\.[^.]+$/', '', basename( $filename ) ),
      'post_content'   => '',
      'post_status'    => 'inherit'
    );

    // Вставка вложения.
    $attach_id = wp_insert_attachment( $attachment, $filename, $post_id );

    // Убедитесь, что этот файл подключен, так как wp_generate_attachment_metadata() зависит от него.
    require_once( ABSPATH . 'wp-admin/includes/image.php' );

    // Генерация метаданных для вложения и обновление записи в базе данных.
    $attach_data = wp_generate_attachment_metadata( $attach_id, $filename );
    wp_update_attachment_metadata( $attach_id, $attach_data );

    //Сохранение ID вложения в мета
update_field( $field, $attach_id , $post_id );

Вот упрощенный пример “псевдокода”, как вы могли бы установить изображения галереи как вложения к вашей записи. Основная идея заключается в том, чтобы установить текущий ID записи как родителя поста для изображений.

У вас должен быть какой-то условный проверка в цикле, чтобы проверить, должны ли текущая итерация / изображение быть прикреплены или не прикреплены к записи. В противном случае изображения останутся прикрепленными к записи, хотя вы бы удалили их ID из мета записи.

Надеюсь, этот пример иллюстрирует, как вы можете установить отношение изображение-пост, и вы сможете модифицировать свой существующий код с помощью этого.

function your_save_function($post_ID, $post, $update) {

  // условные проверки, должен ли этот код выполняться или нет

  // цикл по ID изображений
  foreach ($gallery_image_ids as $gallery_image_id) {
    // должно ли изображение быть прикреплено или удалено из записи
    $no_parent_or_current_post = ( $some_condition ) ? $post_ID: 0;
    // обновить родителя вложения поста
    $att_args = array(
      'ID'          => $gallery_image_id,
      'post_parent' => $no_parent_or_current_post,
    );
    $att_updated = wp_update_post( $att_args, true );
    // лог, если что-то пошло не так
    if ( is_wp_error( $att_updated ) ) {
      error_log( print_r( $att_updated, true ) );
    }    
  }

}

Ответ или решение

Проблема с Непривязанным Галереями Изображений в Кастомном Метабоксе

При разработке кастомных метабоксов для загрузки изображений в WordPress, часто возникает проблема, когда загруженные изображения не привязываются к посту в медиабиблиотеке, а остаются "непривязанными". Ваша задача заключается в том, чтобы заставить загруженные изображения привязываться к конкретному посту. В этой статье мы рассмотрим, как это можно исправить с помощью нескольких корректировок в вашем коде.

Анализ Исходного Кода

Вы уже имеете базовую структуру для создания метабокса и загрузки изображений. Давайте сначала разберем код, который вы представили:

  1. Создание Метабокса:
    Вы успешно создали кастомный метабокс с возможностью загрузки изображений. Убедитесь, что этот блок корректно отображается на странице редактирования вашего поста.

  2. Сохранение Данных:
    Функция agch_properties_save_custom_meta() отвечает за сохранение загруженных изображений. Вы собираете идентификаторы изображений и сохраняете их в метаданные поста. Однако на данный момент изображения не привязываются к посту.

Шаги По Исправлению

Для того чтобы изображения привязывались к посту в медиабиблиотеке, необходимо установить post_parent для каждого изображения. Вот как это можно сделать:

  1. Расширьте Функцию Сохранения:
    Внутри функции agch_properties_save_custom_meta() добавьте логику для привязки изображений к посту.
function agch_properties_save_custom_meta($post_id) {
    global $custom_meta_fields;

    // Проверка nonce, автосохранения и разрешений пользователя
    if (!isset($_POST['custom_meta_box_nonce']) || !wp_verify_nonce($_POST['custom_meta_box_nonce'], basename(__FILE__))) return $post_id;
    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return $post_id;
    if (!current_user_can('edit_post', $post_id)) return $post_id;

    foreach ($custom_meta_fields as $field) {
        $new_meta_value = esc_attr($_POST[$field['id']]);
        $meta_key = $field['id'];

        // Обновление метаданных поста
        if ($new_meta_value) {
            update_post_meta($post_id, $meta_key, $new_meta_value);

            // Преобразование строки идентификаторов в массив
            $meta_array = explode(',', $new_meta_value);
            foreach ($meta_array as $image_id) {
                // Обновление родительского поста для каждого изображения
                $att_args = array(
                    'ID'          => $image_id,
                    'post_parent' => $post_id,
                );
                wp_update_post($att_args);
            }           
        } else {
            delete_post_meta($post_id, $meta_key);
        }
    }
}
  1. Проверка Условий:
    Обязательно добавьте условия для проверки, необходима ли привязка изображения, чтобы не создать потенциальные проблемы с ненужными привязками.

Ключевые Моменты

  • Важно: После внесения изменений, убедитесь, что изображения корректно загружаются и их привязка проходит успешно. Проверить можно через медиабиблиотеку WordPress.
  • Тестирование: Проверьте функциональность на различных постах, чтобы убедиться, что изображения привязываются только к постам, для которых они были загружены.

Заключение

Данный подход поможет вам привязать загружаемые изображения к нужным постам в медиабиблиотеке WordPress. Не забудьте протестировать изменения на локальной среде перед развертыванием на живом сайте. Подобное решение не лише улучшит возможности работы с изображениями, но и сделает вашу реализацию более профессиональной и функциональной. В случае возникновения дополнительных вопросов или проблем, смело обращайтесь к сообществу WordPress или профессиональным разработчикам, чтобы получить необходимую поддержку.

Оцените материал
Добавить комментарий

Капча загружается...