Subversion Repositories Applications.papyrus

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2005 Aurelien 1
<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
2
/**
3
 * CodeIgniter
4
 *
5
 * An open source application development framework for PHP 4.3.2 or newer
6
 *
7
 * @package		CodeIgniter
8
 * @author		ExpressionEngine Dev Team
9
 * @copyright	Copyright (c) 2008, 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
 */
29
class 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
	function CI_Trackback()
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
		if ( ! eregi("<error>0</error>", $this->response))
271
		{
272
			$message = 'An unknown error was encountered';
273
274
			if (preg_match("/<message>(.*?)<\/message>/is", $this->response, $match))
275
			{
276
				$message = trim($match['1']);
277
			}
278
279
			$this->set_error($message);
280
			return FALSE;
281
		}
282
283
		return TRUE;
284
	}
285
286
	// --------------------------------------------------------------------
287
288
	/**
289
	 * Extract Trackback URLs
290
	 *
291
	 * This function lets multiple trackbacks be sent.
292
	 * It takes a string of URLs (separated by comma or
293
	 * space) and puts each URL into an array
294
	 *
295
	 * @access	public
296
	 * @param	string
297
	 * @return	string
298
	 */
299
	function extract_urls($urls)
300
	{
301
		// Remove the pesky white space and replace with a comma.
302
		$urls = preg_replace("/\s*(\S+)\s*/", "\\1,", $urls);
303
304
		// If they use commas get rid of the doubles.
305
		$urls = str_replace(",,", ",", $urls);
306
307
		// Remove any comma that might be at the end
308
		if (substr($urls, -1) == ",")
309
		{
310
			$urls = substr($urls, 0, -1);
311
		}
312
313
		// Break into an array via commas
314
		$urls = preg_split('/[,]/', $urls);
315
316
		// Removes duplicates
317
		$urls = array_unique($urls);
318
319
		array_walk($urls, array($this, 'validate_url'));
320
321
		return $urls;
322
	}
323
324
	// --------------------------------------------------------------------
325
326
	/**
327
	 * Validate URL
328
	 *
329
	 * Simply adds "http://" if missing
330
	 *
331
	 * @access	public
332
	 * @param	string
333
	 * @return	string
334
	 */
335
	function validate_url($url)
336
	{
337
		$url = trim($url);
338
339
		if (substr($url, 0, 4) != "http")
340
		{
341
			$url = "http://".$url;
342
		}
343
	}
344
345
	// --------------------------------------------------------------------
346
347
	/**
348
	 * Find the Trackback URL's ID
349
	 *
350
	 * @access	public
351
	 * @param	string
352
	 * @return	string
353
	 */
354
	function get_id($url)
355
	{
356
		$tb_id = "";
357
358
		if (strstr($url, '?'))
359
		{
360
			$tb_array = explode('/', $url);
361
			$tb_end   = $tb_array[count($tb_array)-1];
362
363
			if ( ! is_numeric($tb_end))
364
			{
365
				$tb_end  = $tb_array[count($tb_array)-2];
366
			}
367
368
			$tb_array = explode('=', $tb_end);
369
			$tb_id	= $tb_array[count($tb_array)-1];
370
		}
371
		else
372
		{
373
			if (ereg("/$", $url))
374
			{
375
				$url = substr($url, 0, -1);
376
			}
377
378
			$tb_array = explode('/', $url);
379
			$tb_id	= $tb_array[count($tb_array)-1];
380
381
			if ( ! is_numeric($tb_id))
382
			{
383
				$tb_id  = $tb_array[count($tb_array)-2];
384
			}
385
		}
386
387
		if ( ! preg_match ("/^([0-9]+)$/", $tb_id))
388
		{
389
			return false;
390
		}
391
		else
392
		{
393
			return $tb_id;
394
		}
395
	}
396
397
	// --------------------------------------------------------------------
398
399
	/**
400
	 * Convert Reserved XML characters to Entities
401
	 *
402
	 * @access	public
403
	 * @param	string
404
	 * @return	string
405
	 */
406
	function convert_xml($str)
