Verwandeln Sie eine URL in einen Anhang / eine Beitrags-ID

32

Kann ich eine URL eines Bildes verwenden, um den Anhang oder die Beitrags-ID dieses Bildes in der Datenbank zu finden?

Hier ist die Situation:

Ich gehe in einer Schleife alle "img" -Tags durch, die in meinem Beitragsinhalt von "a" -Tags umgeben sind. Wenn das src-Attribut des 'img'-Tags nicht mit dem href-Attribut des äußeren' a'-Tags übereinstimmt, möchte ich das 'img'-Tag ersetzen. Wenn sich das zu entfernende 'img' in der Galerie befindet, möchte ich diesen Beitrag löschen und dann mein Ersatz-'img 'an seine Stelle setzen. Ich habe versucht, eine Funktion wie diese zu verwenden:

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;
}

Dies ist anscheinend nicht richtig, da die Anleitung ironischerweise nicht global eindeutig ist. Ich hatte (früher im selben Skript) eine Datei mit demselben Namen hochgeladen (warum? Weil sie eine höhere Auflösung hatte und ich versuche, niedrig aufgelöste Versionen desselben Bildes zu ersetzen) und obwohl WordPress das Bild unter einem anderen Namen speichern wird Das Verzeichnis und die Guids waren identisch. (möglicherweise ein Bug).

Gibt es eine andere Technik, die ich verwenden kann?

Ankur
quelle
Sie können Anforderungsvariablen gemäß Ihrer URL festlegen, WP_Query instanziieren und die Informationen daraus abrufen.
Hakre
Es wäre hilfreich, wenn Sie Ihre Frage aktualisieren und einige Beispiele für Ihren HTML-Code veröffentlichen könnten, die URLs enthalten, die Sie ersetzen möchten, damit wir sie diskutieren können.
MikeSchinkel
Mike ist genau dort. Sind die größeren Bilder, auf die Sie verweisen, auf externen Websites? Wenn nicht, müssen Sie nur die volle Größe auswählen, wenn Sie das Bild zu Ihrem Beitrag hinzufügen, und Sie haben die Option, es nirgendwo zu verlinken, wenn es keinen Sinn mehr ergibt.
Ranchothefat

Antworten:

30

Massiv verbesserte Funktion für bildlastiges Plugin entwickelt:

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;
    }
}
Rarst
quelle
1
Können Sie erklären, warum Sie beide _wp_attached_fileund abfragen _wp_attachment_metadata?
Stephen Harris
3
@StephenHarris, da die URL auf eine der Bildgrößen verweisen kann, die alle unterschiedliche Dateinamen haben
Rarst
1
Das funktioniert prima, aber es ist erwähnenswert, dass es seit WordPress 4 eine eingebaute Funktion gibt, die Gabriel in einer anderen Antwort erwähnt. Es funktioniert genauso wie dieses.
Chris Rae
2
@ChrisRae Wenn Sie sich die Quelle ansehen, funktioniert die Kernfunktion nicht für Bildgrößen, sondern nur für das Hauptbild.
Rarst
Ich denke, die integrierte WordPress-Funktion funktioniert besser. Dies funktionierte in meiner Produktion nicht, funktionierte jedoch in Staging (das kein SSL-Zertifikat besitzt). Die eingebaute Funktion (wie von Ego Ipse unten ausgeführt) funktioniert in beiden Umgebungen.
Syed Priom
15

Alle diese komplexen Funktionen können auf eine einfache Funktion reduziert werden:

attachment_url_to_postid ()

Sie müssen nur die Bild-URL analysieren, um die Anhang-ID abzurufen:

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

Das ist alles was du brauchst.

Ego Ipse
quelle
6
Dies funktioniert insbesondere nicht bei Bildgrößen. Die Hauptversion durchsucht nur die angehängte "Haupt" -Datei.
Rarst
3

Ich habe Rarsts Code so geändert, dass Sie nur den Dateinamen anstelle des vollständigen Pfads verwenden können. Dies ist hilfreich, wenn Sie das Bild seitlich laden möchten, falls es nicht vorhanden ist. Derzeit funktioniert dies nur, wenn die Dateinamen eindeutig sind, aber ich werde später eine Hash-Prüfung hinzufügen, um bei Bildern mit demselben Dateinamen zu helfen.

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;
}
Luke Gedeon
quelle
3

Ok, ich habe die Antwort gefunden, die niemand im Netz hat, nach der ich seit Tagen gesucht habe. In meinem Fall funktioniert dies nur, wenn Ihr Theme oder Plugin verwendet. WP_Customize_Image_Control()Wenn Sie WP_Customize_Media_Control()das verwenden, get_theme_mod()wird die ID und nicht die URL zurückgegeben.

Für meine Lösung verwendete ich die neuere Version WP_Customize_Image_Control()

Viele Beiträge in den Foren haben das get_attachment_id()was nicht mehr geht. ich benutzteattachment_url_to_postid()

Hier ist, wie ich es geschafft habe. Hoffe das hilft jemandem da draußen

// 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 );

Markup

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

Hier ist eine alternative Lösung:

$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');

Seit WP 4.0 haben sie eine Funktion eingeführt attachment_url_to_postid(), die sich ähnlich wie Ihre verhältfind_image_post_id()

Bitte überprüfen Sie diese URL als Referenz.

Lefan
quelle