[P2-php-svn] [748] expack:

Back to archive index

svnno****@sourc***** svnno****@sourc*****
2009年 12月 31日 (木) 01:35:14 JST


Revision: 748
          http://sourceforge.jp/projects/p2-php/svn/view?view=rev&revision=748
Author:   rsk
Date:     2009-12-31 01:35:14 +0900 (Thu, 31 Dec 2009)

Log Message:
-----------
expack:
- P2KeyValueStore::__construct() での引数チェックに
  誤りがあったのを修正。
- 2ch公式p2 (http://p2.2ch.net/p2/) 経由での書き込み機能を実装。
-- メニュー > 設定管理 > ユーザ設定編集 > be/p2 で公式p2の
   アカウント情報を設定しておくと、書き込みフォームに
   「公式p2で書き込む」チェックボックスが現れる。
-- この機能を利用するには予め公式p2(モリタポ)のアカウントを
   取得し、公式p2での書き込みを有効にしておく必要がある。

Modified Paths:
--------------
    p2ex/trunk/conf/conf_user_def.inc.php
    p2ex/trunk/edit_conf_user.php
    p2ex/trunk/lib/P2KeyValueStore.php
    p2ex/trunk/lib/post_form.inc.php
    p2ex/trunk/lib/post_options_loader.inc.php
    p2ex/trunk/post.php

Added Paths:
-----------
    p2ex/trunk/lib/P2Client.php
    p2ex/trunk/lib/P2DOM.php
    p2ex/trunk/lib/P2Exception.php


-------------- next part --------------
Modified: p2ex/trunk/conf/conf_user_def.inc.php
===================================================================
--- p2ex/trunk/conf/conf_user_def.inc.php	2009-12-30 01:34:58 UTC (rev 747)
+++ p2ex/trunk/conf/conf_user_def.inc.php	2009-12-30 16:35:14 UTC (rev 748)
@@ -14,6 +14,15 @@
 $conf_user_def['be_2ch_mail'] = ""; // ("")
 
 // }}}
+// {{{ p2.2ch.netƒAƒJƒEƒ“ƒg
+
+// p2.2ch.net‚Ì“o˜^ƒ[ƒ‹ƒAƒhƒŒƒX
+$conf_user_def['p2_2ch_mail'] = ""; // ("")
+
+// p2.2ch.net‚̃ƒOƒCƒ“ƒpƒXƒ[ƒh
+$conf_user_def['p2_2ch_pass'] = ""; // ("")
+
+// }}}
 // {{{ PATH
 
 // ‰E‰º•”•ª‚ɍŏ‰‚É•\Ž¦‚³‚ê‚éƒy[ƒWBƒIƒ“ƒ‰ƒCƒ“URL‚à‰ÂB

Modified: p2ex/trunk/edit_conf_user.php
===================================================================
--- p2ex/trunk/edit_conf_user.php	2009-12-30 01:34:58 UTC (rev 747)
+++ p2ex/trunk/edit_conf_user.php	2009-12-30 16:35:14 UTC (rev 748)
@@ -19,6 +19,7 @@
 define('P2_EDIT_CONF_USER_HIDDEN',      2);
 define('P2_EDIT_CONF_USER_DISABLED',    4);
 define('P2_EDIT_CONF_USER_SKIPPED',     8);
+define('P2_EDIT_CONF_USER_PASSWORD',   16);
 define('P2_EDIT_CONF_FILE_ADMIN',    1024);
 define('P2_EDIT_CONF_FILE_ADMIN_EX', 2048);
 
@@ -186,9 +187,9 @@
 }
 
 // {{{ rep2Šî–{Ý’è
-// {{{ be.2ch.net ƒAƒJƒEƒ“ƒg
+// {{{ 'be/p2'
 
-$groupname = 'be.2ch.net ƒAƒJƒEƒ“ƒg';
+$groupname = 'be/p2';
 $groups[] = $groupname;
 $flags = getGroupShowFlags($groupname);
 if ($flags & P2_EDIT_CONF_USER_SKIPPED) {
@@ -197,6 +198,8 @@
     $conflist = array(
         array('be_2ch_code', '<a href="http://be.2ch.net/" target="_blank">be.2ch.net</a>‚Ì”FØƒR[ƒh(ƒpƒXƒ[ƒh‚Å‚Í‚È‚¢)', P2_EDIT_CONF_USER_LONGTEXT),
         array('be_2ch_mail', 'be.2ch.net‚Ì“o˜^ƒ[ƒ‹ƒAƒhƒŒƒX', P2_EDIT_CONF_USER_LONGTEXT),
+        array('p2_2ch_mail', '<a href="http://p2.2ch.net/" target="_blank">p2.2ch.net</a>‚Ì“o˜^ƒ[ƒ‹ƒAƒhƒŒƒX', P2_EDIT_CONF_USER_LONGTEXT),
+        array('p2_2ch_pass', 'p2.2ch.net‚̃ƒOƒCƒ“ƒpƒXƒ[ƒh', P2_EDIT_CONF_USER_LONGTEXT | P2_EDIT_CONF_USER_PASSWORD),
     );
     printEditConfGroupHtml($groupname, $conflist, $flags);
 }
