【问题标题】:How to create new post with photo attached in WordPress using XMLRPC?如何使用 XMLRPC 在 WordPress 中创建附有照片的新帖子?
【发布时间】:2011-09-30 07:51:12
【问题描述】:

有人知道如何使用 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 )
}
?>

【问题讨论】:

    标签: php wordpress xml-rpc attachment metaweblog


    【解决方案1】:

    当您发帖时,WordPress 将在帖子中扫描 IMG 标签。 如果 WP 找到图像,则将其加载到其媒体库中。如果正文中有图片,它会自动将其附加到帖子中。

    基本上你必须:

    • 先发布媒体(图片)
    • 获取其网址
    • 在帖子正文中包含带有 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
            )
        );
    }
    

    【讨论】:

      【解决方案2】:

      我参与了 WordPress 网站(我现在的雇主使用其中的 3 个)并且每天大量发布内容,这迫使我使用我最擅长的东西——脚本!

      它们是基于 PHP 的,使用和部署快速且简单。和安全?只需使用 .htaccess 来保护它。

      根据研究,涉及文件的 XMLRPC 是 wordpress 真正糟糕的一件事。上传文件后,您无法将该附件与特定帖子相关联!我知道,这很烦人。

      所以我决定自己解决。我花了一个星期来整理它。您需要 100% 控制符合 XMLRPC 的发布客户端,否则这对您没有任何意义!

      您将需要,从您的 WordPress 安装中:

      • class-IXR.php,位于 /wp-admin/includes
      • class-wp-xmlrpc-server.php,位于/wp-includes

      如果您像我一样制作自己的发布工具,则需要 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。如果您使用其他东西,那么我无法帮助您。 :(

      希望这对某些人有所帮助。

      【讨论】:

      【解决方案3】:

      调用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 for PHP 进行了测试,其余代码与问题中的完全相同。

      【讨论】:

        【解决方案4】:

        这是一些示例代码,用于从 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 );  
        }
        ?>
        

        【讨论】:

        • 对不起。感谢您的示例代码,但我正在寻找在 XML-RPC 中完成的方法。
        【解决方案5】:

        几个月前我不得不这样做。这是可能的,但不仅是hacky和无证我不得不通过wordpress源挖掘来弄清楚。我当时写的:

        绝对没有记录的一件事是将图像附加到帖子的方法。经过一番挖掘,我发现了 attach_uploads() ,这是 wordpress 每次通过 xml-rpc 创建或编辑帖子时都会调用的函数。它所做的是搜索未附加的媒体对象列表,并查看新/编辑的帖子是否包含指向它们的链接。由于我试图附加图像以便主题库使用它们,我不一定想链接到帖子中的图像,也不想编辑 wordpress。所以我最终做的是在 html 评论中包含图像 url。 -- danieru.com

        就像我说的杂乱无章,但我到处寻找更好的方法,我有理由确定不存在。

        【讨论】:

        • $id = media_handle_sideload( $data, $this-&gt;_post_id, $title ) + update_post_meta( $this-&gt;_post_id, '_thumbnail_id', $this-&gt;_thumb_id = $id )
        【解决方案6】:

        从 Wordpress 3.5 开始,newmediaobject 现在可以半原生地识别 hack。

        不再需要破解 class-wp-xmlrpc-server.php。

        相反,您的 xml-rpc 客户端需要将帖子编号发送到名为 post_id 的变量。 (以前只是变量'post')

        希望对某人有所帮助。

        【讨论】:

        • 嗨,那么是否可以在不编辑 wordpress 的情况下在 XMLRPC 中完成所有操作?如果是的话,步骤是什么?我在这里提出了一个新问题stackoverflow.com/questions/17722743/… 谢谢。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-17
        • 1970-01-01
        • 2012-11-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多