OSDN Git Service

git-svn-id: https://svn.sourceforge.jp/svnroot/nucleus-jp/plugin@1022 1ca29b6e-896d...
authorshizuki <shizuki@1ca29b6e-896d-4ea0-84a5-967f57386b96>
Mon, 29 Jun 2009 08:39:18 +0000 (08:39 +0000)
committershizuki <shizuki@1ca29b6e-896d-4ea0-84a5-967f57386b96>
Mon, 29 Jun 2009 08:39:18 +0000 (08:39 +0000)
NP_TrackBack/branches/DOM-branch/NP_TrackBack.php

index 6da2b1c..3a7dbcd 100644 (file)
@@ -1267,7 +1267,7 @@ ___FORMEXTRA___;
     dc:identifier="{$uri}"\r
     dc:title="{$title}"\r
     dc:description="{$desc}"\r
-    trackback:ping="{$tburi}"\r
+    trackback:ping="{$tburl}"\r
     dc:date="{$time}" />\r
 </rdf:RDF>\r
 -->\r
@@ -1344,83 +1344,103 @@ ___RDFCODE___;
      * Send a Trackback ping to another website\r
      *\r
      * @param int\r
-     * @param str\r
-     * @param str\r
-     * @param str\r
-     * @param str\r
-     * @param str\r
+     * @param arr\r
+     * @param arr\r
+     * @param arr\r
      */\r
