Как создать новый пост с фотографией, прикрепленной в WordPress, используя XMLRPC? - PullRequest
5 голосов
/ 30 сентября 2011

Кто-нибудь знает, как создать новое сообщение с фотографией, прикрепленной в WordPress, с помощью XMLRPC?

Я могу создать новое сообщение и загрузить новое изображение отдельно, но похоже, что нет никакого способаприкрепить загруженное фото к созданному посту?

Ниже приведены коды, которые я сейчас использую.

<?php
DEFINE('WP_XMLRPC_URL', 'http://www.blog.com/xmlrpc.php');
DEFINE('WP_USERNAME', 'username');
DEFINE('WP_PASSWORD', 'password');

require_once("./IXR_Library.php");
$rpc = new IXR_Client(WP_XMLRPC_URL);
$status = $rpc->query("system.listMethods"); // method name
if(!$status){
    print "Error (".$rpc->getErrorCode().") : ";
    print $rpc->getErrorMessage()."\n";
    exit;
}

$content['post_type'] = 'post'; // post title
$content['title'] = 'Post Title '.date("F j, Y, g:i a"); // post title
$content['categories'] = array($response[1]['categoryName']); // psot categories
$content['description'] = '<p>Hello World!</p>'; // post body
$content['mt_keywords'] = 'tag keyword 1, tag keyword 2, tag keyword 3'; // post tags
$content['mt_allow_comments'] = 1; // allow comments
$content['mt_allow_pings'] = 1; // allow pings
$content['custom_fields'] = array(array('key'=>'Key Name', 'value'=>'Value One')); // custom fields
$publishBool = true;

if(!$rpc->query('metaWeblog.newPost', '', WP_USERNAME, WP_PASSWORD, $content, $publishBool)){
    die('An error occurred - '.$rpc->getErrorCode().":".$rpc->getErrorMessage());
}
$postID = $rpc->getResponse();
echo 'POST ID: '.$postID.'<br/>';

if($postID){ // if post has successfully created

    $fs = filesize(dirname(__FILE__).'/image.jpg');
    $file = fopen(dirname(__FILE__).'/image.jpg', 'rb');
    $filedata = fread($file, $fs);
    fclose($file);

    $data = array(
        'name'  => 'image.jpg',
        'type'  => 'image/jpg',
        'bits'  => new IXR_Base64($filedata),
        false // overwrite
    );

    $status = $rpc->query(
        'metaWeblog.newMediaObject',
        $postID,
        WP_USERNAME,
        WP_PASSWORD,
        $data
    );
    echo print_r($rpc->getResponse()); // Array ( [file] => image.jpg [url] => http://www.blog.com/wp-content/uploads/2011/09/image.jpg [type] => image/jpg )
}
?>

Ответы [ 6 ]

9 голосов
/ 31 декабря 2011

Я принимал участие в сайтах WordPress (мой нынешний работодатель использует 3 из них) и ежедневно публиковал материалы, и в массовом порядке вынудил меня использовать то, что я делаю лучше всего - скрипты!

Они основаны на PHP, быстры и просты в использовании и развертывании. А безопасность? Просто используйте .htaccess, чтобы обезопасить его.

Согласно исследованию, XMLRPC, когда дело доходит до файлов, - это одна вещь, которую WordPress действительно тянет. После загрузки файла вы не можете связать это вложение с определенным сообщением! Я знаю, это раздражает.

Поэтому я решил выяснить это для себя. Мне потребовалась неделя, чтобы разобраться. Вам потребуется 100% контроль над вашим издательским клиентом, совместимым с XMLRPC, иначе это ничего не будет значить для вас!

Вам понадобится из вашей установки WordPress:

  • class-IXR.php, расположенный в / wp-admin / включает в себя
  • class-wp-xmlrpc-server.php, расположенный в / wp-includes

