PageRenderTime 46ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/system/libraries/Trackback.php

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