Функция wp_delete_attachment() в WordPress: описание, примеры, хуки

## WP_DELETE_ATTACHMENT() │ WP 2.0.0

Функция для удаления вложений (attachments) в WordPress.

### Описание

Когда вложение (например, изображение или файл) удаляется полностью, файл также будет удален с сервера. Процесс удаления включает в себя удаление всех метатегов, таксономий, комментариев и т.д., связанных с вложением (кроме основного поста).

**Важно:** Вложение сначала перемещается в Корзину (Trash), если:

- Корзина для медиафайлов не отключена;
- Вложение уже находится в Корзине;
- Параметр $force_delete установлен в true.

### Используется вместе с

- wp_delete_attachment_files()

### Хуки функции

- pre_delete_attachment 
- delete_attachment 
- delete_post 
- deleted_post 

### Возвращаемое значение

Функция возвращает объект поста (WP_Post) в случае успеха или false/null в случае ошибки.

### Пример использования

```php
wp_delete_attachment( $post_id, $force_delete );
  • $post_id (int) (обязательный) — ID вложения.
  • $force_delete (bool) — Пропустить Корзину и принудительно удалить.
    • По умолчанию: false.

Примеры

Пример 1: Полное удаление вложения

Мы навсегда удалим вложение с ID 54:

wp_delete_attachment( 54, true );

Пример 2: Удаление всех вложений поста при его удалении

Иногда удобно, чтобы при удалении поста все прикрепленные к нему медиафайлы также удалялись. Это можно сделать так:

// Удаляет все вложения поста вместе с самим постом
add_action( 'before_delete_post', 'wpkama_delete_attaches_with_post' );
function wpkama_delete_attaches_with_post( $post_id ) {
    $post = get_post( $post_id );

    $post_types = ['article', 'question']; // Удаляем вложения только для этих типов постов

    if ( ! $post || ! in_array( $post->post_type, $post_types ) ) {
        return;
    }

    $attaches = get_children( [
        'post_type' => 'attachment',
        'post_parent' => $post_id,
    ]);

    if ( ! $attaches ) {
        return;
    }

    foreach( $attaches as $attach ) {
        wp_delete_attachment( $attach->ID, true );
    }
}

Хук before_delete_post используется, потому что при удалении поста все вложения становятся "неприкрепленными", то есть теряют значение post_parent. Поэтому хуки delete_post и after_delete_post не сработают.

Пример 3: Проверка удаления медиафайла

Давайте удалим вложение и проверим, действительно ли файл был удален:

if ( false === wp_delete_attachment( 54, true ) ) {
    echo "Не удалось удалить медиафайл";
} else {
    echo "Медиафайл был удален";
}

Заметки

  • Глобальный объект. $wpdb — объект абстракции базы данных WordPress.

Журнал изменений

  • С версии 2.0.0 — добавлено в ядро WordPress.

Исходный код WP_DELETE_ATTACHMENT()

Функция wp_delete_attachment находится в файле wp-includes/post.php:

function wp_delete_attachment( $post_id, $force_delete = false ) {
    global $wpdb;

    $post = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE ID = %d", $post_id ) );

    if ( ! $post ) {
        return $post;
    }

    $post = get_post( $post );

    if ( 'attachment' !== $post->post_type ) {
        return false;
    }

    if ( ! $force_delete && EMPTY_TRASH_DAYS && MEDIA_TRASH && 'trash' !== $post->post_status ) {
        return wp_trash_post( $post_id );
    }

    // Проверяем, можем ли мы удалить вложение
    $check = apply_filters( 'pre_delete_attachment', null, $post, $force_delete );
    if ( null !== $check ) {
        return $check;
    }

    // Удаляем метатеги, связанные с корзиной
    delete_post_meta( $post_id, '_wp_trash_meta_status' );
    delete_post_meta( $post_id, '_wp_trash_meta_time' );

    $meta = wp_get_attachment_metadata( $post_id );
    $backup_sizes = get_post_meta( $post->ID, '_wp_attachment_backup_sizes', true );
    $file = get_attached_file( $post_id );

    // Для мультисайтовой установки
    if ( is_multisite() && is_string( $file ) && ! empty( $file ) ) {
        clean_dirsize_cache( $file );
    }

    // Событие перед удалением вложения
    do_action( 'delete_attachment', $post_id, $post );

    // Удаляем связи со таксономиями
    wp_delete_object_term_relationships( $post_id, array( 'category', 'post_tag' ) );
    wp_delete_object_term_relationships( $post_id, get_object_taxonomies( $post->post_type ) );

    // Удаляем все связи и комментарии
    delete_metadata( 'post', null, '_thumbnail_id', $post_id, true );
    wp_defer_comment_counting( true );

    $comment_ids = $wpdb->get_col( $wpdb->prepare( "SELECT comment_ID FROM $wpdb->comments WHERE comment_post_ID = %d ORDER BY comment_ID DESC", $post_id ) );
    foreach ( $comment_ids as $comment_id ) {
        wp_delete_comment( $comment_id, true );
    }

    wp_defer_comment_counting( false );

    // Удаляем метаданные поста
    $post_meta_ids = $wpdb->get_col( $wpdb->prepare( "SELECT meta_id FROM $wpdb->postmeta WHERE post_id = %d ", $post_id ) );
    foreach ( $post_meta_ids as $mid ) {
        delete_metadata_by_mid( 'post', $mid );
    }

    // Событие после удаления поста
    do_action( 'delete_post', $post_id, $post );
    $result = $wpdb->delete( $wpdb->posts, array( 'ID' => $post_id ) );

    if ( ! $result ) {
        return false;
    }

    do_action( 'deleted_post', $post_id, $post );
    wp_delete_attachment_files( $post_id, $meta, $backup_sizes, $file );

    clean_post_cache( $post );

    return $post;
}

Связанные функции (вложения)

  • get_attached_file()
  • get_attached_media()
  • get_attachment_link()
  • get_children()
  • get_post_mime_type()
  • is_local_attachment()
  • the_attachment_link()
  • wp_attachment_is()
  • wp_get_attachment_link()
  • wp_get_attachment_url()
  • wp_get_original_image_path()
  • wp_get_original_image_url()
  • wp_insert_attachment()

Leave a Reply

Ваш адрес email не будет опубликован. Обязательные поля помечены *