PageRenderTime 55ms CodeModel.GetById 8ms RepoModel.GetById 0ms app.codeStats 0ms

/system/libraries/Trackback.php

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