root/tags/1.1.0/xmlrpc.php

Revision 1707, 9.4 KB (checked in by jeena, 10 months ago)

changed require prepend.inc.php instead setting.inc.php

Line 
1<?php # A class for getting and sending Pingbacks
2 $HTTP_RAW_POST_DATA = trim($HTTP_RAW_POST_DATA);
3 if(!defined('JLOG_BASEPATH')) require_once('.'.DIRECTORY_SEPARATOR.'scripts'.DIRECTORY_SEPARATOR.'prepend.inc.php');
4 require_once(JLOG_BASEPATH.'scripts'.DIRECTORY_SEPARATOR.'ixr-library.inc.php');
5 require_once(JLOG_BASEPATH.'scripts'.DIRECTORY_SEPARATOR.'jlogHTTP_Request.php');
6
7
8    if(defined("JLOG_ADMIN") === false) {
9        function ping($args) {
10
11            $pingback = new Jlog_GetPingback(JLOG_DB_CONTENT, JLOG_DB_COMMENTS, JLOG_PATH, new_sid());
12            $pingback->get_ping($args);
13            if($pingback->validate()) {
14                $pingback->write_to_db();
15                return "Thanks for your ping.";
16            }
17        }
18        $server = new IXR_Server(array('pingback.ping' => 'ping'));
19    }
20
21class Jlog_GetPingback {
22
23    var $errors = array();        // array
24    var $method = "";             // string
25    var $sourceURI = "";          // string
26    var $targetURI = array();     // array incl: orginal, parsed [array from parse_url()], y, m, url
27    var $title = "";              // string
28    var $sid = "";                // string
29
30    function Jlog_GetPingback($db_content, $db_comments, $path, $sid = NULL) {
31        $this->db_content = $db_content;
32        $this->db_comments = $db_comments;
33        $this->path = $path;
34        if($sid != NULL) $this->sid = $sid;
35    }
36
37    function get_ping($uris) {
38
39        $ymurls = array();
40        $tmp_host_got = "";
41        $tmp_host_path_parsed = array();
42        $tmp_host_path = "";
43
44        $this->sourceURI = trim($uris[0]);
45        $this->targetURI['orginal'] = trim(str_replace(array('&quot;','&lt;', '&gt;', '&amp;'), array('"', '<', '>', '&'), $uris[1]));
46        $this->targetURI['parsed'] = parse_url($this->targetURI['orginal']);
47        $tmp_host_got = str_replace('www.', '', $this->targetURI['parsed']['host']).$this->targetURI['parsed']['path'];
48        $tmp_host_path_parsed = parse_url($this->path);
49        $tmp_host_path = str_replace('www.', '', $tmp_host_path_parsed['host']).'/log.php';
50
51        if(!empty($this->targetURI['parsed']['query']) AND ($tmp_host_got == $tmp_host_path)) {
52
53            $ymurls = explode('&', $this->targetURI['parsed']['query']);
54            $this->_counter = count($ymurls);
55
56            foreach($ymurls AS $ymurl) {
57                if(substr($ymurl, 0, 2) == 'y=') $this->targetURI['y'] = substr($ymurl, 2);
58                elseif(substr($ymurl, 0, 2) == 'm=') $this->targetURI['m'] = substr($ymurl, 2);
59                elseif(substr($ymurl, 0, 4) == 'url=') $this->targetURI['url'] = substr($ymurl, 4);
60            }
61        }
62        else {
63            ### Plugin Hook
64            global $plugins;
65            $tmp_URI = $plugins->callHook('xmlrpcPermalink', $this->targetURI['orginal']);
66           
67            $regex = "#^".$this->path."/([0-9]{4})/?([0-9]{2})/?([a-z0-9_\-]+)$#";
68            preg_match($regex, $tmp_URI, $matches);
69            $this->targetURI['y'] = $matches[1];
70            $this->targetURI['m'] = $matches[2];
71            $this->targetURI['url'] = $matches[3];
72        }
73
74    }
75
76    function validate() {
77
78
79        if(!strpos($this->targetURI['orginal'], str_replace(array('http://', 'https://'), '', str_replace('www.', '', $this->path))))
80            $this->send_error(0, 'Target URI ('.$this->targetURI['orginal'].') is not this page: '.$this->path);
81
82
83        // is there such a post?
84        $sql = "SELECT  id, allowpingback FROM ".$this->db_content." WHERE
85                        YEAR(date)  = '".escape_for_mysql($this->targetURI['y'])."' AND
86                        MONTH(date) = '".escape_for_mysql($this->targetURI['m'])."' AND
87                        url         = '".escape_for_mysql($this->targetURI['url'])."' AND
88                        section     = 'weblog'
89                  LIMIT 1";
90        $blog = new Query($sql);
91       if($blog->error()) $this->send_error(0, 'Could not read my database.');
92        $blogrow = $blog->fetch();
93
94        if($blog->numRows() != 1) $this->send_error(32, 'The specified target URI does not exist.'.$this->targetURI['orginal']);
95        if($blogrow['allowpingback'] === 0) $this->send_error(33, 'The specified target URI cannot be used as a target. It it is not a pingback-enabled resource.');
96        else $this->reference = $blogrow['id'];
97
98        $s =& new HTTP_Request($this->sourceURI);
99        if(PEAR::isError($s->sendRequest())) $this->send_error(16, 'The source URI does not exist.');
100        else {
101                                                $source = $s->getResponseBody();
102            $source = strip_tags(str_replace('<!DOCTYPE','<DOCTYPE', $source), '<title><a>');
103
104            if (!$this->isLinkInHTML($this->targetURI['orginal'], $source))
105                $this->send_error(17, 'The source URI does not contain a link to the target URI, and so cannot be used as a source.');
106
107            preg_match('|<title>([^<]*?)</title>|is', $source, $title);
108
109                                                if(! $utf8 = preg_match ('/charset\s*=\s*utf-8/i', $s->getResponseHeader("Content-Type")))
110              $utf8 = 'application/xhtml+xml' == strtolower(trim($s->getResponseHeader("Content-Type")));
111
112            $this->title = empty($title[1]) ? $this->sourceURI : html_entity_decode($utf8 ? utf8_decode($title[1]) : $title[1]);
113        }
114
115        $sql = "SELECT COUNT(*) AS ping FROM ".$this->db_comments." WHERE
116                    reference = '".escape_for_mysql($blogrow['id'])."' AND
117                    homepage = '".escape_for_mysql($this->sourceURI)."' AND
118                    name = '".escape_for_mysql($this->title)."' AND
119                    type = 'pingback'
120                  LIMIT 1";
121        $p = new Query($sql);
122        if($p->error()) $this->send_error(0, 'Could not read my database.');
123        $f = $p->fetch();
124
125        if($f['ping'] > 0) $this->send_error(48, 'The pingback has already been registered.');
126
127        if(count($this->errors) > 0) return false;
128        else return true;
129    }
130
131    function write_to_db() {
132        $sql = "INSERT INTO ".$this->db_comments." (
133            sid,
134            name,
135            homepage,
136            reference,
137            date,
138            type
139          )
140           VALUES (
141            '".escape_for_mysql($this->sid)."',
142            '".escape_for_mysql($this->title)."',
143            '".escape_for_mysql($this->sourceURI)."',
144            '".escape_for_mysql($this->reference)."',
145            NOW(),
146            'pingback'
147           )";
148        $ping = new Query($sql);
149
150       if($ping->error()) $this->send_error(0, 'Could not write to database.');
151
152    }
153   
154    function send_error($nr, $string) {
155        $this->errors[] = $nr." ".$string;
156        $error = new IXR_Error($nr, $string);
157        $this->send_xml($error->getXml());
158    }
159   
160    function get_errors() {
161        return $this->errors;
162    }
163   
164    function send_xml($xml) {
165        header('Connection: close');
166        header('Content-Length: '.strlen($xml));
167        header('Content-Type: text/xml');
168        header('Date: '.date('r'));
169        echo $xml;
170        exit;
171    }
172
173    function isLinkInHTML($search, $html) {
174        preg_match_all('#<a[^>]+href\s*=\s*("([^"]+)"|\'([^\']+)\')[^>]*>(.+)</a>#Ui', $html, $matches);
175        $links =  array_unique(array_merge($matches[2], $matches[3]));
176
177        foreach($links as $link) {
178            if($search === str_replace('&amp;', '&', $link)) return true;
179        }
180        return false;
181    }
182
183}
184
185class Jlog_SendPingback {
186
187    var $pageslinkedto = array();
188    var $useragent = "";
189
190    function Jlog_SendPingback($html, $pagelinkedfrom, $useragent) {
191        $this->pagelinkedfrom = $pagelinkedfrom;
192        $this->useragent = $useragent;
193
194        preg_match_all('#<a[^>]+href\s*=\s*("([^"]+)"|\'([^\']+)\')[^>]*>(.+)</a>#Ui', $html, $matches);
195        $pageslinkedto = array();
196        $pageslinkedto = array_unique(array_merge($matches[2], $matches[3]));
197        $count = count($pageslinkedto);
198        for($i = 0; $count > $i; $i++) {
199            if(substr($pageslinkedto[$i], 0, 4) !== "http") unset($pageslinkedto[$i]);
200            else $pageslinkedto[$i] = str_replace(array('&quot;','&lt;', '&gt;', '&amp;'), array('"', '<', '>', '&'), $pageslinkedto[$i]);
201        }
202        $this->pageslinkedto = $pageslinkedto;
203    }
204
205    function doPingbacks() {
206        foreach($this->pageslinkedto as $pagelinkedto) {
207            $feedback[] = $this->send($pagelinkedto);
208        }
209        return $feedback;
210    }
211
212    function send($pagelinkedto) {
213
214        $s =& new HTTP_Request($pagelinkedto);
215        if(PEAR::isError($s->sendRequest())) return $pagelinkedto." &mdash; Error: The source URI does not exist.";
216        else {
217            $xmlrpcserver = $s->getResponseHeader("X-Pingback");
218            if(!empty($xmlrpcserver));
219            else {
220                if(preg_match('<link rel="pingback" href="([^"]+)" ?/?>', $s->getResponseBody(), $matches)) {
221                    $xmlrpcserver = $matches[1];
222                }
223                else return $pagelinkedto." &mdash; This is not a pingback-enabled resource.";
224            }
225
226            $client = new IXR_Client($xmlrpcserver);
227            $client->timeout = 3;
228            $client->useragent = $this->useragent;
229
230            // when set to true, this outputs debug messages by itself
231            $client->debug = false;
232
233            if (! $client->query('pingback.ping', $this->pagelinkedfrom, $pagelinkedto ) )
234                return $pagelinkedto." &mdash; Error: ".$client->getErrorMessage();
235
236            else return $pagelinkedto." &mdash; ".$client->getResponse();
237        }
238    }
239
240}
241?>
Note: See TracBrowser for help on using the browser.