Use files for favicons

This commit is contained in:
Alexis Mousset 2015-12-07 14:18:27 +01:00
parent c511b2264c
commit 1efeee42d9
8 changed files with 88 additions and 10 deletions

View File

@ -62,6 +62,11 @@ if (! is_writable(DATA_DIRECTORY)) {
die('The data directory must be writeable by your web server user');
}
// Check if favicon directory is writeable
if (! is_writable(FAVICON_DIRECTORY)) {
die('The favicon directory must be writeable by your web server user');
}
// Include password_compat for PHP < 5.5
if (version_compare(PHP_VERSION, '5.5.0', '<')) {
require __DIR__.'/lib/password.php';

View File

@ -15,6 +15,9 @@ defined('BASE_URL_DIRECTORY') or define('BASE_URL_DIRECTORY', dirname($_SERVER['
defined('ROOT_DIRECTORY') or define('ROOT_DIRECTORY', __DIR__);
defined('DATA_DIRECTORY') or define('DATA_DIRECTORY', ROOT_DIRECTORY.DIRECTORY_SEPARATOR.'data');
defined('FAVICON_DIRECTORY') or define('FAVICON_DIRECTORY', DATA_DIRECTORY.DIRECTORY_SEPARATOR.'favicons');
defined('FAVICON_PUBLIC_DIRECTORY') or define('FAVICON_PUBLIC_DIRECTORY', 'data'.DIRECTORY_SEPARATOR.'favicons');
defined('ENABLE_MULTIPLE_DB') or define('ENABLE_MULTIPLE_DB', true);
defined('DB_FILENAME') or define('DB_FILENAME', 'db.sqlite');

View File

@ -9,6 +9,12 @@ define('HTTP_MAX_RESPONSE_SIZE', 2097152);
// DATA_DIRECTORY => default is data (writable directory)
define('DATA_DIRECTORY', __DIR__.'/data');
// FAVICON_DIRECTORY => default is favicons (writable directory)
define('FAVICON_DIRECTORY', DATA_DIRECTORY.DIRECTORY_SEPARATOR.'favicons');
// FAVICON_PUBLIC_DIRECTORY => default is data/favicons/
define('FAVICON_PUBLIC_DIRECTORY', 'data'.DIRECTORY_SEPARATOR.'favicons');
// DB_FILENAME => default value is db.sqlite (default database filename)
define('DB_FILENAME', 'db.sqlite');

1
data/favicons/.htaccess Normal file
View File

@ -0,0 +1 @@
Allow from all

View File

@ -122,7 +122,8 @@ route('favicons', function() {
->table('favicons')
->columns(
'feed_id',
'icon'
'file',
'type'
)
->findAll();
@ -130,7 +131,7 @@ route('favicons', function() {
foreach ($favicons as $favicon) {
$response['favicons'][] = array(
'id' => (int) $favicon['feed_id'],
'data' => $favicon['icon']
'data' => 'data:'.$favicon['type'].';base64,'.base64_encode(file_get_contents(FAVICON_DIRECTORY.DIRECTORY_SEPARATOR.$favicon['file']))
);
}
}

View File

@ -29,10 +29,30 @@ function parse_app_version($refnames, $commithash)
return $version;
}
/*
* get Image extension from mime type
*/
function favicon_extension($type)
{
$types = array(
'image/png' => '.png',
'image/gif' => '.gif',
'image/x-icon' => '.ico',
'image/jpeg' => '.jpg',
'image/jpg' => '.jpg'
);
if (in_array($type, $types)) {
return $types[$type];
} else {
return '.ico';
}
}
function favicon(array $favicons, $feed_id)
{
if (! empty($favicons[$feed_id])) {
return '<img src="'.$favicons[$feed_id].'" class="favicon"/>';
return '<img src="'.FAVICON_PUBLIC_DIRECTORY.DIRECTORY_SEPARATOR.$favicons[$feed_id].'" class="favicon"/>';
}
return '';

View File

@ -6,6 +6,7 @@ use UnexpectedValueException;
use Model\Config;
use Model\Item;
use Model\Group;
use Helper;
use SimpleValidator\Validator;
use SimpleValidator\Validators;
use PicoDb\Database;
@ -19,17 +20,40 @@ use PicoFeed\Client\InvalidUrlException;
const LIMIT_ALL = -1;
// Store the favicon
function store_favicon($feed_id, $link, $icon)
function store_favicon($feed_id, $link, $type, $icon)
{
$file = $feed_id.Helper\favicon_extension($type);
if (file_put_contents(FAVICON_DIRECTORY.DIRECTORY_SEPARATOR.$file, $icon) === false) {
return false;
}
return Database::getInstance('db')
->table('favicons')
->save(array(
'feed_id' => $feed_id,
'link' => $link,
'icon' => $icon,
'file' => $file,
'type' => $type
));
}
// Delete the favicon
function delete_favicon($feed_id)
{
foreach (get_favicons(array ($feed_id)) as $favicon) {
unlink(FAVICON_DIRECTORY.DIRECTORY_SEPARATOR.$favicon);
}
}
// Delete all the favicons
function delete_all_favicons()
{
foreach (get_all_favicons() as $favicon) {
unlink(FAVICON_DIRECTORY.DIRECTORY_SEPARATOR.$favicon);
}
}
// Download favicon
function fetch_favicon($feed_id, $site_url, $icon_link)
{
@ -37,10 +61,11 @@ function fetch_favicon($feed_id, $site_url, $icon_link)
$favicon = new Favicon;
$link = $favicon->find($site_url, $icon_link);
$icon = $favicon->getDataUri();
$icon = $favicon->getContent();
$type = $favicon->getType();
if ($icon !== '') {
store_favicon($feed_id, $link, $icon);
store_favicon($feed_id, $link, $type, $icon);
}
}
}
@ -61,7 +86,7 @@ function get_favicons(array $feed_ids)
$db = Database::getInstance('db')
->hashtable('favicons')
->columnKey('feed_id')
->columnValue('icon');
->columnValue('file');
// pass $feeds_ids as argument list to hashtable::get(), use ... operator with php 5.6+
return call_user_func_array(array($db, 'get'), $feed_ids);
@ -88,7 +113,7 @@ function get_all_favicons()
return Database::getInstance('db')
->hashtable('favicons')
->getAll('feed_id', 'icon');
->getAll('feed_id', 'file');
}
// Update feed information
@ -409,6 +434,7 @@ function update_cache($feed_id, $last_modified, $etag)
// Remove one feed
function remove($feed_id)
{
delete_favicon($feed_id);
// Items are removed by a sql constraint
return Database::getInstance('db')->table('feeds')->eq('id', $feed_id)->remove();
}
@ -416,6 +442,7 @@ function remove($feed_id)
// Remove all feeds
function remove_all()
{
delete_all_favicons();
return Database::getInstance('db')->table('feeds')->remove();
}

View File

@ -5,7 +5,22 @@ namespace Schema;
use PDO;
use Model\Config;
const VERSION = 41;
const VERSION = 42;
function version_42(PDO $pdo)
{
$pdo->exec('DROP TABLE favicons');
$pdo->exec(
'CREATE TABLE favicons (
feed_id INTEGER UNIQUE,
link TEXT,
file TEXT,
type TEXT,
FOREIGN KEY(feed_id) REFERENCES feeds(id) ON DELETE CASCADE
)'
);
}
function version_41(PDO $pdo)
{