0byt3m1n1-V2
Path:
/
home
/
magalijoj
/
www
/
blog
/
inc
/
core
/
[
Home
]
File: class.dc.trackback.php
<?php # ***** BEGIN LICENSE BLOCK ***** # This file is part of DotClear. # Copyright (c) 2005 Olivier Meunier. All rights # reserved. # # DotClear is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # DotClear is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with DotClear; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # ***** END LICENSE BLOCK ***** /** @ingroup DC_CORE @brief Trackbacks sender and server Sends and receives trackbacks. Also handles trackbacks auto discovery. */ class dcTrackback { public $core; ///< <b>dcCore</b> dcCore instance public $table; ///< <b>string</b> done pings table name /** Object constructor @param core <b>dcCore</b> dcCore instance */ public function __construct(&$core) { $this->core =& $core; $this->con =& $this->core->con; $this->table = $this->core->prefix.'ping'; } /// @name Send trackbacks //@{ /** Get all pings sent for a given post. @param post_id <b>integer</b> Post ID @return <b>record</b> */ public function getPostPings($post_id) { $strReq = 'SELECT ping_url, ping_dt '. 'FROM '.$this->table.' '. 'WHERE post_id = '.(integer) $post_id; return $this->con->select($strReq); } /** Sends a ping to given <var>$url</var>. @param url <b>string</b> URL to ping @param post_id <b>integer</b> Post ID @param post_title <b>string</b> Post title @param post_excerpt <b>string</b> Post excerpt @param post_url <b>string</b> Post URL */ public function ping($url,$post_id,$post_title,$post_excerpt,$post_url) { if ($this->core->blog === null) { return false; } $post_id = (integer) $post_id; # Check for previously done trackback $strReq = 'SELECT post_id, ping_url FROM '.$this->table.' '. 'WHERE post_id = '.$post_id.' '. "AND ping_url = '".$this->con->escape($url)."' "; $rs = $this->con->select($strReq); if (!$rs->isEmpty()) { throw new Exception(sprintf(__('%s has still been pinged'),$url)); } $data = array( 'title' => $post_title, 'excerpt' => $post_excerpt, 'url' => $post_url, 'blog_name' => trim(html::escapeHTML(html::clean($this->core->blog->name))) //,'__debug' => false ); # Ping try { $http = self::initHttp($url,$path); $http->post($path,$data,'UTF-8'); $res = $http->getContent(); } catch (Exception $e) { throw new Exception(__('Unable to ping URL')); } $pattern = '|<response>.*<error>(.*)</error>(.*)'. '(<message>(.*)</message>(.*))?'. '</response>|msU'; if (!preg_match($pattern,$res,$match)) { throw new Exception(sprintf(__('%s is not a ping URL'),$url)); } $ping_error = trim($match[1]); $ping_msg = (!empty($match[4])) ? $match[4] : ''; if ($ping_error != '0') { throw new Exception(sprintf(__('%s, ping error:'),$url).' '.$ping_msg); } else { # Notify ping result in database $cur = $this->con->openCursor($this->table); $cur->post_id = $post_id; $cur->ping_url = $url; $cur->ping_dt = array('NOW()'); $cur->insert(); } } //@} /// @name Receive trackbacks //@{ /** Receives a trackback and insert it as a comment of given post. @param post_id <b>integer</b> Post ID */ public function receive($post_id) { header('Content-Type: text/xml; charset=UTF-8'); if (empty($_POST)) { http::head(405,'Method Not Allowed'); echo '<?xml version="1.0" encoding="utf-8"?>'."\n". "<response>\n". " <error>1</error>\n". " <message>POST request needed</message>\n". "</response>"; return; } $post_id = (integer) $post_id; $title = !empty($_POST['title']) ? $_POST['title'] : ''; $excerpt = !empty($_POST['excerpt']) ? $_POST['excerpt'] : ''; $url = !empty($_POST['url']) ? $_POST['url'] : ''; $blog_name = !empty($_POST['blog_name']) ? $_POST['blog_name'] : ''; $charset = ''; $comment = ''; $err = false; $msg = ''; if ($this->core->blog === null) { $err = true; $msg = 'No blog.'; } elseif ($url == '') { $err = true; $msg = 'URL parameter is requiered.'; } elseif ($blog_name == '') { $err = true; $msg = 'Blog name is requiered.'; } if (!$err) { $post = $this->core->blog->getPosts(array('post_id'=>$post_id)); if ($post->isEmpty()) { $err = true; $msg = 'No such post.'; } elseif (!$post->trackbacksActive()) { $err = true; $msg = 'Trackbacks are not allowed for this post or weblog.'; } } if (!$err) { $charset = self::getCharsetFromRequest(); if (!$charset) { $charset = mb_detect_encoding($title.' '.$excerpt.' '.$blog_name, 'UTF-8,ISO-8859-1,ISO-8859-2,ISO-8859-3,'. 'ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,'. 'ISO-8859-9,ISO-8859-10,ISO-8859-13,ISO-8859-14,ISO-8859-15'); } if (strtolower($charset) != 'utf-8') { $title = iconv($charset,'UTF-8',$title); $excerpt = iconv($charset,'UTF-8',$excerpt); $blog_name = iconv($charset,'UTF-8',$blog_name); } $title = trim(html::clean($title)); $title = html::decodeEntities($title); $title = html::escapeHTML($title); $title = text::cutString($title,60); $excerpt = trim(html::clean($excerpt)); $excerpt = html::decodeEntities($excerpt); $excerpt = preg_replace('/\s+/ms',' ',$excerpt); $excerpt = text::cutString($excerpt,252); $excerpt = html::escapeHTML($excerpt).'...'; $blog_name = trim(html::clean($blog_name)); $blog_name = html::decodeEntities($blog_name); $blog_name = html::escapeHTML($blog_name); $blog_name = text::cutString($blog_name,60); $url = trim(html::clean($url)); if (!$blog_name) { $blog_name = 'Anonymous blog'; } $comment = "<!-- TB -->\n". '<p><strong>'.($title ? $title : $blog_name)."</strong></p>\n". '<p>'.$excerpt.'</p>'; $cur = $this->core->con->openCursor($this->core->prefix.'comment'); $cur->comment_author = (string) $blog_name; $cur->comment_site = (string) $url; $cur->comment_content = (string) $comment; $cur->post_id = $post_id; $cur->comment_trackback = 1; $cur->comment_status = $this->core->blog->settings->trackbacks_pub ? 1 : -1; $cur->comment_ip = http::realIP(); try { # --BEHAVIOR-- publicBeforeTrackbackCreate $this->core->callBehavior('publicBeforeTrackbackCreate',$cur); $comment_id = $this->core->blog->addComment($cur); # --BEHAVIOR-- publicAfterTrackbackCreate $this->core->callBehavior('publicAfterTrackbackCreate',$cur,$comment_id); } catch (Exception $e) { $err = 1; $msg = 'Something went wrong : '.$e->getMessage(); } } $debug_trace = " <debug>\n". ' <title>'.$title."</title>\n". ' <excerpt>'.$excerpt."</excerpt>\n". ' <url>'.$url."</url>\n". ' <blog_name>'.$blog_name."</blog_name>\n". ' <charset>'.$charset."</charset>\n". ' <comment>'.$comment."</comment>\n". " </debug>\n"; $resp = '<?xml version="1.0" encoding="utf-8"?>'."\n". "<response>\n". ' <error>'.(integer) $err."</error>\n"; if ($msg) { $resp .= ' <message>'.$msg."</message>\n"; } if (!empty($_POST['__debug'])) { $resp .= $debug_trace; } echo $resp."</response>"; } //@} private static function initHttp($url,&$path) { $client = netHttp::initClient($url,$path,5); $client->setUserAgent('Dotclear - http://www.dotclear.net/'); $client->useGzip(false); $client->setPersistReferers(false); return $client; } private static function getCharsetFromRequest() { if (isset($_SERVER['CONTENT_TYPE'])) { if (preg_match('|charset=([a-zA-Z0-9-]+)|',$_SERVER['CONTENT_TYPE'],$m)) { return $m[1]; } } return null; } /// @name Trackbacks auto discovery //@{ /** Returns an array containing all discovered trackbacks URLs in <var>$text</var>. @param text <b>string</b> Input text @return <b>array</b> */ public function discover($text) { $res = array(); foreach ($this->getTextLinks($text) as $link) { if (($url = $this->getPingURL($link)) !== null) { $res[] = $url; } } return $res; } //@} private function getTextLinks($text) { $res = array(); # href attribute on "a" tags if (preg_match_all('/<a ([^>]+)>/ms', $text, $match, PREG_SET_ORDER)) { for ($i = 0; $i<count($match); $i++) { if (preg_match('/href="(http:\/\/[^"]+)"/ms', $match[$i][1], $matches)) { $res[$matches[1]] = 1; } } } unset($match); # cite attributes on "blockquote" and "q" tags if (preg_match_all('/<(blockquote|q) ([^>]+)>/ms', $text, $match, PREG_SET_ORDER)) { for ($i = 0; $i<count($match); $i++) { if (preg_match('/cite="(http:\/\/[^"]+)"/ms', $match[$i][2], $matches)) { $res[$matches[1]] = 1; } } } return array_keys($res); } private function getPingURL($url) { try { $http = self::initHttp($url,$path); $http->get($path); $page_content = $http->getContent(); } catch (Exception $e) { return false; } $pattern_rdf = '/<rdf:RDF.*?>.*?'. '<rdf:Description\s+(.*?)\/>'. '.*?<\/rdf:RDF>'. '/ms'; preg_match_all($pattern_rdf,$page_content,$rdf_all,PREG_SET_ORDER); for ($i=0; $i<count($rdf_all); $i++) { $rdf = $rdf_all[$i][1]; if (preg_match('/dc:identifier="'.preg_quote($url,'/').'"/ms',$rdf)) { if (preg_match('/trackback:ping="(.*?)"/ms',$rdf,$tb_link)) { return $tb_link[1]; } } } return null; } } ?>
©
2018.