Перетворіть URL-адресу в ідентифікатор додатка / публікації


32

Чи я можу взяти URL-адресу зображення і знайти вкладення або розмістити ідентифікатор цього зображення в базі даних?

Ось така ситуація:

Я в циклі переглядаю всі теги 'img', які оточені тегами 'a' у моєму вмісті публікації. якщо атрибут src тегу 'img' не відповідає атрибуту href зовнішнього тега 'a', то я хочу замінити тег 'img'. Роблячи це, якщо 'img', який потрібно видалити, знаходиться в галереї, я хочу видалити цю публікацію, а потім помістити замість неї «img» на її місце. Я спробував використовувати таку функцію:

function find_image_post_id($url) {
  global $wpdb;
  $postid = $wpdb->get_var($wpdb->prepare("SELECT DISTINCT ID FROM $wpdb->posts WHERE guid='$url'"));
  if ($postid) {
    return $postid;
  }
  return false;
}

Це, мабуть, невірно, оскільки настанова, як не дивно, не є єдиною в усьому світі. Я (раніше в тому ж сценарії) завантажив файл з тим самим іменем (чому? Тому, що він був більш високою роздільною здатністю, і я намагаюся замінити версії з низькою роздільною здатністю на те саме зображення), і хоча WordPress збереже зображення з іншим ім'ям у каталог, орієнтири були встановлені однаковими. (можливо, помилка).

Чи є інша техніка, яку я можу використовувати?


Ви можете налаштувати змінні запиту відповідно до вашої URL-адреси, створити інстанцію WP_Query та отримати інформацію з неї.
хакре

Це допоможе, якщо ви можете оновити своє запитання та опублікувати кілька прикладів вашого HTML, що включає URL-адреси, які ви хочете замінити, щоб ми могли їх обговорити.
MikeSchinkel

Майк тут. Чи є більші зображення, на які ви посилаєтесь, на зовнішніх сайтах? Якщо ні, то вам просто потрібно вибрати повний розмір, коли ви додасте зображення до своєї публікації, і у вас є можливість не пов’язувати його нікуди, якщо це вже не має сенсу.
sanchothefat

Відповіді:


30

Масивно вдосконалена функція, розроблена для плагіна, важкого для зображень:

if ( ! function_exists( 'get_attachment_id' ) ) {
    /**
     * Get the Attachment ID for a given image URL.
     *
     * @link   http://wordpress.stackexchange.com/a/7094
     *
     * @param  string $url
     *
     * @return boolean|integer
     */
    function get_attachment_id( $url ) {

        $dir = wp_upload_dir();

        // baseurl never has a trailing slash
        if ( false === strpos( $url, $dir['baseurl'] . '/' ) ) {
            // URL points to a place outside of upload directory
            return false;
        }

        $file  = basename( $url );
        $query = array(
            'post_type'  => 'attachment',
            'fields'     => 'ids',
            'meta_query' => array(
                array(
                    'key'     => '_wp_attached_file',
                    'value'   => $file,
                    'compare' => 'LIKE',
                ),
            )
        );

        // query attachments
        $ids = get_posts( $query );

        if ( ! empty( $ids ) ) {

            foreach ( $ids as $id ) {

                // first entry of returned array is the URL
                if ( $url === array_shift( wp_get_attachment_image_src( $id, 'full' ) ) )
                    return $id;
            }
        }

        $query['meta_query'][0]['key'] = '_wp_attachment_metadata';

        // query attachments again
        $ids = get_posts( $query );

        if ( empty( $ids) )
            return false;

        foreach ( $ids as $id ) {

            $meta = wp_get_attachment_metadata( $id );

            foreach ( $meta['sizes'] as $size => $values ) {

                if ( $values['file'] === $file && $url === array_shift( wp_get_attachment_image_src( $id, $size ) ) )
                    return $id;
            }
        }

        return false;
    }
}

1
Чи можете ви пояснити, чому ви запитуєте і те, _wp_attached_fileі _wp_attachment_metadata?
Стівен Гарріс

3
@StephenHarris, оскільки URL може вказувати на будь-який розмір зображення, у якого всі назви файлів мають різні
Rarst,

