root/trackback/files/lib/util/Trackback.class.php @ 29

Revision 29, 16.4 kB (checked in by d0nut, 6 years ago)

many, many updates in trackback mod. bis step to 0.0.2

Line 
1<?php
2
3/**
4 * PHP Class to handle TrackBacks (send/ping, receive, retreive, detect, seed, etc...)
5 *
6 * <code><?php
7 * include('trackback_cls.php');
8 * $trackback = new Trackback('BLOGish', 'Ran Aroussi', 'UTF-8');
9 * ?></code>
10 *
11 * ==============================================================================
12 *
13 * @version $Id: trackback_cls.php,v 1.2 2004/12/11 18:54:32 Ran Exp $
14 * @copyright Copyright (c) 2004 Ran Aroussi (http://www.blogish.org)
15 * @author Ran Aroussi <ran@blogish.org>
16 * @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
17 *
18 * ==============================================================================
19 */
20
21/**
22 * Trackback - The main class
23 *
24 * @param string $blog_name
25 * @param string $author
26 * @param string $encoding
27 */
28class Trackback {
29    var $blog_name = ''; // Default blog name used throughout the class (ie. BLOGish)
30    var $author = ''; // Default author name used throughout the class (ie. Ran Aroussi)
31    var $encoding = ''; // Default encoding used throughout the class (ie. UTF-8)
32    var $get_id = ''; // Retreives and holds $_GET['id'] (if not empty)
33    var $post_id = ''; // Retreives and holds $_POST['id'] (if not empty)
34    var $url = ''; // Retreives and holds $_POST['url'] (if not empty)
35    var $title = ''; // Retreives and holds $_POST['title'] (if not empty)
36    var $expert = ''; // Retreives and holds $_POST['expert'] (if not empty)
37    /**
38     * Class Constructure
39     *
40     * @param string $blog_name
41     * @param string $author
42     * @param string $encoding
43     * @return
44     */
45    function Trackback($blog_name, $author, $encoding = "UTF-8")
46    {
47        $this->blog_name = $blog_name;
48        $this->author = $author;
49        $this->encoding = $encoding; 
50               
51        // Gather $_POST information
52        if (isset($_GET['id'])) {
53            $this->get_id = $HTTP_GET_VARS['id'];
54        } 
55        if (isset($_POST['id'])) {
56            $this->post_id = $HTTP_POST_VARS['id'];
57        } 
58        if (isset($_POST['url'])) {
59            $this->url = $HTTP_POST_VARS['url'];
60        } 
61        if (isset($_POST['title'])) {
62            $this->title = $HTTP_POST_VARS['url'];
63        } 
64        if (isset($_POST['expert'])) {
65            $this->expert = $HTTP_POST_VARS['expert'];
66        } 
67    } 
68
69    /**
70     * Sends a trackback ping to a specified trackback URL.
71     * allowing clients to auto-discover the TrackBack Ping URL.
72     *
73     * <code><?php
74     * include('trackback_cls.php');
75     * $trackback = new Trackback('BLOGish', 'Ran Aroussi', 'UTF-8');
76     * if ($trackback->ping('http://tracked-blog.com', 'http://your-url.com', 'Your entry title')) {
77     *  echo "Trackback sent successfully...";
78     * } else {
79     *  echo "Error sending trackback....";
80     * }
81     * ?></code>
82     *
83     * @param string $tb
84     * @param string $url
85     * @param string $title
86     * @param string $excerpt
87     * @return boolean
88     */
89    function ping($tb, $url, $title = "", $excerpt = "")
90    {
91        $response = "";
92        $reason = ""; 
93        // Set default values
94        if (empty($title)) {
95            $title = "Trackbacking your entry...";
96        } 
97        if (empty($excerpt)) {
98            $excerpt = "I found your entry interesting do I've added a Trackback to it on my weblog :)";
99        } 
100        // Parse the target
101        $target = parse_url($tb);
102
103        if ((isset($target["query"])) && ($target["query"] != "")) {
104            $target["query"] = "?" . $target["query"];
105        } else {
106            $target["query"] = "";
107        } 
108
109        if ((isset($target["port"]) && !is_numeric($target["port"])) || (!isset($target["port"]))) {
110            $target["port"] = 80;
111        } 
112        // Open the socket
113        $tb_sock = fsockopen($target["host"], $target["port"]); 
114        // Something didn't work out, return
115        if (!is_resource($tb_sock)) {
116            return '$trackback->ping: can\'t connect to: ' . $tb . '.';
117            exit;
118        } 
119        // Put together the things we want to send
120        $tb_send = "url=" . rawurlencode($url) . "&title=" . rawurlencode($title) . "&blog_name=" . rawurlencode($this->blog_name) . "&excerpt=" . rawurlencode($excerpt); 
121        // Send the trackback
122        fputs($tb_sock, "POST " . $target["path"] . $target["query"] . " HTTP/1.1\r\n");
123        fputs($tb_sock, "Host: " . $target["host"] . "\r\n");
124        fputs($tb_sock, "Content-type: application/x-www-form-urlencoded\r\n");
125        fputs($tb_sock, "Content-length: " . strlen($tb_send) . "\r\n");
126        fputs($tb_sock, "Connection: close\r\n\r\n");
127        fputs($tb_sock, $tb_send); 
128        // Gather result
129        while (!feof($tb_sock)) {
130            $response .= fgets($tb_sock, 128);
131        } 
132        // Close socket
133        fclose($tb_sock); 
134        // Did the trackback ping work
135        strpos($response, '<error>0</error>') ? $return = true : $return = false; 
136        // send result
137        return $return;
138    } 
139
140    /**
141     * Produces XML response for trackbackers with ok/error message.
142     *
143     * <code><?php
144     * // Set page header to XML
145     * header('Content-Type: text/xml'); // MUST be the 1st line
146     * //
147         * // Instantiate the class
148         * //
149     * include('trackback_cls.php');
150     * $trackback = new Trackback('BLOGish', 'Ran Aroussi', 'UTF-8');
151         * //
152     * // Get trackback information
153         * //
154     * $tb_id = $trackback->post_id; // The id of the item being trackbacked
155     * $tb_url = $trackback->url; // The URL from which we got the trackback
156     * $tb_title = $trackback->title; // Subject/title send by trackback
157     * $tb_expert = $trackback->expert; // Short text send by trackback
158         * // 
159     * // Do whatever to log the trackback (save in DB, flatfile, etc...)
160         * //
161     * if (TRACKBACK_LOGGED_SUCCESSFULLY) {
162     *  // Logged successfully...
163     *  echo $trackback->recieve(true);
164     * } else {
165     *  // Something went wrong...
166     *  echo $trackback->recieve(false, 'Explain why you return error');
167     * }
168     * ?></code>
169     *
170     * @param boolean $success
171     * @param string $err_response
172     * @return boolean
173     */
174    function recieve($success = false, $err_response = "")
175    { 
176        // Default error response in case of problems...
177        if (!$success && empty($err_response)) {
178            $err_response = "An error occured while tring to log your trackback...";
179        } 
180        // Start response to trackbacker...
181        $return = '<?xml version="1.0" encoding="' . $this->encoding . '"?>' . "\n";
182        $return .= "<response> \n"; 
183        // Send back response...
184        if ($success) {
185            // Trackback received successfully...
186            $return .= "        <error>0</error> \n";
187        } else {
188            // Something went wrong...
189            $return .= "        <error>1</error> \n";
190            $return .= "        <message>" . $this->xml_safe($err_response) . "</message>\n";
191        } 
192        // End response to trackbacker...
193        $return .= "</response>";
194
195        return $return;
196    } 
197
198    /**
199     * Feteched trackback information and produces an RSS-0.91 feed.
200     *
201     * <code><?php
202     * // 1
203     * header('Content-Type: text/xml'); // MUST be the 1st line
204     * // 2
205     * include('trackback_cls.php');
206     * $trackback = new Trackback('BLOGish', 'Ran Aroussi', 'UTF-8');
207     * // 3
208     * $tb_id = $trackback->get_id;
209     * // 4
210     * Do whatever to get trackback information by ID (search db, etc...)
211     * if (GOT_TRACKBACK_INFO) {
212     *  // Successful - pass trackback info as array()...
213     *  $tb_info = array('title' => string TRACKBACK_TITLE,
214     *                  'expert'        => string TRACKBACK_EXPERT,
215     *                  'permalink' => string PERMALINK_URL,
216     *                  'trackback' => string TRACKBACK_URL
217     *          );
218     *  echo $trackback->fetch(true, $tb_info);
219     * } else {
220     *  // Something went wrong - tell my why...
221     *  echo $trackback->fetch(false, string RESPONSE);
222     * }
223     * ?></code>
224     *
225     * @param boolean $success
226     * @param string $response
227     * @return string XML response to the caller
228     */
229    function fetch($success = false, $response = "")
230    {
231        if (!$success && empty($response)) {
232            $response = "An error occured while tring to retreive trackback information...";
233        } 
234        // Start response to caller
235        $return = '<?xml version="1.0" encoding="' . $this->encoding . '"?>' . "\n";
236        $return .= "<response> \n"; 
237        // Send back response...
238        if ($success) {
239            // Trackback retreived successfully...
240            // Sending back an RSS (0.91) - trackback information from $response (array)...
241            $return .= "        <error>0</error> \n";
242            $return .= "        <rss version=\"0.91\"> \n";
243            $return .= "        <channel> \n";
244            $return .= "          <title>" . $this->xml_safe($response['title']) . "</title> \n";
245            $return .= "          <link>" . $this->xml_safe($response['trackback']) . "</link> \n";
246            $return .= "          <description>" . $this->xml_safe($response['expert']) . "</description> \n";
247            $return .= "          <item> \n";
248            $return .= "                <title>" . $this->xml_safe($response['title']) . "</title> \n";
249            $return .= "                <link>" . $this->xml_safe($response['permalink']) . "</link> \n";
250            $return .= "                <description>" . $this->xml_safe($response['expert']) . "</description> \n";
251            $return .= "          </item> \n";
252            $return .= "        </channel> \n";
253            $return .= "        </rss> \n";
254        } else {
255            // Something went wrong - provide reason from $response (string)...
256            $return .= "        <error>1</error> \n";
257            $return .= "        <message>" . $this->xml_safe($response) . "</message>\n";
258        } 
259        // End response to trackbacker
260        $return .= "</response>";
261
262        return $return;
263    } 
264
265    /**
266     * Produces embedded RDF representing metadata about the entry,
267     * allowing clients to auto-discover the TrackBack Ping URL.
268     *
269     * NOTE: DATE should be string in RFC822 Format - Use RFC822_from_datetime().
270     *
271     * <code><?php
272     * include('trackback_cls.php');
273     * $trackback = new Trackback('BLOGish', 'Ran Aroussi', 'UTF-8');
274     *
275     * echo $trackback->rdf_autodiscover(string DATE, string TITLE, string EXPERT, string PERMALINK, string TRACKBACK [, string AUTHOR]);
276     * ?></code>
277     *
278     * @param string $RFC822_date
279     * @param string $title
280     * @param string $expert
281     * @param string $permalink
282     * @param string $trackback
283     * @param string $author
284     * @return string
285     */
286    function rdf_autodiscover($RFC822_date, $title, $expert, $permalink, $trackback, $author = "")
287    {
288        if (!$author) {
289            $author = $this->author;
290        } 
291
292        $return = "<!-- \n";
293        $return .= "<rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" \n";
294        $return .= "    xmlns:dc=\"http://purl.org/dc/elements/1.1/\" \n";
295        $return .= "    xmlns:trackback=\"http://madskills.com/public/xml/rss/module/trackback/\"> \n";
296        $return .= "<rdf:Description \n";
297        $return .= "    rdf:about=\"" . $this->xml_safe($permalink) . "\" \n";
298        $return .= "    dc:identifier=\"" . $this->xml_safe($permalink) . "\" \n";
299        $return .= "    trackback:ping=\"" . $this->xml_safe($trackback) . "\" \n";
300        $return .= "    dc:title=\"" . $this->xml_safe($title) . "\" \n";
301        $return .= "    dc:subject=\"TrackBack\" \n";
302        $return .= "    dc:description=\"" . $this->xml_safe($this->cut_short($expert)) . "\" \n";
303        $return .= "    dc:creator=\"" . $this->xml_safe($author) . "\" \n";
304        $return .= "    dc:date=\"" . $RFC822_date . "\" /> \n";
305        $return .= "</rdf:RDF> \n";
306        $return .= "-->  \n";
307
308        return $return;
309    } 
310
311    /**
312     * Search text for links, and searches links for trackback URLs.
313     *
314     * <code><?php
315     *
316     * include('trackback_cls.php');
317     * $trackback = new Trackback('BLOGish', 'Ran Aroussi', 'UTF-8');
318     *
319     * if ($tb_array = $trackback->auto_discovery(string TEXT)) {
320     *  // Found trackbacks in TEXT. Looping...
321     *  foreach($tb_array as $tb_key => $tb_url) {
322     *  // Attempt to ping each one...
323     *          if ($trackback->ping($tb_url, string URL, [string TITLE], [string EXPERT])) {
324     *                  // Successful ping...
325     *                  echo "Trackback sent to <i>$tb_url</i>...\n";
326     *          } else {
327     *                  // Error pinging...
328     *                  echo "Trackback to <i>$tb_url</i> failed....\n";
329     *          }
330     *  }
331     * } else {
332     *  // No trackbacks in TEXT...
333     *  echo "No trackbacks were auto-discover...\n"
334     * }
335     * ?></code>
336     *
337     * @param string $text
338     * @return array Trackback URLs.
339     */
340    function auto_discovery($text)
341    { 
342        // Get a list of UNIQUE links from text...
343        // ---------------------------------------
344        // RegExp to look for (0=>link, 4=>host in 'replace')
345        $reg_exp = "/(http)+(s)?:(\\/\\/)((\\w|\\.)+)(\\/)?(\\S+)?/i"; 
346        // Make sure each link ends with [sapce]
347        $text = eregi_replace("www.", "http://www.", $text);
348        $text = eregi_replace("http://http://", "http://", $text);
349        $text = eregi_replace("\"", " \"", $text);
350        $text = eregi_replace("'", " '", $text);
351        $text = eregi_replace(">", " >", $text); 
352        // Create an array with unique links
353        $uri_array = array();
354        if (preg_match_all($reg_exp, strip_tags($text, "<a>"), $array, PREG_PATTERN_ORDER)) {
355            foreach($array[0] as $key => $link) {
356                foreach((array(",", ".", ":", ";")) as $t_key => $t_value) {
357                    $link = trim($link, $t_value);
358                } 
359                $uri_array[] = ($link);
360            } 
361            $uri_array = array_unique($uri_array);
362        } 
363        // Get the trackback URIs from those links...
364        // ------------------------------------------
365        // Loop through the URIs array and extract RDF segments
366        $rdf_array = array(); // <- holds list of RDF segments
367        foreach($uri_array as $key => $link) {
368            if ($link_content = implode("", @file($link))) {
369                preg_match_all('/(<rdf:RDF.*?<\/rdf:RDF>)/sm', $link_content, $link_rdf, PREG_SET_ORDER);
370                for ($i = 0; $i < count($link_rdf); $i++) {
371                    if (preg_match('|dc:identifier="' . preg_quote($link) . '"|ms', $link_rdf[$i][1])) {
372                        $rdf_array[] = trim($link_rdf[$i][1]);
373                    } 
374                } 
375            } 
376        } 
377        // Loop through the RDFs array and extract trackback URIs
378        $tb_array = array(); // <- holds list of trackback URIs
379        if (!empty($rdf_array)) {
380            for ($i = 0; $i < count($rdf_array); $i++) {
381                if (preg_match('/trackback:ping="([^"]+)"/', $rdf_array[$i], $array)) {
382                    $tb_array[] = trim($array[1]);
383                } 
384            } 
385        } 
386        // Return Trackbacks
387        return $tb_array;
388    } 
389
390    /**
391     * Other Useful functions used in this class
392     */
393
394    /**
395     * Converts MySQL datetime to a standart RFC 822 date format
396     *
397     * @param string $datetime
398     * @return string RFC 822 date
399     */
400    function RFC822_from_datetime($datetime)
401    {
402        $timestamp = mktime(
403            substr($datetime, 8, 2), substr($datetime, 10, 2), substr($datetime, 12, 2),
404            substr($datetime, 4, 2), substr($datetime, 6, 2), substr($datetime, 0, 4)
405            );
406        return date("r", $timestamp);
407    } 
408
409    /**
410     * Converts a string into an XML-safe string (replaces &, <, >, " and ')
411     *
412     * @param string $string
413     * @return string
414     */
415    function xml_safe($string)
416    {
417        return htmlspecialchars($string, ENT_QUOTES);
418    } 
419
420    /**
421     * Cuts a string short (with "...") accroding to $max_length...
422     *
423     * @param string $string
424     * @param integer $max_length
425     * @return string
426     */
427    function cut_short($string, $max_length = 255)
428    {
429        if (strlen($string) > $max_length) {
430            $string = substr($string, 0, $max_length) . '...';
431        } 
432
433        return $string;
434    } 
435} 
436
437?>
Note: See TracBrowser for help on using the browser.