Вопрос или проблема
Я создал пользовательский метабокс с загрузчиком изображений, который загружает несколько изображений в галерею, которую я затем могу запрашивать. Все работает, кроме того факта, что изображения не отображаются как прикрепленные к записи в медиатеке. Они отображаются как не прикрепленные. Есть идеи, народ?
<?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, часто возникает проблема, когда загруженные изображения не привязываются к посту в медиабиблиотеке, а остаются "непривязанными". Ваша задача заключается в том, чтобы заставить загруженные изображения привязываться к конкретному посту. В этой статье мы рассмотрим, как это можно исправить с помощью нескольких корректировок в вашем коде.
Анализ Исходного Кода
Вы уже имеете базовую структуру для создания метабокса и загрузки изображений. Давайте сначала разберем код, который вы представили:
-
Создание Метабокса:
Вы успешно создали кастомный метабокс с возможностью загрузки изображений. Убедитесь, что этот блок корректно отображается на странице редактирования вашего поста. -
Сохранение Данных:
Функцияagch_properties_save_custom_meta()
отвечает за сохранение загруженных изображений. Вы собираете идентификаторы изображений и сохраняете их в метаданные поста. Однако на данный момент изображения не привязываются к посту.
Шаги По Исправлению
Для того чтобы изображения привязывались к посту в медиабиблиотеке, необходимо установить post_parent
для каждого изображения. Вот как это можно сделать:
- Расширьте Функцию Сохранения:
Внутри функции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);
}
}
}
- Проверка Условий:
Обязательно добавьте условия для проверки, необходима ли привязка изображения, чтобы не создать потенциальные проблемы с ненужными привязками.
Ключевые Моменты
- Важно: После внесения изменений, убедитесь, что изображения корректно загружаются и их привязка проходит успешно. Проверить можно через медиабиблиотеку WordPress.
- Тестирование: Проверьте функциональность на различных постах, чтобы убедиться, что изображения привязываются только к постам, для которых они были загружены.
Заключение
Данный подход поможет вам привязать загружаемые изображения к нужным постам в медиабиблиотеке WordPress. Не забудьте протестировать изменения на локальной среде перед развертыванием на живом сайте. Подобное решение не лише улучшит возможности работы с изображениями, но и сделает вашу реализацию более профессиональной и функциональной. В случае возникновения дополнительных вопросов или проблем, смело обращайтесь к сообществу WordPress или профессиональным разработчикам, чтобы получить необходимую поддержку.