[ Index ] |
|
Code source de GeekLog 1.4.1 |
1 <?php 2 3 /* Reminder: always indent with 4 spaces (no tabs). */ 4 // +---------------------------------------------------------------------------+ 5 // | Geeklog 1.4 | 6 // +---------------------------------------------------------------------------+ 7 // | pingback.php | 8 // | | 9 // | Handle pingbacks for stories and plugins. | 10 // +---------------------------------------------------------------------------+ 11 // | Copyright (C) 2005-2006 by the following authors: | 12 // | | 13 // | Author: Dirk Haun - dirk AT haun-online DOT de | 14 // +---------------------------------------------------------------------------+ 15 // | | 16 // | This program is free software; you can redistribute it and/or | 17 // | modify it under the terms of the GNU General Public License | 18 // | as published by the Free Software Foundation; either version 2 | 19 // | of the License, or (at your option) any later version. | 20 // | | 21 // | This program is distributed in the hope that it will be useful, | 22 // | but WITHOUT ANY WARRANTY; without even the implied warranty of | 23 // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 24 // | GNU General Public License for more details. | 25 // | | 26 // | You should have received a copy of the GNU General Public License | 27 // | along with this program; if not, write to the Free Software Foundation, | 28 // | Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | 29 // | | 30 // +---------------------------------------------------------------------------+ 31 // 32 // $Id: pingback.php,v 1.16 2006/09/30 19:15:27 dhaun Exp $ 33 34 require_once ('lib-common.php'); 35 36 // once received, we're handling pingbacks like trackbacks, 37 // so we use the trackback library even when trackback may be disabled 38 require_once ($_CONF['path_system'] . 'lib-trackback.php'); 39 40 // PEAR class to handle XML-RPC 41 require_once ('XML/RPC/Server.php'); 42 43 // Note: Error messages are hard-coded in English since there is no way of 44 // knowing which language the sender of the pingback may prefer. 45 $PNB_ERROR = array ( 46 'success' => 'Thank you.', // success message; not an error ... 47 'skipped' => '(skipped)', // not an error 48 'spam' => 'Spam detected.', 49 'speedlimit' => 'Your last pingback was %d seconds ago. This site requires at least %d seconds between pingbacks.', 50 'disabled' => 'Pingback is disabled.', 51 'uri_invalid' => 'Invalid targetURI.', 52 'no_access' => 'Access denied.', 53 'multiple' => 'Multiple posts not allowed.' 54 ); 55 56 57 /** 58 * Handle a pingback for an entry. 59 * 60 * Also takes care of the speedlimit and spam. Assumes that the caller of this 61 * function has already checked permissions! 62 * 63 * @param string $id ID of entry that got pinged 64 * @param string $type type of that entry ('article' for stories, etc.) 65 * @param string $url URL of the page that pinged us 66 * @param string $oururl URL that got pinged on our site 67 * @return object XML-RPC response 68 * 69 */ 70 function PNB_handlePingback ($id, $type, $url, $oururl) 71 { 72 global $_CONF, $_TABLES, $PNB_ERROR; 73 74 require_once ('HTTP/Request.php'); 75 76 if (!isset ($_CONF['check_trackback_link'])) { 77 $_CONF['check_trackback_link'] = 2; 78 } 79 80 // handle pingbacks to articles on our own site 81 $skip_speedlimit = false; 82 if ($_SERVER['REMOTE_ADDR'] == $_SERVER['SERVER_ADDR']) { 83 if (!isset ($_CONF['pingback_self'])) { 84 $_CONF['pingback_self'] = 0; // default: skip self-pingbacks 85 } 86 87 if ($_CONF['pingback_self'] == 0) { 88 return new XML_RPC_Response (new XML_RPC_Value ($PNB_ERROR['skipped'])); 89 } else if ($_CONF['pingback_self'] == 2) { 90 $skip_speedlimit = true; 91 } 92 } 93 94 COM_clearSpeedlimit ($_CONF['commentspeedlimit'], 'pingback'); 95 if (!$skip_speedlimit) { 96 $last = COM_checkSpeedlimit ('pingback'); 97 if ($last > 0) { 98 return new XML_RPC_Response (0, 49, 99 sprintf ($PNB_ERROR['speedlimit'], $last, 100 $_CONF['commentspeedlimit'])); 101 } 102 } 103 104 // update speed limit in any case 105 COM_updateSpeedlimit ('pingback'); 106 107 if ($_SERVER['REMOTE_ADDR'] != $_SERVER['SERVER_ADDR']) { 108 if ($_CONF['check_trackback_link'] & 4) { 109 $parts = parse_url ($url); 110 if (empty ($parts['host'])) { 111 TRB_logRejected ('Pingback: No valid URL', $url); 112 return new XML_RPC_Response (0, 33, $PNB_ERROR['uri_invalid']); 113 } else { 114 $ip = gethostbyname ($parts['host']); 115 if ($ip != $_SERVER['REMOTE_ADDR']) { 116 TRB_logRejected ('Pingback: IP address mismatch', $url); 117 return new XML_RPC_Response (0, 49, $PNB_ERROR['spam']); 118 } 119 } 120 } 121 } 122 123 // See if we can read the page linking to us and extract at least 124 // the page's title out of it ... 125 $title = ''; 126 $req = new HTTP_Request ($url); 127 $req->addHeader ('User-Agent', 'GeekLog/' . VERSION); 128 $response = $req->sendRequest (); 129 if (PEAR::isError ($response)) { 130 if ($_CONF['check_trackback_link'] & 3) { 131 // we were supposed to check for backlinks but didn't get the page 132 COM_errorLog ("Pingback verification: " . $response->getMessage() 133 . " when requesting $url"); 134 return new XML_RPC_Response (0, 33, $PNB_ERROR['uri_invalid']); 135 } 136 // else: silently ignore errors - we'll simply do without the title 137 } else { 138 if ($req->getResponseCode () == 200) { 139 $body = $req->getResponseBody (); 140 141 if ($_CONF['check_trackback_link'] & 3) { 142 if (!TRB_containsBacklink ($body, $oururl)) { 143 TRB_logRejected ('Pingback: No link to us', $url); 144 $comment = TRB_formatComment ($url); 145 PLG_spamAction ($comment, $_CONF['spamx']); 146 147 return new XML_RPC_Response (0, 49, $PNB_ERROR['spam']); 148 } 149 } 150 151 preg_match (':<title>(.*)</title>:i', $body, $content); 152 if (empty ($content[1])) { 153 $title = ''; // no title found 154 } else { 155 $title = trim (COM_undoSpecialChars ($content[1])); 156 } 157 158 // we could also run the rest of the other site's page 159 // through the spam filter here ... 160 } else if ($_CONF['check_trackback_link'] & 3) { 161 COM_errorLog ("Pingback verification: Got HTTP response code " 162 . $req->getResponseCode () 163 . " when requesting $url"); 164 return new XML_RPC_Response (0, 33, $PNB_ERROR['uri_invalid']); 165 } 166 // else: silently ignore errors - we'll simply do without the title 167 } 168 169 // check for spam first 170 $saved = TRB_checkForSpam ($url, $title); 171 172 if ($saved == TRB_SAVE_SPAM) { 173 return new XML_RPC_Response (0, 49, $PNB_ERROR['spam']); 174 } 175 176 // save as a trackback comment 177 $saved = TRB_saveTrackbackComment ($id, $type, $url, $title); 178 179 if ($saved == TRB_SAVE_REJECT) { 180 return new XML_RPC_Response (0, 49, $PNB_ERROR['multiple']); 181 } 182 183 if (isset ($_CONF['notification']) && 184 in_array ('pingback', $_CONF['notification'])) { 185 TRB_sendNotificationEmail ($saved, 'pingback'); 186 } 187 188 return new XML_RPC_Response (new XML_RPC_Value ($PNB_ERROR['success'])); 189 } 190 191 /** 192 * Check if the targetURI really points to us 193 * 194 * @param string $url targetURI, a URL on our site 195 * @return bool true = is a URL on our site 196 * 197 */ 198 function PNB_validURL ($url) 199 { 200 global $_CONF; 201 202 $retval = false; 203 204 if (substr ($url, 0, strlen ($_CONF['site_url'])) == $_CONF['site_url']) { 205 $retval = true; 206 } 207 208 return $retval; 209 } 210 211 /** 212 * Try to determine what has been pinged 213 * 214 * Checks if the URL contains 'article.php' for articles. Otherwise tries to 215 * figure out if a plugin's page has been pinged. 216 * 217 * @param string $url targetURI, a URL on our site 218 * @return string 'article' or plugin name or empty string for error 219 * 220 */ 221 function PNB_getType ($url) 222 { 223 global $_CONF, $_TABLES; 224 225 $retval = ''; 226 227 $part = substr ($url, strlen ($_CONF['site_url']) + 1); 228 if (substr ($part, 0, strlen ('article.php')) == 'article.php') { 229 $retval = 'article'; 230 } else { 231 $parts = explode ('/', $part); 232 if (strpos ($parts[0], '?') === false) { 233 $plugin = addslashes ($parts[0]); 234 if (DB_getItem ($_TABLES['plugins'], 'pi_enabled', 235 "pi_name = '$plugin'") == 1) { 236 $retval = $parts[0]; 237 } 238 } 239 } 240 241 return $retval; 242 } 243 244 /** 245 * Extract story ID (sid) from the URL 246 * 247 * Accepts rewritten and old-style URLs. Also checks permissions. 248 * 249 * @param string $url targetURI, a URL on our site 250 * @return string story ID or empty string for error 251 * 252 */ 253 function PNB_getSid ($url) 254 { 255 global $_CONF, $_TABLES; 256 257 $retval = ''; 258 259 $sid = ''; 260 $params = substr ($url, strlen ($_CONF['site_url'] . '/article.php')); 261 if (substr ($params, 0, 1) == '?') { // old-style URL 262 $pos = strpos ($params, 'story='); 263 if ($pos !== false) { 264 $part = substr ($params, $pos + strlen ('story=')); 265 $parts = explode ('&', $part); 266 $sid = $parts[0]; 267 } 268 } else if (substr ($params, 0, 1) == '/') { // rewritten URL 269 $parts = explode ('/', substr ($params, 1)); 270 $sid = $parts[0]; 271 } 272 if (!empty ($sid)) { 273 $parts = explode ('#', $sid); 274 $sid = $parts[0]; 275 } 276 277 // okay, so we have a SID - but are they allowed to access the story? 278 if (!empty ($sid)) { 279 $testsid = addslashes ($sid); 280 $result = DB_query ("SELECT trackbackcode FROM {$_TABLES['stories']} WHERE sid = '$testsid'" . COM_getPermSql ('AND') . COM_getTopicSql ('AND')); 281 if (DB_numRows ($result) == 1) { 282 $A = DB_fetchArray ($result); 283 if ($A['trackbackcode'] == 0) { 284 $retval = $sid; 285 } 286 } 287 } 288 289 return $retval; 290 } 291 292 /** 293 * We've received a pingback - handle it ... 294 * 295 * @param object $params parameters of the pingback XML-RPC call 296 * @return object XML-RPC response 297 * 298 */ 299 function PNB_receivePing ($params) 300 { 301 global $_CONF, $_TABLES, $PNB_ERROR; 302 303 if (!$_CONF['pingback_enabled']) { 304 return new XML_RPC_Response (0, 33, $PNB_ERROR['disabled']); 305 } 306 307 $s = $params->getParam (0); 308 $p1 = $s->scalarval (); // the page linking to us 309 310 if (is_array ($p1)) { 311 // WordPress sends the 2 URIs as an array ... 312 $sourceURI = $p1[0]->scalarval (); 313 $targetURI = $p1[1]->scalarval (); 314 } else { 315 $sourceURI = $p1; 316 317 $s = $params->getParam (1); 318 $targetURI = $s->scalarval (); // the page being linked to (on our site) 319 } 320 321 if (!PNB_validURL ($targetURI)) { 322 return new XML_RPC_Response (0, 33, $PNB_ERROR['uri_invalid']); 323 } 324 325 $type = PNB_getType ($targetURI); 326 if (empty ($type)) { 327 return new XML_RPC_Response (0, 33, $PNB_ERROR['uri_invalid']); 328 } 329 330 if ($type == 'article') { 331 $id = PNB_getSid ($targetURI); 332 } else { 333 $id = PLG_handlePingComment ($type, $targetURI, 'acceptByURI'); 334 } 335 if (empty ($id)) { 336 return new XML_RPC_Response (0, 49, $PNB_ERROR['no_access']); 337 } 338 339 return PNB_handlePingback ($id, $type, $sourceURI, $targetURI); 340 } 341 342 343 // MAIN 344 345 // fire up the XML-RPC server - it does all the work for us 346 $s = new XML_RPC_Server ( array ( 347 'pingback.ping' => array ('function' => 'PNB_receivePing') 348 )); 349 350 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Wed Nov 21 12:27:40 2007 | par Balluche grâce à PHPXref 0.7 |
![]() |