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'); 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 // Include password_compat for PHP < 5.5
if (version_compare(PHP_VERSION, '5.5.0', '<')) { if (version_compare(PHP_VERSION, '5.5.0', '<')) {
require __DIR__.'/lib/password.php'; 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('ROOT_DIRECTORY') or define('ROOT_DIRECTORY', __DIR__);
defined('DATA_DIRECTORY') or define('DATA_DIRECTORY', ROOT_DIRECTORY.DIRECTORY_SEPARATOR.'data'); 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('ENABLE_MULTIPLE_DB') or define('ENABLE_MULTIPLE_DB', true);
defined('DB_FILENAME') or define('DB_FILENAME', 'db.sqlite'); 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) // DATA_DIRECTORY => default is data (writable directory)
define('DATA_DIRECTORY', __DIR__.'/data'); 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) // DB_FILENAME => default value is db.sqlite (default database filename)
define('DB_FILENAME', 'db.sqlite'); 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') ->table('favicons')
->columns( ->columns(
'feed_id', 'feed_id',
'icon' 'file',
'type'
) )
->findAll(); ->findAll();
@ -130,7 +131,7 @@ route('favicons', function() {
foreach ($favicons as $favicon) { foreach ($favicons as $favicon) {
$response['favicons'][] = array( $response['favicons'][] = array(
'id' => (int) $favicon['feed_id'], '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; 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) function favicon(array $favicons, $feed_id)
{ {
if (! empty($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 ''; return '';

View File

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

View File

@ -5,7 +5,22 @@ namespace Schema;
use PDO; use PDO;
use Model\Config; 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) function version_41(PDO $pdo)
{ {