首页 文章

如何使用XMLRPC在WordPress中创建附有照片的新帖子?

提问于
浏览
5

Anyone knows how to create new post with photo attached in WordPress using 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.'
'; 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 回答

  • 3

    我参与过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附带的那个 .

    您还需要在编程方面有一定的经验才能与此相关 . 我会尽量更清楚 .

    • 修改class-wp-xmlrpc-server.php

    • 通过ftp将此文件下载到您的计算机 . 备份副本,以防万一 .

    • 在文本编辑器中打开文件 . 如果它没有't come formatted, (typically it should, else, it'的unix型运输休息,他们正在使用)在别处打开它或使用像ultraedit这样的东西 .

    • 注意 mw_newMediaObject 功能 . 这是我们的目标 . 这里有一点点说明; WordPress借用博客和移动类型的功能 . 尽管WordPress还为xmlrpc提供了一个独特的类集,但他们选择保持功能的通用性,以便无论使用何种平台,它们都能正常工作 .

    • 寻找函数 mw_newMediaObject($args) . 通常情况下,这应该在第2948行 . 请注意文本编辑器's status bar to find what line number you are in. If you can' t找到它,使用文本编辑器的搜索/查找功能查找它 .

    • 向下滚动一点,你应该看到这样的东西:

    $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现在占用$ post的值,该值来自xmlrpc请求 . 一旦将其提交给附件,它将与您想要的任何帖子相关联!

    这可以改进 . 可以分配默认值,这样如果没有输入值,事情就不会被破坏 . 虽然在我这边,我把默认值放在我的客户端,没有其他人访问XMLRPC接口,但我 .

    • 完成更改后,保存文件并将其重新上传到找到它的同一路径中 . 再次确保进行备份 .

    警惕影响此模块的WordPress更新 . 如果发生这种情况,您需要再次重新应用此编辑!

    • 在PHP类型编辑器中包含class-IXR.php . 如果你正在使用其他东西,那么,我无法帮助你 . :(

    希望这可以帮助一些人 .

  • 1

    当您发布时,WordPress将在帖子上扫描IMG标签 . 如果WP找到图像,它就会加载到它的媒体库中 . 如果身体中有图像,它会自动将其附加到帖子上 .

    基本上你必须:

    • 首先发布媒体(图像)

    • grab 其网址

    • 包含帖子正文中带有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

    在调用方法 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进行测试,其余的代码与问题完全一样 .

  • 0

    以下是一些示例代码,用于附加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'] . '
    '; $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

    几个月前我不得不这样做 . 这是可能的,但不仅是hacky和无证我不得不深入挖掘wordpress来源来解决它 . 那时我写的是:

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

    就像我说的凌乱,但我搜索高低,以获得更好的方法,我有理由相信没有存在 .

  • 9

    从Wordpress 3.5开始,newmediaobject现在可以半原生地识别黑客攻击 .

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

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

    希望能帮助别人 .

相关问题