PageRenderTime 42ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/modules/mod_jw_srfr/helper.php

https://bitbucket.org/pastor399/newcastleunifc
PHP | 291 lines | 83 code | 28 blank | 180 comment | 15 complexity | 039e42def32adaa17e530ecbeb30bd29 MD5 | raw file
  1. <?php
  2. /**
  3. * @version 3.0
  4. * @package Simple RSS Feed Reader (module)
  5. * @author JoomlaWorks - http://www.joomlaworks.net
  6. * @copyright Copyright (c) 2006 - 2013 JoomlaWorks Ltd. All rights reserved.
  7. * @license GNU/GPL license: http://www.gnu.org/copyleft/gpl.html
  8. */
  9. // no direct access
  10. defined('_JEXEC') or die('Restricted access');
  11. class SimpleRssFeedReaderHelper {
  12. function getFeeds($feedsArray,$totalFeedItems,$perFeedItems,$feedTimeout,$dateFormat,$wordLimit,$cacheLocation,$cacheTime,$imageHandling,$riWidth){
  13. /*
  14. Legend for '$imageHandling':
  15. 0 - no images
  16. 1 - fetch first image only and hide others
  17. 2 - fetch and resize first image only and hide others
  18. */
  19. // API
  20. $mainframe = JFactory::getApplication();
  21. $cacheTime = $cacheTime*60;
  22. // Check if the cache folder exists
  23. $cacheFolderPath = JPATH_SITE.DS.$cacheLocation;
  24. if(file_exists($cacheFolderPath) && is_dir($cacheFolderPath)){
  25. // all OK
  26. } else {
  27. mkdir($cacheFolderPath);
  28. }
  29. $feeds = self::multiRequest($feedsArray,$cacheTime);
  30. $parsedFeeds = self::parseFeeds($feeds);
  31. $feedItemsArray = array();
  32. foreach($parsedFeeds as $feed){
  33. foreach($feed->feedItems as $key=>$item){
  34. // Create an object to store feed elements
  35. $feedElements[$key] = new JObject;
  36. $feedElements[$key]->itemTitle = $item->title;
  37. $feedElements[$key]->itemLink = $item->link;
  38. $feedElements[$key]->itemDate = strftime($dateFormat,strtotime($item->pubDate));
  39. $feedElements[$key]->itemDateRSS = $item->pubDate;
  40. $feedElements[$key]->itemDescription = $item->description;
  41. $feedElements[$key]->feedImageSrc = '';
  42. $feedElements[$key]->feedTitle = self::wordLimiter($feed->feedTitle,10);
  43. $feedElements[$key]->feedURL = $feed->feedSubscribeUrl;
  44. $feedElements[$key]->siteURL = $feed->feedLink;
  45. // Give each feed an index based on date
  46. $itemDateIndex = strftime('%Y%m%d%H%M',strtotime($item->pubDate));
  47. // Pass all feed objects to an array
  48. $feedItemsArray[$itemDateIndex] = $feedElements[$key];
  49. }
  50. }
  51. // Reverse sort by key (=feed date)
  52. krsort($feedItemsArray);
  53. // Limit output
  54. $outputArray = array();
  55. $counter = 0;
  56. foreach($feedItemsArray as $feedItem){
  57. if($counter>=$totalFeedItems) continue;
  58. // Clean up the feed title
  59. $feedItem->itemTitle = trim(htmlentities($feedItem->itemTitle, ENT_QUOTES, 'utf-8'));
  60. // Determine if an image reference exists in the feed description
  61. if($imageHandling==1 || $imageHandling==2){
  62. $feedImage = self::getFirstImage($feedItem->itemDescription);
  63. // If it does, copy, resize and store it locally
  64. if(isset($feedImage) && $feedImage['ext']){
  65. // first remove the img tag from the description
  66. $feedItem->itemDescription = str_replace($feedImage['tag'],'',trim($feedItem->itemDescription));
  67. // then resize and/or assign to variable
  68. if($imageHandling==2){
  69. $feedItem->feedImageSrc = 'http://src'.rand(1,6).'.sencha.io/'.$riWidth.'/'.$feedImage['src'];
  70. } else {
  71. $feedItem->feedImageSrc = $feedImage['src'];
  72. }
  73. } else {
  74. $feedItem->feedImageSrc = '';
  75. }
  76. }
  77. // Strip out images from the description
  78. $feedItem->itemDescription = preg_replace("#<img.+?>#s","",$feedItem->itemDescription);
  79. // Word limit
  80. if($wordLimit){
  81. $feedItem->itemDescription = self::wordLimiter($feedItem->itemDescription,$wordLimit);
  82. }
  83. $outputArray[] = $feedItem;
  84. $counter++;
  85. }
  86. return $outputArray;
  87. }
  88. // Get array of feeds
  89. function multiRequest($data,$cacheTime) {
  90. // Set max_execution_time to 120
  91. ini_set('max_execution_time',120);
  92. $cacheTime = $cacheTime*60;
  93. $result = array();
  94. foreach ($data as $id => $url) {
  95. $feed = self::getFile($url,$cacheTime,$subFolderName='feeds');
  96. $result[$id] = JFile::read($feed);
  97. }
  98. return $result;
  99. }
  100. // Parse array of feeds
  101. function parseFeeds($feeds){
  102. $feedContents = array();
  103. foreach($feeds as $key=>$feed){
  104. libxml_use_internal_errors(true);
  105. $xml = simplexml_load_string($feed);
  106. if(is_object($xml) && $items = $xml->xpath("/rss/channel/item")) {
  107. $feedContents[$key]->feedSubscribeUrl = $feed;
  108. $feedContents[$key]->feedTitle = $xml->channel->title;
  109. $feedContents[$key]->feedLink = $xml->channel->link;
  110. $feedContents[$key]->feedPubDate = $xml->channel->pubDate;
  111. $feedContents[$key]->feedDescription = $xml->channel->description;
  112. foreach($items as $item){
  113. $feedContents[$key]->feedItems[] = $item;
  114. }
  115. } elseif(is_object($xml) && $items = $xml->xpath("/*[local-name()='feed' and namespace-uri()='http://www.w3.org/2005/Atom'] /*[local-name()='entry' and namespace-uri()='http://www.w3.org/2005/Atom']")) {
  116. $feedContents[$key]->feedSubscribeUrl = $feed;
  117. $feedContents[$key]->feedTitle = (string)$xml->title;
  118. $feedContents[$key]->feedLink = (string)$xml->link->attributes()->href;
  119. $feedContents[$key]->feedPubDate = (string)$xml->updated;
  120. $feedContents[$key]->feedDescription = (string)$xml->subtitle;
  121. foreach ($items as $item) {
  122. $tmp = new stdClass();
  123. $tmp->title = (string)$item->title;
  124. $tmp->link = (string)$item->link->attributes()->href;
  125. $tmp->pubDate = (string)$item->updated;
  126. $tmp->description = (!empty($item->content)) ? $item->content:$item->summary;
  127. $tmp->author = (string)$item->author->name;
  128. $feedContents[$key]->feedItems[] = $tmp;
  129. }
  130. }
  131. }
  132. return $feedContents;
  133. }
  134. // Word Limiter
  135. function wordLimiter($str,$limit=100,$end_char='[&#8230;]'){
  136. if (trim($str) == '') return $str;
  137. $str = strip_tags($str);
  138. preg_match('/\s*(?:\S*\s*){'. (int) $limit .'}/', $str, $matches);
  139. if (strlen($matches[0]) == strlen($str)) $end_char = '';
  140. return rtrim($matches[0]).$end_char;
  141. }
  142. // Grab the first image in a string
  143. function getFirstImage($string){
  144. // find images
  145. $regex = "#<img.+?>#s";
  146. if (preg_match_all($regex, $string, $matches, PREG_PATTERN_ORDER) > 0){
  147. $img = array();
  148. // Entire <img> tag
  149. $img['tag'] = $matches[0][0];
  150. // Image src
  151. if(preg_match("#src=\".+?\"#s",$img['tag'],$imgSrc)){
  152. $img['src'] = str_replace('src="','',$imgSrc[0]);
  153. $img['src'] = str_replace('"','',$img['src']);
  154. } else {
  155. $img['src'] = false;
  156. }
  157. // Is this a real content image?
  158. if(preg_match("#\.(jpg|jpeg|png|gif|bmp)#s",strtolower($img['src']),$imgExt)){
  159. $img['ext'] = true;
  160. } else {
  161. $img['ext'] = false;
  162. }
  163. return $img;
  164. }
  165. }
  166. // Get remote file
  167. function getFile($url, $cacheTime=3600, $subFolderName='', $extensionName='mod_jw_srfr'){
  168. jimport('joomla.filesystem.file');
  169. // Check cache folder
  170. if($subFolderName){
  171. $cacheFolderPath = JPATH_SITE.DS.'cache'.DS.$extensionName.DS.$subFolderName;
  172. } else {
  173. $cacheFolderPath = JPATH_SITE.DS.'cache'.DS.$extensionName;
  174. }
  175. if(file_exists($cacheFolderPath) && is_dir($cacheFolderPath)){
  176. // all OK
  177. } else {
  178. mkdir($cacheFolderPath);
  179. }
  180. $url = trim($url);
  181. if(substr($url,0,4)=="http"){
  182. $turl = explode("?", $url);
  183. $matchComponents = array("#(http|https)\:\/\/#s","#www\.#s");
  184. $replaceComponents = array("","");
  185. $turl = preg_replace($matchComponents,$replaceComponents,$turl[0]);
  186. $turl = str_replace(array("/","-","."),array("_","_","_"),$turl);
  187. $tmpFile = $cacheFolderPath.DS.urlencode($turl).'.cache';
  188. } else {
  189. $tmpFile = $cacheFolderPath.DS.'cached_'.md5($url);
  190. }
  191. // Check if a cached copy exists otherwise create it
  192. if(file_exists($tmpFile) && is_readable($tmpFile) && (filemtime($tmpFile)+$cacheTime) > time()){
  193. $result = $tmpFile;
  194. } else {
  195. // Get file
  196. if(substr($url,0,4)=="http"){
  197. // remote file
  198. if(ini_get('allow_url_fopen')){
  199. // file_get_contents
  200. $fgcOutput = JFile::read($url);
  201. // cleanup the content received
  202. $fgcOutput = preg_replace("#(\n|\r|\s\s+|<!--(.*?)-->)#s", "", $fgcOutput);
  203. $fgcOutput = preg_replace("#(\t)#s", " ", $fgcOutput);
  204. JFile::write($tmpFile,$fgcOutput);
  205. } elseif(in_array('curl',get_loaded_extensions())) {
  206. // cURL
  207. $ch = curl_init();
  208. curl_setopt($ch, CURLOPT_URL, $url);
  209. curl_setopt($ch, CURLOPT_HEADER, false);
  210. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
  211. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  212. $chOutput = curl_exec($ch);
  213. curl_close($ch);
  214. JFile::write($tmpFile,$chOutput);
  215. } else {
  216. // fsockopen
  217. $readURL = parse_url($url);
  218. $relativePath = (isset($readURL['query'])) ? $readURL['path']."?".$readURL['query'] : $readURL['path'];
  219. $fp = fsockopen($readURL['host'], 80, $errno, $errstr, 5);
  220. if (!$fp) {
  221. JFile::write($tmpFile,'');
  222. } else {
  223. $out = "GET ".$relativePath." HTTP/1.1\r\n";
  224. $out .= "Host: ".$readURL['host']."\r\n";
  225. $out .= "Connection: Close\r\n\r\n";
  226. fwrite($fp, $out);
  227. $header = '';
  228. $body = '';
  229. do { $header .= fgets($fp,128); } while (strpos($header,"\r\n\r\n")=== false); // get the header data
  230. while (!feof($fp)) $body .= fgets($fp,128); // get the actual content
  231. fclose($fp);
  232. JFile::write($tmpFile,$body);
  233. }
  234. }
  235. $result = $tmpFile;
  236. } else {
  237. // local file
  238. $result = $url;
  239. }
  240. }
  241. return $result;
  242. }
  243. } // END CLASS