root/trackback/requirements/de.easy-coding.wcf.trackback/files/lib/util/XMLRPCServer.class.php @ 805

Revision 805, 5.8 kB (checked in by d0nut, 4 years ago)

changed paths for publicseorewriter

Line 
1<?php
2require_once(WBB_DIR.'lib/page/PublicSEORewriter.class.php');
3require_once(WCF_DIR.'lib/util/StringUtil.class.php');
4require_once(WBB_DIR.'lib/data/post/Post.class.php');
5require_once(WBB_DIR.'lib/util/IXR.class.php');
6require_once(WBB_DIR.'lib/util/TrackbackUtil.class.php');
7require_once(WBB_DIR.'lib/data/thread/Thread.class.php');
8
9// Some browser-embedded clients send cookies. We don't want them.
10$_COOKIE = array();
11
12// A bug in PHP < 5.2.2 makes $HTTP_RAW_POST_DATA not set by default,
13// but we can do it ourself.
14if(!isset($HTTP_RAW_POST_DATA)) {
15        $HTTP_RAW_POST_DATA = file_get_contents('php://input');
16}
17
18# fix for mozBlog and other cases where '<?xml' isn't on the very first line
19if(isset($HTTP_RAW_POST_DATA)) {
20        $HTTP_RAW_POST_DATA = trim($HTTP_RAW_POST_DATA);
21}
22
23
24/**
25 * xmlrpc util
26 *
27 * @author      Torben Brodt
28 * @package     de.easy-coding.wcf.trackback
29 * @license     GNU General Public License <http://opensource.org/licenses/gpl-3.0.html>
30 */
31class XMLRPCServer extends IXR_Server {
32        protected $rewriter;
33
34        /**
35         * constructor
36         */
37        public function __construct() {
38                $this->methods = array(
39                        'pingback.ping' => 'this:pingback_ping'
40                );
41               
42                $this->rewriter = new PublicSEORewriter();
43
44                parent::IXR_Server($this->methods);
45        }
46       
47        /**
48         * escapes strings
49         * @param arr
50         */
51        protected function escape(&$arr) {
52                foreach ($arr as $k => $v ) {
53                        $arr[$k] = escapeString($v);
54                }
55        }
56
57        /**
58         * gets a pingback and registers it
59         * @param args array(linkedfrom, linkedto)
60         */
61        public function pingback_ping($args) {
62                $this->escape($args);
63
64                $pagelinkedfrom = StringUtil::decodeHTML($args[0]);
65                $pagelinkedto   = StringUtil::decodeHTML($args[1]);
66
67                $title = '';
68
69                $error_code = -1;
70
71                // Check if the page linked to is in our site
72                $pos1 = strpos($pagelinkedto, str_replace(array('http://www.','http://','https://www.','https://'), '', PAGE_URL));
73                if(!$pos1) {
74                        return new IXR_Error(0, 'Is there no link to us?');
75                }
76
77                // let's find which post is linked to
78                $threadID = $this->rewriter->thread2threadID($pagelinkedto);
79                if($threadID === NULL) {
80                        return new IXR_Error(33, 'The specified target URL cannot be resolved as a thread url.');
81                }
82               
83                $thread = new Thread($threadID);
84
85                // Check if post exists
86                if($thread->firstPostID) {
87                        $post = new Post($thread->firstPostID);
88                } else {
89                        return new IXR_Error(33, 'The specified target URL cannot be used as a target. It doesn\'t exist.');
90                }
91
92                // Check if pings are on
93                if(!$post->hasTrackback) {
94                        return new IXR_Error(33, 'The specified target URL cannot be used as a target. It is not a pingback-enabled resource.');
95                }
96
97                // check for duplicates
98                $sql = "SELECT  COUNT(*) AS c
99                        FROM    wbb".WBB_N."_trackback
100                        WHERE   postID = ".$post->postID."
101                        AND     url = '".escapeString($pagelinkedfrom)."' ";
102                       
103                $row = WBBCore::getDB()->getFirstRow($sql);
104                if(intval($row['c']) > 0) {
105                        return new IXR_Error(48, 'The pingback has already been registered.');
106                }
107
108                // very stupid, but gives time to the 'from' server to publish !
109                sleep(1);
110
111                // Let's check the remote site
112                extract(parse_url($pagelinkedfrom), EXTR_SKIP);
113
114                $path  = ( !isset($path) ) ? '/'          : $path;
115                $path .= ( isset($query) ) ? '?' . $query : '';
116                $port  = ( isset($port)  ) ? $port        : 80;
117
118                // Try to connect to the server at $host
119                $fp = @fsockopen($host, $port, $errno, $errstr, 2);
120                if(!$fp) {
121                        return new IXR_Error(16, 'The source URL does not exist.');
122                }
123               
124                $request = "GET $path HTTP/1.1\r\nHost: $host\r\nUser-Agent: ".TrackbackUtil::$agent." \r\n\r\n";
125                fputs($fp, $request);
126                $linea = '';
127                while (!feof($fp)) {
128                        $linea .= fgets($fp, 4096);
129                }
130
131                // Work around bug in strip_tags():
132                $linea = str_replace('<!DOC', '<DOC', $linea);
133                $linea = preg_replace( '/[\s\r\n\t]+/', ' ', $linea ); // normalize spaces
134                $linea = preg_replace( "/ <(h1|h2|h3|h4|h5|h6|p|th|td|li|dt|dd|pre|caption|input|textarea|button|body)[^>]*>/", "\n\n", $linea );
135
136                preg_match('|<title>([^<]*?)</title>|is', $linea, $matchtitle);
137                $title = $matchtitle[1];
138                if(empty($title)) {
139                        return new IXR_Error(32, 'We cannot find a title on that page.');
140                }
141
142                $linea = strip_tags($linea, '<a>'); // just keep the tag we need
143                $p = explode("\n\n", $linea);
144
145                $preg_target = preg_quote($pagelinkedto);
146
147                foreach($p as $para) {
148                        if(strpos($para, $pagelinkedto) !== false) { // it exists, but is it a link?
149                                preg_match("|<a[^>]+?".$preg_target."[^>]*>([^>]+?)</a>|", $para, $context);
150
151                                // If the URL isn't in a link context, keep looking
152                                if(empty($context)) {
153                                        continue;
154                                }
155
156                                // We're going to use this fake tag to mark the context in a bit
157                                // the marker is needed in case the link text appears more than once in the paragraph
158                                $excerpt = preg_replace('|\</?wpcontext\>|', '', $para);
159
160                                // prevent really long link text
161                                if(strlen($context[1]) > 100) {
162                                        $context[1] = substr($context[1], 0, 100).'...';
163                                }
164
165                                $marker = '<wpcontext>'.$context[1].'</wpcontext>';    // set up our marker
166                                $excerpt= str_replace($context[0], $marker, $excerpt); // swap out the link for our marker
167                                $excerpt = strip_tags($excerpt, '<wpcontext>');        // strip all tags but our context marker
168                                $excerpt = trim($excerpt);
169                                $preg_marker = preg_quote($marker);
170                                $excerpt = preg_replace("|.*?\s(.{0,100}$preg_marker.{0,100})\s.*|s", '$1', $excerpt);
171                                $excerpt = strip_tags($excerpt); // YES, again, to remove the marker wrapper
172                                break;
173                        }
174                }
175
176                if(empty($context)) { 
177                        // Link to target not found
178                        return new IXR_Error(17, 'The source URL does not contain a link to the target URL, and so cannot be used as a source.');
179                }
180
181                // save incoming
182                TrackbackUtil::save($postID, $pagelinkedto, $title, $excerpt, $pagelinkedfrom, $title);
183
184                return sprintf('Pingback from %1$s to %2$s registered. Keep the web talking! :-)', $pagelinkedfrom, $pagelinkedto);
185        }
186}
187?>
Note: See TracBrowser for help on using the browser.