[ Index ]
 

Code source de Dotclear 2.0-beta6

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/inc/core/ -> class.dc.trackback.php (source)

   1  <?php
   2  # ***** BEGIN LICENSE BLOCK *****
   3  # This file is part of DotClear.
   4  # Copyright (c) 2005 Olivier Meunier. All rights
   5  # reserved.
   6  #
   7  # DotClear is free software; you can redistribute it and/or modify
   8  # it under the terms of the GNU General Public License as published by
   9  # the Free Software Foundation; either version 2 of the License, or
  10  # (at your option) any later version.
  11  # 
  12  # DotClear is distributed in the hope that it will be useful,
  13  # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15  # GNU General Public License for more details.
  16  # 
  17  # You should have received a copy of the GNU General Public License
  18  # along with DotClear; if not, write to the Free Software
  19  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  20  #
  21  # ***** END LICENSE BLOCK *****
  22  
  23  /**
  24  @ingroup DC_CORE
  25  @brief Trackbacks sender and server
  26  
  27  Sends and receives trackbacks. Also handles trackbacks auto discovery.
  28  */
  29  class dcTrackback
  30  {
  31      public $core;        ///< <b>dcCore</b> dcCore instance
  32      public $table;        ///< <b>string</b> done pings table name
  33      
  34      /**
  35      Object constructor
  36      
  37      @param    core        <b>dcCore</b>        dcCore instance
  38      */
  39  	public function __construct(&$core)
  40      {
  41          $this->core =& $core;
  42          $this->con =& $this->core->con;
  43          $this->table = $this->core->prefix.'ping';
  44      }
  45      
  46      /// @name Send trackbacks
  47      //@{
  48      /**
  49      Get all pings sent for a given post.
  50      
  51      @param    post_id    <b>integer</b>        Post ID
  52      @return    <b>record</b>
  53      */
  54  	public function getPostPings($post_id)
  55      {
  56          $strReq = 'SELECT ping_url, ping_dt '.
  57                  'FROM '.$this->table.' '.
  58                  'WHERE post_id = '.(integer) $post_id;
  59          
  60          return $this->con->select($strReq);
  61      }
  62      
  63      /**
  64      Sends a ping to given <var>$url</var>.
  65      
  66      @param    url            <b>string</b>        URL to ping
  67      @param    post_id        <b>integer</b>        Post ID
  68      @param    post_title    <b>string</b>        Post title
  69      @param    post_excerpt    <b>string</b>        Post excerpt
  70      @param    post_url        <b>string</b>        Post URL
  71      */
  72  	public function ping($url,$post_id,$post_title,$post_excerpt,$post_url)
  73      {
  74          if ($this->core->blog === null) {
  75              return false;
  76          }
  77          
  78          $post_id = (integer) $post_id;
  79          
  80          # Check for previously done trackback
  81          $strReq = 'SELECT post_id, ping_url FROM '.$this->table.' '.
  82                  'WHERE post_id = '.$post_id.' '.
  83                  "AND ping_url = '".$this->con->escape($url)."' ";
  84          
  85          $rs = $this->con->select($strReq);
  86          
  87          if (!$rs->isEmpty()) {
  88              throw new Exception(sprintf(__('%s has still been pinged'),$url));
  89          }
  90          
  91          $data = array(
  92              'title' => $post_title,
  93              'excerpt' => $post_excerpt,
  94              'url' => $post_url,
  95              'blog_name' => trim(html::escapeHTML(html::clean($this->core->blog->name)))
  96              //,'__debug' => false
  97          );
  98          
  99          # Ping
 100          try
 101          {
 102              $http = self::initHttp($url,$path);
 103              $http->post($path,$data,'UTF-8');
 104              $res = $http->getContent();
 105          }
 106          catch (Exception $e)
 107          {
 108              throw new Exception(__('Unable to ping URL'));
 109          }
 110          
 111          $pattern =
 112          '|<response>.*<error>(.*)</error>(.*)'.
 113          '(<message>(.*)</message>(.*))?'.
 114          '</response>|msU';
 115          
 116          if (!preg_match($pattern,$res,$match))
 117          {
 118              throw new Exception(sprintf(__('%s is not a ping URL'),$url));
 119          }
 120          
 121          $ping_error = trim($match[1]);
 122          $ping_msg = (!empty($match[4])) ? $match[4] : '';
 123          
 124          if ($ping_error != '0') {
 125              throw new Exception(sprintf(__('%s, ping error:'),$url).' '.$ping_msg);
 126          } else {
 127              # Notify ping result in database
 128              $cur = $this->con->openCursor($this->table);
 129              $cur->post_id = $post_id;
 130              $cur->ping_url = $url;
 131              $cur->ping_dt = array('NOW()');
 132              
 133              $cur->insert();
 134          }
 135      }
 136      //@}
 137      
 138      /// @name Receive trackbacks
 139      //@{
 140      /**
 141      Receives a trackback and insert it as a comment of given post.
 142      
 143      @param    post_id        <b>integer</b>        Post ID
 144      */
 145  	public function receive($post_id)
 146      {
 147          header('Content-Type: text/xml; charset=UTF-8');
 148          if (empty($_POST)) {
 149              http::head(405,'Method Not Allowed');
 150              echo
 151              '<?xml version="1.0" encoding="utf-8"?>'."\n".
 152              "<response>\n".
 153              "  <error>1</error>\n".
 154              "  <message>POST request needed</message>\n".
 155              "</response>";
 156              return;
 157          }
 158          
 159          $post_id = (integer) $post_id;
 160          
 161          $title = !empty($_POST['title']) ? $_POST['title'] : '';
 162          $excerpt = !empty($_POST['excerpt']) ? $_POST['excerpt'] : '';
 163          $url = !empty($_POST['url']) ? $_POST['url'] : '';
 164          $blog_name = !empty($_POST['blog_name']) ? $_POST['blog_name'] : '';
 165          $charset = '';
 166          $comment = '';
 167          
 168          $err = false;
 169          $msg = '';
 170          
 171          if ($this->core->blog === null)
 172          {
 173              $err = true;
 174              $msg = 'No blog.';
 175          }
 176          elseif ($url == '')
 177          {
 178              $err = true;
 179              $msg = 'URL parameter is requiered.';
 180          }
 181          elseif ($blog_name == '') {
 182              $err = true;
 183              $msg = 'Blog name is requiered.';
 184          }
 185          
 186          if (!$err)
 187          {
 188              $post = $this->core->blog->getPosts(array('post_id'=>$post_id));
 189              
 190              if ($post->isEmpty())
 191              {
 192                  $err = true;
 193                  $msg = 'No such post.';
 194              }
 195              elseif (!$post->trackbacksActive())
 196              {
 197                  $err = true;
 198                  $msg = 'Trackbacks are not allowed for this post or weblog.';
 199              }
 200          }
 201          
 202          if (!$err)
 203          {
 204              $charset = self::getCharsetFromRequest();
 205              
 206              if (!$charset) {
 207                  $charset = mb_detect_encoding($title.' '.$excerpt.' '.$blog_name,
 208                  'UTF-8,ISO-8859-1,ISO-8859-2,ISO-8859-3,'.
 209                  'ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,'.
 210                  'ISO-8859-9,ISO-8859-10,ISO-8859-13,ISO-8859-14,ISO-8859-15');
 211              }
 212              
 213              if (strtolower($charset) != 'utf-8') {
 214                  $title = iconv($charset,'UTF-8',$title);
 215                  $excerpt = iconv($charset,'UTF-8',$excerpt);
 216                  $blog_name = iconv($charset,'UTF-8',$blog_name);
 217              }
 218              
 219              $title = trim(html::clean($title));
 220              $title = html::decodeEntities($title);
 221              $title = html::escapeHTML($title);
 222              $title = text::cutString($title,60);
 223              
 224              $excerpt = trim(html::clean($excerpt));
 225              $excerpt = html::decodeEntities($excerpt);
 226              $excerpt = preg_replace('/\s+/ms',' ',$excerpt);
 227              $excerpt = text::cutString($excerpt,252); 
 228              $excerpt = html::escapeHTML($excerpt).'...';
 229              
 230              $blog_name = trim(html::clean($blog_name));
 231              $blog_name = html::decodeEntities($blog_name);
 232              $blog_name = html::escapeHTML($blog_name);
 233              $blog_name = text::cutString($blog_name,60);
 234              
 235              $url = trim(html::clean($url));
 236              
 237              if (!$blog_name) {
 238                  $blog_name = 'Anonymous blog';
 239              }
 240              
 241              $comment =
 242              "<!-- TB -->\n".
 243              '<p><strong>'.($title ? $title : $blog_name)."</strong></p>\n".
 244              '<p>'.$excerpt.'</p>';
 245              
 246              $cur = $this->core->con->openCursor($this->core->prefix.'comment');
 247              $cur->comment_author = (string) $blog_name;
 248              $cur->comment_site = (string) $url;
 249              $cur->comment_content = (string) $comment;
 250              $cur->post_id = $post_id;
 251              $cur->comment_trackback = 1;
 252              $cur->comment_status = $this->core->blog->settings->comments_pub ? 1 : -1;
 253              $cur->comment_ip = http::realIP();
 254              
 255              try
 256              {
 257                  # --BEHAVIOR-- publicBeforeTrackbackCreate
 258                  $this->core->callBehavior('publicBeforeTrackbackCreate',$cur);
 259                  
 260                  $comment_id = $this->core->blog->addComment($cur);
 261                  
 262                  # --BEHAVIOR-- publicAfterTrackbackCreate
 263                  $this->core->callBehavior('publicAfterTrackbackCreate',$cur,$comment_id);
 264              }
 265              catch (Exception $e)
 266              {
 267                  $err = 1;
 268                  $msg = 'Something went wrong : '.$e->getMessage();
 269              }
 270          }
 271          
 272          
 273          $debug_trace =
 274          "  <debug>\n".
 275          '    <title>'.$title."</title>\n".
 276          '    <excerpt>'.$excerpt."</excerpt>\n".
 277          '    <url>'.$url."</url>\n".
 278          '    <blog_name>'.$blog_name."</blog_name>\n".
 279          '    <charset>'.$charset."</charset>\n".
 280          '    <comment>'.$comment."</comment>\n".
 281          "  </debug>\n";
 282          
 283          $resp =
 284          '<?xml version="1.0" encoding="utf-8"?>'."\n".
 285          "<response>\n".
 286          '  <error>'.(integer) $err."</error>\n";
 287          
 288          if ($msg) {
 289              $resp .= '  <message>'.$msg."</message>\n";
 290          }
 291          
 292          if (!empty($_POST['__debug'])) {
 293              $resp .= $debug_trace;
 294          }
 295          
 296          echo    $resp."</response>";
 297      }
 298      //@}
 299      
 300  	private static function initHttp($url,&$path)
 301      {
 302          $client = netHttp::initClient($url,$path,5);
 303          $client->setUserAgent('Dotclear - http://www.dotclear.net/');
 304          $client->useGzip(false);
 305          $client->setPersistReferers(false);
 306          
 307          return $client;
 308      }
 309      
 310  	private static function getCharsetFromRequest()
 311      {
 312          if (isset($_SERVER['CONTENT_TYPE']))
 313          {
 314              if (preg_match('|charset=([a-zA-Z0-9-]+)|',$_SERVER['CONTENT_TYPE'],$m)) {
 315                  return $m[1];
 316              }
 317          }
 318          
 319          return null;
 320      }
 321      
 322      /// @name Trackbacks auto discovery
 323      //@{
 324      /**
 325      Returns an array containing all discovered trackbacks URLs in
 326      <var>$text</var>.
 327      
 328      @param    text        <b>string</b>        Input text
 329      @return    <b>array</b>
 330      */
 331  	public function discover($text)
 332      {
 333          $res = array();
 334          
 335          foreach ($this->getTextLinks($text) as $link)
 336          {
 337              if (($url = $this->getPingURL($link)) !== null) {
 338                  $res[] = $url;
 339              }
 340          }
 341          
 342          return $res;
 343      }
 344      //@}
 345      
 346  	private function getTextLinks($text)
 347      {
 348          $res = array();
 349          
 350          # href attribute on "a" tags
 351          if (preg_match_all('/<a ([^>]+)>/ms', $text, $match, PREG_SET_ORDER))
 352          {
 353              for ($i = 0; $i<count($match); $i++)
 354              {
 355                  if (preg_match('/href="(http:\/\/[^"]+)"/ms', $match[$i][1], $matches)) {
 356                      $res[$matches[1]] = 1;
 357                  }
 358              }
 359          }
 360          unset($match);
 361          
 362          # cite attributes on "blockquote" and "q" tags
 363          if (preg_match_all('/<(blockquote|q) ([^>]+)>/ms', $text, $match, PREG_SET_ORDER))
 364          {
 365              for ($i = 0; $i<count($match); $i++)
 366              {
 367                  if (preg_match('/cite="(http:\/\/[^"]+)"/ms', $match[$i][2], $matches)) {
 368                      $res[$matches[1]] = 1;
 369                  }
 370              }
 371          }
 372          
 373          return array_keys($res);
 374      }
 375      
 376  	private function getPingURL($url)
 377      {
 378          try
 379          {
 380              $http = self::initHttp($url,$path);
 381              $http->get($path);
 382              $page_content = $http->getContent();
 383          }
 384          catch (Exception $e)
 385          {
 386              return false;
 387          }
 388          
 389          $pattern_rdf =
 390          '/<rdf:RDF.*?>.*?'.
 391          '<rdf:Description\s+(.*?)\/>'.
 392          '.*?<\/rdf:RDF>'.
 393          '/ms';
 394          
 395          preg_match_all($pattern_rdf,$page_content,$rdf_all,PREG_SET_ORDER);
 396          
 397          for ($i=0; $i<count($rdf_all); $i++)
 398          {
 399              $rdf = $rdf_all[$i][1];
 400              
 401              if (preg_match('/dc:identifier="'.preg_quote($url,'/').'"/ms',$rdf)) {
 402                  if (preg_match('/trackback:ping="(.*?)"/ms',$rdf,$tb_link)) {
 403                      return $tb_link[1];
 404                  }
 405              }
 406          }
 407          
 408          return null;
 409      }
 410  }
 411  ?>


Généré le : Fri Feb 23 22:16:06 2007 par Balluche grâce à PHPXref 0.7