1
Це чудово працює, але тут варто відзначити, що, оскільки WordPress 4, існує вбудована функція, щоб зробити це так, як згадував Габріель в іншій відповіді. Це працює точно так само, як це робить.
Chris Rae

2
@ChrisRae, якщо ви подивитесь на джерело, основна функція не буде працювати на розміри зображень, лише на основному зображенні.
Рарст

Я думаю, що вбудована функція WordPress працює краще. Це не працювало в моєму виробництві, але працювало над Staging (який не має сертифікату SSL). Вбудована функція (як вказує Его Іпсе нижче) працює в обох середовищах.
Syed Priom

15

Усі ці складні функції можна звести до однієї простої функції:

attachment_url_to_postid ()

Вам потрібно лише проаналізувати URL-адресу зображення, щоб отримати ідентифікатор вкладеного файлу:

$attachment_id = attachment_url_to_postid( $image_url );
echo $attachment_id;

Це все, що вам потрібно.


6
Зокрема, це не буде працювати з розмірами зображення, основна версія шукає лише "основний" доданий файл.
Рарст

3

Я змінив код Rarst, щоб дозволити вам відповідати лише імені файлу замість повного шляху. Це корисно, якщо ви збираєтеся завантажувати зображення, якщо воно не існує. В даний час це працює лише в тому випадку, якщо назви файлів є унікальними, але пізніше я додаватиму хеш-перевірку, щоб допомогти із зображеннями з таким самим ім'ям файлу.

function get_attachment_id( $url, $ignore_path = false ) {

if ( ! $ignore_path ) {

    $dir = wp_upload_dir();
    $dir = trailingslashit($dir['baseurl']);

    if( false === strpos( $url, $dir ) )
        return false;
}

$file = basename($url);

$query = array(
    'post_type' => 'attachment',
    'fields' => 'ids',
    'meta_query' => array(
        array(
            'key'     => '_wp_attached_file',
            'value'   => $file,
            'compare' => 'LIKE',
        )
    )
);

$ids = get_posts( $query );

foreach( $ids as $id ) {
    $match = array_shift( wp_get_attachment_image_src($id, 'full') );
    if( $url == $match || ( $ignore_path && strstr( $match, $file ) ) )
        return $id;
}

$query['meta_query'][0]['key'] = '_wp_attachment_metadata';
$ids = get_posts( $query );

foreach( $ids as $id ) {

    $meta = wp_get_attachment_metadata($id);

    foreach( $meta['sizes'] as $size => $values ) {
        if( $values['file'] == $file && ( $ignore_path || $url == array_shift( wp_get_attachment_image_src($id, $size) ) ) )
            return $id;
    }
}

return false;
}

3

Гаразд, я знайшов відповідь, що нікого немає в мережі, яку я шукав цілими днями. Зберігати в шахті це працює тільки , якщо ваша тема або плагін з допомогою , WP_Customize_Image_Control()якщо ви використовуєте повертає ідентифікатор , а не URL - адреса.WP_Customize_Media_Control()get_theme_mod()

Для свого рішення я використовував новішу версію WP_Customize_Image_Control()

Дуже багато публікацій на форумах є тим, get_attachment_id()що більше не працює. я використавattachment_url_to_postid()

Ось як мені вдалося це зробити. Сподіваюся, це допомагає комусь там

// This is getting the image / url
$feature1 = get_theme_mod('feature_image_1');

// This is getting the post id
$feature1_id = attachment_url_to_postid($feature1);

// This is getting the alt text from the image that is set in the media area
$image1_alt = get_post_meta( $feature1_id, '_wp_attachment_image_alt', true );

Розмітка

<a href="<?php echo $feature1_url; ?>"><img class="img-responsive center-block" src="<?php echo $feature1; ?>" alt="<?php echo $image1_alt; ?>"></a>

0

Ось альтернативне рішення:

$image_url = get_field('main_image'); // in case of custom field usage
$image_id = attachment_url_to_postid($image_url);

// retrieve the thumbnail size of our image
$image_thumb = wp_get_attachment_image_src($image_id, 'thumbnail');

З WP 4.0 вони ввели функцію, attachment_url_to_postid()яка поводиться аналогічно вашійfind_image_post_id()

Перевірте цю URL-адресу для довідки.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.