407
	{
408
		$temp = '__TEMP_AMPERSANDS__';
409
410
		$str = preg_replace("/&#(\d+);/", "$temp\\1;", $str);
411
		$str = preg_replace("/&(\w+);/",  "$temp\\1;", $str);
412
413
		$str = str_replace(array("&","<",">","\"", "'", "-"),
414
						   array("&amp;", "&lt;", "&gt;", "&quot;", "&#39;", "&#45;"),
415
						   $str);
416
417
		$str = preg_replace("/$temp(\d+);/","&#\\1;",$str);
418
		$str = preg_replace("/$temp(\w+);/","&\\1;", $str);
419
420
		return $str;
421
	}
422
423
	// --------------------------------------------------------------------
424
425
	/**
426
	 * Character limiter
427
	 *
428
	 * Limits the string based on the character count. Will preserve complete words.
429
	 *
430
	 * @access	public
431
	 * @param	string
432
	 * @param	integer
433
	 * @param	string
434
	 * @return	string
435
	 */
436
	function limit_characters($str, $n = 500, $end_char = '&#8230;')
437
	{
438
		if (strlen($str) < $n)
439
		{
440
			return $str;
441
		}
442
443
		$str = preg_replace("/\s+/", ' ', str_replace(array("\r\n", "\r", "\n"), ' ', $str));
444
445
		if (strlen($str) <= $n)
446
		{
447
			return $str;
448
		}
449
450
		$out = "";
451
		foreach (explode(' ', trim($str)) as $val)
452
		{
453
			$out .= $val.' ';
454
			if (strlen($out) >= $n)
455
			{
456
				return trim($out).$end_char;
457
			}
458
		}
459
	}
460
461
	// --------------------------------------------------------------------
462
463
	/**
464
	 * High ASCII to Entities
465
	 *
466
	 * Converts Hight ascii text and MS Word special chars
467
	 * to character entities
468
	 *
469
	 * @access	public
470
	 * @param	string
471
	 * @return	string
472
	 */
473
	function convert_ascii($str)
474
	{
475
	   $count	= 1;
476
	   $out	= '';
477
	   $temp	= array();
478
479
	   for ($i = 0, $s = strlen($str); $i < $s; $i++)
480
	   {
481
		   $ordinal = ord($str[$i]);
482
483
		   if ($ordinal < 128)
484
		   {
485
			   $out .= $str[$i];
486
		   }
487
		   else
488
		   {
489
			   if (count($temp) == 0)
490
			   {
491
				   $count = ($ordinal < 224) ? 2 : 3;
492
			   }
493
494
			   $temp[] = $ordinal;
495
496
			   if (count($temp) == $count)
497
			   {
498
				   $number = ($count == 3) ? (($temp['0'] % 16) * 4096) + (($temp['1'] % 64) * 64) + ($temp['2'] % 64) : (($temp['0'] % 32) * 64) + ($temp['1'] % 64);
499
500
				   $out .= '&#'.$number.';';
501
				   $count = 1;
502
				   $temp = array();
503
			   }
504
		   }
505
	   }
506
507
	   return $out;
508
	}
509
510
	// --------------------------------------------------------------------
511
512
	/**
513
	 * Set error message
514
	 *
515
	 * @access	public
516
	 * @param	string
517
	 * @return	void
518
	 */
519
	function set_error($msg)
520
	{
521
		log_message('error', $msg);
522
		$this->error_msg[] = $msg;
523
	}
524
525
	// --------------------------------------------------------------------
526
527
	/**
528
	 * Show error messages
529
	 *
530
	 * @access	public
531
	 * @param	string
532
	 * @param	string
533
	 * @return	string
534
	 */
535
	function display_errors($open = '<p>', $close = '</p>')
536
	{
537
		$str = '';
538
		foreach ($this->error_msg as $val)
539
		{
540
			$str .= $open.$val.$close;
541
		}
542
543
		return $str;
544
	}
545
546
}
547
// END Trackback Class
548
549
/* End of file Trackback.php */
550
/* Location: ./system/libraries/Trackback.php */