root/tags/1.0.0/xmlrpc.php

Revision 1541, 9.1 KB (checked in by jeena, 3 years ago)

implemented some plugin interfaces

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.'personal'.DIRECTORY_SEPARATOR.'settings.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            $this->title = $title[1];
109        }
110
111        $sql = "SELECT COUNT(*) AS ping FROM ".$this->db_comments." WHERE
112                    reference = '".escape_for_mysql($blogrow['id'])."' AND
113                    homepage = '".escape_for_mysql($this->sourceURI)."' AND
114                    name = '".escape_for_mysql($this->title)."' AND
115                    type = 'pingback'
116                  LIMIT 1";
117        $p = new Query($sql);
118        if($p->error()) $this->send_error(0, 'Could not read my database.');
119        $f = $p->fetch();
120
121        if($f['ping'] > 0) $this->send_error(48, 'The pingback has already been registered.');
122
123        if(count($this->errors) > 0) return false;
124        else return true;
125    }
126
127    function write_to_db() {
128        $sql = "INSERT INTO ".$this->db_comments." (
129            sid,
130            name,
131            homepage,
132            reference,
133            date,
134            type
135          )
136           VALUES (
137            '".escape_for_mysql($this->sid)."',
138            '".escape_for_mysql($this->title)."',
139            '".escape_for_mysql($this->sourceURI)."',
140            '".escape_for_mysql($this->reference)."',
141            NOW(),
142            'pingback'
143           )";
144        $ping = new Query($sql);
145
146       if($ping->error()) $this->send_error(0, 'Could not write to database.');
147
148    }
149   
150    function send_error($nr, $string) {
151        $this->errors[] = $nr." ".$string;
152        $error = new IXR_Error($nr, $string);
153        $this->send_xml($error->getXml());
154    }
155   
156    function get_errors() {
157        return $this->errors;
158    }
159   
160    function send_xml($xml) {
161        header('Connection: close');
162        header('Content-Length: '.strlen($xml));
163        header('Content-Type: text/xml');
164        header('Date: '.date('r'));
165        echo $xml;
166        exit;
167    }
168
169    function isLinkInHTML($search, $html) {
170        preg_match_all('#<a[^>]+href\s*=\s*("([^"]+)"|\'([^\']+)\')[^>]*>(.+)</a>#Ui', $html, $matches);
171        $links =  array_unique(array_merge($matches[2], $matches[3]));
172
173        foreach($links as $link) {
174            if($search === str_replace('&amp;', '&', $link)) return true;
175        }
176        return false;
177    }
178
179}
180
181class Jlog_SendPingback {
182
183    var $pageslinkedto = array();
184    var $useragent = "";
185
186    function Jlog_SendPingback($html, $pagelinkedfrom, $useragent) {
187        $this->pagelinkedfrom = $pagelinkedfrom;
188        $this->useragent = $useragent;
189
190        preg_match_all('#<a[^>]+href\s*=\s*("([^"]+)"|\'([^\']+)\')[^>]*>(.+)</a>#Ui', $html, $matches);
191        $pageslinkedto = array();
192        $pageslinkedto = array_unique(array_merge($matches[2], $matches[3]));
193        $count = count($pageslinkedto);
194        for($i = 0; $count > $i; $i++) {
195            if(substr($pageslinkedto[$i], 0, 4) !== "http") unset($pageslinkedto[$i]);
196            else $pageslinkedto[$i] = str_replace(array('&quot;','&lt;', '&gt;', '&amp;'), array('"', '<', '>', '&'), $pageslinkedto[$i]);
197        }
198        $this->pageslinkedto = $pageslinkedto;
199    }
200
201    function doPingbacks() {
202        foreach($this->pageslinkedto as $pagelinkedto) {
203            $feedback[] = $this->send($pagelinkedto);
204        }
205        return $feedback;
206    }
207
208    function send($pagelinkedto) {
209
210        $s =& new HTTP_Request($pagelinkedto);
211        if(PEAR::isError($s->sendRequest())) return $pagelinkedto." &mdash; Error: The source URI does not exist.";
212        else {
213            $xmlrpcserver = $s->getResponseHeader("X-Pingback");
214            if(!empty($xmlrpcserver));
215            else {
216                if(preg_match('<link rel="pingback" href="([^"]+)" ?/?>', $s->getResponseBody(), $matches)) {
217                    $xmlrpcserver = $matches[1];
218                }
219                else return $pagelinkedto." &mdash; This is not a pingback-enabled resource.";
220            }
221
222            $client = new IXR_Client($xmlrpcserver);
223            $client->timeout = 3;
224            $client->useragent = $this->useragent;
225
226            // when set to true, this outputs debug messages by itself
227            $client->debug = false;
228
229            if (! $client->query('pingback.ping', $this->pagelinkedfrom, $pagelinkedto ) )
230                return $pagelinkedto." &mdash; Error: ".$client->getErrorMessage();
231
232            else return $pagelinkedto." &mdash; ".$client->getResponse();
233        }
234    }
235
236}
237?>
Note: See TracBrowser for help on using the browser.