PageRenderTime 59ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/html/AppCode/expressionengine/modules/rss/mod.rss.php

https://github.com/w3bg/www.hsifin.com
PHP | 595 lines | 491 code | 56 blank | 48 comment | 43 complexity | 05d49e492f2382488c869ff1ff6f1dcc MD5 | raw file
Possible License(s): AGPL-3.0
  1. <?php
  2. /*
  3. =====================================================
  4. ExpressionEngine - by EllisLab
  5. -----------------------------------------------------
  6. http://expressionengine.com/
  7. -----------------------------------------------------
  8. Copyright (c) 2003 - 2010, EllisLab, Inc.
  9. =====================================================
  10. THIS IS COPYRIGHTED SOFTWARE
  11. PLEASE READ THE LICENSE AGREEMENT
  12. http://expressionengine.com/user_guide/license.html
  13. =====================================================
  14. File: mod.rss.php
  15. -----------------------------------------------------
  16. Purpose: RSS generating class
  17. =====================================================
  18. */
  19. if ( ! defined('EXT'))
  20. {
  21. exit('Invalid file request');
  22. }
  23. class Rss {
  24. var $debug = FALSE;
  25. /**
  26. * RSS feed
  27. *
  28. * This function fetches the channel metadata used in
  29. * the channel section of RSS feeds
  30. *
  31. * Note: The item elements are generated using the channel class
  32. */
  33. function feed()
  34. {
  35. // Make a local reference to the ExpressionEngine super object
  36. $this->EE =& get_instance();
  37. $this->EE->TMPL->encode_email = FALSE;
  38. if ($this->EE->TMPL->fetch_param('debug') == 'yes')
  39. {
  40. $this->debug = TRUE;
  41. }
  42. if ( ! $channel = $this->EE->TMPL->fetch_param('channel'))
  43. {
  44. $this->EE->lang->loadfile('rss');
  45. return $this->_empty_feed($this->EE->lang->line('no_weblog_specified'));
  46. }
  47. // Create Meta Query
  48. //
  49. // Since UTC_TIMESTAMP() is what we need, but it is not available until
  50. // MySQL 4.1.1, we have to use this ever so clever SQL to figure it out:
  51. // DATE_ADD( '1970-01-01', INTERVAL UNIX_TIMESTAMP() SECOND )
  52. // -Paul
  53. $sql = "SELECT exp_channel_titles.entry_id, exp_channel_titles.entry_date, exp_channel_titles.edit_date,
  54. GREATEST((UNIX_TIMESTAMP(exp_channel_titles.edit_date) +
  55. (UNIX_TIMESTAMP(DATE_ADD( '1970-01-01', INTERVAL UNIX_TIMESTAMP() SECOND)) - UNIX_TIMESTAMP())),
  56. exp_channel_titles.entry_date) AS last_update
  57. FROM exp_channel_titles
  58. LEFT JOIN exp_channels ON exp_channel_titles.channel_id = exp_channels.channel_id
  59. LEFT JOIN exp_members ON exp_members.member_id = exp_channel_titles.author_id
  60. WHERE exp_channel_titles.entry_id !=''
  61. AND exp_channels.site_id IN ('".implode("','", $this->EE->TMPL->site_ids)."') ";
  62. $xql = "SELECT channel_id FROM exp_channels WHERE ";
  63. $str = $this->EE->functions->sql_andor_string($channel, 'channel_name');
  64. if (substr($str, 0, 3) == 'AND')
  65. $str = substr($str, 3);
  66. $xql .= $str;
  67. $query = $this->EE->db->query($xql);
  68. if ($query->num_rows() == 0)
  69. {
  70. $this->EE->lang->loadfile('rss');;
  71. return $this->_empty_feed($this->EE->lang->line('rss_invalid_weblog'));
  72. }
  73. if ($query->num_rows() == 1)
  74. {
  75. $sql .= "AND exp_channel_titles.channel_id = '".$query->row('channel_id') ."' ";
  76. }
  77. else
  78. {
  79. $sql .= "AND (";
  80. foreach ($query->result_array() as $row)
  81. {
  82. $sql .= "exp_channel_titles.channel_id = '".$row['channel_id']."' OR ";
  83. }
  84. $sql = substr($sql, 0, - 3);
  85. $sql .= ") ";
  86. }
  87. // We only select entries that have not expired
  88. $timestamp = ($this->EE->TMPL->cache_timestamp != '') ? $this->EE->localize->set_gmt($this->EE->TMPL->cache_timestamp) : $this->EE->localize->now;
  89. if ($this->EE->TMPL->fetch_param('show_future_entries') != 'yes')
  90. {
  91. $sql .= " AND exp_channel_titles.entry_date < ".$timestamp." ";
  92. }
  93. if ($this->EE->TMPL->fetch_param('show_expired') != 'yes')
  94. {
  95. $sql .= " AND (exp_channel_titles.expiration_date = 0 OR exp_channel_titles.expiration_date > ".$timestamp.") ";
  96. }
  97. // Add status declaration
  98. $sql .= "AND exp_channel_titles.status != 'closed' ";
  99. if ($status = $this->EE->TMPL->fetch_param('status'))
  100. {
  101. $status = str_replace('Open', 'open', $status);
  102. $status = str_replace('Closed', 'closed', $status);
  103. $sql .= $this->EE->functions->sql_andor_string($status, 'exp_channel_titles.status');
  104. }
  105. else
  106. {
  107. $sql .= "AND exp_channel_titles.status = 'open' ";
  108. }
  109. // Limit to (or exclude) specific users
  110. if ($username = $this->EE->TMPL->fetch_param('username'))
  111. {
  112. // Shows entries ONLY for currently logged in user
  113. if ($username == 'CURRENT_USER')
  114. {
  115. $sql .= "AND exp_members.member_id = '".$this->EE->session->userdata['member_id']."' ";
  116. }
  117. elseif ($username == 'NOT_CURRENT_USER')
  118. {
  119. $sql .= "AND exp_members.member_id != '".$this->EE->session->userdata['member_id']."' ";
  120. }
  121. else
  122. {
  123. $sql .= $this->EE->functions->sql_andor_string($username, 'exp_members.username');
  124. }
  125. }
  126. // Find Edit Date
  127. $query = $this->EE->db->query($sql." ORDER BY last_update desc LIMIT 1");
  128. if ($query->num_rows() > 0)
  129. {
  130. $last_update = $query->row('last_update') + ($this->EE->localize->set_server_time() - $this->EE->localize->now);
  131. $edit_date = $query->row('edit_date') ;
  132. $entry_date = $query->row('entry_date') ;
  133. }
  134. $sql .= " ORDER BY exp_channel_titles.entry_date desc LIMIT 1";
  135. $query = $this->EE->db->query($sql);
  136. if ($query->num_rows() == 0)
  137. {
  138. $this->EE->lang->loadfile('rss');
  139. return $this->_empty_feed($this->EE->lang->line('no_matching_entries'));
  140. }
  141. $entry_id = $query->row('entry_id') ;
  142. $sql = "SELECT exp_channels.channel_id, exp_channels.channel_title, exp_channels.channel_url, exp_channels.channel_lang, exp_channels.channel_description,
  143. exp_channel_titles.entry_date,
  144. exp_members.email, exp_members.username, exp_members.screen_name, exp_members.url
  145. FROM exp_channel_titles
  146. LEFT JOIN exp_channels ON exp_channel_titles.channel_id = exp_channels.channel_id
  147. LEFT JOIN exp_members ON exp_members.member_id = exp_channel_titles.author_id
  148. WHERE exp_channel_titles.entry_id = '$entry_id'
  149. AND exp_channels.site_id IN ('".implode("','", $this->EE->TMPL->site_ids)."') ";
  150. $query = $this->EE->db->query($sql);
  151. foreach ($query->row_array() as $key => $val)
  152. {
  153. $$key = $val;
  154. }
  155. $request = ( ! function_exists('getallheaders')) ? array() : @getallheaders();
  156. $start_on = '';
  157. $diffe_request = false;
  158. $feed_request = false;
  159. // Check for 'diff -e' request
  160. if (isset($request['A-IM']) && stristr($request['A-IM'],'diffe') !== false)
  161. {
  162. $items_start = strpos($this->EE->TMPL->tagdata, '{exp:channel:entries');
  163. if ($items_start !== false)
  164. {
  165. // We add three, for three line breaks added later in the script
  166. $diffe_request = count(preg_split("/(\r\n)|(\r)|(\n)/", trim(substr($this->EE->TMPL->tagdata,0,$items_start)))) + 3;
  167. }
  168. }
  169. // Check for 'feed' request
  170. if (isset($request['A-IM']) && stristr($request['A-IM'],'feed') !== false)
  171. {
  172. $feed_request = true;
  173. $diffe_request = false;
  174. }
  175. // Check for the 'If-Modified-Since' Header
  176. if ($this->EE->config->item('send_headers') == 'y' && isset($request['If-Modified-Since']) && trim($request['If-Modified-Since']) != '')
  177. {
  178. $x = explode(';',$request['If-Modified-Since']);
  179. $modify_tstamp = strtotime($x['0']);
  180. // ---------------------------------------------------------
  181. // If new content *and* 'feed' or 'diffe', create start on time.
  182. // Otherwise, we send back a Not Modified header
  183. // ---------------------------------------------------------
  184. if ($last_update <= $modify_tstamp)
  185. {
  186. @header("HTTP/1.0 304 Not Modified");
  187. @header('HTTP/1.1 304 Not Modified');
  188. @exit;
  189. }
  190. else
  191. {
  192. if ($diffe_request !== false OR $feed_request !== false)
  193. {
  194. //$start_on = $this->EE->localize->set_human_time($this->EE->localize->set_server_time($modify_tstamp), FALSE);
  195. $start_on = gmdate('Y-m-d h:i A',$this->EE->localize->set_localized_time($modify_tstamp));
  196. }
  197. }
  198. }
  199. $chunks = array();
  200. $marker = 'H94e99Perdkie0393e89vqpp';
  201. if (preg_match_all("/{exp:channel:entries.+?{".'\/'."exp:channel:entries}/s", $this->EE->TMPL->tagdata, $matches))
  202. {
  203. for($i = 0; $i < count($matches['0']); $i++)
  204. {
  205. $this->EE->TMPL->tagdata = str_replace($matches['0'][$i], $marker.$i, $this->EE->TMPL->tagdata);
  206. // Remove limit if we have a start_on and dynamic_start
  207. if ($start_on != '' && stristr($matches['0'][$i],'dynamic_start="on"'))
  208. {
  209. $matches['0'][$i] = preg_replace("/limit=[\"\'][0-9]{1,5}[\"\']/", '', $matches['0'][$i]);
  210. }
  211. // Replace dynamic_start="on" parameter with start_on="" param
  212. $start_on_switch = ($start_on != '') ? 'start_on="'.$start_on.'"' : '';
  213. $matches['0'][$i] = preg_replace("/dynamic_start\s*=\s*[\"|']on[\"|']/i", $start_on_switch, $matches['0'][$i]);
  214. $chunks[$marker.$i] = $matches['0'][$i];
  215. }
  216. }
  217. // Fetch all the date-related variables
  218. // We do this here to avoid processing cycles in the foreach loop
  219. $entry_date_array = array();
  220. $gmt_date_array = array();
  221. $gmt_entry_date_array = array();
  222. $edit_date_array = array();
  223. $gmt_edit_date_array = array();
  224. $date_vars = array('date', 'gmt_date', 'gmt_entry_date', 'edit_date', 'gmt_edit_date');
  225. foreach ($date_vars as $val)
  226. {
  227. if (preg_match_all("/".LD.$val."\s+format=[\"'](.*?)[\"']".RD."/s", $this->EE->TMPL->tagdata, $matches))
  228. {
  229. for ($j = 0; $j < count($matches['0']); $j++)
  230. {
  231. $matches['0'][$j] = str_replace(LD, '', $matches['0'][$j]);
  232. $matches['0'][$j] = str_replace(RD, '', $matches['0'][$j]);
  233. switch ($val)
  234. {
  235. case 'date' : $entry_date_array[$matches['0'][$j]] = $this->EE->localize->fetch_date_params($matches['1'][$j]);
  236. break;
  237. case 'gmt_date' : $gmt_date_array[$matches['0'][$j]] = $this->EE->localize->fetch_date_params($matches['1'][$j]);
  238. break;
  239. case 'gmt_entry_date' : $gmt_entry_date_array[$matches['0'][$j]] = $this->EE->localize->fetch_date_params($matches['1'][$j]);
  240. break;
  241. case 'edit_date' : $edit_date_array[$matches['0'][$j]] = $this->EE->localize->fetch_date_params($matches['1'][$j]);
  242. break;
  243. case 'gmt_edit_date' : $gmt_edit_date_array[$matches['0'][$j]] = $this->EE->localize->fetch_date_params($matches['1'][$j]);
  244. break;
  245. }
  246. }
  247. }
  248. }
  249. foreach ($this->EE->TMPL->var_single as $key => $val)
  250. {
  251. // {channel_id}
  252. if ($key == 'channel_id')
  253. {
  254. $this->EE->TMPL->tagdata = $this->EE->TMPL->swap_var_single(
  255. $key,
  256. $channel_id,
  257. $this->EE->TMPL->tagdata
  258. );
  259. }
  260. // {encoding}
  261. if ($key == 'encoding')
  262. {
  263. $this->EE->TMPL->tagdata = $this->EE->TMPL->swap_var_single(
  264. $key,
  265. $this->EE->config->item('output_charset'),
  266. $this->EE->TMPL->tagdata
  267. );
  268. }
  269. // {channel_language}
  270. if ($key == 'channel_language')
  271. {
  272. $this->EE->TMPL->tagdata = $this->EE->TMPL->swap_var_single(
  273. $key,
  274. $channel_lang,
  275. $this->EE->TMPL->tagdata
  276. );
  277. }
  278. // {channel_description}
  279. if ($key == 'channel_description')
  280. {
  281. $this->EE->TMPL->tagdata = $this->EE->TMPL->swap_var_single(
  282. $key,
  283. $channel_description,
  284. $this->EE->TMPL->tagdata
  285. );
  286. }
  287. // {channel_url}
  288. if ($key == 'channel_url')
  289. {
  290. $this->EE->TMPL->tagdata = $this->EE->TMPL->swap_var_single(
  291. $key,
  292. $channel_url,
  293. $this->EE->TMPL->tagdata
  294. );
  295. }
  296. // {channel_name}
  297. if ($key == 'channel_name')
  298. {
  299. $this->EE->TMPL->tagdata = $this->EE->TMPL->swap_var_single(
  300. $key,
  301. $channel_title,
  302. $this->EE->TMPL->tagdata
  303. );
  304. }
  305. // {email}
  306. if ($key == 'email')
  307. {
  308. $this->EE->TMPL->tagdata = $this->EE->TMPL->swap_var_single(
  309. $key,
  310. $email,
  311. $this->EE->TMPL->tagdata
  312. );
  313. }
  314. // {url}
  315. if ($key == 'url')
  316. {
  317. $this->EE->TMPL->tagdata = $this->EE->TMPL->swap_var_single(
  318. $key,
  319. $url,
  320. $this->EE->TMPL->tagdata
  321. );
  322. }
  323. // {date}
  324. if (isset($entry_date_array[$key]))
  325. {
  326. foreach ($entry_date_array[$key] as $dvar)
  327. $val = str_replace($dvar, $this->EE->localize->convert_timestamp($dvar, $entry_date, TRUE), $val);
  328. $this->EE->TMPL->tagdata = $this->EE->TMPL->swap_var_single($key, $val, $this->EE->TMPL->tagdata);
  329. }
  330. // GMT date - entry date in GMT
  331. if (isset($gmt_entry_date_array[$key]))
  332. {
  333. foreach ($gmt_entry_date_array[$key] as $dvar)
  334. $val = str_replace($dvar, $this->EE->localize->convert_timestamp($dvar, $entry_date, FALSE), $val);
  335. $this->EE->TMPL->tagdata = $this->EE->TMPL->swap_var_single($key, $val, $this->EE->TMPL->tagdata);
  336. }
  337. if (isset($gmt_date_array[$key]))
  338. {
  339. foreach ($gmt_date_array[$key] as $dvar)
  340. $val = str_replace($dvar, $this->EE->localize->convert_timestamp($dvar, $entry_date, FALSE), $val);
  341. $this->EE->TMPL->tagdata = $this->EE->TMPL->swap_var_single($key, $val, $this->EE->TMPL->tagdata);
  342. }
  343. // parse "last edit" date
  344. if (isset($edit_date_array[$key]))
  345. {
  346. foreach ($edit_date_array[$key] as $dvar)
  347. $val = str_replace($dvar, $this->EE->localize->convert_timestamp($dvar, $edit_date, TRUE), $val);
  348. $this->EE->TMPL->tagdata = $this->EE->TMPL->swap_var_single($key, $val, $this->EE->TMPL->tagdata);
  349. }
  350. // "last edit" date as GMT
  351. if (isset($gmt_edit_date_array[$key]))
  352. {
  353. foreach ($gmt_edit_date_array[$key] as $dvar)
  354. $val = str_replace($dvar, $this->EE->localize->convert_timestamp($dvar, $this->EE->localize->timestamp_to_gmt($edit_date), FALSE), $val);
  355. $this->EE->TMPL->tagdata = $this->EE->TMPL->swap_var_single($key, $val, $this->EE->TMPL->tagdata);
  356. }
  357. // {author}
  358. if ($key == 'author')
  359. {
  360. $this->EE->TMPL->tagdata = $this->EE->TMPL->swap_var_single($val, ($screen_name != '') ? $screen_name : $username, $this->EE->TMPL->tagdata);
  361. }
  362. // {version}
  363. if ($key == 'version')
  364. {
  365. $this->EE->TMPL->tagdata = $this->EE->TMPL->swap_var_single($val, APP_VER, $this->EE->TMPL->tagdata);
  366. }
  367. // {trimmed_url} - used by Atom feeds
  368. if ($key == "trimmed_url")
  369. {
  370. $channel_url = (isset($channel_url) AND $channel_url != '') ? $channel_url : '';
  371. $channel_url = str_replace('http://', '', $channel_url);
  372. $channel_url = str_replace('www.', '', $channel_url);
  373. $ex = explode("/", $channel_url);
  374. $channel_url = current($ex);
  375. $this->EE->TMPL->tagdata = $this->EE->TMPL->swap_var_single($val, $channel_url, $this->EE->TMPL->tagdata);
  376. }
  377. }
  378. if (count($chunks) > 0)
  379. {
  380. $diff_top = ($start_on != '' && $diffe_request !== false) ? "1,".($diffe_request-1)."c\n" : '';
  381. // Last Update Time
  382. $this->EE->TMPL->tagdata = '<ee:last_update>'.$last_update."</ee:last_update>\n\n".$diff_top.trim($this->EE->TMPL->tagdata);
  383. // Diffe stuff before items
  384. if ($diffe_request !== false)
  385. {
  386. $this->EE->TMPL->tagdata = str_replace($marker.'0', "\n.\n".$diffe_request."a\n".$marker.'0', $this->EE->TMPL->tagdata);
  387. $this->EE->TMPL->tagdata = str_replace($marker.(count($chunks)-1), $marker.(count($chunks)-1)."\n.\n$\n-1\n;c\n", $this->EE->TMPL->tagdata);
  388. }
  389. foreach ($chunks as $key => $val)
  390. {
  391. $this->EE->TMPL->tagdata = str_replace($key, $val, $this->EE->TMPL->tagdata);
  392. }
  393. }
  394. // 'ed' input mode is terminated by entering a single period (.) on a line
  395. $this->EE->TMPL->tagdata = ($diffe_request !== false) ? trim($this->EE->TMPL->tagdata)."\n.\n" : trim($this->EE->TMPL->tagdata);
  396. return $this->EE->TMPL->tagdata;
  397. }
  398. // --------------------------------------------------------------------
  399. /**
  400. * Empty feed handler
  401. */
  402. function _empty_feed($error = '')
  403. {
  404. if ($error != '')
  405. {
  406. $this->EE->TMPL->log_item($error);
  407. }
  408. $empty_feed = '';
  409. if (preg_match("/".LD."if empty_feed".RD."(.*?)".LD.'\/'."if".RD."/s", $this->EE->TMPL->tagdata, $match))
  410. {
  411. if (stristr($match['1'], LD.'if'))
  412. {
  413. $match['0'] = $this->EE->functions->full_tag($match['0'], $this->EE->TMPL->tagdata, LD.'if', LD.'\/'."if".RD);
  414. }
  415. $empty_feed = substr($match['0'], strlen(LD."if empty_feed".RD), -strlen(LD.'/'."if".RD));
  416. $empty_feed = str_replace(LD.'error'.RD, $error, $empty_feed);
  417. }
  418. if ($empty_feed == '')
  419. {
  420. $empty_feed = $this->_default_empty_feed($error);
  421. }
  422. return $empty_feed;
  423. }
  424. // --------------------------------------------------------------------
  425. /**
  426. * Default empty feed
  427. */
  428. function _default_empty_feed($error = '')
  429. {
  430. $this->EE->lang->loadfile('rss');
  431. $encoding = $this->EE->config->item('charset');
  432. $title = $this->EE->config->item('site_name');
  433. $link = $this->EE->config->item('site_url');
  434. $version = APP_VER;
  435. $pubdate = date('D, d M Y H:i:s', $this->EE->localize->now).' GMT';
  436. $content = ($this->debug === TRUE && $error != '') ? $error : $this->EE->lang->line('empty_feed');
  437. return <<<HUMPTYDANCE
  438. <?xml version="1.0" encoding="{$encoding}"?>
  439. <rss version="2.0">
  440. <channel>
  441. <title>{$title}</title>
  442. <link>{$link}</link>
  443. <description></description>
  444. <docs>http://www.rssboard.org/rss-specification</docs>
  445. <generator>ExpressionEngine v{$version} http://expressionengine.com/</generator>
  446. <item>
  447. <title>{$content}</title>
  448. <description>{$content}</description>
  449. <pubDate>{$pubdate}</pubDate>
  450. </item>
  451. </channel>
  452. </rss>
  453. HUMPTYDANCE;
  454. }
  455. /* END */
  456. }
  457. // END CLASS
  458. /* End of file mod.rss.php */
  459. /* Location: ./system/expressionengine/modules/rss/mod.rss.php */