PageRenderTime 26ms CodeModel.GetById 29ms RepoModel.GetById 1ms app.codeStats 0ms

/rssr/view.php

https://github.com/PM2D/G3
PHP | 168 lines | 127 code | 15 blank | 26 comment | 33 complexity | dfa305824402f27d39e120bb229765cc MD5 | raw file
  1. <?php
  2. // This file is a part of GIII (g3.steelwap.org)
  3. require($_SERVER['DOCUMENT_ROOT'].'/etc/main.php');
  4. $n =& getvar('n');
  5. $n = intval($n);
  6. $id =& getvar('i');
  7. $id = intval($id) - 1;
  8. $arr = file($_SERVER['DOCUMENT_ROOT'].'/var/rssr.dat');
  9. if (!isset($arr[$id])) raise_error('No feed?');
  10. $arr = explode('|', $arr[$id]);
  11. $file = $_SERVER['DOCUMENT_ROOT'].'/var/cache/rss/'.abs(crc32($arr[0])).'.dat';
  12. if (file_exists($file)) {
  13. $mtime = filemtime($file);
  14. } else {
  15. $mtime = 0;
  16. }
  17. $ttl = $arr[2];
  18. if ($mtime < $TIME-$ttl) {
  19. $url = parse_url('http://'.$arr[0]);
  20. if (!isset($url['query'])) $url['query'] = NULL;
  21. // создаем новое подключение
  22. $http = new httpquery($url['host'], $url['path'].'?'.$url['query']);
  23. // добавляем для прикола user-agent и отправляем GET-запрос
  24. $http->sendHeaders['User-Agent'] = 'G3-RSSReader/2.0.2';
  25. $http->SendQuery();
  26. // слушаем ответ
  27. $http->GetResponse();
  28. // закрываем подключение
  29. $http->Close();
  30. $data = $http->responseData;
  31. if (strpos($data, 'g="windows-1251"')) {
  32. $data = strtr($data, array('g="windows-1251"'=>'g="UTF-8"'));
  33. $data = iconv('Windows-1251', 'UTF-8', $data);
  34. }
  35. // Известно 2 способа записи html кода в текст новости без нарушений правил xml:
  36. // 1. через замену тегов на коды символов вроде &gt;
  37. // 2. запись текста новости внутри CDATA
  38. // Если нет CDATA, то пробуем добавить CDATA в description
  39. // и возвращаем нормальные теги, если html код был записан по 1 способу
  40. if(!strpos($data, 'CDATA'))
  41. $data = strtr($data, array(
  42. '<description>'=>'<description><![CDATA[',
  43. '</description>'=>']]></description>',
  44. '&lt;'=>'<',
  45. '&gt;'=>'>',
  46. '&amp;'=>'&',
  47. '&quot;'=>'"'
  48. ));
  49. // target нет в спецификации wml и xhtml-mobile
  50. $data = strtr($data, array('target=_blank'=>NULL));
  51. // подправляем некоторые теги и ссылки
  52. $data = strtr($data, array(
  53. '<br>'=>'<br/>',
  54. '<li>'=>'<br/>&middot; ',
  55. '"http:'=>'"/go.php?http:',
  56. '\'http:'=>'\'/go.php?http:'
  57. ));
  58. // для картинок отправляем на ресайзер
  59. $data = strtr($data, array('src="/go.php?'=>'src="img.php?'));
  60. // мега костыль для тех лент, которые не используют нормальные &amp;
  61. $data = preg_replace('/&([a-z]*([\s=]|$))/', '&amp;\\1', $data);
  62. // на всякий случай
  63. $data = trim($data);
  64. if(!$data) throw new Exception('No data in '.$url['host'].$url['path'].'?'.$url['query']);
  65. // парсим xml в массив
  66. // может и не самый лучший способ, но работает нормально (вроде :))
  67. $xml = new XMLReader;
  68. $xml->XML($data);
  69. $arr = array();
  70. $i = 0;
  71. while ($xml->read()) {
  72. if ($xml->name == 'item' && $xml->nodeType == XMLReader::ELEMENT) {
  73. while ($xml->read() && $xml->name != 'item') {
  74. if ($xml->name[0]!='#') $name = $xml->name;
  75. if ($xml->nodeType == XMLReader::TEXT || $xml->nodeType == XMLReader::CDATA) {
  76. $arr[$i][$name] = strip_tags($xml->value, '<a><img><br/>');
  77. }
  78. }
  79. $i++;
  80. }
  81. }
  82. $xml->close();
  83. // сохраняем все это в кеш (файл)
  84. $f = fopen($file, 'w');
  85. fwrite($f, serialize($arr));
  86. //chmod($file, 0666);
  87. fclose($f);
  88. unset($data);
  89. }
  90. // Debug
  91. // $arr = unserialize(file_get_contents($file)); print_r($arr); exit;
  92. $tmpl = new template;
  93. // правильное кэширование
  94. header('Expires: '.gmdate('D, d M Y H:i:s', $TIME + $ttl).' GMT');
  95. if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
  96. if (strtotime(substr($_SERVER['HTTP_IF_MODIFIED_SINCE'], 5)) >= $mtime) {
  97. header('HTTP/1.1 304 Not Modified', 304, TRUE); exit;
  98. }
  99. }
  100. header('Last-Modified: '.gmdate('D, d M Y H:i:s', $mtime).' GMT', TRUE);
  101. $tmpl->SendHeaders();
  102. header('Cache-Control: public', TRUE);
  103. $compress->Enable();
  104. $tmpl->Vars['TITLE'] = 'Просмотр новостной ленты';
  105. $tmpl->Vars['LIST'] = array();
  106. $arr = unserialize(file_get_contents($file));
  107. // если это не просмотр одной отдельной новости то используем цикл
  108. if (!isset($_GET['e'])) {
  109. $tmpl->Vars['VIEWONE'] = FALSE;
  110. $total = sizeof($arr);
  111. $arr = array_slice($arr, $n, $USER['np']);
  112. $cnt = sizeof($arr);
  113. for ($i=0; $i<$cnt; $i++) {
  114. // чтобы не было ошибок, если канал не содержит некоторых данных, используем пустые
  115. if (!isset($arr[$i]['description'])) $arr[$i]['description'] = NULL;
  116. if (!isset($arr[$i]['pubDate'])) $arr[$i]['pubDate'] = NULL;
  117. if (!isset($arr[$i]['link'])) $arr['link'] = NULL;
  118. // обрезаем новость если слишком длинная
  119. if (isset($arr[$i]['description'][520])) {
  120. $arr[$i]['description'] = mb_substr($arr[$i]['description'], 0, 255, 'UTF-8');
  121. $arr[$i]['description'] = strip_tags($arr[$i]['description'], '<br/><img>');
  122. $arr[$i]['description'] = preg_replace('/&([a-z]){0,6}$/', NULL, $arr[$i]['description']);
  123. $arr[$i]['description'] .= '...';
  124. $arr[$i]['more'] = 'view.php?i='.($id+1).'&amp;e='.($i+$n).'&amp;'.SID;
  125. } else {
  126. $arr[$i]['more'] = FALSE;
  127. }
  128. }
  129. $tmpl->Vars['LIST'] = $arr;
  130. $tmpl->UseNav();
  131. $tmpl->Vars['NAV']['pos'] = $n;
  132. $tmpl->Vars['NAV']['total'] = $total;
  133. $tmpl->Vars['NAV']['limit'] = $USER['np'];
  134. $tmpl->Vars['NAV']['add'] = 'i='.($id+1);
  135. $tmpl->Vars['NEXT'] = FALSE;
  136. $tmpl->Vars['PREV'] = FALSE;
  137. // вывод только одной новости полностью
  138. } else {
  139. $item = intval($_GET['e']);
  140. $tmpl->Vars['VIEWONE'] = TRUE;
  141. $tmpl->Vars['FEEDID'] = $id+1;
  142. $tmpl->Vars['BACK'] = $item;
  143. $tmpl->Vars['NEXT'] = isset($arr[$item+1]) ? ($item+1) : FALSE;
  144. $tmpl->Vars['PREV'] = isset($arr[$item-1]) ? ($item-1) : FALSE;
  145. $arr = $arr[$item];
  146. if (!isset($arr['link'])) $arr['link'] = NULL;
  147. if (!isset($arr[$item]['pubDate'])) $arr[$item]['pubDate'] = NULL;
  148. $arr['more'] = FALSE;
  149. $tmpl->Vars['LIST'][] = $arr;
  150. }
  151. $online->Add('Читaeт rss-лeнту');
  152. echo $tmpl->Parse('rssr/view.tmpl');
  153. ?>