@@ -1390,8 +1393,9 @@
         } else {
             $input_size_at = '';
         }
+        $input_type = ($flags & P2_EDIT_CONF_USER_PASSWORD) ? 'password' : 'text';
         $form_ht = <<<EOP
-<input type="text" name="conf_edit[{$name}]" value="{$name_view}"{$input_size_at}>
+<input type="{$input_type}" name="conf_edit[{$name}]" value="{$name_view}"{$input_size_at}>
 EOP;
         if (is_string($conf_user_def[$name])) {
             $def_views[$name] = htmlspecialchars($conf_user_def[$name], ENT_QUOTES);

Added: p2ex/trunk/lib/P2Client.php
===================================================================
--- p2ex/trunk/lib/P2Client.php	                        (rev 0)
+++ p2ex/trunk/lib/P2Client.php	2009-12-30 16:35:14 UTC (rev 748)
@@ -0,0 +1,411 @@
+<?php
+require_once 'HTTP/Client.php';
+require_once dirname(__FILE__) . '/P2DOM.php';
+require_once dirname(__FILE__) . '/P2KeyValueStore/Serializing.php';
+
+// {{{ P2Client
+
+/**
+ * p2.2ch.net ƒNƒ‰ƒCƒAƒ“ƒg
+ *
+ * ƒvƒƒoƒCƒ_‹K§Žž‚ɏ‘‚«ž‚Þ‚½‚߂ɐ݌v‚µ‚½B
+ * ƒ‚ƒŠƒ^ƒ|‚ðÁ”‚ÄdatŽæ“¾Œ ŒÀ‚Ì–³‚¢dat—Ž‚¿ƒXƒŒƒbƒh‚Ì
+ * ¶dat‚ðŽæ“¾‚Å‚«‚é‚悤‚É‚È‚Á‚½‚È‚çA‘¦‘Ήž‚·‚éB
+ */
+class P2Client
+{
+    // {{{ constants
+
+    /**
+     * Cookie‚ð•Û‘¶‚·‚éSQLite3ƒf[ƒ^ƒx[ƒX‚̃tƒ@ƒCƒ‹–¼
+     */
+    const COOKIE_STORE_NAME = 'p2_2ch_net_cookie.sq3';
+
+    /**
+     * ŒöŽ®P2‚ÌURI‚ÆŠeƒGƒ“ƒgƒŠƒ|ƒCƒ“ƒg
+     */
+    const P2_ROOT_URI = 'http://p2.2ch.net/p2/';
+    const SCRIPT_NAME_READ = 'read.php';
+    const SCRIPT_NAME_POST = 'post.php';
+
+    /**
+     * User-Agent
+     */
+    const HTTP_USER_AGENT = 'Monazilla/1.0 (rep2-expack-p2client)';
+
+    /**
+     * ƒtƒH[ƒ€‚̃pƒ‰ƒ[ƒ^–¼
+     */
+    const FIELD_NAME_LOGIN_ID   = 'form_login_id';
+    const FIELD_NAME_LOGIN_PASS = 'form_login_pass';
+    const FIELD_NAME_POPUP      = 'popup';
+    const FIELD_NAME_FROM       = 'FROM';
+    const FIELD_NAME_MAIL       = 'mail';
+    const FIELD_NAME_MESSAGE    = 'MESSAGE';
+    const FIELD_NAME_BERES      = 'submit_beres';
+
+    /**
+     * ‘‚«ž‚ݐ³”Û”»’è‚Ì‚½‚߂̐³‹K•\Œ»
+     */
+    const REGEX_SUCCESS = '{<title>.*(?:‘‚«(?:ž|‚±)‚Ý‚Ü‚µ‚½|‘‚«ž‚ݏI—¹ - SubAll BBS).*</title>}is';
+    const REGEX_COOKIE  = '{<!-- 2ch_X:cookie -->|<title>¡ ‘‚«ž‚ÝŠm”F ¡</title>|>‘‚«ž‚ÝŠm”FB<}';
+
+    // }}}
+    // {{{ properties
+
+    /**
+     * p2.2ch.net/ƒ‚ƒŠƒ^ƒ| ƒƒOƒCƒ“ID (ƒ[ƒ‹ƒAƒhƒŒƒX)
+     *
+     * @var string
+     */
+    private $_loginId;
+
+    /**
+     * p2.2ch.net/ƒ‚ƒŠƒ^ƒ| ƒƒOƒCƒ“ƒpƒXƒ[ƒh
+     *
+     * @var string
+     */
+    private $_loginPass;
+
+    /**
+     * Cookie‚ð•Û‘¶‚·‚éKey-Value StoreƒIƒuƒWƒFƒNƒg
+     *
+     * @var P2KeyValueStore_Serializing
+     */
+    private $_cookieStore;
+
+    /**
+     * Cookie‚ðŠÇ—‚·‚éƒIƒuƒWƒFƒNƒg
+     *
+     * @var HTTP_Client_CookieManager
+     */
+    private $_cookieManager;
+
+    /**
+     * HTTPƒNƒ‰ƒCƒAƒ“ƒgƒIƒuƒWƒFƒNƒg
+     *
+     * @var HTTP_Client
+     */
+    private $_httpClient;
+
+    // }}}
+    // {{{ constructor
+
+    /**
+     * ƒRƒ“ƒXƒgƒ‰ƒNƒ^
+     *
+     * @param string $loginId
+     * @param string $loginPass
+     * @param string $cookieSaveDir
+     * @throws P2Exception
+     */
+    public function __construct($loginId, $loginPass, $cookieSaveDir)
+    {
+        try {
+            $cookieSavePath = $cookieSaveDir . DIRECTORY_SEPARATOR . self::COOKIE_STORE_NAME;
+            $cookieStore = P2KeyValueStore::getStore($cookieSavePath, 'Serializing');
+        } catch (Exception $e) {
+            throw new P2Exception(get_class($e) . ': ' . $e->getMessage());
+        }
+
+        if ($cookieManager = $cookieStore->get($loginId)) {
+            if (!$cookieManager instanceof HTTP_Client_CookieManager) {
+                throw new Exception('Cannot restore the cookie manager.');
+            }
+        } else {
+            $cookieManager = new HTTP_Client_CookieManager;
+        }
+
+        $this->_loginId = $loginId;
+        $this->_loginPass = $loginPass;
+        $this->_cookieStore = $cookieStore;
+        $this->_cookieManager = $cookieManager;
+
+        $defaultHeaders = array(
+            'User-Agent' => self::HTTP_USER_AGENT,
+        );
+        $this->_httpClient = new HTTP_Client(null, $defaultHeaders, $cookieManager);
+    }
+
+    // }}}
+    // {{{ destructor
+
+    /**
+     * ƒf[ƒ^ƒx[ƒX‚ÉCookie‚ð•Û‘¶‚·‚é
+     *
+     * @param void
+     */
+    public function __destruct()
+    {
+        $this->_cookieStore->set($this->_loginId, $this->_cookieManager);
+    }
+
+    // }}}
+    // {{{ login()
+
+    /**
+     * ŒöŽ®p2‚ɃƒOƒCƒ“‚·‚é
+     *
+     * @param string $uri
+     * @param array $data
+     * @param P2DOM $dom
+     * @param DOMElement $form
+     * @return array HTTPƒŒƒXƒ|ƒ“ƒX
+     * @throws P2Exception
+     */
+    public function login($uri = null, array $data = array(),
+                          P2DOM $dom = null, DOMElement $form = null)
+    {
+        if ($uri === null) {
+            $uri = self::P2_ROOT_URI;
+        }
+
+        if ($dom === null) {
+            $response = $this->httpGet($uri);
+            $dom = new P2DOM($response['body']);
+        }
+
+        if ($form === null) {
+            $form = $this->getLoginForm($dom);
+            if ($form === null) {
+                throw new P2Exception('Login form not found.');
+            }
+        }
+
+        $postData = array();
+        foreach ($data as $name => $value) {
+            $postData[$name] = rawurlencode($value);
+        }
+        $postData = $this->getFormValues($dom, $form, $postData);
+        $postData[self::FIELD_NAME_LOGIN_ID] = rawurlencode($this->_loginId);
+        $postData[self::FIELD_NAME_LOGIN_PASS] = rawurlencode($this->_loginPass);
+
+        return $this->httpPost($uri, $postData, true);
+    }
+
+    // }}}
+    // {{{ readThread()
+
+    /**
+     * ƒXƒŒƒbƒh‚ð“Ç‚Þ
+     *
+     * @param string $host
+     * @param string $bbs
+     * @param string $key
+     * @param string|integer $ls
+     * @param mixed &$response
+     * @return string HTTPƒŒƒXƒ|ƒ“ƒXƒ{ƒfƒB
+     * @throws P2Exception
+     */
+    public function readThread($host, $bbs, $key, $ls = 1, &$response = null)
+    {
+        $getData = array(
+            'host'  => (string)$host,
+            'bbs'   => (string)$bbs,
+            'key'   => (string)$key,
+            'ls'    => (string)$ls,
+        );
+
+        $uri = self::P2_ROOT_URI . self::SCRIPT_NAME_READ;
+        $response = $this->httpGet($uri, $getData);
+        $dom = new P2DOM($response['body']);
+
+        if ($form = $this->getLoginForm($dom)) {
+            $response = $this->login($uri, $getData, $dom, $form);
+            $dom = new P2DOM($response['body']);
+            if ($this->getLoginForm($dom)) {
+                throw new P2Exception('Login failed.');
+            }
+        }
+
+        return $response['body'];
+    }
+
+    // }}}
+    // {{{ post()
+
+    /**
+     * ƒXƒŒƒbƒh‚ɏ‘‚«ž‚Þ
+     *
+     * csrfId‚ðŽæ“¾‚µA‚©‚ÂŒöŽ®p2‚ÌŠù“Ç‚ðÅV‚·‚邽‚߁A‚Ü‚¸ read.php ‚ð’@‚­B
+     * ’ʐM—Ê‚ðß–ñ‚Å‚«‚é‚悤‚É ls=l1n ‚Æ‚µ‚Ä‚¢‚éB
+     * popup=1 ‚͏‘‚«ž‚ÝŒã‚̃y[ƒW‚ɃŠƒ_ƒCƒŒƒNƒg‚³‚¹‚È‚¢‚½‚߁B
+     *
+     * @param string $host
+     * @param string $bbs
+     * @param string $key
+     * @param string $from
+     * @param string $mail
+     * @param string $message
+     * @param bool $beres
+     * @param mixed &$response
+     * @return bool
+     * @throws P2Exception
+     */
+    public function post($host, $bbs, $key, $from, $mail, $message,
+                         $beres, &$response = null)
+    {
+        $dom = new P2DOM($this->readThread($host, $bbs, $key, 'l1n', $response));
+        if ($form = $this->getPostForm($dom)) {
+            $uri = self::P2_ROOT_URI . self::SCRIPT_NAME_POST;
+
+            $postData = $this->getFormValues($dom, $form);
+            $postData[self::FIELD_NAME_POPUP]   = '1';
+            $postData[self::FIELD_NAME_FROM]    = rawurlencode($from);
+            $postData[self::FIELD_NAME_MAIL]    = rawurlencode($mail);
+            $postData[self::FIELD_NAME_MESSAGE] = rawurlencode($message);
+            if ($beres) {
+                $postData[self::FIELD_NAME_BERES] = '1';
+            } elseif (array_key_exists(self::FIELD_NAME_BERES, $postData)) {
+                unset($postData[self::FIELD_NAME_BERES]);
+            }
+
+            $response = $this->httpPost($uri, $postData, true);
+
+            if (preg_match(self::REGEX_COOKIE, $response['body'])) {
+                $dom = new P2DOM($response['body']);
+                $expression = './/form[contains(@action, "' . self::SCRIPT_NAME_POST . '")]';
+                $result = $dom->query($expression);
+                if ($result instanceof DOMNodeList && $result->length > 0) {
+                    $postData = $this->getFormValues($dom, $result->item(0));
+                    $response = $this->httpPost($uri, $postData, true);
+                }
+            }
+
+            $body = mb_convert_encoding($response['body'], 'SJIS-win', 'CP51932,SJIS-win,UTF-8');
+            return (bool)preg_match(self::REGEX_SUCCESS, $body);
+        } else {
+            throw new P2Exception('Post form not found.');
+        }
+    }
+
+    // }}}
+    // {{{ httpGet()
+
+    /**
+     * HTTP_Client::get() ‚̃‰ƒbƒp[ƒƒ\ƒbƒh
+     *
+     * @param string $uri
+     * @param mixed $data
+     * @param bool $preEncoded
+     * @param array $headers
+     * @return array HTTPƒŒƒXƒ|ƒ“ƒX
+     * @throws P2Exception
+     */
+    protected function httpGet($uri, $data = null, $preEncoded = false,
+                               $headers = array())
+    {
+        $code = $this->_httpClient->get($uri, $data, $preEncoded, $headers);
+        P2Exception::pearErrorToP2Exception($code);
+        if ($code < 200 || $code >= 300) {
+            throw new P2Exception('HTTP Error: '. $code);
+        }
+        return $this->_httpClient->currentResponse();
+    }
+
+    // }}}
+    // {{{ httpPost()
+
+    /**
+     * HTTP_Client::post() ‚̃‰ƒbƒp[ƒƒ\ƒbƒh
+     *
+     * @param string $uri
+     * @param mixed $data
+     * @param bool $preEncoded
+     * @param array $files
+     * @param array $headers
+     * @return array HTTPƒŒƒXƒ|ƒ“ƒX
+     * @throws P2Exception
+     */
+    protected function httpPost($uri, $data, $preEncoded = false,
+                                $files = array(), $headers = array())
+    {
+        $code = $this->_httpClient->post($uri, $data, $preEncoded, $files, $headers);
+        P2Exception::pearErrorToP2Exception($code);
+        if ($code < 200 || $code >= 300) {
+            throw new P2Exception('HTTP Error: '. $code);
+        }
+        return $this->_httpClient->currentResponse();
+    }
+
+    // }}}
+    // {{{ getLoginForm()
+
+    /**
+     * ƒƒOƒCƒ“ƒtƒH[ƒ€‚𒊏o‚·‚é
+     *
+     * @paramP2DOM $dom
+     * @return DOMElement|null
+     */
+    protected function getLoginForm(P2DOM $dom)
+    {
+        $result = $dom->query('.//form[@action and @id="login"]');
+        if ($result instanceof DOMNodeList && $result->length > 0) {
+            return $result->item(0);
+        }
+        return null;
+    }
+
+    // }}}
+    // {{{ getPostForm()
+
+    /**
+     * read.php/post_form.php ‚̏o—Í‚©‚珑‚«ž‚݃tƒH[ƒ€‚𒊏o‚·‚é
+     *
+     * @paramP2DOM $dom
+     * @return DOMElement|null
+     */
+    protected function getPostForm(P2DOM $dom)
+    {
+        $result = $dom->query('.//form[@action and @id="resform"]');
+        if ($result instanceof DOMNodeList && $result->length > 0) {
+            return $result->item(0);
+        }
+        return null;
+    }
+
+    // }}}
+    // {{{ getFormValues()
+
+    /**
+     * ƒtƒH[ƒ€‚©‚çinput—v‘f‚𒊏o‚µA˜A‘z”z—ñ‚𐶐¬‚·‚é
+     *
+     * select—v‘f‚Ætextarea—v‘f‚Í–³Ž‹‚·‚éB
+     * ‚Ü‚½A<input type="checkbox" name="foo[]" value="bar"> ‚̂悤‚É
+     * name‘®«‚Å”z—ñ‚ðŽwŽ¦‚µ‚Ä‚¢‚é‚à‚̂͐³‚µ‚­ˆµ‚¦‚È‚¢B
+     * (‚±‚̃Nƒ‰ƒXŽ©‘Ì‚ª‚»‚¤‚¢‚Á‚½—v‘f‚ðˆµ‚¤•K—v‚Ì‚ ‚éê‡‚ðl—¶‚µ‚Ä‚¢‚È‚¢)
+     *
+     * @param P2DOM $dom
+     * @param DOMElement $form
+     * @param array $data
+     * @return array
+     */
+    protected function getFormValues(P2DOM $dom, DOMElement $form,
+                                     array $data = array())
+    {
+        $fields = $dom->query('.//input[@name and @value]', $form);
+        foreach ($fields as $field) {
+            $name = $field->getAttribute('name');
+            $value = $field->getAttribute('value');
+            $value = rawurlencode(mb_convert_encoding($value, 'SJIS-win', 'UTF-8'));
+            $data[$name] = $value;
+        }
+
+        return $data;
+    }
+
+    // }}}
+}
+
+// }}}
+
+/*
+ * Local Variables:
+ * mode: php
+ * coding: cp932
+ * tab-width: 4
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
+// vim: set syn=php fenc=cp932 ai et ts=4 sw=4 sts=4 fdm=marker:

Added: p2ex/trunk/lib/P2DOM.php
===================================================================
--- p2ex/trunk/lib/P2DOM.php	                        (rev 0)
+++ p2ex/trunk/lib/P2DOM.php	2009-12-30 16:35:14 UTC (rev 748)
@@ -0,0 +1,132 @@
+<?php
+
+require_once dirname(__FILE__) . '/P2Exception.php';
+
+// {{{ P2DOM
+
+/**
+ * DOMDocument‚ÆDOMXPath‚̃‰ƒbƒp[ƒNƒ‰ƒX
+ */
+class P2DOM
+{
+    // {{{ properties
+
+    /**
+     * @var DOMDocument
+     */
+    private $_document;
+
+    /**
+     * @var DOMXPath
+     */
+    private $_xpath;
+
+    // }}}
+    // {{{ constructor
+
+    /**
+     * @param string $html
+     * @throws P2Exception
+     */
+    public function __construct($html)
+    {
+        $level = error_reporting(E_ALL & ~E_WARNING);
+
+        try {
+            $document = new DOMDocument;
+            $document->loadHTML($html);
+            $xpath = new DOMXPath($document);
+        } catch (Exception $e) {
+            error_reporting($level);
+            throw new P2Exception('Failed to create DOM: ' .
+                                  get_class($e) . ': ' . $e->getMessage());
+        }
+        error_reporting($level);
+
+        $this->_document = $document;
+        $this->_xpath = $xpath;
+    }
+
+    // }}}
+    // {{{ getter
+
+    /**
+     * @param string $name
+     * @return mixed
+     */
+    public function __get($name)
+    {
+        if ($name === 'document') {
+            return $this->_document;
+        }
+        if ($name === 'xpath') {
+            return $this->_xpath;
+        }
+
+        return null;
+    }
+
+    // }}}
+    // {{{ export()
+
+    /**
+     * @param DOMNode $node
+     */
+    public function export(DOMNode $node = null)
+    {
+        if ($node === null) {
+            return $this->_document->saveXML();
+        } else {
+            return $this->_document->saveXML($node);
+        }
+    }
+
+    // }}}
+    // {{{ evaluate()
+
+    /**
+     * @param string $expression
+     * @param DOMNode $contextNode
+     * @return mixed
+     */
+    public function evaluate($expression, DOMNode $contextNode = null)
+    {
+        if ($contextNode === null) {
+            return $this->_xpath->evaluate($expression);
+        } else {
+            return $this->_xpath->evaluate($expression, $contextNode);
+        }
+    }
+
+    // }}}
+    // {{{ query()
+
+    /**
+     * @param string $expression
+     * @param DOMNode $contextNode
+     * @return DOMNodeList
+     */
+    public function query($expression, DOMNode $contextNode = null)
+    {
+        if ($contextNode === null) {
+            return $this->_xpath->query($expression);
+        } else {
+            return $this->_xpath->query($expression, $contextNode);
+        }
+    }
+
+    // }}}
+}
+
+// }}}
+
+/*
+ * Local Variables:
+ * mode: php
+ * coding: cp932
+ * tab-width: 4
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
+// vim: set syn=php fenc=cp932 ai et ts=4 sw=4 sts=4 fdm=marker:

Added: p2ex/trunk/lib/P2Exception.php
===================================================================
--- p2ex/trunk/lib/P2Exception.php	                        (rev 0)
+++ p2ex/trunk/lib/P2Exception.php	2009-12-30 16:35:14 UTC (rev 748)
@@ -0,0 +1,43 @@
+<?php
+
+require_once 'PEAR.php';
+
+// {{{ P2Exception
+
+/**
+ * —áŠOƒ‰ƒbƒp[ƒNƒ‰ƒX
+ */
+class P2Exception extends Exception
+{
+    // {{{ pearErrorToP2Exception()
+
+    /**
+     * @param mixed $value
+     * @param string $errorMessagePrefix
+     * @return void
+     * @throws P2Exception
+     */
+    static public function pearErrorToP2Exception($value, $errorMessagePrefix = '')
+    {
+        if (PEAR::isError($value)) {
+            $message = $errorMessagePrefix . ': '
+                     . get_class($value) . ': ' . $value->getMessage();
+            throw new P2Exception($message);
+        }
+    }
+
+    // }}}
+}
+
+// }}}
+
+/*
+ * Local Variables:
+ * mode: php
+ * coding: cp932
+ * tab-width: 4
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
+// vim: set syn=php fenc=cp932 ai et ts=4 sw=4 sts=4 fdm=marker:

Modified: p2ex/trunk/lib/P2KeyValueStore.php
===================================================================
--- p2ex/trunk/lib/P2KeyValueStore.php	2009-12-30 01:34:58 UTC (rev 747)
+++ p2ex/trunk/lib/P2KeyValueStore.php	2009-12-30 16:35:14 UTC (rev 748)
@@ -86,7 +86,7 @@
         if (!is_string($fileName)) {
             throw new InvalidArgumentException('Parameter #1 \'$fileName\' should be a string value');
         }
-        if (!is_string($className)) {
+        if (!is_string($type)) {
             throw new InvalidArgumentException('Parameter #2 \'$className\' should be a string value');
         }
 

Modified: p2ex/trunk/lib/post_form.inc.php
===================================================================
--- p2ex/trunk/lib/post_form.inc.php	2009-12-30 01:34:58 UTC (rev 747)
+++ p2ex/trunk/lib/post_form.inc.php	2009-12-30 16:35:14 UTC (rev 748)
@@ -13,6 +13,10 @@
     $readnew_hidden_ht = '';
 }
 
+// ŒöŽ®p2‚ðŽg‚Á‚½ƒXƒŒ—§‚Ä‚Í–¢ŽÀ‘• (P2Client.php)
+if ($newthread_hidden_ht !== '') {
+    $htm['p2res'] = '';
+}
 
 if ($_conf['ktai']) {
     $htm['k_br'] = '<br>';
@@ -89,6 +93,7 @@
 {$htm['table_break2']}
 <input id="kakiko_submit" type="submit" name="submit" value="{$submit_value}"{$htm['kaiko_set_hidden_js']}{$htm['submit_extra_at']}>
 {$htm['be2ch']}
+{$htm['p2res']}
 {$htm['table_end']}
 
 <input type="hidden" name="bbs" value="{$bbs}">

Modified: p2ex/trunk/lib/post_options_loader.inc.php
===================================================================
--- p2ex/trunk/lib/post_options_loader.inc.php	2009-12-30 01:34:58 UTC (rev 747)
+++ p2ex/trunk/lib/post_options_loader.inc.php	2009-12-30 16:35:14 UTC (rev 748)
@@ -19,7 +19,8 @@
 $hd['MESSAGE'] = '';
 $hd['subject'] = '';
 
-$htm['be2ch'] = '';
+$htm['beres'] = '';
+$htm['p2res'] = '';
 $htm['sage_cb'] = '';
 $htm['maru_post'] = '';
 $htm['block_submit'] = '';
@@ -133,9 +134,14 @@
 
 // Be.2ch
 if (P2Util::isHost2chs($host) and $_conf['be_2ch_code'] && $_conf['be_2ch_mail']) {
-    $htm['be2ch'] = '<input type="submit" id="submit_beres" name="submit_beres" value="BE‚ŏ‘‚«ž‚Þ" onclick="setHiddenValue(this);">';
+    $htm['beres'] = '<input type="checkbox" id="beres" name="beres" value="1"><label for="beres">BE‚ŏ‘‚«ž‚Þ</label>';
 }
 
+// ŒöŽ®p2
+if ((P2Util::isHost2chs($host) || P2Util::isHostMachiBbs($host)) && $_conf['p2_2ch_mail'] && $_conf['p2_2ch_pass']) {
+    $htm['p2res'] = '<input type="checkbox" id="p2res" name="p2res" value="1"><label for="p2res">ŒöŽ®p2‚ŏ‘‚«ž‚Þ</label>';
+}
+
 // PC—p sage checkbox
 if (!$_conf['ktai']) {
     $on_check_sage = ' onchange="checkSage();"';

Modified: p2ex/trunk/post.php
===================================================================
--- p2ex/trunk/post.php	2009-12-30 01:34:58 UTC (rev 747)
+++ p2ex/trunk/post.php	2009-12-30 16:35:14 UTC (rev 748)
@@ -32,7 +32,7 @@
 
 $post_param_keys    = array('bbs', 'key', 'time', 'FROM', 'mail', 'MESSAGE', 'subject', 'submit');
 $post_internal_keys = array('host', 'sub', 'popup', 'rescount', 'ttitle_en');
-$post_optional_keys = array('newthread', 'submit_beres', 'from_read_new', 'maru', 'csrfid');
+$post_optional_keys = array('newthread', 'beres', 'p2res', 'from_read_new', 'maru', 'csrfid');
 $post_p2_flag_keys  = array('b', 'p2_post_confirm_cookie');
 
 foreach ($post_param_keys as $pk) {
@@ -176,22 +176,61 @@
 // ‘‚«ž‚ݏˆ—
 //================================================================
 
-//=============================================
+// ‘‚«ž‚Ý‚ðˆêŽž“I‚É•Û‘¶
+$failed_post_file = P2Util::getFailedPostFilePath($host, $bbs, $key);
+$cont = serialize($post_cache);
+DataPhp::writeDataPhp($failed_post_file, $cont, $_conf['res_write_perm']);
+
 // ƒ|ƒXƒgŽÀs
-//=============================================
-$posted = postIt($host, $bbs, $key, $post);
+if (!empty($_POST['p2res']) && empty($_POST['newthread'])) {
+    // ŒöŽ®p2‚Ń|ƒXƒg
+    if (!class_exists('P2Client', false)) {
+        include P2_LIB_DIR . '/P2Client.php';
+    }
+    if (!is_dir($_conf['cookie_dir'])) {
+        FileCtl::mkdir_for($_conf['cookie_dir'] . '/dummy_filename');
+    }
+    if (P2Util::isHostBe2chNet($host) || !empty($_REQUEST['beres'])) {
+        $beres = true;
+    } else {
+        $beres = false;
+    }
 
-//=============================================
-// cookie •Û‘¶
-//=============================================
-FileCtl::make_datafile($cookie_file, $_conf['p2_perm']); // ‚È‚¯‚ê‚ΐ¶¬
-if ($p2cookies) {$cookie_cont = serialize($p2cookies);}
-if ($cookie_cont) {
-    if (FileCtl::file_write_contents($cookie_file, $cookie_cont) === false) {
-        p2die('cannot write file.');
+    try {
+        $client = new P2Client($_conf['p2_2ch_mail'], $_conf['p2_2ch_pass'], $_conf['cookie_dir']);
+        $posted = $client->post($host, $bbs, $key, $FROM, $mail, $MESSAGE, $beres, $response);
+    } catch (P2Exception $e) {
+        p2die('ŒöŽ®p2ƒ|ƒXƒgŽ¸”s', $e->getMessage());
     }
+
+    if ($posted) {
+        $reload = empty($_POST['from_read_new']);
+        showPostMsg(true, '‘‚«‚±‚Ý‚ªI‚í‚è‚Ü‚µ‚½B', $reload);
+    } else {
+        $result_msg = 'ŒöŽ®p2ƒ|ƒXƒgŽ¸”s</p>'
+                    . '<pre>' . htmlspecialchars($response['body'], ENT_QUOTES, 'Shift_JIS') . '</pre>'
+                    . '<p>-';
+        showPostMsg(false, $result_msg, false);
+    }
+} else {
+    // ’ʏíƒ|ƒXƒg
+    $posted = postIt($host, $bbs, $key, $post);
+
+    // cookie •Û‘¶
+    FileCtl::make_datafile($cookie_file, $_conf['p2_perm']); // ‚È‚¯‚ê‚ΐ¶¬
+    if ($p2cookies) {$cookie_cont = serialize($p2cookies);}
+    if ($cookie_cont) {
+        if (FileCtl::file_write_contents($cookie_file, $cookie_cont) === false) {
+            p2die('cannot write file.');
+        }
+    }
 }
 
+// “ŠeŽ¸”s‹L˜^‚ðíœ
+if ($posted && file_exists($failed_post_file)) {
+    unlink($failed_post_file);
+}
+
 //=============================================
 // ƒXƒŒ—§‚ЬŒ÷‚È‚çAsubject‚©‚çkey‚ðŽæ“¾
 //=============================================
@@ -335,7 +374,7 @@
 function postIt($host, $bbs, $key, $post)
 {
     global $_conf, $post_result, $post_error2ch, $p2cookies, $popup, $rescount, $ttitle_en;
-    global $bbs_cgi, $post_cache;
+    global $bbs_cgi;
 
     $method = 'POST';
     $bbs_cgi_url = 'http://' . $host . $bbs_cgi;
@@ -376,7 +415,7 @@
     }
 
     // be.2ch.net ”FØƒNƒbƒL[
-    if (P2Util::isHostBe2chNet($host) || !empty($_REQUEST['submit_beres'])) {
+    if (P2Util::isHostBe2chNet($host) || !empty($_REQUEST['beres'])) {
         $cookies_to_send .= ' MDMD='.$_conf['be_2ch_code'].';';    // be.2ch.net‚Ì”FØƒR[ƒh(ƒpƒXƒ[ƒh‚Å‚Í‚È‚¢)
         $cookies_to_send .= ' DMDM='.$_conf['be_2ch_mail'].';';    // be.2ch.net‚Ì“o˜^ƒ[ƒ‹ƒAƒhƒŒƒX
     }
@@ -411,11 +450,6 @@
     }
     // }}}
 
-    // ‘‚«ž‚Ý‚ðˆêŽž“I‚É•Û‘¶
-    $failed_post_file = P2Util::getFailedPostFilePath($host, $bbs, $key);
-    $cont = serialize($post_cache);
-    DataPhp::writeDataPhp($failed_post_file, $cont, $_conf['res_write_perm']);
-
     // WEBƒT[ƒo‚֐ڑ±
     $fp = fsockopen($send_host, $send_port, $errno, $errstr, $_conf['fsockopen_time_limit']);
     if (!$fp) {
@@ -501,11 +535,6 @@
         $reload = empty($_POST['from_read_new']);
         showPostMsg(true, '‘‚«‚±‚Ý‚ªI‚í‚è‚Ü‚µ‚½B', $reload);
 
-        // “ŠeŽ¸”s‹L˜^‚ðíœ
-        if (file_exists($failed_post_file)) {
-            unlink($failed_post_file);
-        }
-
         return true;
         //$response_ht = htmlspecialchars($response, ENT_QUOTES);
         //echo "<pre>{$response_ht}</pre>";
@@ -532,7 +561,7 @@
  */
 function showPostMsg($isDone, $result_msg, $reload)
 {
-    global $_conf, $location_ht, $popup, $ttitle;
+    global $_conf, $location_ht, $popup, $ttitle, $ptitle;
     global $STYLE, $skin_en;
     global $_info_msg_ht;
 
@@ -574,7 +603,7 @@
 EOHEADER;
 
     if ($isDone) {
-        echo "    <title>p2 - ‘‚«‚±‚Ý‚Ü‚µ‚½B</title>";
+        echo "    <title>rep2 - ‘‚«‚±‚Ý‚Ü‚µ‚½B</title>";
     } else {
         echo "    <title>{$ptitle}</title>";
     }



P2-php-svn メーリングリストの案内
Back to archive index