PageRenderTime 57ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/application/controllers/helpers/Updater.php

https://bitbucket.org/skuda/rsslounge
PHP | 295 lines | 171 code | 45 blank | 79 comment | 18 complexity | 7b9426f4d26df522328030649cad607c MD5 | raw file
  1. <?PHP
  2. /**
  3. * Helper class for refresh the feeds (search and fetch new items)
  4. *
  5. * @package application_controllers
  6. * @subpackage helpers
  7. * @copyright Copyright (c) Tobias Zeising (http://www.aditu.de)
  8. * @license GPLv3 (http://www.gnu.org/licenses/gpl-3.0.html)
  9. */
  10. class Helper_Updater extends Zend_Controller_Action_Helper_Abstract {
  11. /**
  12. * updates a given feed
  13. * returns an error or true on success
  14. *
  15. * @return int timestamp for this refresh
  16. * @param mixed $feed current feed model
  17. */
  18. public function feed($feed) {
  19. @set_time_limit(Zend_Registry::get('config')->rss->timelimit);
  20. @error_reporting(E_ERROR);
  21. // logging
  22. $logger = Zend_Registry::get('logger');
  23. $logger->log('start feed fetching "' . $feed->name.'"', Zend_Log::DEBUG);
  24. // get feed plugin
  25. $logger->log('load feed plugin', Zend_Log::DEBUG);
  26. $messagesModel = new application_models_messages();
  27. $plugin = Zend_Controller_Action_HelperBroker::getStaticHelper('pluginloader')->getPlugin($feed->source);
  28. if($plugin===false) {
  29. $logger->log('error loading feed plugin ' . $feed->source, Zend_Log::ERR);
  30. return $messagesModel->add($feed, 'unknown plugin');
  31. }
  32. // receive new content
  33. $logger->log('load feed content', Zend_Log::DEBUG);
  34. try {
  35. $plugin->load($feed->url);
  36. } catch(Exception $e) {
  37. $logger->log('error loading feed content: ' . $e->getMessage(), Zend_Log::ERR);
  38. return $messagesModel->add($feed, $e->getMessage());
  39. }
  40. // update html url of the feed
  41. $feed->htmlurl = $plugin->getHtmlUrl();
  42. $feed->save();
  43. // current date
  44. $now = Zend_Date::now();
  45. $now->sub(Zend_Registry::get('session')->deleteItems, Zend_Date::DAY);
  46. $logger->log('current date ' . $now, Zend_Log::DEBUG);
  47. // include htmLawed
  48. if(!function_exists('htmLawed'))
  49. require(Zend_Registry::get('config')->includePaths->library . '/htmLawed.php');
  50. // insert new items in database
  51. $logger->log('start item fetching', Zend_Log::DEBUG);
  52. $itemsModel = new application_models_items();
  53. foreach ($plugin as $item) {
  54. // test date: continue with next if item too old
  55. $date = new Zend_Date($item->getDate(), Zend_Date::ISO_8601);
  56. if($now->compare($date)==1 && Zend_Registry::get('session')->deleteItems!=0) {
  57. $logger->log('item "' . $item->getTitle() . '" (' . $date . ') older than '.Zend_Registry::get('session')->deleteItems.' days', Zend_Log::DEBUG);
  58. continue;
  59. }
  60. // filter match?
  61. try {
  62. if($this->filter($feed, $item)===false)
  63. continue;
  64. } catch(Exception $e) {
  65. $messagesModel->add($feed, 'filter error');
  66. continue;
  67. }
  68. // item already in database?
  69. if($this->itemExists($item)===true)
  70. continue;
  71. // insert new item
  72. $logger->log('---', Zend_Log::DEBUG);
  73. $logger->log('start insertion of new item "'.$item->getTitle().'"', Zend_Log::DEBUG);
  74. // sanitize content html
  75. $content = htmLawed(
  76. $item->getContent(),
  77. array(
  78. "safe" => 1,
  79. "deny_attribute" => Zend_Registry::get('config')->rss->allowed->deniedattribs,
  80. "keep_bad" => 0,
  81. "comment" => 1,
  82. "cdata" => 1,
  83. "elements" => Zend_Registry::get('config')->rss->allowed->tags
  84. )
  85. );
  86. $title = htmLawed($item->getTitle(), array("deny_attribute" => "*", "elements" => "-*"));
  87. $logger->log('item content sanitized', Zend_Log::DEBUG);
  88. $nitem = array(
  89. 'title' => $title,
  90. 'content' => $content,
  91. 'feed' => $feed->id,
  92. 'unread' => 1,
  93. 'starred' => 0,
  94. 'datetime' => $item->getDate(),
  95. 'uid' => $item->getId(),
  96. 'link' => htmLawed($item->getLink(), array("deny_attribute" => "*", "elements" => "-*"))
  97. );
  98. $logger->log('item in database inserted', Zend_Log::DEBUG);
  99. // multimedia item: get and save thumbnail
  100. if($plugin->multimedia) {
  101. try {
  102. // download and generate thumbnail
  103. $thumbnail = $this->generateThumbnail($item->getThumbnail());
  104. $logger->log('thumbnail "'.$thumbnail.'" generated', Zend_Log::DEBUG);
  105. // set thumbnailpath as content
  106. $nitem = array_merge(
  107. $nitem,
  108. array(
  109. 'content' => $thumbnail
  110. )
  111. );
  112. } catch(Exception $e) {
  113. $logger->log('thumbnail error ' . $e->getMessage(), Zend_Log::ERR);
  114. $messagesModel->add($feed, $e->getMessage());
  115. continue;
  116. }
  117. }
  118. // insert new item
  119. $itemsModel->insert($nitem);
  120. $logger->log('item inserted', Zend_Log::DEBUG);
  121. }
  122. // success: set lastrefresh
  123. $feed->lastrefresh = Zend_Date::now()->get(Zend_Date::TIMESTAMP);
  124. $feed->error = 0;
  125. $feed->save();
  126. // cleanup old items
  127. $logger->log('cleanup old items', Zend_Log::DEBUG);
  128. $this->cleanupOldItems();
  129. // cleanup old message items
  130. $messagesModel->cleanup();
  131. // destroy feed object (prevent memory issues)
  132. $logger->log('destroy feed object', Zend_Log::DEBUG);
  133. $plugin->destroy();
  134. return $feed->lastrefresh;
  135. }
  136. /**
  137. * clean up orphaned thumbnails
  138. *
  139. * @return void
  140. */
  141. public function cleanupThumbnails() {
  142. $itemsModel = new application_models_items();
  143. $itemsModel->cleanupThumbnails();
  144. }
  145. /**
  146. * clean up old items
  147. *
  148. * @return void
  149. */
  150. public function cleanupOldItems() {
  151. if(Zend_Registry::get('session')->deleteItems==0)
  152. return;
  153. $itemsModel = new application_models_items();
  154. $date = Zend_Date::now();
  155. $date->sub(Zend_Registry::get('session')->deleteItems, Zend_Date::DAY);
  156. $itemsModel->delete(
  157. $itemsModel->getAdapter()->quoteInto('starred=0 AND datetime<?', $date->toString('YYYY-MM-dd') . ' 00:00:00')
  158. );
  159. }
  160. /**
  161. * set timeout in the session and
  162. * returns the timeout for the next refresh
  163. *
  164. * @return int timeout
  165. */
  166. public function timeout() {
  167. // load lastrefresh from database
  168. $settings = new application_models_settings();
  169. $lastrefresh = $settings->get('lastrefresh');
  170. if($lastrefresh!==false)
  171. Zend_Registry::get('session')->lastrefresh = $lastrefresh;
  172. // no lastrefresh set
  173. if(Zend_Registry::get('session')->lastrefresh==0)
  174. Zend_Registry::get('session')->timeout = 0;
  175. else {
  176. // calc seconds between now and last refresh
  177. $now = Zend_Date::now();
  178. $last = new Zend_Date();
  179. $last->set(Zend_Registry::get('session')->lastrefresh,Zend_Date::TIMESTAMP);
  180. $diff = $now->sub($last)->toValue();
  181. $diff = (Zend_Registry::get('session')->refresh*60) - $diff;
  182. // set timeout 0 if refresh intervall was exceed
  183. if($diff<0)
  184. $diff = 0;
  185. // set timeout in session
  186. Zend_Registry::get('session')->timeout = $diff;
  187. }
  188. return Zend_Registry::get('session')->timeout;
  189. }
  190. /**
  191. * download and create thumbnail
  192. *
  193. * @return string generated filename
  194. * @param string $thumbnail url of the target image
  195. */
  196. protected function generateThumbnail($thumbnail) {
  197. // target filename
  198. $thumbnailFile = Zend_Registry::get('config')->thumbnails->path . md5($thumbnail);
  199. // load, resize and save
  200. $image = WideImage::load($thumbnail)
  201. ->resize(
  202. Zend_Registry::get('config')->thumbnails->width,
  203. Zend_Registry::get('config')->thumbnails->height)
  204. ->saveToFile(
  205. $thumbnailFile . '.jpg'
  206. );
  207. return md5($thumbnail) . '.jpg';
  208. }
  209. /**
  210. * check whether filter match or not
  211. *
  212. * @return boolean true if filter match, false if not
  213. * @param Zend_Db_Table_Row $feed the current feed
  214. * @param mixed the current item
  215. */
  216. protected function filter($feed, $item) {
  217. if(strlen(trim($feed->filter))!=0) {
  218. $resultTitle = @preg_match($feed->filter, $item->getTitle());
  219. $resultContent = @preg_match($feed->filter, $item->getContent());
  220. // wrong filter
  221. if($resultTitle===false || $resultContent===false) {
  222. Zend_Registry::get('logger')->log('filter error ' . $feed->filter, Zend_Log::ERR);
  223. throw new Exception();
  224. }
  225. // test filter
  226. if($resultTitle==0 && $resultContent==0)
  227. return false;
  228. }
  229. return true;
  230. }
  231. /**
  232. * item still in database?
  233. *
  234. * @return boolean true if item is already in database
  235. * @param mixed the current item
  236. */
  237. protected function itemExists($item) {
  238. $itemsModel = new application_models_items();
  239. $res = $itemsModel->fetchAll(
  240. $itemsModel->select()
  241. ->from($itemsModel, array('amount' => 'Count(*)'))
  242. ->where('uid="'.$item->getId().'"')
  243. );
  244. if($res[0]['amount']>0) {
  245. Zend_Registry::get('logger')->log('item "' . $item->getTitle() . '" already fetched', Zend_Log::DEBUG);
  246. return true;
  247. }
  248. return false;
  249. }
  250. }