前两篇文章介绍了插件设置页面的编写和osc open api的授权相关内容,这节我们将实现把文章同步到osc博客上。我们先看文档关于这个api的描述 :http://www.oschina.net/openapi/docs/blog_pub

测试restful api时,我推荐安装chrome的postman扩展。从设置页复制access token,其他参数按照文档的说法填写,如图:

屏幕截图 2016-07-08 22.00.19

成功后返回的数据:

success

不得不吐槽一下,oschina博客相关 api很简陋,CURD只实现了Create的和Read部分,没有Delete,没有Update, 而且接口返回内容也不太对劲,讲道理的话,本应返回个成功后的blog文章id或者url吧,方便将wp的文章id跟oschina的文章id进行对应,并且需要 id 才可以使用文章详情的api吧,只给个“操作成功完成” 也太草草事了吧。希望oschina之后能改进。

还有一点,文档没有详细说明部分参数的作用和取值,比如catalog,实际上取值博客主页里的”工作日志”,”日常记录”和”转帖文章”的数字id,把鼠标放上去可以看到url上的数字。

aaaaa

还有一个是classification,就是分类的id,可以在文章编辑器下的分类中查看,取值是option的value.

value

 

好了,接下来开始写 wordpress 插件的部分,这里需要用到 publish_post action

向__construct方法加入一个新的钩子。

add_action('publish_post', array($this,'publish_post'),10,2); 

第三个参数10表示执行的优先级,在wordpress里一个钩子可以挂靠多个回调函数,这个参数数值越大,执行的回调方法的顺序越靠后,10是默认值。

最后一个参数表示回调函数接收几个参数,publish_post action 接收文章两个参数,id和$post对象,所以填2。

现在我们加入两个方法。

// 发布文章时同步到osc
public function publish_post($ID,$post) {

    //$permalink = get_permalink( $ID ); 固定链接


    $post_arr = array();
    $tags = "";
    $post_arr['title'] = $post->post_title;
    $post_arr['content'] = $post->post_content;
    $tags_arr = wp_get_post_tags($ID);
    if(!empty($tags_arr)){
        foreach($tags_arr as $tag) {
            $tags .= $tag->name .',';
        }
        $tags = rtrim($tags,',');
    }
    $post_arr['tags'] = $tags;
    $response = $this->_blog_pub($post_arr);
    if(is_wp_error()){
        var_dump($response);
        exit;
    }


}

// open api发布博客
protected function _blog_pub($args = array()){
    /**
     * access_token    true   string     oauth2_token获取的access_token
    title  true   string     博客标题
    content    true   string     博客内容
    save_as_draft  false  int    保存到草稿 是:1 否:0  0
    catalog    false  string     博客分类, 工作日志:304043,日常记录:304044,转帖的文章:304045
    abstracts  false  string     博客摘要
    tags   false  string     博客标签,用逗号隔开
    classification     true   int    系统博客分类     0
    428602>移动开发
    428612>前端开发
    428640>服务端开发/管理
    429511>游戏开发
    428609>编程语言
    428610>数据库
    428611>企业开发
    428647>图像/多媒体
    428613>系统运维
    428638>软件工程
    428639>云计算
    430884>开源硬件
    430381>其他类型
    type   false  int    原创:1、转载:4  1
    origin_url     false  string     转载的原文链接
    privacy    false  string     公开:0、私有:1  0
    deny_comment   false  string     允许评论:0、禁止评论:1  0
    auto_content   false  string     自动生成目录:0、不自动生成目录:1     0
    as_top     false  string     非置顶:0、置顶:1     0
     */

    $defaults = array(
        'title' => "",
        "content" => "",
        "save_as_draft" => 0,
        "catalog" => 304043,//工作日志:304043,日常记录:304044,转帖的文章:304045
        "abstracts" => "",
        "tags" => "",
        "classification" => 430381,
        "type" => 1,
        "origin_url" => "",
        "privacy" => 0,
        "deny_comment" => 1,
        "auto_content" => 0,
        "as_top" => 0,
        "access_token" => $this->_get_access_token()
    );

    $args = wp_parse_args($args, $defaults);
    $url = $this->api_site . '/action/openapi/blog_pub';
    $response = wp_remote_post($url, array('body' => $args,'sslverify'=>true));
    return $response;

}

 

好了,我们测试一下,在wordpress新建一篇文章,随便写点内容,点击发布。这时我们再打开osc的个人主页,文章已经同步过来了。

屏幕截图 2016-07-11 09.44.08

屏幕截图 2016-07-11 09.45.12

 

文章同步成功了,接下来我们来自定义同步的一些选项吧,比如同步时选择分类,置顶,是否转帖等。

增加一个meta box,就是类似文章编辑页下面和旁边的区块,里面有一些可以设置的内容,比如标签:

屏幕截图 2016-07-11 10.31.38

首先在构造器上加入一个action,

add_action( 'add_meta_boxes', array($this,'add_meta_boxes') );