-    function sendPing($itemid, $title, $url, $excerpt, $blog_name, $ping_url)\r
+    function sendPing($itemid, $pingData, $pingURLs, &$res)\r
     {\r
-//        $sendEncoding = 'UTF-8';\r
         // 1. Check some basic things\r
         if (!$this->canSendPing()) {\r
-            return _TB_msgNOTALLOWED_SEND;\r
+            $res[]['mess'] = _TB_msgNOTALLOWED_SEND;\r
+            $res[]['url']  = '';\r
+            return;\r
         }\r
         if ($this->getOption('SendPings') == 'no') {\r
-            return _TB_msgDISABLED_SEND;\r
-        }\r
-        if ($ping_url == '') {\r
-            return _TB_msgNO_SENDER_URL;\r
+            $res[]['mess'] = _TB_msgDISABLED_SEND;\r
+            $res[]['url']  = '';\r
+            return;\r
         }\r
-        // 2. Check if protocol is correct http URL\r
-        $parsed_url = parse_url($ping_url);\r
-        if (strpos($parsed_url['scheme'], 'http') !== 0 || !$parsed_url['host']) {\r
-                return _TB_msgBAD_SENDER_URL;\r
+        if (empty($pingURLs) || !is_array($pingURLs)) {\r
+            $res[]['mess'] = _TB_msgNO_SENDER_URL;\r
+            $res[]['url']  = '';\r
+            return;\r
         }\r
-        // 3. Create contents\r
-//        if ($sendEncoding != _CHARSET) {\r
+\r
+        // 2. Check if protocol is correct http URL & Create handle\r
+        $cmh = curl_multi_init();\r
         if (strtoupper(_CHARSET) != 'UTF-8') {\r
-            $title     = mb_convert_encoding($title, 'UTF-8', _CHARSET);\r
-            $excerpt   = mb_convert_encoding($excerpt, 'UTF-8', _CHARSET);\r
-            $blog_name = mb_convert_encoding($blog_name, 'UTF-8', _CHARSET);\r
-        }\r
-        $ch      = curl_init();\r
-        $data    = array(\r
-            'title'     => $title,\r
-            'url'       => $url,\r
-            'excerpt'   => $excerpt,\r
-            'blog_name' => $blog_name\r
-        );\r
-        $options = array(\r
-            CURLOPT_URL            => $ping_url,\r
-            CURLOPT_POST           => 1,\r
-            CURLOPT_POSTFIELDS     => $data,\r
-            CURLOPT_RETURNTRANSFER => 1,\r
-        );\r
-        curl_setopt_array($ch, $options);\r
-        $response = curl_exec($ch);\r
-        if ($response === false) {\r
-            return sprintf(_TB_msgCOULDNOT_SEND_PING, curl_error($ch), curl_errno($ch));\r
-        }\r
-        $respCd = curl_getinfo($ch, CURLINFO_HTTP_CODE);\r
-        if ($respCd != 200) {\r
-            return sprintf(_TB_msgRESP_HTTP_ERROR, $respCd, curl_error($ch));\r
-        }\r
-        $domDoc   = new DOMDocument;\r
-        $domDoc->preserveWhiteSpace = false;\r
-        $domDoc->loadXML($response);\r
-        $encoding = $dom->encoding;\r
-        if (empty($encoding)) {\r
-            $encoding = $this->_detect_encoding($response);  //mb_detect_encoding($response, 'ASCII,ISO-2022-JP,UTF-8,EUC-JP,SJIS')\r
-        }\r
-        if (strtoupper($encoding) != "UTF-8" && strtoupper($encoding) != "ISO-8859-1") {\r
-            $response = @mb_convert_encoding($response, "UTF-8", $encoding);\r
+            $pingData['title']     = mb_convert_encoding($pingData['title'], 'UTF-8', _CHARSET);\r
+            $pingData['excerpt']   = mb_convert_encoding($pingData['excerpt'], 'UTF-8', _CHARSET);\r
+            $pingData['blog_name'] = mb_convert_encoding($pingData['blog_name'], 'UTF-8', _CHARSET);\r
+        }\r
+        foreach ($pingURLs as $key => $pingURL) {\r
+            $parsed = parse_url($pingURL);\r
+            if (strpos($parsed['scheme'], 'http') !== 0 || !$parsed['host']) {\r
+                $res[]['mess'] = _TB_msgBAD_SENDER_URL;\r
+                $res[]['url']  = $pingURL;\r
+                unset($pingURLs[$key]);\r
+            } else {\r
+                $ch[$key] = curl_init();\r
+                $options = array(\r
+                    CURLOPT_URL            => $pingURL,\r
+                    CURLOPT_POST           => 1,\r
+                    CURLOPT_POSTFIELDS     => $pingData,\r
+                    CURLOPT_RETURNTRANSFER => 1,\r
+                );\r
+                curl_setopt_array($ch[$key], $options);\r
+                curl_multi_add_handle($cmh, $ch[$key]); \r
+            }\r
+        }\r
+        if (empty($pingURLs)) {\r
+            return;\r
+        }\r
+\r
+        // 3. Send TrackBack ping data\r
+        $running = null;\r
+        do {\r
+            curl_multi_exec($cmh, $running);\r
+        } while($running > 0);\r
+\r
+        // 4. Get response and remove handle\r
+        foreach($ch as $key => $c) {\r
+            $response = curl_multi_getcontent($c);\r
+            if ($response === false) {\r
+                $res[]['mess'] = sprintf(_TB_msgCOULDNOT_SEND_PING, curl_error($c), curl_errno($c));\r
+                $res[]['url']  = $pingURLs[$key];\r
+            }\r
+            $respCd = curl_getinfo($c, CURLINFO_HTTP_CODE);\r
+            if ($respCd != 200) {\r
+                $res[]['mess'] = sprintf(_TB_msgRESP_HTTP_ERROR, $respCd, curl_error($c));\r
+                $res[]['url']  = $pingURLs[$key];\r
+            }\r
             $domDoc   = new DOMDocument;\r
             $domDoc->preserveWhiteSpace = false;\r
             $domDoc->loadXML($response);\r
-        }\r
-        $errors  = $domDoc->getElementsByTagName('error');\r
-        $error   = $errors->item(0)->nodeValue;\r
-        if (intval($error)) {\r
-            $mesages = $domDoc->getElementsByTagName('message');\r
-            $mesage  = $mesages->item(0)->nodeValue;\r
-            if (strtoupper(_CHARSET) != 'UTF-8') {\r
-                $mesage = @mb_convert_encoding($mesage, _CHARSET, "UTF-8");\r
+            $encoding = $dom->encoding;\r
+            if (empty($encoding)) {\r
+                $encoding = $this->_detect_encoding($response);  //mb_detect_encoding($response, 'ASCII,ISO-2022-JP,UTF-8,EUC-JP,SJIS')\r
+            }\r
+            if (strtoupper($encoding) != "UTF-8" && strtoupper($encoding) != "ISO-8859-1") {\r
+                $response = @mb_convert_encoding($response, "UTF-8", $encoding);\r
+                $domDoc   = new DOMDocument;\r
+                $domDoc->preserveWhiteSpace = false;\r
+                $domDoc->loadXML($response);\r
+            }\r
+            $errors = $domDoc->getElementsByTagName('error');\r
+            $error  = $errors->item(0)->nodeValue;\r
+            if (intval($error)) {\r
+                $mesages = $domDoc->getElementsByTagName('message');\r
+                $mesage  = $mesages->item(0)->nodeValue;\r
+                if (strtoupper(_CHARSET) != 'UTF-8') {\r
+                    $mesage = @mb_convert_encoding($mesage, _CHARSET, "UTF-8");\r
+                }\r
+                $res[]['mess'] = sprintf(_TB_msgAN_ERROR_OCCURRED, htmlspecialchars($mesage, ENT_QUOTES));\r
+                $res[]['url']  = $pingURLs[$key];\r
             }\r
-            return sprintf(_TB_msgAN_ERROR_OCCURRED, htmlspecialchars($mesage, ENT_QUOTES));\r
+            curl_multi_remove_handle($cmh, $c);\r
         }\r
-        return '';\r
+        curl_multi_close($mh);\r
     }\r
 \r
 // }}}\r
@@ -1534,7 +1554,7 @@ ___RDFCODE___;
                     `block` = 1 and \r
                     `url`   = "' . sql_real_escape_string($url) . '"\r
             ');\r
-            if (mysql_num_rows($res) != 0) {\r
+            if (sql_num_rows($res) != 0) {\r
                 // NP_Trackback has blocked tb !\r
                 ACTIONLOG :: add(INFO, sprintf(_TB_msgDUPLICATED_TB_BLOCKED, $tb_id, $url));\r
                 return _TB_tplNO_ACCEPT;\r
@@ -1808,121 +1828,251 @@ ___RDFCODE___;
     function pingTrackback($data)\r
     {\r
         global $manager, $CONF;\r
-        $ping_urls_count = 0;\r
-        $ping_urls       = array();\r
-        $ping_url        = requestVar('trackback_ping_url');\r
-        $localflag       = array();\r
-        if (trim($ping_url)) {\r
-            $ping_urlsTemp = array();\r
-            $ping_urlsTemp = preg_split("/[\s,]+/", trim($ping_url));\r
-            for ($i=0; $i<count($ping_urlsTemp); $i++) {\r
-                $ping_urls[] = trim($ping_urlsTemp[$i]);\r
-                $ping_urls_count++;\r
-            }\r
-        }\r
-        $tb_url_amount   = requestVar('tb_url_amount');\r
-        for ($i=0; $i<$tb_url_amount; $i++) {\r
-            $tb_temp_url = requestVar('tb_url_' . $i);\r
-            if ($tb_temp_url) {\r
-                $ping_urls[$ping_urls_count] = $tb_temp_url;\r
-                $localflag[$ping_urls_count] = (requestVar('tb_url_' . $i . '_local') == 'on') ? 1 : 0;\r
-                $ping_urls_count++;\r
+        $localPing = array();\r
+        $pingURLs  = array();\r
+        $pingCount = 0;\r
+        if ($tmpPings = trim(requestVar('trackback_ping_url'))) {\r
+            $pingURLs  = array_map('trim', preg_split("/[\s,]+/", $tmpPings));\r
+            $pingCount = count($pingURLs);\r
+        }\r
+        $URLamount = intRequestVar('tb_url_amount');\r
+        for ($i = 0; $i < $URLamount; $i++;) {\r
+            if ($tmpURL = requestVar('tb_url_' . $i)) {\r
+                if (requestVar('tb_url_' . $i . '_local') == 'on') {\r
+                    $localPing[] = $tmpURL;\r
+                } else {\r
+                    $pingURLs[$pingCount] = $tmpURL;\r
+                    $pingCount++;\r
+                }\r
             }\r
         }\r
-        if ($ping_urls_count <= 0) {\r
+        if ($pingCount <= 0 && count($localPing) <= 0) {\r
             return;\r
         }\r
-        $itemid =  $data['itemid'];\r
+        $itemid =  intval($data['itemid']);\r
         $item   =& $manager->getItem($itemid, 0, 0);\r
-        if (!$item) {\r
+        if (empty($item)) {\r
             return; // don't ping for draft & future\r
         }\r
-        if ($item['draft']) {\r
-            return;   // don't ping on draft items\r
+        // gather some more information, needed to send the ping (blog name, etc)\r
+        $blog     =& $manager->getBlog(getBlogIDFromItemID($itemid));\r
+        $pingData =  array(\r
+            'blog_name' => $blog->getName(),\r
+            'title'     => strip_tags($item['title']),\r
+            'excerpt'   => $this->_cut_string(strip_tags($item['body']), 200),\r
+            'url'       => $this->_createItemLink($itemid, $blog);\r
+        );\r
+        $res = array();\r
+        if ($pingCount) {\r
+            $this->sendPing($itemid, $pingData, $pingURLs, &$res);\r
         }\r
-        // gather some more information, needed to send the ping (blog name, etc)      \r
-        $blog      =& $manager->getBlog(getBlogIDFromItemID($itemid));\r
-        $blog_name =  $blog->getName();\r
-        $title     =  $data['title'] != '' ? $data['title'] : $item['title'];\r
-        $title     =  strip_tags($title);\r
-        $excerpt   =  $data['body'] != '' ? $data['body'] : $item['body'];\r
-        $excerpt   =  strip_tags($excerpt);\r
-        $excerpt   =  $this->_cut_string($excerpt, 200);\r
-        $url       =  $this->_createItemLink($item['itemid'], $blog);    \r
-        for ($i=0; $i<count($ping_urls); $i++) {\r
-            if (!$localflag[$i]) {\r
-                $res = $this->sendPing($itemid, $title, $url, $excerpt, $blog_name, $ping_urls[$i]);\r
-            } else {\r
-                $res = $this->handleLocalPing($itemid, $title, $excerpt, $blog_name, $ping_urls[$i]);\r
+        if (count($localPing)) {\r
+            $this->handleLocalPing($itemid, $pingData, $pingURLs, &$res);\r
+        }\r
+        if (!empty($res)) {\r
+            foreach ($res as $value) {\r
+                ACTIONLOG::add(WARNING, sprintf(_TB_msgTRACKBACK_ERROR, $value['mess7}, $value['url']));\r
             }\r
-            if ($res) {\r
-                ACTIONLOG::add(WARNING, 'TrackBack Error:' . $res . ' (' . $ping_urls[$i] . ')');\r
-            \r
         }\r
     }\r
 \r
+// }}}\r
+// {{{ function autoDiscovery($text)\r
 \r
+    /**\r
+     * Auto-Discovery of TrackBack Ping URLs based on HTML story\r
+     *\r
+     * @param str\r
+     * @return arr\r
+     */\r
+    function autoDiscovery($text)\r
+    {\r
+        $dom = new DOMDocument;\r
+        $dom->preserveWhiteSpace = false;\r
+        $dom->loadHTML($text);\r
+\r
+        $links  = $this->getPermaLinksFromText($text);\r
+        $result = array();\r
+        foreach ($links as $link) {\r
+            list($url, $title) => $this->getURIfromLink($link);\r
+            if (!empty($url)) {\r
+                $result[$url] = $title;\r
+            }\r
+        }\r
+        return $result;\r
+    }\r
 \r
+// }}}\r
+// {{{ function getURIfromLink($link)\r
 \r
+    /**\r
+     * Auto-Discovery of TrackBack Ping URLs based on single link\r
+     *\r
+     * @param str\r
+     * @return arr\r
+     */\r
+    function getURIfromLink($link)\r
+    {\r
+        // Check to see if the cache contains this link\r
+        $res = sql_query('\r
+            SELECT\r
+                `url`,\r
+                `title`,\r
+            FROM\r
+                `' . sql_table('plugin_tb_lookup') . '`\r
+            WHERE\r
+                `link` = "' . sql_real_escape_string($link) . '"\r
+        ');\r
+        if ($row = sql_fetch_assoc($res)) {\r
+            if ($row['title'] != '') {\r
+                if (strtoupper(_CHARSET) != 'UTF-8') {\r
+                    $row['title'] = mb_convert_encoding($row['title'], 'UTF-8', _CHARSET);\r
+                    $row['title'] = $this->_decode_entities($row['title']);\r
+                }\r
+                return array(\r
+                    $row['url'],\r
+                    $row['title'],\r
+                );\r
+            } else {\r
+                return array(\r
+                    $row['url'],\r
+                    $row['url'],\r
+                );\r
+            }\r
+        }\r
+        $rdf = $this->retrieveUrl($link);\r
+        if ($rdf) {\r
+            if (($uri = $this->getAttributeFromRDF($rdf, 'trackback:ping')) !== false) {\r
+                if (($title = $this->getAttributeFromRDF($rdf, 'dc:title')) !== false) {\r
+                    if (($author = $this->getAttributeFromRDF($rdf, 'dc:creator')) !== false) {\r
+                        $title = $author . ": " . $title;\r
+                    }\r
+                    $uri = $this->_decode_entities($uri);\r
+                    $convertedTitle = (strtoupper(_CHARSET) != 'UTF-8') ? mb_convert_encoding($title, _CHARSET, 'UTF-8')\r
+                                                                        : $title;\r
+                    $res = sql_query("\r
+                        INSERT INTO \r
+                            `" . sql_table('plugin_tb_lookup') . "`\r
+                        (\r
+                            `link`,\r
+                            `url`,\r
+                            `title`\r
+                        ) VALUES (\r
+                            '" . sql_real_escape_string($link) . "',\r
+                            '" . sql_real_escape_string($uri) . "',\r
+                            '" . sql_real_escape_string($convertedTitle) . "'\r
+                        )\r
+                    ");\r
+                    $title = $this->_decode_entities($title);\r
+                    return array (\r
+                        $uri,\r
+                        $title\r
+                    );\r
+                } else {\r
+                    $uri = html_entity_decode($uri, ENT_COMPAT);\r
+                    $res = sql_query("\r
+                        INSERT INTO \r
+                            `" . sql_table('plugin_tb_lookup') . "`\r
+                        (\r
+                            `link`,\r
+                            `url`,\r
+                            `title`\r
+                        ) VALUES (\r
+                            '" . sql_real_escape_string($link) . "',\r
+                            '" . sql_real_escape_string($uri) . "',\r
+                            ''\r
+                        )\r
+                    ");\r
+                    return array (\r
+                        $uri,\r
+                        $uri\r
+                    );\r
+                }\r
+            }\r
+        }\r
+        $res = sql_query("\r
+            INSERT INTO \r
+                `" . sql_table('plugin_tb_lookup') . "`\r
+            (\r
+                `link`,\r
+                `url`,\r
+                `title`\r
+            ) VALUES (\r
+                '" . sql_real_escape_string($link) . "',\r
+                '',\r
+                ''\r
+            )\r
+        ");\r
+        return array (\r
+            '',\r
+            ''\r
+        );\r
+    }\r
 \r
+// }}}\r
+// {{{ function getPermaLinksFromText($text)\r
 \r
-    \r
-    \r
-    \r
-\r
-    \r
-/*\r
-            $CONF['ItemURL'] = preg_replace('/\/$/', '', $blog->getURL());   \r
-            $url = createItemLink($itemid);\r
-*/\r
-    \r
-            // send the ping(s) (add errors to actionlog)\r
-\r
-\r
-\r
+    /**\r
+     * Detect links used in HTML code\r
+     *\r
+     * @param str\r
+     * @return arr\r
+     */\r
+    function getPermaLinksFromText($text)\r
+    {\r
+        $lnk = array();\r
+        $dom = new DOMDocument;\r
+        $dom->load($text);\r
+        $anc = $dom->getElementsByTagName('a');\r
+        foreach ($anc as $a) {\r
+            $ink[] = $a->getAttribute('href');\r
+        }\r
+        return $lnk;\r
+    }\r
 \r
+// }}}\r
+// {{{ function retrieveUrl($link)\r
 \r
+    /**\r
+     * Retrieve the contents of an external (X)HTML document\r
+     *\r
+     * @param str\r
+     * @return str\r
+     */\r
+    function retrieveUrl($url)\r
+    {\r
+        $ua  = ini_set('user_agent', $this->userAgent);\r
+        $ch  = curl_init();\r
+        $opt = array(\r
+            CURLOPT_URL            => $url,\r
+            CURLOPT_HEADER         => 1,\r
+            CURLOPT_BINARYTRANSFER => 1,\r
+            CURLOPT_FOLLOWLOCATION => 1,\r
+            CURLOPT_MAXREDIRS      => 5,\r
+            CURLOPT_RETURNTRANSFER => 1,\r
+            CURLOPT_TIMEOUT        => 20,\r
+            CURLOPT_USERAGENT      => $this->userAgent,\r
+        );\r
+        curl_setopt_array($ch, $opt);\r
+        // Retrieve response\r
+        $raw  = curl_exec($ch);\r
+        $info = curl_getinfo($ch);\r
+        // Split into headers and contents\r
+        $headers  = substr($raw, 0, $info['header_size']);\r
+        $contents = substr($raw, $info['header_size']);\r
+        curl_close($ch);\r
+        ini_set('user_agent', $ua);\r
+        // Next normalize the encoding to UTF8...\r
+        $contents = $this->_convert_to_utf8_auto($contents, $headers);\r
+        return $contents;\r
+    }\r
 \r
 \r
 \r
 \r
 \r
 \r
-            $dom      =  new DOMDocument('1.0', 'UTF-8');\r
-            $response =  $dom->appendChild($dom->createElement('response'));\r
-            $response->appendChild($dom->createElement('error', '0'));\r
-            $rss      =  $response->appendChild($dom->createElement('rss'));\r
-            $rss->setAttribute("version", "0.91");\r
-            $channel  =  $rss->appendChild($dom->createElement('channel'));\r
-            $channel->appendChild($dom->createElement('title', htmlspecialchars($title, ENT_QUOTES)));\r
-            $channel->appendChild($dom->createElement('link', htmlspecialchars($url, ENT_QUOTES)));\r
-            $channel->appendChild($dom->createElement('description', htmlspecialchars($excerpt, ENT_QUOTES)));\r
 \r
-            $query = 'SELECT '\r
-                   .    '`url`, '\r
-                   .    '`blog_name`, '\r
-                   .    '`excerpt`, '\r
-                   .    '`title`, '\r
-                   .    'UNIX_TIMESTAMP(`timestamp`) as timestamp '\r
-                   . 'FROM '\r
-                   .    sql_table('plugin_tb') . ' '\r
-                   . 'WHERE '\r
-                   .    '`tb_id` = ' . $tb_id . ' AND '\r
-                   .    '`block` = 0 '\r
-                   . 'ORDER BY '\r
-                   .    '`timestamp` DESC';\r
-            $res   = sql_query($query);\r
-            while($data = sql_fetch_assoc($res)) {\r
-                $data['title']   = htmlspecialchars($this->_restore_to_utf8($data['title']), ENT_QUOTES);\r
-                $data['excerpt'] = htmlspecialchars($this->_restore_to_utf8($data['excerpt']), ENT_QUOTES);\r
-                $data['url']     = htmlspecialchars($data['url'], ENT_QUOTES);\r
-                $item            = $channel->appendChild($dom->createElement('item'));\r
-                $item->appendChild($dom->createElement('title', $data['title']);\r
-                $item->appendChild($dom->createElement('link', $data['url']);\r
-                $item->appendChild($dom->createElement('description', $data['excerpt']);\r
-            }\r
-            header('Content-Type: text/xml');\r
-            echo $dom->saveXML();\r
 \r
 \r
 \r