WLW(Windows Live Write)真是一個方便的好工具,尤其它對於不同部落格系統的相容更是讓不少部落客愛不釋手。

但這好用的 WLW 最近出了一點毛病,當我要發佈或張貼含有附件圖檔的檔案時,就會出現 Invalid response document returned from XmlRpc server 這樣的錯誤訊息,但到 WP 後台去查看,文章和圖片也都有正常的上傳。

wlw-error

按照過去開發程式的經驗,一個程式能從正常運作到出現錯誤,必然是有變數或環境出現變化(事出必有因),但,我已經忘了這是那時發生的 #@$%! … 好吧,那就只能土法煉鋼,開始 Debug~

1. 打開 WLW 的 Log 查看

WindowsLiveWriter,1.5648,None,00048,03-Nov-2012 04:34:52.650,"XML-RPC response:

http://yenpai.idis.com.tw/xmlrpc.php

<?xml version=""1.0""?>
<methodResponse>
  <fault>
    <value>
      <struct>
        <member>
          <name>faultCode</name>
          <value><int>404</int></value>
        </member>
        <member>
          <name>faultString</name>
          <value><string>不正確的文章 ID。</string></value>
        </member>
      </struct>
    </value>
  </fault>
</methodResponse>
",""
WindowsLiveWriter,1.5648,None,00049,03-Nov-2012 04:34:53.222,"Exception parsing XML-RPC response:

WindowsLive.Writer.CoreServices.XmlRpcClientInvalidResponseException: Invalid response document returned from XmlRpc server ---> System.Xml.XmlException: 在根層次的資料無效。 第 1 行,位置 1。
   於 System.Xml.XmlTextReaderImpl.Throw(Exception e)
   於 System.Xml.XmlTextReaderImpl.Throw(String res, String arg)
   於 System.Xml.XmlTextReaderImpl.ParseRootLevelWhitespace()
   於 System.Xml.XmlTextReaderImpl.ParseDocumentContent()
   於 System.Xml.XmlTextReaderImpl.Read()
   於 System.Xml.XmlLoader.Load(XmlDocument doc, XmlReader reader, Boolean preserveWhitespace)
   於 System.Xml.XmlDocument.Load(XmlReader reader)
   於 System.Xml.XmlDocument.LoadXml(String xml)
   於 WindowsLive.Writer.CoreServices.XmlRpcMethodResponse..ctor(String responseText)
   --- 內部例外狀況堆疊追蹤的結尾 ---
   於 WindowsLive.Writer.CoreServices.XmlRpcMethodResponse..ctor(String responseText)
   於 WindowsLive.Writer.CoreServices.XmlRpcClient.CallMethod(String methodName, XmlRpcValue[] parameters)

Warning: strpos(): Empty delimiter in /data-disk/vhost/yenpai.idis.com.tw/public_html/wp-includes/class-wp-xmlrpc-server.php on line 3954

Warning: strpos(): Em",""
WindowsLiveWriter,1.5648,Fail,00050,03-Nov-2012 04:34:53.234,"WindowsLive.Writer.Extensibility.BlogClient.BlogClientInvalidServerResponseException: 無效的伺服器回應 - 收到部落格伺服器對於 metaWeblog.newPost 方法的無效回應:

很好,似乎從中發現一個簡單的答案,就是 XML-RPC 出了問題,並且眼尖的你應該也有發現,最後 PHP 程式呼叫 strpos() 函數時發生了錯誤。

2. 找出 PHP 的 Error Log

既然 PHP 會有 Warning,那應該在 Log 檔中能找出一些端倪

2012/11/03 04:34:45 [error] 11945#0: *405807 FastCGI sent in stderr: "PHP message: PHP Warning:  strpos(): Empty delimiter in /data-disk/vhost/yenpai.idis.com.tw/public_html/wp-includes/class-wp-xmlrpc-server.php on line 3954
PHP message: PHP Warning:  strpos(): Empty delimiter in /data-disk/vhost/yenpai.idis.com.tw/public_html/wp-includes/class-wp-xmlrpc-server.php on line 3954" while reading response header from upstream, client: 114.32.224.216, server: yenpai.idis.com.tw, request: "POST /xmlrpc.php HTTP/1.1", upstream: "fastcgi://unix:/tmp/php-fpm-yenpai.idis.com.tw.socket:", host: "yenpai.idis.com.tw"

OK,兇手似乎看到了,class-wp-xmlrpc-server.php 這隻程式的第 3954 行呼叫了 strpos() 函數,並發生了錯誤。

3. 打開 class-wp-xmlrpc-server.php 並修正錯誤

/**
 * Attach upload to a post.
 *
 * @since 2.1.0
 *
 * @param int $post_ID Post ID.
 * @param string $post_content Post Content for attachment.
 */
function attach_uploads( $post_ID, $post_content ) {
    global $wpdb;

    // find any unattached files
    $attachments = $wpdb->get_results( "SELECT ID, guid FROM {$wpdb->posts} WHERE post_parent = '0' AND post_type = 'attachment'" );
    if ( is_array( $attachments ) ) {
        foreach ( $attachments as $file ) {
            if ( strpos( $post_content, $file->guid ) !== false )
                $wpdb->update($wpdb->posts, array('post_parent' => $post_ID), array('ID' => $file->ID) );
        }
    }
}

錯誤發生在 if ( strpos( $post_content, $file->guid ) !== false ) 這行,依據錯誤訊息表示 $file->guid 可能為空(Empty delimiter),外加並沒有判斷處理,所以我將它加入判斷處理,如下:

/**
 * Attach upload to a post.
 *
 * @since 2.1.0
 *
 * @param int $post_ID Post ID.
 * @param string $post_content Post Content for attachment.
 */
function attach_uploads( $post_ID, $post_content ) {
    global $wpdb;

    // find any unattached files
    $attachments = $wpdb->get_results( "SELECT ID, guid FROM {$wpdb->posts} WHERE post_parent = '0' AND post_type = 'attachment'" );
    if ( is_array( $attachments ) ) {
        foreach ( $attachments as $file ) {
            if ( $file->guid && strpos( $post_content, $file->guid ) !== false )
                $wpdb->update($wpdb->posts, array('post_parent' => $post_ID), array('ID' => $file->ID) );
        }
    }
}

測試~OK~WLW又再次回到我的擁抱~

PS. 其實修改很簡單,網路上也有一堆說法,但瞎搞亂試總不是辦法,就是要自己動動手,才會知道真相,功力也能相對提升~ (獎勵 = 白頭髮…?…哈哈哈)

Related Posts Plugin for WordPress, Blogger...

您可以延伸閱讀這些文章:

  1. [教學] WordPress 安裝 Syntax Highlighter 高亮度語法外掛
Tagged with:
 
About The Author

阿百

大家好,我是陳彥百(YenPai Chen)

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *

*

你可以使用這些 HTML 標籤與屬性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>