class-IXR.php понадобится, если вы создадите свой собственный инструмент для публикации сообщений, как я. У них есть правильно работающий кодер base64. Не доверяйте тому, что поставляется с PHP.

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

  1. Изменить class-wp-xmlrpc-server.php

    • Загрузите это на свой компьютер через ftp. Сделайте резервную копию на всякий случай.
    • Откройте файл в текстовом редакторе. Если он не отформатирован, (как правило, это должны быть разрывы каретки Unix-типа, которые они используют), откройте его в другом месте или используйте что-то вроде ultraedit.
    • Обратите внимание на функцию mw_newMediaObject. Это наша цель. Небольшое примечание здесь; WordPress позаимствовал функциональность у блоггера и movabletype. Хотя WordPress также имеет уникальные наборы классов для xmlrpc, они предпочитают поддерживать функциональность общей, чтобы они работали независимо от используемой платформы.
    • Ищите функцию mw_newMediaObject($args). Как правило, это должно быть в строке 2948. Обратите внимание на строку состояния вашего текстового редактора, чтобы узнать, в каком номере строки вы находитесь. Если вы все еще не можете найти его, найдите его, используя функцию поиска / поиска вашего текстового редактора.
    • Прокрутите немного вниз, и у вас должно получиться что-то похожее на это:

       $name = sanitize_file_name( $data['name'] );
       $type = $data['type'];
       $bits = $data['bits'];
      
    • После переменной $ name мы что-нибудь добавим. Смотри ниже.

       $name = sanitize_file_name( $data['name'] );
       $post = $data['post']; //the post ID to attach to.
       $type = $data['type'];
       $bits = $data['bits'];
      

      Обратите внимание на новую переменную $ post. Это означает, что всякий раз, когда вы будете подавать новый запрос на загрузку файла, вам будет доступен аргумент «post».

      Как найти номер вашего сообщения, зависит от того, как вы добавляете сообщения с помощью клиента, совместимого с xmlrpc. Как правило, вы должны получить это в результате публикации. Это числовое значение.

      После того как вы отредактировали вышесказанное, пришло время перейти к строке 3000.

      // Construct the attachment array
      // attach to post_id 0
      $post_id = 0;
      $attachment = array(
          'post_title' => $name,
          'post_content' => '',
          'post_type' => 'attachment',
          'post_parent' => $post_id,
          'post_mime_type' => $type,
          'guid' => $upload[ 'url' ]
      );
      
    • Так вот почему ни одно изображение не связано ни с одним сообщением! По умолчанию это всегда 0 для аргумента post_parent! Это больше не будет так.

      // Construct the attachment array
      // attach to post_id 0
      $post_id = $post;
      $attachment = array(
          'post_title' => $name,
          'post_content' => '',
          'post_type' => 'attachment',
          'post_parent' => $post_id,
          'post_mime_type' => $type,
          'guid' => $upload[ 'url' ]
      );
      

      $ post_id теперь принимает значение $ post, полученное из запроса xmlrpc. Как только это будет зафиксировано во вложении, оно будет связано с любым сообщением, которое вы пожелаете!

      Это можно улучшить. Может быть назначено значение по умолчанию, чтобы все не нарушалось, если значение не введено. Хотя со своей стороны я установил значение по умолчанию на своем клиенте, и никто, кроме меня, не обращается к интерфейсу XMLRPC.

    • После внесения изменений сохраните файл и повторно загрузите его по тому же пути, в котором вы его нашли. Опять же, обязательно делайте резервные копии.

      Остерегайтесь обновлений WordPress, которые влияют на этот модуль. Если это произойдет, вам нужно повторно применить это изменение еще раз!

  2. Включите class-IXR.php в ваш редактор PHP-типов. Если вы используете что-то еще, ну, я не могу вам там помочь. (

Надеюсь, это поможет некоторым людям.

3 голосов
/ 06 июня 2012

Когда вы публикуете, WordPress будет сканировать в посте IMG-теги.Если WP находит изображение, оно загружается в его медиатеку.Если в теле есть изображение, оно будет автоматически прикреплено к сообщению.

В основном вам необходимо:

  • сначала опубликовать медиа (изображение)
  • Захватите его URL
  • , включите URL изображения с тегом IMG в текст вашего сообщения.
  • затем создайте сообщение

Вот пример кода.Требуется обработка ошибок и дополнительная документация.

$admin ="***";
$userid ="****";
$xmlrpc = 'http://localhost/web/blog/xmlrpc.php';
include '../blog/wp-includes/class-IXR.php';
$client = new IXR_Client($xmlrpc);

$author         =   "test";    
$title          =   "Test Posting";
$categories     =   "chess,coolbeans";
$body           =   "This is only a test disregard </br>";

$tempImagesfolder = "tempImages";
$img = "1338494719chessBoard.jpg";


$attachImage = uploadImage($tempImagesfolder,$img);
$body .= "<img src='$attachImage' width='256' height='256' /></a>";

createPost($title,$body,$categories,$author);

/*
*/
function createPost($title,$body,$categories,$author){
    global $username, $password,$client;
    $authorID =  findAuthor($author); //lookup id of author

    /*$categories is a list seperated by ,*/
    $cats = preg_split('/,/', $categories, -1, PREG_SPLIT_NO_EMPTY);
    foreach ($cats as $key => $data){
        createCategory($data,"","");
    }

    //$time = time();
    //$time += 86400;
    $data = array(
        'title' => $title,
        'description' => $body,
        'dateCreated' => (new IXR_Date(time())),
        //'dateCreated' => (new IXR_Date($time)),  //publish in the future
        'mt_allow_comments' => 0, // 1 to allow comments
        'mt_allow_pings' => 0,// 1 to allow trackbacks
        'categories' => $cats,
        'wp_author_id' => $authorID     //id of the author if set       
    );
    $published = 0; // 0 - draft, 1 - published
    $res = $client->query('metaWeblog.newPost', '', $username, $password, $data, $published);
}

/*
*/
function uploadImage($tempImagesfolder,$img){
    global $username, $password,$client;
    $filename = $tempImagesfolder ."/" . $img;

    $fs = filesize($filename);   
    $file = fopen($filename, 'rb');  
    $filedata = fread($file, $fs);    
    fclose($file); 

    $data = array(
        'name'  => $img, 
        'type'  => 'image/jpg',  
        'bits'  => new IXR_Base64($filedata), 
        false //overwrite
    );

    $res = $client->query('wp.uploadFile',1,$username, $password,$data);
    $returnInfo = $client->getResponse();

    return $returnInfo['url'];     //return the url of the posted Image
}

/*
*/
function findAuthor($author){
    global $username, $password,$client;
    $client->query('wp.getAuthors ', 0, $username, $password);
    $authors = $client->getResponse();
    foreach ($authors as $key => $data){
        //  echo $authors[$key]['user_login'] . $authors[$key]['user_id'] ."</br>";
        if($authors[$key]['user_login'] == $author){
            return $authors[$key]['user_id'];
        }
    }
    return "not found";
}

/*
*/
function createCategory($catName,$catSlug,$catDescription){
    global $username, $password,$client;
    $res = $client->query('wp.newCategory', '', $username, $password,
        array(
            'name' => $catName,
            'slug' => $catSlug,
            'parent_id' => 0,
            'description' => $catDescription
        )
    );
}
1 голос
/ 07 июня 2014

После вызова метода metaWeblog.newMediaObject нам нужно отредактировать запись изображения в базе данных, чтобы добавить родителя (ранее созданный пост с metaWeblog.newPost).

Если мы попробуем с metaWeblog.editPost, выдается ошибка 401, которая указывает, что

// Use wp.editPost to edit post types other than post and page.
if ( ! in_array( $postdata[ 'post_type' ], array( 'post', 'page' ) ) )
    return new IXR_Error( 401, __( 'Invalid post type' ) );

Решением является вызов wp.editPost, который принимает следующие аргументы:

$blog_id        = (int) $args[0];
$username       = $args[1];
$password       = $args[2];
$post_id        = (int) $args[3];
$content_struct = $args[4];

Итак, сразу после newMediaObject мы делаем:

$status = $rpc->query(
    'metaWeblog.newMediaObject',
    $postID,
    WP_USERNAME,
    WP_PASSWORD,
    $data
);
$response = $rpc->getResponse();
if( isset($response['id']) ) {
    // ATTACH IMAGE TO POST
    $image['post_parent'] = $postID;
    if( !$rpc->query('wp.editPost', '1', WP_USERNAME, WP_PASSWORD, $response['id'], $image)) {
        die( 'An error occurred - ' . $rpc->getErrorCode() . ":" . $rpc->getErrorMessage() );
    }
    echo 'image: ' . $rpc->getResponse();

    // SET FEATURED IMAGE
    $updatePost['custom_fields'] = array( array( 'key' => '_thumbnail_id', 'value' => $response['id'] ) );
    if( !$rpc->query( 'metaWeblog.editPost', $postID, WP_USERNAME, WP_PASSWORD, $updatePost, $publishBool ) ) {
        die( 'An error occurred - ' . $rpc->getErrorCode() . ":" . $rpc->getErrorMessage() );
    }
    echo 'update: ' . $rpc->getResponse();
}

Я использовал для проверки Incutio XML-RPC Library для PHP , а остальная часть кода точно такая же, как в вопросе.

1 голос
/ 30 сентября 2011

Вот пример кода для вложения изображения из пути, не поддерживаемого WordPress (wp-content)

<?php
function attach_wordpress_images($productpicture,$newid)
{
    include('../../../../wp-load.php');
    $upload_dir = wp_upload_dir();
    $dirr = $upload_dir['path'].'/';

    $filename = $dirr . $productpicture;                    
    # print "the path is : $filename \n";                    
    # print "Filnamn: $filename \n";                
    $uploads = wp_upload_dir(); // Array of key => value pairs
    # echo $uploads['basedir'] . '<br />';
    $productpicture = str_replace('/uploads','',$productpicture);
    $localfile =  $uploads['basedir'] .'/' .$productpicture;
    #  echo "Local path = $localfile \n";         

    if (!file_exists($filename))
    {
        echo "hittade inte $filename !";
        die ("no image for flaska $id $newid !");                                                   
    }
    if (!copy($filename, $localfile)) 
    {
        wp_delete_post($newid);
        echo  "Failed to copy the file $filename to $localfile ";
        die("Failed to copy the file $filename to $localfile ");
    }

    $wp_filetype = wp_check_filetype(basename($localfile), null );
    $attachment = array(
        'post_mime_type' => $wp_filetype['type'],
        'post_title' => preg_replace('/\.[^.]+$/', '', basename($localfile)),
        'post_content' => '',
        'post_status' => 'inherit'
        );
    $attach_id = wp_insert_attachment( $attachment, $localfile, $newid );

    // you must first include the image.php file
    // for the function wp_generate_attachment_metadata() to work

    require_once(ABSPATH . 'wp-admin/includes/image.php');        
    $attach_data = wp_generate_attachment_metadata( $attach_id, $localfile );
    wp_update_attachment_metadata( $attach_id, $attach_data );  
}
?>
0 голосов
/ 29 декабря 2012

Начиная с Wordpress 3.5, newmediaobject теперь распознает хак почти естественным образом.

больше не нужно взламывать class-wp-xmlrpc-server.php.

Вместо этого ваш xml-rpc клиент должен отправить номер записи в переменную с именем post_id. (Ранее это была просто переменная 'post')

Надеюсь, это поможет кому-то.

0 голосов
/ 04 ноября 2011

Я должен был сделать это несколько месяцев назад. Это возможно, но не только потому, что это нахально и недокументировано. Мне пришлось копаться в источнике WordPress, чтобы понять это. То, что я написал тогда:

Одной вещью, которая была абсолютно недокументирована, был способ прикрепить изображение к сообщению. После некоторых копаний я обнаружил метод attach_uploads (), который wordpress вызывает каждый раз, когда сообщение создается или редактируется через xml-rpc. Он выполняет поиск по списку неприкрепленных медиа-объектов и проверяет, содержит ли новая / отредактированная запись ссылку на них. Так как я пытался прикрепить изображения, чтобы галерея их использовала их, я не хотел ссылаться на изображения в сообщении, а также не хотел редактировать WordPress. В итоге я включил ссылку на изображение в html-комментарий. - danieru.com

Как я и сказал, грязно, но я искал все выше и ниже для лучшего метода, и я вполне уверен, что ни один не существует.

...