然后新加入两个方法:

public function add_meta_boxes(){
    //加入一个metabox
    add_meta_box( "oscpress_meta_box", '<strong>OSCPress文章同步</strong>', array($this,'meta_box_callback')) ;
}

// 显示在metabox的内容
public function meta_box_callback(){
    echo "hello, meta box";
}

完成后刷新文章编辑页,可以看到metabox出现在编辑器下方了。

屏幕截图 2016-07-11 10.48.51

把选项的html加到meta_box_callback里去:

    // 显示在metabox的内容
    public function meta_box_callback(){
?>
        <div class="oscpress_options">
            <strong>是否同步这篇文章:</strong>
            <label><input type="radio" name="oscpress_syn_enable" value="1" />是</label>
            <label><input type="radio" name="oscpress_syn_enable" value="0" checked/>否</label>
        </div>
        <div class="oscpress_options">
            <strong>分类:</strong>
            <label><input type="radio" name="oscpress_syn[catalog]" value="304043" checked/>工作日志</label>
            <label><input type="radio" name="oscpress_syn[catalog]" value="304044" />日常记录</label>
            <label><input type="radio" name="oscpress_syn[catalog]" value="304044" />转帖的文章</label>
        </div>

        <div class="oscpress_options">
            <strong>系统分类:</strong>
            <select class="select_box" name="oscpress_syn[classification]" id="blogcatalogselect">
                <option value="428602" ref="blog-classification">移动开发</option>
                <option value="428612" ref="blog-classification">前端开发</option>
                <option value="428640" ref="blog-classification">服务端开发/管理</option>
                <option value="429511" ref="blog-classification">游戏开发</option>
                <option value="428609" ref="blog-classification">编程语言</option>
                <option value="428610" ref="blog-classification">数据库</option>
                <option value="428611" ref="blog-classification">企业开发</option>
                <option value="428647" ref="blog-classification">图像/多媒体</option>
                <option value="428613" ref="blog-classification">系统运维</option>
                <option value="428638" ref="blog-classification">软件工程</option>
                <option value="428639" ref="blog-classification">云计算</option>
                <option value="430884" ref="blog-classification">开源硬件</option>
                <option value="430381" ref="blog-classification" selected>其他类型</option>
            </select>
        </div>
        <div class="oscpress_options">
            <strong>文章类型:</strong>
            <label><input type="radio" name="oscpress_syn[type]" value="0">原创</label>
            <label><input type="radio" name="oscpress_syn[type]" value="1">转帖</label>
        </div>
        <div class="oscpress_options">
            <strong>原文链接:</strong>
            <label><input type="text" size=80 name="oscpress_syn[origin_url]" value="" placeholder="原文链接,可留空"></label>

        </div>
        <div class="oscpress_options">
            <strong>是否对所有人可见:</strong>
            <label><input type="radio" name="oscpress_syn[privacy]" value="0" checked>可见</label>
            <label><input type="radio" name="oscpress_syn[privacy]" value="1" >私密</label>
        </div>
        <div class="oscpress_options">
            <strong>是否允许评论:</strong>
            <label><input type="radio" name="oscpress_syn[deny_comment]" value="0" checked>允许</label>
            <label><input type="radio" name="oscpress_syn[deny_comment]" value="1" >禁止</label>
        </div>
        <div class="oscpress_options">
            <strong>是否自动生成目录:</strong>
            <label><input type="radio" name="oscpress_syn[auto_content]" value="0" checked>不生成目录</label>
            <label><input type="radio" name="oscpress_syn[auto_content]" value="1" >生成目录</label>
        </div>
        <div class="oscpress_options">
            <strong>是否在博客列表置顶:</strong>
            <label><input type="radio" name="oscpress_syn[as_top]" value="0" checked>不置顶</label>
            <label><input type="radio" name="oscpress_syn[as_top]" value="1" >置顶</label>
        </div>

        <?php
    }

效果如图:

屏幕截图 2016-07-11 11.43.04

