Changeset 3415:5cdbb2593595
- Timestamp:
- 11/23/16 08:21:31 (9 years ago)
- Branch:
- default
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
admin/post.php
r3340 r3415 169 169 { 170 170 try { 171 # --BEHAVIOR-- adminBeforePingTrackback 172 $core->callBehavior('adminBeforePingTrackback',$tb_url,$post_id,$tb_post_title,$tb_excerpt,$tb_post_url); 173 171 174 $TB->ping($tb_url, $post_id, $tb_post_title, $tb_excerpt, $tb_post_url); 172 175 } catch (Exception $e) { -
inc/core/class.dc.trackback.php
r3340 r3415 35 35 } 36 36 37 /// @name Send trackbacks37 /// @name Send 38 38 //@{ 39 39 /** … … 81 81 82 82 $ping_parts = explode('|',$url); 83 84 # Let's walk by the trackback way 85 if (count($ping_parts) < 2) { 83 # Maybe a webmention 84 if (count($ping_parts) == 3) { 85 $payload = http_build_query(array( 86 'source' => $post_url, 87 'target' => $ping_parts[1] 88 )); 89 90 try { 91 $http = self::initHttp($ping_parts[0],$path); 92 $http->setMoreHeader('Content-Type: application/x-www-form-urlencoded'); 93 $http->post($path,$payload,'UTF-8'); 94 95 # Read response status 96 $status = $http->getStatus(); 97 $ping_error = '0'; 98 } 99 catch (Exception $e) { 100 throw new Exception(__('Unable to ping URL')); 101 } 102 103 if (!in_array($status,array('200','201','202'))) { 104 $ping_error = $http->getStatus(); 105 $ping_msg = __('Bad server response code'); 106 } 107 } 108 # No, let's walk by the trackback way 109 elseif (count($ping_parts) < 2) { 86 110 $data = array( 87 111 'title' => $post_title, … … 93 117 94 118 # Ping 95 try 96 { 119 try { 97 120 $http = self::initHttp($url,$path); 98 121 $http->post($path,$data,'UTF-8'); 99 122 $res = $http->getContent(); 100 123 } 101 catch (Exception $e) 102 { 124 catch (Exception $e) { 103 125 throw new Exception(__('Unable to ping URL')); 104 126 } … … 109 131 '</response>|msU'; 110 132 111 if (!preg_match($pattern,$res,$match)) 112 { 133 if (!preg_match($pattern,$res,$match)) { 113 134 throw new Exception(sprintf(__('%s is not a ping URL'),$url)); 114 135 } … … 135 156 if ($ping_error != '0') { 136 157 throw new Exception(sprintf(__('%s, ping error:'),$url).' '.$ping_msg); 137 } else { 158 } 159 else { 138 160 # Notify ping result in database 139 161 $cur = $this->con->openCursor($this->table); … … 147 169 //@} 148 170 149 private function pingAlreadyDone($post_id, $from_url) 150 { 151 $params = array( 152 'post_id' => $post_id, 153 'comment_site' => $from_url, 154 'comment_trackback' => 1, 155 ); 156 157 $rs = $this->core->blog->getComments($params, true); 158 if ($rs && !$rs->isEmpty()) { 159 return ($rs->f(0)); 160 } 161 162 return false; 163 } 164 165 private function addBacklink($post_id, $url, $blog_name, $title, $excerpt, &$comment) 166 { 167 if (empty($blog_name)) { 168 $blog_name = 'Anonymous blog'; 169 } 170 171 $comment = 172 "<!-- TB -->\n". 173 '<p><strong>'.($title ?: $blog_name)."</strong></p>\n". 174 '<p>'.$excerpt.'</p>'; 175 176 $cur = $this->core->con->openCursor($this->core->prefix.'comment'); 177 $cur->comment_author = (string) $blog_name; 178 $cur->comment_site = (string) $url; 179 $cur->comment_content = (string) $comment; 180 $cur->post_id = $post_id; 181 $cur->comment_trackback = 1; 182 $cur->comment_status = $this->core->blog->settings->system->trackbacks_pub ? 1 : -1; 183 $cur->comment_ip = http::realIP(); 184 185 # --BEHAVIOR-- publicBeforeTrackbackCreate 186 $this->core->callBehavior('publicBeforeTrackbackCreate',$cur); 187 if ($cur->post_id) { 188 $comment_id = $this->core->blog->addComment($cur); 189 190 # --BEHAVIOR-- publicAfterTrackbackCreate 191 $this->core->callBehavior('publicAfterTrackbackCreate',$cur,$comment_id); 192 } 193 } 194 195 /// @name Receive trackbacks 171 /// @name Receive 196 172 //@{ 197 173 /** … … 200 176 @param post_id <b>integer</b> Post ID 201 177 */ 202 public function receive ($post_id)178 public function receiveTrackback($post_id) 203 179 { 204 180 header('Content-Type: text/xml; charset=UTF-8'); … … 226 202 $msg = ''; 227 203 228 if ($this->core->blog === null) 229 { 204 if ($this->core->blog === null) { 230 205 $err = true; 231 206 $msg = 'No blog.'; 232 207 } 233 elseif ($url == '') 234 { 208 elseif ($url == '') { 235 209 $err = true; 236 210 $msg = 'URL parameter is required.'; … … 241 215 } 242 216 243 if (!$err) 244 { 217 if (!$err) { 245 218 $post = $this->core->blog->getPosts(array('post_id'=>$post_id,'post_type'=>'')); 246 219 247 if ($post->isEmpty()) 248 { 220 if ($post->isEmpty()) { 249 221 $err = true; 250 222 $msg = 'No such post.'; 251 223 } 252 elseif (!$post->trackbacksActive()) 253 { 224 elseif (!$post->trackbacksActive()) { 254 225 $err = true; 255 226 $msg = 'Trackbacks are not allowed for this post or weblog.'; … … 257 228 258 229 $url = trim(html::clean($url)); 259 if ($this->pingAlreadyDone($post->post_id, 230 if ($this->pingAlreadyDone($post->post_id,$url)) { 260 231 $err = true; 261 232 $msg = 'The trackback has already been registered'; … … 263 234 } 264 235 265 if (!$err) 266 { 236 if (!$err) { 267 237 $charset = self::getCharsetFromRequest(); 268 238 … … 293 263 $blog_name = text::cutString($blog_name,60); 294 264 295 try 296 { 297 $this->addBacklink($post_id, $url, $blog_name, $title, $excerpt, $comment); 298 } 299 catch (Exception $e) 300 { 265 try { 266 $this->addBacklink($post_id,$url,$blog_name,$title,$excerpt,$comment); 267 } 268 catch (Exception $e) { 301 269 $err = 1; 302 270 $msg = 'Something went wrong : '.$e->getMessage(); … … 327 295 echo $resp."</response>"; 328 296 } 329 //@} 330 331 /// @name Receive pingbacks 332 //@{ 297 333 298 /** 334 299 Receives a pingback and insert it as a comment of given post. … … 337 302 @param to_url <b>string</b> Target URL 338 303 */ 339 public function receive_pb($from_url, $to_url) 304 public function receivePingback($from_url,$to_url) 305 { 306 try { 307 $posts = $this->getTargetPost($to_url); 308 309 if ($this->pingAlreadyDone($posts->post_id,$from_url)) { 310 throw new Exception(__('Don\'t repeat yourself, please.'), 48); 311 } 312 313 $remote_content = $this->getRemoteContent($from_url); 314 315 # We want a title... 316 if (!preg_match('!<title>([^<].*?)</title>!mis',$remote_content,$m)) { 317 throw new Exception(__('Where\'s your title?'), 0); 318 } 319 $title = trim(html::clean($m[1])); 320 $title = html::decodeEntities($title); 321 $title = html::escapeHTML($title); 322 $title = text::cutString($title,60); 323 324 preg_match('!<body[^>]*?>(.*)?</body>!msi',$remote_content,$m); 325 $source = $m[1]; 326 $source = preg_replace('![\r\n\s]+!ms',' ',$source); 327 $source = preg_replace( "/<\/*(h\d|p|th|td|li|dt|dd|pre|caption|input|textarea|button)[^>]*>/","\n\n",$source ); 328 $source = strip_tags($source,'<a>'); 329 $source = explode("\n\n",$source); 330 331 $excerpt = ''; 332 foreach ($source as $line) { 333 if (strpos($line, $to_url) !== false) { 334 if (preg_match("!<a[^>]+?".$to_url."[^>]*>([^>]+?)</a>!",$line,$m)) { 335 $excerpt = strip_tags($line); 336 break; 337 } 338 } 339 } 340 if ($excerpt) { 341 $excerpt = '(…) '.text::cutString(html::escapeHTML($excerpt),200).' (…)'; 342 } 343 else { 344 $excerpt = '(…)'; 345 } 346 347 $this->addBacklink($posts->post_id,$from_url,'',$title,$excerpt,$comment); 348 } 349 catch (Exception $e) { 350 throw new Exception(__('Sorry, an internal problem has occured.'),0); 351 } 352 353 return __('Thanks, mate. It was a pleasure.'); 354 } 355 356 /** 357 Receives a webmention and insert it as a comment of given post. 358 359 NB: plugin Fair Trackback check source content to find url. 360 361 @return <b>null</b> Null on success, else throw an exception 362 */ 363 public function receiveWebmention() 364 { 365 $err = $post_id = false; 366 header('Content-Type: text/html; charset=UTF-8'); 367 368 try { 369 # Check if post and target are valid URL 370 if (empty($_POST['source']) || empty($_POST['target'])) { 371 throw new Exception('Source or target is not valid',0); 372 } 373 374 $from_url = urldecode($_POST['source']); 375 $to_url = urldecode($_POST['target']); 376 377 self::checkURLs($from_url,$to_url); 378 379 # Try to find post 380 $posts = $this->getTargetPost($to_url); 381 $post_id = $posts->post_id; 382 383 # Check if it's an updated mention 384 if ($this->pingAlreadyDone($post_id,$from_url)) { 385 $this->delBacklink($post_id,$from_url); 386 } 387 388 # Create a comment for received webmention 389 // maybe better to try to fetch a title from the source ?... 390 $title = __('A website mention this entry.'); 391 $comment = ''; 392 $excerpt = sprintf('<a href="%s" rel="nofollow">%s</a>',$from_url,$from_url); 393 $this->addBacklink($post_id,$from_url,'',$title,$excerpt,$comment); 394 395 # All done, thanks 396 $code = $this->core->blog->settings->system->trackbacks_pub ? 200 : 202; 397 http::head($code); 398 return; 399 } 400 catch (Exception $e) { 401 $err = $e->getMessage(); 402 } 403 404 http::head(400); 405 echo $err ?: 'Something went wrong.'; 406 return; 407 } 408 409 /** 410 Check if a post previously received a ping a from an URL. 411 412 @param post_id <b>integer</b> Post ID 413 @param from_url <b>string</b> Source URL 414 @return <b>boolean</b> 415 */ 416 private function pingAlreadyDone($post_id,$from_url) 417 { 418 $params = array( 419 'post_id' => $post_id, 420 'comment_site' => $from_url, 421 'comment_trackback' => 1, 422 ); 423 424 $rs = $this->core->blog->getComments($params,true); 425 if ($rs && !$rs->isEmpty()) { 426 return ($rs->f(0)); 427 } 428 429 return false; 430 } 431 432 /** 433 Create a comment marked as trackback for a given post. 434 435 @param post_id <b>integer</b> Post ID 436 @param url <b>string</b> Discovered URL 437 @param blog name <b>string</b> Source blog name 438 @param title <b>string</b> Comment title 439 @param excerpt <b>string</b> Source excerpt 440 @param comment <b>string</b> Comment content 441 */ 442 private function addBacklink($post_id,$url,$blog_name,$title,$excerpt,&$comment) 443 { 444 if (empty($blog_name)) { 445 $blog_name = 'Anonymous blog'; 446 } 447 448 $comment = 449 "<!-- TB -->\n". 450 '<p><strong>'.($title ?: $blog_name)."</strong></p>\n". 451 '<p>'.$excerpt.'</p>'; 452 453 $cur = $this->core->con->openCursor($this->core->prefix.'comment'); 454 $cur->comment_author = (string) $blog_name; 455 $cur->comment_site = (string) $url; 456 $cur->comment_content = (string) $comment; 457 $cur->post_id = $post_id; 458 $cur->comment_trackback = 1; 459 $cur->comment_status = $this->core->blog->settings->system->trackbacks_pub ? 1 : -1; 460 $cur->comment_ip = http::realIP(); 461 462 # --BEHAVIOR-- publicBeforeTrackbackCreate 463 $this->core->callBehavior('publicBeforeTrackbackCreate',$cur); 464 if ($cur->post_id) { 465 $comment_id = $this->core->blog->addComment($cur); 466 467 # --BEHAVIOR-- publicAfterTrackbackCreate 468 $this->core->callBehavior('publicAfterTrackbackCreate',$cur,$comment_id); 469 } 470 } 471 472 /** 473 Delete previously received comment made from an URL for a given post. 474 475 @param post_id <b>integer</b> Post ID 476 @param url <b>string</b> Source URL 477 */ 478 private function delBacklink($post_id,$url) 479 { 480 $this->con->execute( 481 'DELETE FROM '.$this->core->prefix.'comment '. 482 'WHERE post_id = '.((integer) $post_id).' '. 483 "AND comment_site = '".$this->core->con->escape((string) $url)."' ". 484 'AND comment_trackback = 1 ' 485 ); 486 } 487 488 /** 489 Find Charset from HTTP headers. 490 491 @param header <b>string</b> Source header 492 @return <b>string</b> 493 */ 494 private static function getCharsetFromRequest($header = '') 495 { 496 if (!$header && isset($_SERVER['CONTENT_TYPE'])) { 497 $header = $_SERVER['CONTENT_TYPE']; 498 } 499 500 if ($header) { 501 if (preg_match('|charset=([a-zA-Z0-9-]+)|',$header,$m)) { 502 return $m[1]; 503 } 504 } 505 506 return null; 507 } 508 509 /** 510 Detect encoding. 511 512 @param content <b>string</b> Source URL 513 @return <b>string</b> 514 */ 515 private static function detectCharset($content) 516 { 517 return mb_detect_encoding($content, 518 'UTF-8,ISO-8859-1,ISO-8859-2,ISO-8859-3,'. 519 'ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,'. 520 'ISO-8859-9,ISO-8859-10,ISO-8859-13,ISO-8859-14,ISO-8859-15'); 521 } 522 523 /** 524 Retreive local post from a given IRL 525 526 @param to_url <b>string</b> Target URL 527 @return <b>string</b> 528 */ 529 private function getTargetPost($to_url) 340 530 { 341 531 $reg = '!^'.preg_quote($this->core->blog->url).'(.*)!'; … … 343 533 344 534 # Are you dumb? 345 if (!preg_match($reg, $to_url,$m)) {346 throw new Exception(__('Any chance you ping one of my contents? No? Really?'), 535 if (!preg_match($reg,$to_url,$m)) { 536 throw new Exception(__('Any chance you ping one of my contents? No? Really?'),0); 347 537 } 348 538 … … 352 542 $post_types = $this->core->getPostTypes(); 353 543 foreach ($post_types as $k => $v) { 354 $reg = '!^'.preg_quote(str_replace('%s', '',$v['public_url'])).'(.*)!';355 if (preg_match($reg, $url_part,$n)) {544 $reg = '!^'.preg_quote(str_replace('%s','',$v['public_url'])).'(.*)!'; 545 if (preg_match($reg,$url_part,$n)) { 356 546 $p_type = $k; 357 547 $post_url = $n[1]; … … 361 551 362 552 if (empty($p_type)) { 363 throw new Exception(__('Sorry but you can not ping this type of content.'), 553 throw new Exception(__('Sorry but you can not ping this type of content.'),33); 364 554 } 365 555 … … 373 563 # Missed! 374 564 if ($posts->isEmpty()) { 375 throw new Exception(__('Oops. Kinda "not found" stuff. Please check the target URL twice.'), 565 throw new Exception(__('Oops. Kinda "not found" stuff. Please check the target URL twice.'),33); 376 566 } 377 567 378 568 # Nice try. But, sorry, no. 379 569 if (!$posts->trackbacksActive()) { 380 throw new Exception(__('Sorry, dude. This entry does not accept pingback at the moment.'), 33); 381 } 382 383 if ($this->pingAlreadyDone($posts->post_id, $from_url)) { 384 throw new Exception(__('Don\'t repeat yourself, please.'), 48); 385 } 386 387 # OK. We've found our champion. Time to check the remote part. 388 try { 389 $http = self::initHttp($from_url, $from_path); 390 391 # First round : just to be sure the ping comes from an acceptable resource type. 392 $http->setHeadersOnly(true); 393 $http->get($from_path); 394 $c_type = explode(';', $http->getHeader('content-type')); 395 396 # Bad luck. Bye, bye... 397 if (!in_array($c_type[0],array('text/html', 'application/xhtml+xml'))) { 398 throw new Exception(__('Your source URL does not look like a supported content type. Sorry. Bye, bye!'), 0); 399 } 400 401 # Second round : let's go fetch and parse the remote content 402 $http->setHeadersOnly(false); 403 $http->get($from_path); 404 $remote_content = $http->getContent(); 405 406 $charset = self::getCharsetFromRequest($http->getHeader('content-type')); 407 408 if (!$charset) { 409 $charset = self::detectCharset($remote_content); 410 } 411 412 if (strtolower($charset) != 'utf-8') { 413 $remote_content = iconv($charset,'UTF-8',$remote_content); 414 } 415 416 # We want a title... 417 if (!preg_match('!<title>([^<].*?)</title>!mis', $remote_content, $m)) { 418 throw new Exception(__('Where\'s your title?'), 0); 419 } 420 $title = trim(html::clean($m[1])); 421 $title = html::decodeEntities($title); 422 $title = html::escapeHTML($title); 423 $title = text::cutString($title,60); 424 425 preg_match('!<body[^>]*?>(.*)?</body>!msi', $remote_content, $m); 426 $source = $m[1]; 427 $source = preg_replace('![\r\n\s]+!ms',' ',$source); 428 $source = preg_replace( "/<\/*(h\d|p|th|td|li|dt|dd|pre|caption|input|textarea|button)[^>]*>/", "\n\n", $source ); 429 $source = strip_tags($source, '<a>'); 430 $source = explode("\n\n",$source); 431 432 $excerpt = ''; 433 foreach ($source as $line) { 434 if (strpos($line, $to_url) !== false) { 435 if (preg_match("!<a[^>]+?".$to_url."[^>]*>([^>]+?)</a>!", $line, $m)) { 436 $excerpt = strip_tags($line); 437 break; 438 } 439 } 440 } 441 if ($excerpt) { 442 $excerpt = '(…) '.text::cutString(html::escapeHTML($excerpt),200).' (…)'; 443 } 444 else { 445 $excerpt = '(…)'; 446 } 447 448 $this->addBacklink($posts->post_id, $from_url, '', $title, $excerpt, $comment); 449 } 450 catch (Exception $e) { 451 throw new Exception(__('Sorry, an internal problem has occured.'), 0); 452 } 453 454 return __('Thanks, mate. It was a pleasure.'); 570 throw new Exception(__('Sorry, dude. This entry does not accept pingback at the moment.'),33); 571 } 572 573 return $posts; 574 } 575 576 /** 577 Returns content of a distant page 578 579 @param from_url <b>string</b> Target URL 580 @return <b>string</b> 581 */ 582 private function getRemoteContent($from_url) 583 { 584 $http = self::initHttp($from_url,$from_path); 585 586 # First round : just to be sure the ping comes from an acceptable resource type. 587 $http->setHeadersOnly(true); 588 $http->get($from_path); 589 $c_type = explode(';',$http->getHeader('content-type')); 590 591 # Bad luck. Bye, bye... 592 if (!in_array($c_type[0],array('text/html','application/xhtml+xml'))) { 593 throw new Exception(__('Your source URL does not look like a supported content type. Sorry. Bye, bye!'),0); 594 } 595 596 # Second round : let's go fetch and parse the remote content 597 $http->setHeadersOnly(false); 598 $http->get($from_path); 599 $remote_content = $http->getContent(); 600 601 # Convert content charset 602 $charset = self::getCharsetFromRequest($http->getHeader('content-type')); 603 if (!$charset) { 604 $charset = self::detectCharset($remote_content); 605 } 606 if (strtolower($charset) != 'utf-8') { 607 $remote_content = iconv($charset,'UTF-8',$remote_content); 608 } 609 610 return $remote_content; 455 611 } 456 612 //@} 457 613 458 private static function initHttp($url,&$path) 459 { 460 $client = netHttp::initClient($url,$path); 461 $client->setTimeout(5); 462 $client->setUserAgent('Dotclear - http://www.dotclear.org/'); 463 $client->useGzip(false); 464 $client->setPersistReferers(false); 465 466 return $client; 467 } 468 469 private static function getCharsetFromRequest($header = '') 470 { 471 if (!$header && isset($_SERVER['CONTENT_TYPE'])) { 472 $header = $_SERVER['CONTENT_TYPE']; 473 } 474 475 if ($header) { 476 if (preg_match('|charset=([a-zA-Z0-9-]+)|',$header,$m)) { 477 return $m[1]; 478 } 479 } 480 481 return null; 482 } 483 484 private static function detectCharset($content) 485 { 486 return mb_detect_encoding($content, 487 'UTF-8,ISO-8859-1,ISO-8859-2,ISO-8859-3,'. 488 'ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,'. 489 'ISO-8859-9,ISO-8859-10,ISO-8859-13,ISO-8859-14,ISO-8859-15'); 490 } 491 492 /// @name Trackbacks auto discovery 614 /// @name Discover 493 615 //@{ 494 616 /** … … 512 634 return $res; 513 635 } 514 //@} 515 636 637 /** 638 Find links into a text. 639 640 @param text <b>string</b> Text to scan 641 @return <b>array</b> 642 */ 516 643 private function getTextLinks($text) 517 644 { … … 519 646 520 647 # href attribute on "a" tags 521 if (preg_match_all('/<a ([^>]+)>/ms', $text, $match, PREG_SET_ORDER)) 522 { 648 if (preg_match_all('/<a ([^>]+)>/ms',$text,$match,PREG_SET_ORDER)) { 523 649 for ($i = 0; $i<count($match); $i++) 524 650 { 525 if (preg_match('/href="((https?:\/)?\/[^"]+)"/ms', $match[$i][1],$matches)) {651 if (preg_match('/href="((https?:\/)?\/[^"]+)"/ms',$match[$i][1],$matches)) { 526 652 $res[$matches[1]] = 1; 527 653 } … … 531 657 532 658 # cite attributes on "blockquote" and "q" tags 533 if (preg_match_all('/<(blockquote|q) ([^>]+)>/ms', $text, $match, PREG_SET_ORDER)) 534 { 659 if (preg_match_all('/<(blockquote|q) ([^>]+)>/ms',$text,$match,PREG_SET_ORDER)) { 535 660 for ($i = 0; $i<count($match); $i++) 536 661 { 537 if (preg_match('/cite="((https?:\/)?\/[^"]+)"/ms', $match[$i][2],$matches)) {662 if (preg_match('/cite="((https?:\/)?\/[^"]+)"/ms',$match[$i][2],$matches)) { 538 663 $res[$matches[1]] = 1; 539 664 } … … 544 669 } 545 670 671 /** 672 Check remote header/content to find api trace. 673 674 @param url <b>string</b> URL to scan 675 @return <b>string</b> 676 */ 546 677 private function getPingURL($url) 547 678 { … … 550 681 } 551 682 552 try 553 { 683 try { 554 684 $http = self::initHttp($url,$path); 555 685 $http->get($path); 556 686 $page_content = $http->getContent(); 557 687 $pb_url = $http->getHeader('x-pingback'); 558 }559 catch (Exception $e)560 {688 $wm_url = $http->getHeader('link'); 689 } 690 catch (Exception $e) { 561 691 return false; 562 692 } … … 587 717 588 718 $url_path = parse_url($url, PHP_URL_PATH); 589 $sanitized_url = str_replace($url_path, html::sanitizeURL($url_path), 719 $sanitized_url = str_replace($url_path, html::sanitizeURL($url_path),$url); 590 720 591 721 for ($i=0; $i<count($rdf_all); $i++) … … 600 730 } 601 731 732 # Nothing, let's try webmention. Only support x/html content 733 if ($wm_url) { 734 $type = explode(';',$http->getHeader('content-type')); 735 if (!in_array($type[0],array('text/html','application/xhtml+xml'))) { 736 $wm_url = false; 737 } 738 } 739 740 # Check HTTP headers for a Link: <ENDPOINT_URL>; rel="webmention" 741 $wm_api = false; 742 if ($wm_url) { 743 if(preg_match('~<((?:https?://)?[^>]+)>; rel="?(?:https?://webmention.org/?|webmention)"?~',$wm_url,$match)) { 744 if (filter_var($match[1],FILTER_VALIDATE_URL) && preg_match('!^https?:!',$match[1])) { 745 $wm_api = $match[1]; 746 } 747 } 748 } 749 750 # Else check content for <link href="ENDPOINT_URL" rel="webmention" /> 751 if ($wm_url && !$wm_api) { 752 $content = preg_replace('/<!--(.*)-->/Us','',$page_content); 753 if (preg_match('/<(?:link|a)[ ]+href="([^"]*)"[ ]+rel="[^" ]* ?webmention ?[^" ]*"[ ]*\/?>/i',$content,$match) 754 || preg_match('/<(?:link|a)[ ]+rel="[^" ]* ?webmention ?[^" ]*"[ ]+href="([^"]*)"[ ]*\/?>/i',$content,$match)) { 755 $wm_api = $match[1]; 756 } 757 } 758 759 # We have a winner, let's add some tricks to make diference 760 if ($wm_api) { 761 return $wm_api.'|'.$url.'|webmention'; 762 } 763 602 764 return null; 603 765 } 766 //@} 767 768 /** 769 HTTP helper. 770 771 @param url <b>string</b> URL 772 @param path <b>string</b> Path 773 @return <b>object</b> 774 */ 775 private static function initHttp($url,&$path) 776 { 777 $client = netHttp::initClient($url,$path); 778 $client->setTimeout(5); 779 $client->setUserAgent('Dotclear - http://www.dotclear.org/'); 780 $client->useGzip(false); 781 $client->setPersistReferers(false); 782 783 return $client; 784 } 785 786 /** 787 URL helper. 788 789 @param from_url <b>string</b> URL a 790 @param to_url <b>string</b> URL b 791 */ 792 public static function checkURLs($from_url,$to_url) 793 { 794 if (!(filter_var($from_url, FILTER_VALIDATE_URL) && preg_match('!^https?://!',$from_url))) { 795 throw new Exception(__('No valid source URL provided? Try again!'), 0); 796 } 797 798 if (!(filter_var($to_url, FILTER_VALIDATE_URL) && preg_match('!^https?://!',$to_url))) { 799 throw new Exception(__('No valid target URL provided? Try again!'), 0); 800 } 801 802 if (html::sanitizeURL(urldecode($from_url)) == html::sanitizeURL(urldecode($to_url))) { 803 throw new Exception(__('LOL!'), 0); 804 } 805 } 604 806 } -
inc/core/class.dc.xmlrpc.php
r3170 r3415 1636 1636 public function pingback_ping($from_url, $to_url) 1637 1637 { 1638 # Come on, buddy! Don't make me waste time with this kind of silliness... 1639 if (!(filter_var($from_url, FILTER_VALIDATE_URL) && preg_match('!^https?://!',$from_url))) { 1640 throw new Exception(__('No valid source URL provided? Try again!'), 0); 1641 } 1642 1643 if (!(filter_var($to_url, FILTER_VALIDATE_URL) && preg_match('!^https?://!',$to_url))) { 1644 throw new Exception(__('No valid target URL provided? Try again!'), 0); 1645 } 1646 1647 if (html::sanitizeURL(urldecode($from_url)) == html::sanitizeURL(urldecode($to_url))) { 1648 throw new Exception(__('LOL!'), 0); 1649 } 1638 dcTrackback::checkURLs($from_url,$to_url); 1639 1640 $args = array('type'=>'pingback','from_url'=>$from_url,'to_url'=>$to_url); 1650 1641 1651 1642 # Time to get things done... 1652 1643 $this->setBlog(true); 1644 1645 # --BEHAVIOR-- publicBeforeReceiveTrackback 1646 $this->core->callBehavior('publicBeforeReceiveTrackback',$this->core,$args); 1647 1653 1648 $tb = new dcTrackback($this->core); 1654 return $tb->receive _pb($from_url,$to_url);1649 return $tb->receivePingback($from_url,$to_url); 1655 1650 } 1656 1651 } -
inc/prepend.php
r3403 r3415 286 286 $core->url->register('feed','feed','^feed/(.+)$',array('dcUrlHandlers','feed')); 287 287 $core->url->register('trackback','trackback','^trackback/(.+)$',array('dcUrlHandlers','trackback')); 288 $core->url->register('webmention','webmention','^webmention(/.+)?$',array('dcUrlHandlers','webmention')); 288 289 $core->url->register('rsd','rsd','^rsd$',array('dcUrlHandlers','rsd')); 289 290 $core->url->register('xmlrpc','xmlrpc','^xmlrpc/(.+)$',array('dcUrlHandlers','xmlrpc')); -
inc/public/lib.urlhandlers.php
r3030 r3415 520 520 if ($_ctx->posts->trackbacksActive()) { 521 521 header('X-Pingback: '.$core->blog->url.$core->url->getURLFor("xmlrpc",$core->blog->id)); 522 header('Link: <'.$core->blog->url.$core->url->getURLFor('webmention').'>; rel="webmention"'); 522 523 } 523 524 self::serveDocument('post.html'); … … 681 682 self::p404(); 682 683 } else { 684 $core =& $GLOBALS['core']; 685 if (!is_array($args)) $args = array(); 686 $args['type'] = 'trackback'; 687 688 # --BEHAVIOR-- publicBeforeReceiveTrackback 689 $core->callBehavior('publicBeforeReceiveTrackback',$core,$args); 690 683 691 $tb = new dcTrackback($GLOBALS['core']); 684 $tb->receive($args); 685 } 692 $tb->receiveTrackback($args); 693 } 694 } 695 696 public static function webmention($args) 697 { 698 $core =& $GLOBALS['core']; 699 if (!is_array($args)) $args = array(); 700 $args['type'] = 'webmention'; 701 702 # --BEHAVIOR-- publicBeforeReceiveTrackback 703 $core->callBehavior('publicBeforeReceiveTrackback',$core,$args); 704 705 $tb = new dcTrackback($core); 706 $tb->receiveWebmention(); 686 707 } 687 708
Note: See TracChangeset
for help on using the changeset viewer.