source: pro-violet-viettel/sourcecode/system/libraries/Trackback.php @ 924

Last change on this file since 924 was 289, checked in by dungnv, 11 years ago
File size: 11.7 KB
Line 
1<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
2/**
3 * CodeIgniter
4 *
5 * An open source application development framework for PHP 5.1.6 or newer
6 *
7 * @package             CodeIgniter
8 * @author              ExpressionEngine Dev Team
9 * @copyright   Copyright (c) 2008 - 2011, EllisLab, Inc.
10 * @license             http://codeigniter.com/user_guide/license.html
11 * @link                http://codeigniter.com
12 * @since               Version 1.0
13 * @filesource
14 */
15
16// ------------------------------------------------------------------------
17
18/**
19 * Trackback Class
20 *
21 * Trackback Sending/Receiving Class
22 *
23 * @package             CodeIgniter
24 * @subpackage  Libraries
25 * @category    Trackbacks
26 * @author              ExpressionEngine Dev Team
27 * @link                http://codeigniter.com/user_guide/libraries/trackback.html
28 */
29class CI_Trackback {
30
31        var $time_format        = 'local';
32        var $charset            = 'UTF-8';
33        var $data                       = array('url' => '', 'title' => '', 'excerpt' => '', 'blog_name' => '', 'charset' => '');
34        var $convert_ascii      = TRUE;
35        var $response           = '';
36        var $error_msg          = array();
37
38        /**
39         * Constructor
40         *
41         * @access      public
42         */
43        public function __construct()
44        {
45                log_message('debug', "Trackback Class Initialized");
46        }
47
48        // --------------------------------------------------------------------
49
50        /**
51         * Send Trackback
52         *
53         * @access      public
54         * @param       array
55         * @return      bool
56         */
57        function send($tb_data)
58        {
59                if ( ! is_array($tb_data))
60                {
61                        $this->set_error('The send() method must be passed an array');
62                        return FALSE;
63                }
64
65                // Pre-process the Trackback Data
66                foreach (array('url', 'title', 'excerpt', 'blog_name', 'ping_url') as $item)
67                {
68                        if ( ! isset($tb_data[$item]))
69                        {
70                                $this->set_error('Required item missing: '.$item);
71                                return FALSE;
72                        }
73
74                        switch ($item)
75                        {
76                                case 'ping_url' : $$item = $this->extract_urls($tb_data[$item]);
77                                        break;
78                                case 'excerpt'  : $$item = $this->limit_characters($this->convert_xml(strip_tags(stripslashes($tb_data[$item]))));
79                                        break;
80                                case 'url'              : $$item = str_replace('&#45;', '-', $this->convert_xml(strip_tags(stripslashes($tb_data[$item]))));
81                                        break;
82                                default                 : $$item = $this->convert_xml(strip_tags(stripslashes($tb_data[$item])));
83                                        break;
84                        }
85
86                        // Convert High ASCII Characters
87                        if ($this->convert_ascii == TRUE)
88                        {
89                                if ($item == 'excerpt')
90                                {
91                                        $$item = $this->convert_ascii($$item);
92                                }
93                                elseif ($item == 'title')
94                                {
95                                        $$item = $this->convert_ascii($$item);
96                                }
97                                elseif ($item == 'blog_name')
98                                {
99                                        $$item = $this->convert_ascii($$item);
100                                }
101                        }
102                }
103
104                // Build the Trackback data string
105                $charset = ( ! isset($tb_data['charset'])) ? $this->charset : $tb_data['charset'];
106
107                $data = "url=".rawurlencode($url)."&title=".rawurlencode($title)."&blog_name=".rawurlencode($blog_name)."&excerpt=".rawurlencode($excerpt)."&charset=".rawurlencode($charset);
108
109                // Send Trackback(s)
110                $return = TRUE;
111                if (count($ping_url) > 0)
112                {
113                        foreach ($ping_url as $url)
114                        {
115                                if ($this->process($url, $data) == FALSE)
116                                {
117                                        $return = FALSE;
118                                }
119                        }
120                }
121
122                return $return;
123        }
124
125        // --------------------------------------------------------------------
126
127        /**
128         * Receive Trackback  Data
129         *
130         * This function simply validates the incoming TB data.
131         * It returns FALSE on failure and TRUE on success.
132         * If the data is valid it is set to the $this->data array
133         * so that it can be inserted into a database.
134         *
135         * @access      public
136         * @return      bool
137         */
138        function receive()
139        {
140                foreach (array('url', 'title', 'blog_name', 'excerpt') as $val)
141                {
142                        if ( ! isset($_POST[$val]) OR $_POST[$val] == '')
143                        {
144                                $this->set_error('The following required POST variable is missing: '.$val);
145                                return FALSE;
146                        }
147
148                        $this->data['charset'] = ( ! isset($_POST['charset'])) ? 'auto' : strtoupper(trim($_POST['charset']));
149
150                        if ($val != 'url' && function_exists('mb_convert_encoding'))
151                        {
152                                $_POST[$val] = mb_convert_encoding($_POST[$val], $this->charset, $this->data['charset']);
153                        }
154
155                        $_POST[$val] = ($val != 'url') ? $this->convert_xml(strip_tags($_POST[$val])) : strip_tags($_POST[$val]);
156
157                        if ($val == 'excerpt')
158                        {
159                                $_POST['excerpt'] = $this->limit_characters($_POST['excerpt']);
160                        }
161
162                        $this->data[$val] = $_POST[$val];
163                }
164
165                return TRUE;
166        }
167
168        // --------------------------------------------------------------------
169
170        /**
171         * Send Trackback Error Message
172         *
173         * Allows custom errors to be set.  By default it
174         * sends the "incomplete information" error, as that's
175         * the most common one.
176         *
177         * @access      public
178         * @param       string
179         * @return      void
180         */
181        function send_error($message = 'Incomplete Information')
182        {
183                echo "<?xml version=\"1.0\" encoding=\"utf-8\"?".">\n<response>\n<error>1</error>\n<message>".$message."</message>\n</response>";
184                exit;
185        }
186
187        // --------------------------------------------------------------------
188
189        /**
190         * Send Trackback Success Message
191         *
192         * This should be called when a trackback has been
193         * successfully received and inserted.
194         *
195         * @access      public
196         * @return      void
197         */
198        function send_success()
199        {
200                echo "<?xml version=\"1.0\" encoding=\"utf-8\"?".">\n<response>\n<error>0</error>\n</response>";
201                exit;
202        }
203
204        // --------------------------------------------------------------------
205
206        /**
207         * Fetch a particular item
208         *
209         * @access      public
210         * @param       string
211         * @return      string
212         */
213        function data($item)
214        {
215                return ( ! isset($this->data[$item])) ? '' : $this->data[$item];
216        }
217
218        // --------------------------------------------------------------------
219
220        /**
221         * Process Trackback
222         *
223         * Opens a socket connection and passes the data to
224         * the server.  Returns TRUE on success, FALSE on failure
225         *
226         * @access      public
227         * @param       string
228         * @param       string
229         * @return      bool
230         */
231        function process($url, $data)
232        {
233                $target = parse_url($url);
234
235                // Open the socket
236                if ( ! $fp = @fsockopen($target['host'], 80))
237                {
238                        $this->set_error('Invalid Connection: '.$url);
239                        return FALSE;
240                }
241
242                // Build the path
243                $ppath = ( ! isset($target['path'])) ? $url : $target['path'];
244
245                $path = (isset($target['query']) && $target['query'] != "") ? $ppath.'?'.$target['query'] : $ppath;
246
247                // Add the Trackback ID to the data string
248                if ($id = $this->get_id($url))
249                {
250                        $data = "tb_id=".$id."&".$data;
251                }
252
253                // Transfer the data
254                fputs ($fp, "POST " . $path . " HTTP/1.0\r\n" );
255                fputs ($fp, "Host: " . $target['host'] . "\r\n" );
256                fputs ($fp, "Content-type: application/x-www-form-urlencoded\r\n" );
257                fputs ($fp, "Content-length: " . strlen($data) . "\r\n" );
258                fputs ($fp, "Connection: close\r\n\r\n" );
259                fputs ($fp, $data);
260
261                // Was it successful?
262                $this->response = "";
263
264                while ( ! feof($fp))
265                {
266                        $this->response .= fgets($fp, 128);
267                }
268                @fclose($fp);
269
270
271                if (stristr($this->response, '<error>0</error>') === FALSE)
272                {
273                        $message = 'An unknown error was encountered';
274
275                        if (preg_match("/<message>(.*?)<\/message>/is", $this->response, $match))
276                        {
277                                $message = trim($match['1']);
278                        }
279
280                        $this->set_error($message);
281                        return FALSE;
282                }
283
284                return TRUE;
285        }
286
287        // --------------------------------------------------------------------
288
289        /**
290         * Extract Trackback URLs
291         *
292         * This function lets multiple trackbacks be sent.
293         * It takes a string of URLs (separated by comma or
294         * space) and puts each URL into an array
295         *
296         * @access      public
297         * @param       string
298         * @return      string
299         */
300        function extract_urls($urls)
301        {
302                // Remove the pesky white space and replace with a comma.
303                $urls = preg_replace("/\s*(\S+)\s*/", "\\1,", $urls);
304
305                // If they use commas get rid of the doubles.
306                $urls = str_replace(",,", ",", $urls);
307
308                // Remove any comma that might be at the end
309                if (substr($urls, -1) == ",")
310                {
311                        $urls = substr($urls, 0, -1);
312                }
313
314                // Break into an array via commas
315                $urls = preg_split('/[,]/', $urls);
316
317                // Removes duplicates
318                $urls = array_unique($urls);
319
320                array_walk($urls, array($this, 'validate_url'));
321
322                return $urls;
323        }
324
325        // --------------------------------------------------------------------
326
327        /**
328         * Validate URL
329         *
330         * Simply adds "http://" if missing
331         *
332         * @access      public
333         * @param       string
334         * @return      string
335         */
336        function validate_url($url)
337        {
338                $url = trim($url);
339
340                if (substr($url, 0, 4) != "http")
341                {
342                        $url = "http://".$url;
343                }
344        }
345
346        // --------------------------------------------------------------------
347
348        /**
349         * Find the Trackback URL's ID
350         *
351         * @access      public
352         * @param       string
353         * @return      string
354         */
355        function get_id($url)
356        {
357                $tb_id = "";
358
359                if (strpos($url, '?') !== FALSE)
360                {
361                        $tb_array = explode('/', $url);
362                        $tb_end   = $tb_array[count($tb_array)-1];
363
364                        if ( ! is_numeric($tb_end))
365                        {
366                                $tb_end  = $tb_array[count($tb_array)-2];
367                        }
368
369                        $tb_array = explode('=', $tb_end);
370                        $tb_id  = $tb_array[count($tb_array)-1];
371                }
372                else
373                {
374                        $url = rtrim($url, '/');
375
376                        $tb_array = explode('/', $url);
377                        $tb_id  = $tb_array[count($tb_array)-1];
378
379                        if ( ! is_numeric($tb_id))
380                        {
381                                $tb_id  = $tb_array[count($tb_array)-2];
382                        }
383                }
384
385                if ( ! preg_match ("/^([0-9]+)$/", $tb_id))
386                {
387                        return FALSE;
388                }
389                else
390                {
391                        return $tb_id;
392                }
393        }
394
395        // --------------------------------------------------------------------
396
397        /**
398         * Convert Reserved XML characters to Entities
399         *
400         * @access      public
401         * @param       string
402         * @return      string
403         */
404        function convert_xml($str)
405        {
406                $temp = '__TEMP_AMPERSANDS__';
407
408                $str = preg_replace("/&#(\d+);/", "$temp\\1;", $str);
409                $str = preg_replace("/&(\w+);/",  "$temp\\1;", $str);
410
411                $str = str_replace(array("&","<",">","\"", "'", "-"),
412                                                        array("&amp;", "&lt;", "&gt;", "&quot;", "&#39;", "&#45;"),
413                                                        $str);
414
415                $str = preg_replace("/$temp(\d+);/","&#\\1;",$str);
416                $str = preg_replace("/$temp(\w+);/","&\\1;", $str);
417
418                return $str;
419        }
420
421        // --------------------------------------------------------------------
422
423        /**
424         * Character limiter
425         *
426         * Limits the string based on the character count. Will preserve complete words.
427         *
428         * @access      public
429         * @param       string
430         * @param       integer
431         * @param       string
432         * @return      string
433         */
434        function limit_characters($str, $n = 500, $end_char = '&#8230;')
435        {
436                if (strlen($str) < $n)
437                {
438                        return $str;
439                }
440
441                $str = preg_replace("/\s+/", ' ', str_replace(array("\r\n", "\r", "\n"), ' ', $str));
442
443                if (strlen($str) <= $n)
444                {
445                        return $str;
446                }
447
448                $out = "";
449                foreach (explode(' ', trim($str)) as $val)
450                {
451                        $out .= $val.' ';
452                        if (strlen($out) >= $n)
453                        {
454                                return trim($out).$end_char;
455                        }
456                }
457        }
458
459        // --------------------------------------------------------------------
460
461        /**
462         * High ASCII to Entities
463         *
464         * Converts Hight ascii text and MS Word special chars
465         * to character entities
466         *
467         * @access      public
468         * @param       string
469         * @return      string
470         */
471        function convert_ascii($str)
472        {
473                $count  = 1;
474                $out    = '';
475                $temp   = array();
476
477                for ($i = 0, $s = strlen($str); $i < $s; $i++)
478                {
479                        $ordinal = ord($str[$i]);
480
481                        if ($ordinal < 128)
482                        {
483                                $out .= $str[$i];
484                        }
485                        else
486                        {
487                                if (count($temp) == 0)
488                                {
489                                        $count = ($ordinal < 224) ? 2 : 3;
490                                }
491
492                                $temp[] = $ordinal;
493
494                                if (count($temp) == $count)
495                                {
496                                        $number = ($count == 3) ? (($temp['0'] % 16) * 4096) + (($temp['1'] % 64) * 64) + ($temp['2'] % 64) : (($temp['0'] % 32) * 64) + ($temp['1'] % 64);
497
498                                        $out .= '&#'.$number.';';
499                                        $count = 1;
500                                        $temp = array();
501                                }
502                        }
503                }
504
505                return $out;
506        }
507
508        // --------------------------------------------------------------------
509
510        /**
511         * Set error message
512         *
513         * @access      public
514         * @param       string
515         * @return      void
516         */
517        function set_error($msg)
518        {
519                log_message('error', $msg);
520                $this->error_msg[] = $msg;
521        }
522
523        // --------------------------------------------------------------------
524
525        /**
526         * Show error messages
527         *
528         * @access      public
529         * @param       string
530         * @param       string
531         * @return      string
532         */
533        function display_errors($open = '<p>', $close = '</p>')
534        {
535                $str = '';
536                foreach ($this->error_msg as $val)
537                {
538                        $str .= $open.$val.$close;
539                }
540
541                return $str;
542        }
543
544}
545// END Trackback Class
546
547/* End of file Trackback.php */
548/* Location: ./system/libraries/Trackback.php */
Note: See TracBrowser for help on using the repository browser.