почему, когда я пытаюсь вставить вложение изображения вместе с сообщением, wp_get_attachment_url дает мне очень неправильный путь к файлу? - PullRequest
1 голос
/ 23 марта 2012

Я использую новый блог в WPMS (3.0.1, обновление, к сожалению, пока не подходит) для объединения записей (и их рекомендуемого изображения) из нескольких блогов в одной установке, и я должен делайте это «программно», а не через готовый плагин из-за ограничений брандмауэра. Я попробовал несколько способов сделать это, и чувствую, что этот метод наиболее перспективен. Поскольку мой экземпляр, кажется, усугубляет сложности, несколько документированных примеров того, как использовать wp_insert_post и wp_insert_attachment, не совсем помогают мне в этом. Вот что я приготовил:

switch_to_blog(oldblognumber);
$zargs  = array( 'numberposts' => 1, 'category_name' => 'featured');
$zlastpost = get_posts( $zargs );
foreach($zlastpost as $post) : setup_postdata($post);
    $extrapost = array();
    $extrapost['post_title'] = get_the_title();
    $extrapost['post_content'] = get_the_content();
    $extrapost['comment_status'] = 'closed';
    $extrapost['post_status'] = 'publish';
    $extrapost['post_date'] = get_the_date( $d = 'Y-m-d H:i:s');
    $extrapost['post_category'] = array(catidnumber);
    $upload_dir = wp_upload_dir();
    $oldid = get_the_ID();
    $image_url = wp_get_attachment_url(get_post_thumbnail_id($oldid));
    $image_data = file_get_contents($image_url);
    $filename = basename($image_url);
    switch_to_blog(newblognumber);          
        $file = $upload_dir['path'] . '/' . $filename; //removed the conditional cuz it was giving me trouble
        file_put_contents($file, $image_data);
        $post_id = wp_insert_post($extrapost);
        $wp_filetype = wp_check_filetype($filename, null );
        $attachment = array(
            'post_mime_type' => $wp_filetype['type'],
            'post_title' => sanitize_file_name($filename),
            'post_content' => '',
            'post_status' => 'inherit',
        );                  
        $attach_id = wp_insert_attachment( $attachment, $file, $post_id );
        require_once(ABSPATH . 'wp-admin/includes/image.php');
        $attach_data = wp_generate_attachment_metadata( $attach_id, $file );
        wp_update_attachment_metadata( $attach_id, $attach_data );
        set_post_thumbnail( $post_id, $attach_id );                       
    restore_current_blog();
    wp_reset_postdata();
endforeach;
restore_current_blog();

Вставка поста работает просто отлично, и она хорошо тянет изображение, но где-то там что-то запутывается, и оно выдает абсурдный URL-адрес вложения: http://myblogs.com/newblog/wp-content/blogs.dir/newblognumber/files//internet/http/wp-content/blogs.dir/oldblognumber/files/year/month/filename.jpg

Аналогично, в цикле, в котором я спрашиваю the_post_thumbnail, я получаю сломанное изображение с src http://myblogs.com/newblog/files//internet/http/wp-content/blogs.dir/oldblognumber/files/year/month/filename-200x100.jpg

Для чего это стоит, так как я использую версию WP pre set_post_thumbnail, я просто вручную определяю функцию в файле newblog functions.php:

function set_post_thumbnail( $post, $thumbnail_id ) {
$post = get_post( $post );
$thumbnail_id = absint( $thumbnail_id );
if ( $post && $thumbnail_id && get_post( $thumbnail_id ) ) {
   $thumbnail_html = wp_get_attachment_image( $thumbnail_id, 'thumbnail' );
   if ( ! empty( $thumbnail_html ) ) {
       update_post_meta( $post->ID, '_thumbnail_id', $thumbnail_id );
       return true;
   }
}
return false;
}

Я пытался обманывать GUID и использовать регулярные выражения, чтобы заставить URL-адреса отправляться среди прочего, но все безрезультатно.

Я также попробовал альтернативный метод установки миниатюры записи для вставленной записи, но при этом просто вызывается исходный файл в каталоге загрузки oldblog, что будет недостаточно, поскольку я хотел бы создать новые размеры изображений для Медиабиблиотека newblog, и я бы предпочел не просматривать и добавлять их в каждый из старых oldblogs. Вот эта попытка:

