Dotclear


Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • inc/core/class.dc.trackback.php

    r1179 r1674  
    8080          } 
    8181           
    82           $data = array( 
    83                'title' => $post_title, 
    84                'excerpt' => $post_excerpt, 
    85                'url' => $post_url, 
    86                'blog_name' => trim(html::escapeHTML(html::clean($this->core->blog->name))) 
    87                //,'__debug' => false 
    88           ); 
    89            
    90           # Ping 
    91           try 
    92           { 
    93                $http = self::initHttp($url,$path); 
    94                $http->post($path,$data,'UTF-8'); 
    95                $res = $http->getContent(); 
    96           } 
    97           catch (Exception $e) 
    98           { 
    99                throw new Exception(__('Unable to ping URL')); 
    100           } 
    101            
    102           $pattern = 
    103           '|<response>.*<error>(.*)</error>(.*)'. 
    104           '(<message>(.*)</message>(.*))?'. 
    105           '</response>|msU'; 
    106            
    107           if (!preg_match($pattern,$res,$match)) 
    108           { 
    109                throw new Exception(sprintf(__('%s is not a ping URL'),$url)); 
    110           } 
    111            
    112           $ping_error = trim($match[1]); 
    113           $ping_msg = (!empty($match[4])) ? $match[4] : ''; 
     82          $ping_parts = explode('|',$url); 
     83           
     84          # Let's walk by the trackback way 
     85          if (count($ping_parts) < 2) { 
     86               $data = array( 
     87                    'title' => $post_title, 
     88                    'excerpt' => $post_excerpt, 
     89                    'url' => $post_url, 
     90                    'blog_name' => trim(html::escapeHTML(html::clean($this->core->blog->name))) 
     91                    //,'__debug' => false 
     92               ); 
     93                
     94               # Ping 
     95               try 
     96               { 
     97                    $http = self::initHttp($url,$path); 
     98                    $http->post($path,$data,'UTF-8'); 
     99                    $res = $http->getContent(); 
     100               } 
     101               catch (Exception $e) 
     102               { 
     103                    throw new Exception(__('Unable to ping URL')); 
     104               } 
     105                
     106               $pattern = 
     107               '|<response>.*<error>(.*)</error>(.*)'. 
     108               '(<message>(.*)</message>(.*))?'. 
     109               '</response>|msU'; 
     110                
     111               if (!preg_match($pattern,$res,$match)) 
     112               { 
     113                    throw new Exception(sprintf(__('%s is not a ping URL'),$url)); 
     114               } 
     115                
     116               $ping_error = trim($match[1]); 
     117               $ping_msg = (!empty($match[4])) ? $match[4] : ''; 
     118          } 
     119          # Damnit ! Let's play pingback 
     120          else { 
     121               try { 
     122                    $xmlrpc = new xmlrpcClient($ping_parts[0]); 
     123                    $res = $xmlrpc->query('pingback.ping', $post_url, $ping_parts[1]); 
     124                    $ping_error = '0'; 
     125               } 
     126               catch (xmlrpcException $e) { 
     127                    $ping_error = $e->getCode(); 
     128                    $ping_msg = $e->getMessage();  
     129               } 
     130               catch (Exception $e) { 
     131                    throw new Exception(__('Unable to ping URL')); 
     132               } 
     133          } 
    114134           
    115135          if ($ping_error != '0') { 
     
    289309     } 
    290310     //@} 
     311 
     312     /// @name Receive pingbacks 
     313     //@{ 
     314     /** 
     315     Receives a pingback and insert it as a comment of given post. 
     316      
     317     @param    from_url       <b>string</b>       Source URL 
     318     @param    to_url              <b>string</b>       Target URL 
     319     */ 
     320     public function receive_pb($from_url, $to_url) 
     321     { 
     322          $reg = '!^'.preg_quote($this->core->blog->url).'(.*)!'; 
     323          $type = $args = $next = ''; 
     324           
     325          # Are you dumb? 
     326          if (!preg_match($reg, $to_url, $m)) { 
     327               throw new Exception(__('Any chance you ping one of my contents? No? Really?'), 0); 
     328          } 
     329           
     330          # Does the targeted URL look like a registered post type?  
     331          $url_part = $m[1]; 
     332          $p_type = ''; 
     333          $post_types = $this->core->getPostTypes(); 
     334          foreach ($post_types as $k => $v) { 
     335               $reg = '!^'.preg_quote(str_replace('%s', '', $v['public_url'])).'(.*)!'; 
     336               if (preg_match($reg, $url_part, $n)) { 
     337                    $p_type = $k; 
     338                    $post_url = $n[1]; 
     339                    break; 
     340               } 
     341          } 
     342           
     343          if (empty($p_type)) { 
     344               throw new Exception(__('Sorry but you can not ping this type of content.'), 33); 
     345          } 
     346 
     347          # Time to see if we've got a winner... 
     348          $params = array( 
     349               'post_type' => $p_type, 
     350               'post_url' => $post_url, 
     351          ); 
     352          $posts = $this->core->blog->getPosts($params); 
     353           
     354          # Missed!  
     355          if ($posts->isEmpty()) { 
     356               throw new Exception(__('Oops. Kinda "not found" stuff. Please check the target URL twice.'), 33); 
     357          } 
     358           
     359          # Nice try. But, sorry, no. 
     360          if (!$posts->trackbacksActive()) { 
     361               throw new Exception(__('Sorry, dude. This entry does not accept pingback at the moment.'), 33); 
     362          } 
     363 
     364          # OK. We've found our champion. Time to check the remote part. 
     365          try { 
     366               $http = self::initHttp($from_url, $from_path); 
     367                
     368               # First round : just to be sure the ping comes from an acceptable resource type. 
     369               $http->setHeadersOnly(true); 
     370               $http->get($from_path); 
     371               $c_type = explode(';', $http->getHeader('content-type')); 
     372 
     373               # Bad luck. Bye, bye... 
     374               if (!in_array($c_type[0],array('text/html', 'application/xhtml+xml'))) { 
     375                    throw new Exception(__('Your source URL does not look like a supported content type. Sorry. Bye, bye!'), 0); 
     376               } 
     377                
     378               # Second round : let's go fetch and parse the remote content 
     379               $http->setHeadersOnly(false); 
     380               $http->get($from_path); 
     381               $remote_content = $http->getContent(); 
     382 
     383               $charset = mb_detect_encoding($remote_content, 
     384                    'UTF-8,ISO-8859-1,ISO-8859-2,ISO-8859-3,'. 
     385                    'ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,'. 
     386                    'ISO-8859-9,ISO-8859-10,ISO-8859-13,ISO-8859-14,ISO-8859-15'); 
     387 
     388               if (strtolower($charset) != 'utf-8') { 
     389                    $remote_content = iconv($charset,'UTF-8',$remote_content); 
     390               } 
     391                
     392               # We want a title... 
     393               if (!preg_match('!<title>([^<].*?)</title>!mis', $remote_content, $m)) { 
     394                    throw new Exception(__('Where\'s your title?'), 0); 
     395               } 
     396               $title = trim(html::clean($m[1])); 
     397               $title = html::decodeEntities($title); 
     398               $title = html::escapeHTML($title); 
     399               $title = text::cutString($title,60); 
     400                
     401               preg_match('!<body[^>]*?>(.*)?</body>!msi', $remote_content, $m); 
     402               $source = $m[1]; 
     403               $source = preg_replace('![\r\n\s]+!ms',' ',$source); 
     404               $source = preg_replace( "/<\/*(h\d|p|th|td|li|dt|dd|pre|caption|input|textarea|button)[^>]*>/", "\n\n", $source ); 
     405               $source = strip_tags($source, '<a>'); 
     406               $source = explode("\n\n",$source); 
     407                
     408               $excerpt = ''; 
     409               foreach ($source as $line) { 
     410                    if (strpos($line, $to_url) !== false) { 
     411                         if (preg_match("!<a[^>]+?".$to_url."[^>]*>([^>]+?)</a>!", $line, $m)) { 
     412                              $excerpt = strip_tags($line); 
     413                              break; 
     414                         } 
     415                    } 
     416               } 
     417               if ($excerpt) { 
     418                    $excerpt = '(&#8230;) '.text::cutString(html::escapeHTML($excerpt),255).' (&#8230;)'; 
     419               } 
     420               else { 
     421                    $excerpt = '(??)'; 
     422               } 
     423 
     424               $comment = 
     425               "<!-- TB -->\n". 
     426               '<p><strong>'.$title."</strong></p>\n". 
     427               '<p>'.$excerpt.'</p>'; 
     428                
     429               $cur = $this->core->con->openCursor($this->core->prefix.'comment'); 
     430               $cur->comment_author = 'Anonymous blog'; 
     431               $cur->comment_site = (string) $from_url; 
     432               $cur->comment_content = (string) $comment; 
     433               $cur->post_id = $posts->post_id; 
     434               $cur->comment_trackback = 1; 
     435               $cur->comment_status = $this->core->blog->settings->system->trackbacks_pub ? 1 : -1; 
     436               $cur->comment_ip = http::realIP(); 
     437                
     438               # --BEHAVIOR-- publicBeforeTrackbackCreate 
     439               $this->core->callBehavior('publicBeforeTrackbackCreate',$cur); 
     440               if ($cur->post_id) { 
     441                    $comment_id = $this->core->blog->addComment($cur); 
     442                     
     443                    # --BEHAVIOR-- publicAfterTrackbackCreate 
     444                    $this->core->callBehavior('publicAfterTrackbackCreate',$cur,$comment_id); 
     445               } 
     446          } 
     447          catch (Exception $e) { 
     448               throw new Exception(__('Sorry, an internal problem has occured.'), 0); 
     449          } 
     450           
     451          return __('Thanks, mate. It was a pleasure.'); 
     452     } 
     453     //@} 
    291454      
    292455     private static function initHttp($url,&$path) 
     
    346509               for ($i = 0; $i<count($match); $i++) 
    347510               { 
    348                     if (preg_match('/href="(http:\/\/[^"]+)"/ms', $match[$i][1], $matches)) { 
     511                    if (preg_match('/href="((https?:\/)?\/[^"]+)"/ms', $match[$i][1], $matches)) { 
    349512                         $res[$matches[1]] = 1; 
    350513                    } 
     
    358521               for ($i = 0; $i<count($match); $i++) 
    359522               { 
    360                     if (preg_match('/cite="(http:\/\/[^"]+)"/ms', $match[$i][2], $matches)) { 
     523                    if (preg_match('/cite="((https?:\/)?\/[^"]+)"/ms', $match[$i][2], $matches)) { 
    361524                         $res[$matches[1]] = 1; 
    362525                    } 
     
    369532     private function getPingURL($url) 
    370533     { 
     534          if (strpos($url,'/') === 0) { 
     535               $url = http::getHost().$url; 
     536          } 
     537           
    371538          try 
    372539          { 
     
    374541               $http->get($path); 
    375542               $page_content = $http->getContent(); 
     543               $pb_url = $http->getHeader('x-pingback'); 
    376544          } 
    377545          catch (Exception $e) 
     
    380548          } 
    381549           
     550          # If we've got a X-Pingback header and it's a valid URL, it will be enough 
     551          if ($pb_url && filter_var($pb_url,FILTER_VALIDATE_URL) && preg_match('!^https?:!',$pb_url)) { 
     552               return $pb_url.'|'.$url; 
     553          } 
     554           
     555          # No X-Pingback header. A link rel=pingback, maybe ? 
     556          $pattern_pingback = '!<link rel="pingback" href="(.*?)"( /)?>!msi'; 
     557           
     558          if (preg_match($pattern_pingback,$page_content,$m)) { 
     559               $pb_url = $m[1]; 
     560               if (filter_var($pb_url,FILTER_VALIDATE_URL) && preg_match('!^https?:!',$pb_url)) { 
     561                    return $pb_url.'|'.$url; 
     562               } 
     563          } 
     564 
     565          # No pingback ? OK, let's check for a trackback data chunk... 
    382566          $pattern_rdf = 
    383567          '/<rdf:RDF.*?>.*?'. 
     
    388572          preg_match_all($pattern_rdf,$page_content,$rdf_all,PREG_SET_ORDER); 
    389573           
     574          $url_path = parse_url($url, PHP_URL_PATH); 
     575          $sanitized_url = str_replace($url_path, html::sanitizeURL($url_path), $url); 
     576           
    390577          for ($i=0; $i<count($rdf_all); $i++) 
    391578          { 
    392579               $rdf = $rdf_all[$i][1]; 
    393                 
    394                if (preg_match('/dc:identifier="'.preg_quote($url,'/').'"/msi',$rdf)) { 
     580               if (preg_match('/dc:identifier="'.preg_quote($url,'/').'"/msi',$rdf) || 
     581                    preg_match('/dc:identifier="'.preg_quote($sanitized_url,'/').'"/msi',$rdf)) { 
    395582                    if (preg_match('/trackback:ping="(.*?)"/msi',$rdf,$tb_link)) { 
    396583                         return $tb_link[1]; 
Note: See TracChangeset for help on using the changeset viewer.

Sites map