6

XMLRPCを使用してWordPressで写真を添付し​​て新しい投稿を作成する方法を知っている人はいますか?

新しい投稿を作成して新しい写真を個別にアップロードすることはできますが、アップロードした写真を作成した投稿に添付する方法がないようです。

以下は私が現在使用しているコードです。

<?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 )
}
?>
4

6 に答える 6

9

私は WordPress サイト (私の現在の雇用主はこれらのうちの 3 つを使用しています) に関与しており、毎日投稿を行っています。

それらは PHP ベースであり、すばやく簡単に使用およびデプロイできます。そしてセキュリティ?.htaccess を使用して保護するだけです。

調査によると、ファイルに関する XMLRPC は、wordpress が本当に苦手とするものの 1 つです。ファイルをアップロードしたら、その添付ファイルを特定の投稿に関連付けることはできません。私は知っています、それは迷惑です。

だから私は自分でそれを理解することにしました。整理するのに1週間かかりました。XMLRPC 準拠の発行クライアントを 100% 制御する必要があります。そうしないと、何の意味もありません。

WordPress のインストールから、次のものが必要になります。

  • /wp-admin/includes にある class-IXR.php
  • /wp-includes にある class-wp-xmlrpc-server.php

私のように独自の投稿ツールを作成する場合は、class-IXR.php が必要になります。それらには、正しく機能する base64 エンコーダーがあります。PHP に付属しているものを信用しないでください。

また、これに関連するには、プログラミングの経験がある程度必要です。私はより明確にしようとします。

  1. class-wp-xmlrpc-server.php を修正

    • これを ftp 経由でコンピュータにダウンロードします。念のため、コピーをバックアップしてください。
    • ファイルをテキスト エディタで開きます。フォーマットされていない場合 (通常はフォーマットされている必要があります。それ以外の場合は、使用している UNIX タイプのキャリッジ ブレークです)、別の場所で開くか、ultraedit などを使用してください。
    • 機能に注意してmw_newMediaObjectください。これが私たちの目標です。ここで少し注意してください。WordPress は、ブロガーと可動タイプの機能を借用しています。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' ]
      );
      
    • どの投稿にも画像が関連付けられていない理由は次のとおりです。post_parent 引数のデフォルトは常に 0 です! そんなことはもうありません。

      // 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 は、xmlrpc リクエストから来る $post の値を取得するようになりました。これが添付ファイルにコミットされると、任意の投稿に関連付けられます!

      これは改善できます。値が入力されていない場合に壊れないように、デフォルト値を割り当てることができます。私の側では、クライアントにデフォルト値を設定しましたが、XMLRPC インターフェイスにアクセスしているのは私だけです。

    • 変更が完了したら、ファイルを保存し、見つかったのと同じパスに再アップロードします。繰り返しますが、必ずバックアップを作成してください。

      このモジュールに影響を与える WordPress の更新には注意してください。その場合は、この編集を再度適用する必要があります。

  2. PHP タイプのエディタに class-IXR.php を含めます。他のものを使用している場合は、まあ、私はあなたを助けることができません. :(

これが一部の人々に役立つことを願っています。

于 2011-12-31T07:01:52.423 に答える
3

投稿すると、WordPress は投稿で IMG タグをスキャンします。WP が画像を見つけると、メディア ライブラリに読み込まれます。本文に画像がある場合は、自動的に投稿に添付されます。

基本的に、次のことを行う必要があります。

  • 最初にメディア (画像) を投稿する
  • その URL を取得します
  • 投稿の本文に IMG タグ付きの画像の URL を含めます。
  • 次に投稿を作成します

ここにいくつかのサンプルコードがあります。エラー処理と、さらにいくつかのドキュメントが必要です。

$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
        )
    );
}
于 2012-06-05T20:47:18.983 に答える
1

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 );  
}
?>
于 2011-09-30T09:03:46.090 に答える
1

メソッドを呼び出した後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();
}

PHP用のIncutio XML-RPC Libraryを使用してテストしましたが、残りのコードは質問とまったく同じです。

于 2014-06-07T10:03:33.217 に答える
0

私は数ヶ月前にこれをしなければなりませんでした。それは可能ですが、それはハッキーで文書化されていないだけでなく、私はそれを理解するためにワードプレスのソースを掘り下げなければなりませんでした。当時私が書いたこと:

完全に文書化されていないことの1つは、投稿に画像を添付する方法でした。少し掘り下げた後、私はattach_uploads()を見つけました。これは、投稿がxml-rpcで作成または編集されるたびに、wordpressが呼び出す関数です。アタッチされていないメディアオブジェクトのリストを検索し、新しい/編集された投稿にそれらへのリンクが含まれているかどうかを確認します。テーマのギャラリーで使用できるように画像を添付しようとしていたので、投稿内の画像にリンクしたり、ワードプレスを編集したりする必要はありませんでした。だから私がやったのは、htmlコメント内に画像のURLを含めることでした。--danieru.com _

私が厄介だと言ったように、私はより良い方法を高低で検索しました、そして私は合理的に何も存在しないと確信しています。

于 2011-11-04T06:16:04.757 に答える
0

Wordpress 3.5 の時点で、newmediaobject はハックをセミネイティブに認識するようになりました。

class-wp-xmlrpc-server.php をハックする必要はなくなりました。

代わりに、xml-rpc クライアントは post_id という変数に投稿番号を送信する必要があります。(以前は変数 'post' だけでした)

それが誰かを助けることを願っています。

于 2012-12-29T05:30:36.537 に答える