switch_to_blog(oldblognumber);
$zargs  = array( 'numberposts' => 1, 'category_name' => 'featured');
$zlastpost = get_posts( $zargs );
foreach($zlastpost as $post) : setup_postdata($post);
    $extrapost = array();
    $extrapost['post_title'] = get_the_title();
    $extrapost['post_content'] = get_the_content();
    $extrapost['comment_status'] = 'closed';
    $extrapost['post_status'] = 'publish';
    $extrapost['post_date'] = get_the_date( $d = 'Y-m-d H:i:s');
    $extrapost['post_category'] = array(catidnumber);
    $oldid = get_the_ID();
    $thumbo = get_the_post_thumbnail($oldid);
    $filename = wp_get_attachment_url( get_post_thumbnail_id($post->ID) );
    switch_to_blog(68);
        $post_id = wp_insert_post($extrapost);
        $wp_filetype = wp_check_filetype(basename($filename), null );
            $wp_upload_dir = wp_upload_dir();
            $attachment = array(
                'guid' => _wp_relative_upload_path( $filename ), 
                'post_mime_type' => $wp_filetype['type'],
                'post_title' => preg_replace('/\.[^.]+$/', '', basename($filename)),
                'post_content' => '',
                'post_status' => 'inherit'
            );
            $attach_id = wp_insert_attachment( $attachment, false, $post_id );
            require_once(ABSPATH . 'wp-admin/includes/image.php');
            $attach_data = wp_generate_attachment_metadata( $attach_id, $filename );
            update_post_meta( $post->ID, '_thumbnail_id', $attachment_id );
            wp_update_attachment_metadata( $attach_id, $attach_data );
            set_post_thumbnail( $post_id, $attach_id);        
        restore_current_blog();
        wp_reset_postdata();
    endforeach;
restore_current_blog();     

Я попытался передать несколько параметров параметру $ filename в wp_insert_attachment, но это не похоже на мой ответ. Дайте мне знать, если у вас есть хорошие идеи для меня!

1 Ответ

1 голос
/ 26 марта 2012

Оказывается, я заколол неправильное (или хотя бы немного другое) дерево с помощью wp_insert_attachment. media_sideload_image удалось вытащить вложения из других блогов при одной и той же многоузловой установке, скопировать их в каталог загрузок агрегирующего блога и сгенерировать миниатюры, в то время как wp_insert_attachment делал то, что предполагалось, а это оказалось не тем, что я хотел. Я понимаю, что это всего лишь небольшое отклонение от других достаточно хорошо объясненных применений аналогичной функциональности, но я решил опубликовать здесь свое решение на тот случай, если кому-то удастся добиться большего успеха в применении этой конкретной комбинации решений.

Мне все еще кажется, что я делаю это не самым эффективным образом, но пока это работает:

function switch_and_insert($srcblog, $targetcat, $fromcat) {
  switch_to_blog($srcblog);
  $args  = array( 'numberposts' => 1, 'category_name' => $fromcat);
  $flastpost = get_posts( $args );
  foreach($flastpost as $post) : setup_postdata($post);
    $extrapost = array();
    $extrapost['post_title'] = get_the_title($post);
    $extrapost['post_content'] = get_the_post_thumbnail();
    $extrapost['comment_status'] = 'closed';
    $extrapost['post_status'] = 'publish';
    $extrapost['post_date'] = get_the_date( $d = 'Y-m-d H:i:s');
    $extrapost['post_category'] = array($targetcat);
    $oldid = get_the_ID();
    if ( has_post_thumbnail($oldid)) {
        $filename = wp_get_attachment_url( get_post_thumbnail_id($post->ID) );
    }
    else $filename = $forchomper; // URL of backup image
    switch_to_blog($aggregator_blog_id);
        $post_id = wp_insert_post($extrapost);
        $wp_filetype = wp_check_filetype(basename($filename), null );
        $wp_upload_dir = wp_upload_dir();
        $attachment = array(
            'guid' => _wp_relative_upload_path( $filename ), 
            'post_mime_type' => $wp_filetype['type'],
            'post_title' => preg_replace('/\.[^.]+$/', '', basename($filename)),
            'post_content' => '',
            'post_status' => 'inherit'
        );
        require_once(ABSPATH . "wp-admin" . '/includes/media.php');
        require_once(ABSPATH . "wp-admin" . '/includes/image.php');
        require_once(ABSPATH . "wp-admin" . '/includes/file.php');
        $sideloaded = media_sideload_image($filename, $post_id);
        $attachments = get_children($post_id);
        foreach ( $attachments as $attachment_id => $attachment );
        set_post_thumbnail($post_id, $attachment_id);
    restore_current_blog();
    wp_reset_postdata();
  endforeach;
  restore_current_blog();
}

Возможно, это не заслуживает внимания, но, тем не менее, я упомяну, что использование этого метода предоставило очень удобную возможность применить изображение-заполнитель в качестве миниатюры / избранного изображения в том случае, если в исходном сообщении его не было, что является другое решение, чем предложенное более широко, которое опирается на условие в теме, используемой для отображения заполнителя, которое фактически не назначает его в качестве эскиза сообщения. Я понимаю, что в большинстве случаев это лучшее решение, но в моем случае эти сообщения должны иметь свои собственные прикрепленные изображения, даже если они являются дубликатами.

Вот пара вещей, которые помогли: https://wordpress.stackexchange.com/a/19847/14351 http://old.nabble.com/Uploading-image-attachments-from-the-front-end-td26307647.html

...