aboutsummaryrefslogtreecommitdiff
path: root/lib/favicons.php
diff options
context:
space:
mode:
authorGravatar Alexandre Alapetite <alexandre@alapetite.fr> 2017-04-23 14:06:37 +0200
committerGravatar Alexandre Alapetite <alexandre@alapetite.fr> 2017-04-23 14:06:37 +0200
commit44c9ae51c44478e56ee70ce692ade6a275981320 (patch)
treeed47cd59439b9f826108886cdb0dfe30f113fbb6 /lib/favicons.php
parent6d5fb27f978c25be09a939d0f426a5c8962e79ec (diff)
Rewriten Favicon library using cURL
Reduce the number of requests, more robust, many more cases working, reduced code
Diffstat (limited to 'lib/favicons.php')
-rw-r--r--lib/favicons.php110
1 files changed, 96 insertions, 14 deletions
diff --git a/lib/favicons.php b/lib/favicons.php
index d8baba342..cc6e54374 100644
--- a/lib/favicons.php
+++ b/lib/favicons.php
@@ -1,22 +1,104 @@
<?php
-
-include(LIB_PATH . '/Favicon/FaviconDLType.php');
-include(LIB_PATH . '/Favicon/DataAccess.php');
-include(LIB_PATH . '/Favicon/Favicon.php');
-
$favicons_dir = DATA_PATH . '/favicons/';
$default_favicon = PUBLIC_PATH . '/themes/icons/default_favicon.ico';
-function download_favicon($website, $dest) {
- global $default_favicon;
+function isImgMime($content) {
+ //Based on https://github.com/ArthurHoaro/favicon/blob/3a4f93da9bb24915b21771eb7873a21bde26f5d1/src/Favicon/Favicon.php#L311-L319
+ if($content == '') {
+ return false;
+ }
+ if (!extension_loaded('fileinfo')) {
+ return true;
+ }
+ $isImage = true;
+ try {
+ $fInfo = finfo_open(FILEINFO_MIME_TYPE);
+ $isImage = strpos(finfo_buffer($fInfo, $content), 'image') !== false;
+ finfo_close($fInfo);
+ } catch (Exception $e) {
+ }
+ return $isImage;
+}
- syslog(LOG_INFO, 'FreshRSS Favicon discovery GET ' . $website);
- $favicon_getter = new \Favicon\Favicon();
- $tmpPath = realpath(TMP_PATH);
- $favicon_getter->setCacheDir($tmpPath);
- $favicon_getter->setCacheTimeout(-1);
- $favicon_path = $favicon_getter->get($website, \Favicon\FaviconDLType::DL_FILE_PATH);
+function downloadHttp(&$url, $curlOptions = array()) {
+ syslog(LOG_INFO, 'FreshRSS Favicon GET ' . $url);
+ if (substr($url, 0, 2) === '//') {
+ $url = 'https:' . $favicon;
+ }
+ if ($url == '' || filter_var($url, FILTER_VALIDATE_URL) === false) {
+ return '';
+ }
+ $ch = curl_init($url);
+ curl_setopt_array($ch, array(
+ CURLOPT_FOLLOWLOCATION => true,
+ CURLOPT_MAXREDIRS => 10,
+ CURLOPT_RETURNTRANSFER => true,
+ CURLOPT_TIMEOUT => 15,
+ CURLOPT_USERAGENT => 'FreshRSS/' . FRESHRSS_VERSION . ' (' . PHP_OS . '; ' . FRESHRSS_WEBSITE . ')',
+ ));
+ if (defined('CURLOPT_ENCODING')) {
+ curl_setopt($ch, CURLOPT_ENCODING, ''); //Enable all encodings
+ }
+ curl_setopt_array($ch, $curlOptions);
+ $response = curl_exec($ch);
+ $info = curl_getinfo($ch);
+ curl_close($ch);
+ if (!empty($info['url']) && (filter_var($info['url'], FILTER_VALIDATE_URL) !== false)) {
+ $url = $info['url'];
+ }
+ return $info['http_code'] == 200 ? $response : '';
+}
+
+function searchFavicon(&$url) {
+ $dom = new DOMDocument();
+ $html = downloadHttp($url);
+ if ($html != '' && @$dom->loadHTML($html, LIBXML_NONET | LIBXML_NOERROR | LIBXML_NOWARNING)) {
+ $rels = array('shortcut icon', 'icon');
+ $links = $dom->getElementsByTagName('link');
+ foreach ($rels as $rel) {
+ foreach ($links as $link) {
+ if ($link->hasAttribute('rel') && $link->hasAttribute('href') &&
+ strtolower(trim($link->getAttribute('rel'))) === $rel) {
+ $href = trim($link->getAttribute('href'));
+ if (substr($href, 0, 2) === '//') {
+ $href = 'https:' . $href;
+ }
+ if (filter_var($href, FILTER_VALIDATE_URL) === false) {
+ $href = SimplePie_IRI::absolutize($url, $href);
+ }
+ $favicon = downloadHttp($href, array(
+ CURLOPT_REFERER => $url,
+ ));
+ if (isImgMime($favicon)) {
+ return $favicon;
+ }
+ }
+ }
+ }
+ }
+ return '';
+}
- return ($favicon_path != false && @rename($tmpPath . '/' . $favicon_path, $dest)) ||
+function download_favicon($url, $dest) {
+ global $default_favicon;
+ $url = trim($url);
+ $favicon = searchFavicon($url);
+ if ($favicon == '') {
+ $rootUrl = preg_replace('%^(https?://[^/]+).*$%i', '$1/', $url);
+ if ($rootUrl != $url) {
+ $url = $rootUrl;
+ $favicon = searchFavicon($url);
+ }
+ if ($favicon == '') {
+ $link = $rootUrl . 'favicon.ico';
+ $favicon = downloadHttp($link, array(
+ CURLOPT_REFERER => $url,
+ ));
+ if (!isImgMime($favicon)) {
+ $favicon = '';
+ }
+ }
+ }
+ return ($favicon != '' && file_put_contents($dest, $favicon)) ||
@copy($default_favicon, $dest);
}