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

Кто-нибудь знает, как создать новую запись с фотографией, прикрепленной в 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:ia"); // 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 ) } ?> 

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

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

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

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

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

  • class-IXR.php, расположенный в / wp-admin / includes
  • class-wp-xmlrpc-server.php, расположенный в / wp-include

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

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

  1. Изменить класс-wp-xmlrpc-server.php

    • Загрузите это на свой компьютер через ftp. Резервное копирование копии на всякий случай.
    • Откройте файл в текстовом редакторе. Если он не отформатирован, (как правило, он должен, иначе, использовать разрывы каретки unix-типа, которые они используют) открыть его в другом месте или использовать что-то вроде ultraedit.
    • Обратите внимание на функцию mw_newMediaObject . Это наша цель. Небольшая заметка здесь; WordPress заимствует функциональность от blogger и 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. Включите класс-IXR.php в свой редактор PHP-типа. Если вы используете что-то еще, я не могу вам помочь. 🙁

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

Когда вы отправляете сообщение, 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 ) ); } 

После вызова метода 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(); } 

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

Вот пример кода для прикрепления изображения с пути, не поддерживаемого 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 ); } ?> в <?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 ); } ?> 

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

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

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

Начиная с WordPress 3.5, newmediaobject теперь распознает хак полуавтоматически.

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

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

Надежда, которая помогает кому-то.