URL을 첨부 파일 / 게시물 ID로 전환


32

이미지의 URL을 가져 와서 데이터베이스에서 해당 이미지의 첨부 파일 또는 게시물 ID를 찾을 수있는 방법이 있습니까?

상황은 다음과 같습니다.

내 게시물 내용에서 'a'태그로 둘러싸인 모든 'img'태그를 반복적으로 처리하고 있습니다. 'img'태그의 src 속성이 외부 'a'태그의 href 속성과 일치하지 않으면 '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;
}

guid가 전적으로 독특하지 않기 때문에 이것은 옳지 않습니다. (동일한 스크립트에서 이전에) 동일한 이름으로 파일을 업로드했습니다 (왜? 해상도가 높고 동일한 이미지의 저해상도 버전을 바꾸려고 시도 중임). 워드 프레스는 이미지를 다른 이름으로 저장하지만 디렉토리, guid와 동일하게 설정되었습니다. (아마도 버그).

사용할 수있는 다른 기술이 있습니까?


URL에 따라 요청 변수를 설정하고 WP_Query를 인스턴스화하고 정보를 얻을 수 있습니다.
hakre

질문을 업데이트하고 바꿀 URL이 포함 된 HTML의 일부 예를 게시하여 토론 할 수 있다면 도움이 될 것입니다.
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
URL이 이미지의 크기를 가리킬 수 있기 때문에 @StephenHarris (파일 이름이 모두 다름)
Rarst

1
이것은 훌륭하게 작동하지만 WordPress 4 이후 가브리엘이 언급 한 것처럼 다른 기능으로 그것을 수행 할 수있는 기능이 내장되어 있습니다. 이것과 같은 방식으로 작동합니다.
Chris Rae

2
@ChrisRae 소스를 보면 핵심 기능은 이미지 크기에서만 작동하지 않고 기본 이미지에서만 작동합니다.
Rarst

내장 된 WordPress 기능이 더 잘 작동한다고 생각합니다. 이것은 프로덕션에서는 작동하지 않지만 SSL 인증서가없는 스테이징에서는 작동했습니다. 내장 기능 (아래 Ego Ipse에서 지적한대로)은 두 환경에서 모두 작동합니다.
Syed Priom

15

이러한 복잡한 모든 기능을 하나의 간단한 기능으로 줄일 수 있습니다.

attachment_url_to_postid ()

첨부 파일 ID를 검색하려면 이미지 URL 만 구문 분석하면됩니다.

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

그게 당신이 필요한 전부입니다.


6
특히 이것은 이미지 크기에서는 작동하지 않습니다. 코어 버전은 "기본"첨부 파일 만 검색합니다.
Rarst

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

Ok 나는 그물에 아무도 며칠 동안 찾고 있지 않은 답을 찾았습니다. 테마 또는 플러그인이 사용하고있을 경우에만 작동 내에서 계속 WP_Customize_Image_Control()사용하는 경우 WP_Customize_Media_Control()get_theme_mod()URL을 ID를 반환하지.

내 솔루션을 위해 최신 버전을 사용하고있었습니다. 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을 참조하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.