我们修改一下样式:

    // 显示在metabox的内容
    public function meta_box_callback(){

?>
        <style>
            .oscpress_options{
                margin: 10px;
            }
            .oscpress_options strong,.oscpress_options label,.oscpress_options select{
                display: inline-block;
                margin-right: 5px;
            }
            .oscpress_options strong {
                font-weight: 200;
            }
        </style>
        <div class="oscpress_options">
            <strong>是否同步这篇文章:</strong>
            <label><input type="radio" name="oscpress_syn_enable" value="1" />是</label>
            <label><input type="radio" name="oscpress_syn_enable" value="0" checked/>否</label>
        </div>
....

这样感觉好多了。

屏幕截图 2016-07-11 11.52.18

好了,我们需要修改一下public_post方法,在同步文章时才能应用这些选项。

// 发布文章时同步到osc
public function publish_post($ID,$post) {

    //$permalink = get_permalink( $ID ); 固定链接

    if( isset($_POST['oscpress_syn_enable']) && $_POST['oscpress_syn_enable'] == 0){
        return ; // 不同步到osc博客
    }


    $post_arr = array();
    $tags = "";
    $post_arr['title'] = $post->post_title;
    $post_arr['content'] = $post->post_content;
    $post_arr['abstracts'] = get_the_excerpt($ID);
    $tags_arr = wp_get_post_tags($ID);
    if(!empty($tags_arr)){
        foreach($tags_arr as $tag) {
            $tags .= $tag->name .',';
        }
        $tags = rtrim($tags,',');
    }
    $post_arr['tags'] = $tags;
    $post_arr = array_merge($post_arr,$_POST['oscpress_syn']);
    $response = $this->_blog_pub($post_arr);



}

同步成功后发送到动弹:

继续修改publish_post方法,发送动弹,并将同步时用户选项写入post_meta。:

// 发布文章时同步到osc
public function publish_post($ID,$post) {



    if( isset($_POST['oscpress_syn_enable']) && $_POST['oscpress_syn_enable'] == 0){
        return ; // 不同步到osc博客
    }

    $post_arr = array();
    $tags = "";
    $post_arr['title'] = $post->post_title;
    $post_arr['content'] = $post->post_content;
    $post_arr['abstracts'] = get_the_excerpt($ID);
    $tags_arr = wp_get_post_tags($ID);
    if(!empty($tags_arr)){
        foreach($tags_arr as $tag) {
            $tags .= $tag->name .',';
        }
        $tags = rtrim($tags,',');
    }
    $post_arr['tags'] = $tags;
    $post_arr = array_merge($post_arr,$_POST['oscpress_syn']);
    unset($post_arr['tweet_enable']);
    $response = $this->_blog_pub($post_arr);
    if(!is_wp_error($response) ){

        if($_POST['oscpress_syn']['tweet_enable']) {
            $post_link = apply_filters('oscpress_sync_link',wp_get_shortlink($ID),$ID); // 发布到osc动弹的文章链接

            $tweet_template ="发布了一篇文章:<<%%post_title%%>>, 链接:%%post_link%%, 自豪地使用 OscPress";
            $tweet_content = str_replace(
                array('%%post_title%%','%%post_link%%'),
                array($post_arr['title'],$post_link),
                $tweet_template
            );
            $response2  = $this->_send_tweet($tweet_content);
        }
        $oscpress_syn = $_POST['oscpress_syn'];
        $oscpress_syn['timestamp'] = current_time('timestamp');
        update_post_meta($ID,'_oscpress_syn',$oscpress_syn);


    }else{
        //var_dump($response);
        //exit;
    }


}

 

增加发送动弹和获取文章同步选项方法:

//  发布一条动弹
protected function _send_tweet($content,$img_path = null)
{
    $url = $this->api_site . '/action/openapi/tweet_pub';

    $args = array(
        'access_token' => $this->_get_access_token(),
        'msg' => $content,
    );
    return  wp_remote_post($url, array('body' => $args));
}
// 获取指定文章同步选项
protected function _get_syn_data( $post_id = null ) {
    $post = get_post($post_id);
    return get_post_meta($post->ID,"_oscpress_syn",true);
}

post meta box增加一个发布动弹的可选项:

    // 显示在metabox的内容
    public function meta_box_callback(){



?>
        <style>
            .oscpress_options{
                margin: 10px;
            }
            .oscpress_options strong,.oscpress_options label,.oscpress_options select{
                display: inline-block;
                margin-right: 5px;
            }
            .oscpress_options strong {
                font-weight: 200;
            }
        </style>

        <div class="oscpress_options">
            <strong>是否同步这篇文章:</strong>
            <label><input type="radio" name="oscpress_syn_enable" value="1" checked />是</label>
            <label><input type="radio" name="oscpress_syn_enable" value="0" />否</label>
        </div>
        <div class="oscpress_options">
            <strong>是否同步后发动弹:</strong>
            <label><input type="radio" name="oscpress_syn[tweet_enable]" value="1" checked />是</label>
            <label><input type="radio" name="oscpress_syn[tweet_enable]" value="0" />否</label>
        </div>
...

最后修改meta box的标题,把同步信息显示出来。

public function add_meta_boxes(){
    //加入一个metabox
    $sync_data = $this->_get_syn_data();
    $sync_info = "";
    if($sync_data){
        $sync_info = sprintf("<span style='font-weight: normal;'> ( 上次同步于: %s ) </span>" , date_i18n('Y-m-d H:i:s',$sync_data['timestamp']));
    }
    add_meta_box( "oscpress_meta_box", '<strong>OSCPress文章同步</strong>'.$sync_info, array($this,'meta_box_callback')) ;
}

完成后再更新文章,可以看到同步的消息已经显示出来了。

屏幕截图 2016-07-11 15.31.15

好了,现在基本功能已经完成,下一节我们将补充一些其他内容。增加更多设置项和代码优化。

- EOF -