PageRenderTime 77ms CodeModel.GetById 41ms RepoModel.GetById 1ms app.codeStats 0ms

/application/controllers/helpers/Icon.php

https://bitbucket.org/skuda/rsslounge
PHP | 289 lines | 143 code | 49 blank | 97 comment | 33 complexity | baad85e81128ba538ea7916f711fd027 MD5 | raw file
  1. <?PHP
  2. /**
  3. * Helper class for fetching and saving an icon
  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_Icon extends Zend_Controller_Action_Helper_Abstract {
  11. protected $iconPositions = false;
  12. /**
  13. * generate one big image containing all icons
  14. * instead of loading hundreds of icons, just
  15. * one file is necessary
  16. *
  17. * @return string target path
  18. */
  19. public function generateIconImage() {
  20. if(Zend_Registry::get('config')->cache->enable!=1 || Zend_Registry::get('config')->cache->iconcaching!=1)
  21. return "";
  22. $target = Zend_Registry::get('config')->favicons->path . Zend_Registry::get('config')->cache->icons;
  23. if(file_exists($target))
  24. return $target;
  25. // get all feeds
  26. $feedModel = new application_models_feeds();
  27. $feeds = $feedModel->fetchAll( $feedModel->select()->order('id ASC') );
  28. // generate big feed image
  29. $bigIconImage = imagecreatetruecolor(16,16*$feeds->count());
  30. imagealphablending($bigIconImage,false);
  31. imagesavealpha($bigIconImage,true);
  32. // insert icons into feed image
  33. $count = 0;
  34. // $reporting = error_reporting();
  35. // error_reporting(0);
  36. foreach($feeds as $feed) {
  37. $icon = false;
  38. // load icon file
  39. if(file_exists(Zend_Registry::get('config')->favicons->path . $feed->icon)) {
  40. $icon = $this->loadIconFileFromFilesystem(Zend_Registry::get('config')->favicons->path . $feed->icon);
  41. // no icon file? load default icon
  42. } else if(strpos($feed->icon,'plugins')!==false) {
  43. $lastslash = strrpos($feed->icon, '/');
  44. $file = substr($feed->icon, 0, $lastslash) . '/public' . substr($feed->icon, $lastslash);
  45. $icon = $this->loadIconFileFromFilesystem(APPLICATION_PATH.'/../'.$file);
  46. }
  47. // no default icon: create empty image
  48. if($icon===false)
  49. $icon = $this->loadIconFileFromFilesystem(APPLICATION_PATH.'/../plugins/rss/public/icon.ico');
  50. // resize and copy
  51. imagecopyresampled($bigIconImage, $icon, 0, $count*16, 0, 0, 16, 16, imagesx($icon), imagesy($icon));
  52. // merge
  53. imagedestroy($icon);
  54. $count++;
  55. }
  56. // error_reporting($reporting);
  57. //header('Content-type: image/png');
  58. imagepng($bigIconImage, $target);
  59. return $target;
  60. }
  61. /**
  62. * renew icon image
  63. *
  64. * @return string target path
  65. */
  66. public function resetIconImage() {
  67. $target = Zend_Registry::get('config')->favicons->path . Zend_Registry::get('config')->cache->icons;
  68. if(file_exists($target))
  69. unlink($target);
  70. return $this->generateIconImage();
  71. }
  72. /**
  73. * return feed positions
  74. *
  75. * @return array of feed positions
  76. */
  77. public function getFeedsIconPosition() {
  78. if($this->iconPositions == false) {
  79. $feedsModel = new application_models_feeds();
  80. $feeds = $feedsModel->fetchAll( $feedsModel->select()->order('id ASC') );
  81. $feedPositions = array();
  82. $count = 0;
  83. foreach($feeds as $feed)
  84. $feedPositions[$feed->id] = $count++;
  85. $this->iconPositions = $feedPositions;
  86. }
  87. return $this->iconPositions;
  88. }
  89. /**
  90. * loads icon using given url and stores it in a given path
  91. *
  92. * -> first search on given url (for <link rel="... tag)
  93. * -> then on domain url (for <link rel="... tag)
  94. * -> then favicon.ico file
  95. *
  96. * @return string|bool the filename of the new generated file, false if no icon was found
  97. * @param string $url source url
  98. * @param string $path target path
  99. */
  100. public function load($url, $path) {
  101. // search on given url
  102. $result = $this->searchAndDownloadIcon($url, $path);
  103. if($result!==false)
  104. return $result;
  105. // search on base page for <link rel="shortcut icon" url...
  106. $url = parse_url($url);
  107. $url = $url['scheme'] . '://'.$url['host'] . '/';
  108. $result = $this->searchAndDownloadIcon($url, $path);
  109. if($result!==false)
  110. return $result;
  111. // search domain/favicon.ico
  112. if(@file_get_contents($url . 'favicon.ico')!==false)
  113. return $this->loadIconFile($url . 'favicon.ico', $path);
  114. return false;
  115. }
  116. /**
  117. * downloads an icon file from given url in given path
  118. *
  119. * @return string|bool filename of the new icon, false on failure
  120. * @param string $url the url of the icon
  121. * @param string $path the target path
  122. */
  123. public function loadIconFile($url, $path) {
  124. // get icon from source
  125. $data = @file_get_contents($url);
  126. if($data===false)
  127. return $data;
  128. // html text (e.g. error page) delivered
  129. if(strpos($data, '<html')!==false)
  130. return false;
  131. // empty file
  132. if(strlen($data)==0)
  133. return false;
  134. // get filetype
  135. $type = strtolower(substr($url, strrpos($url, '.')+1));
  136. if($type!='jpg' && $type!='png' && $type!='ico' && $type!='gif') {
  137. $tmp = $path . md5($url);
  138. file_put_contents($tmp, $data);
  139. $imgInfo = @getimagesize($tmp);
  140. unlink($tmp);
  141. if(strtolower($imgInfo['mime'])=='image/vnd.microsoft.icon')
  142. $type = 'ico';
  143. elseif(strtolower($imgInfo['mime'])=='image/png')
  144. $type = 'png';
  145. elseif(strtolower($imgInfo['mime'])=='image/jpeg')
  146. $type = 'jpg';
  147. elseif(strtolower($imgInfo['mime'])=='image/gif')
  148. $type = 'gif';
  149. elseif($imgInfo == false){
  150. $icoDir = unpack('sidReserved/sidType/sidCount', substr($data, 0, 6));
  151. // http://msdn.microsoft.com/en-us/library/ms997538.aspx#CodeSnippetContainerCode0
  152. // as descripted in comments
  153. if ($icoDir['idReserved']!=0 || $icoDir['idType']!=1 || $icoDir['idCount']<1) return false;
  154. } else {
  155. // do not store other formats
  156. return false;
  157. }
  158. }
  159. // write icon in file
  160. $target = md5($url) . '.' . $type;
  161. file_put_contents($path . $target, $data);
  162. return $target;
  163. }
  164. /**
  165. * loads an html file and search for <link rel="shortcut icon"
  166. * on success: download
  167. *
  168. * @return string|bool filename on succes, false on failure
  169. * @param string $url source url
  170. * @param string $path target path
  171. */
  172. protected function searchAndDownloadIcon($url, $path) {
  173. $icon = $this->getLinkTag(
  174. $this->loadHtml($url)
  175. );
  176. // icon found: download it
  177. if($icon!==false) {
  178. // add http
  179. if(strpos($icon, 'http://') !== 0)
  180. $icon = $url . $icon;
  181. // download icon
  182. return $this->loadIconFile($icon, $path);
  183. }
  184. return false;
  185. }
  186. /**
  187. * loads html page of given url
  188. *
  189. * @return string content as string
  190. * @param string $url the source url
  191. */
  192. protected function loadHtml($url) {
  193. try {
  194. $client = new Zend_Http_Client($url);
  195. $response = $client->request();
  196. return $response->getBody();
  197. } catch(Exception $e) {
  198. return false;
  199. }
  200. }
  201. /**
  202. * searches the first link tag in html page
  203. * with rel="shortcut icon" tag
  204. *
  205. * @return string|bool icon href as string,
  206. * false if no link tag was found
  207. * @param string $content of the html page
  208. */
  209. protected function getLinkTag($content) {
  210. if($content===false)
  211. return false;
  212. try {
  213. $dom = @new Zend_Dom_Query($content);
  214. //$linkTags = $dom->query('link[rel="shortcut icon"]'); // don't work
  215. $linkTags = @$dom->query('link');
  216. foreach($linkTags as $link) {
  217. if($link->getAttribute('rel') == 'shortcut icon')
  218. return $linkTags->current()->getAttribute("href");
  219. }
  220. } catch(Exception $e) {
  221. }
  222. return false;
  223. }
  224. /**
  225. * load local icon file from filesystem as wideimage
  226. * @return WideImage_TrueColorImage
  227. * @param string $source of the ico file
  228. */
  229. protected function loadIconFileFromFilesystem($source) {
  230. $fileContent = file_get_contents($source);
  231. $tmp_image = @imagecreatefromstring($fileContent);
  232. if($tmp_image!==false)
  233. return $tmp_image;
  234. $ico = new floIcon();
  235. $ico->readICO($source);
  236. if(count($ico->images)>0)
  237. return $ico->images[0]->getImageResource();
  238. return false;
  239. }
  240. }