mirror of
https://github.com/YunoHost-Apps/cops_ynh.git
synced 2024-09-03 18:25:57 +02:00
364 lines
10 KiB
PHP
364 lines
10 KiB
PHP
<?php
|
|
/**
|
|
* COPS (Calibre OPDS PHP Server) class file
|
|
*
|
|
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
|
|
* @author Sébastien Lucas <sebastien@slucas.fr>
|
|
*/
|
|
|
|
require 'config.php';
|
|
|
|
define ('VERSION', '1.0.2');
|
|
define ('DB', 'db');
|
|
date_default_timezone_set($config['default_timezone']);
|
|
|
|
|
|
function useServerSideRendering()
|
|
{
|
|
global $config;
|
|
return preg_match('/' . $config['cops_server_side_render'] . '/', $_SERVER['HTTP_USER_AGENT']);
|
|
}
|
|
|
|
function serverSideRender($data)
|
|
{
|
|
// Get the templates
|
|
$theme = getCurrentTemplate ();
|
|
$header = file_get_contents('templates/' . $theme . '/header.html');
|
|
$footer = file_get_contents('templates/' . $theme . '/footer.html');
|
|
$main = file_get_contents('templates/' . $theme . '/main.html');
|
|
$bookdetail = file_get_contents('templates/' . $theme . '/bookdetail.html');
|
|
$page = file_get_contents('templates/' . $theme . '/page.html');
|
|
|
|
// Generate the function for the template
|
|
$template = new doT ();
|
|
$dot = $template->template ($page, array ('bookdetail' => $bookdetail,
|
|
'header' => $header,
|
|
'footer' => $footer,
|
|
'main' => $main));
|
|
// If there is a syntax error in the function created
|
|
// $dot will be equal to FALSE
|
|
if (!$dot) {
|
|
return FALSE;
|
|
}
|
|
// Execute the template
|
|
if (!empty ($data)) {
|
|
return $dot ($data);
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
function getQueryString()
|
|
{
|
|
if (isset($_SERVER['QUERY_STRING'])) {
|
|
return $_SERVER['QUERY_STRING'];
|
|
}
|
|
return "";
|
|
}
|
|
|
|
function notFound()
|
|
{
|
|
header($_SERVER['SERVER_PROTOCOL'].' 404 Not Found');
|
|
header('Status: 404 Not Found');
|
|
|
|
$_SERVER['REDIRECT_STATUS'] = 404;
|
|
}
|
|
|
|
function getURLParam($name, $default = NULL)
|
|
{
|
|
if (!empty ($_GET) && isset($_GET[$name]) && $_GET[$name] != '') {
|
|
return $_GET[$name];
|
|
}
|
|
return $default;
|
|
}
|
|
|
|
function getCurrentOption($option)
|
|
{
|
|
global $config;
|
|
if (isset($_COOKIE[$option])) {
|
|
if (isset($config ['cops_' . $option]) && is_array ($config ['cops_' . $option])) {
|
|
return explode (',', $_COOKIE[$option]);
|
|
} else {
|
|
return $_COOKIE[$option];
|
|
}
|
|
}
|
|
if (isset($config ['cops_' . $option])) {
|
|
return $config ['cops_' . $option];
|
|
}
|
|
|
|
return '';
|
|
}
|
|
|
|
function getCurrentCss()
|
|
{
|
|
return 'templates/' . getCurrentTemplate () . '/styles/style-' . getCurrentOption('style') . '.css';
|
|
}
|
|
|
|
function getCurrentTemplate()
|
|
{
|
|
return getCurrentOption ('template');
|
|
}
|
|
|
|
function getUrlWithVersion($url)
|
|
{
|
|
return $url . '?v=' . VERSION;
|
|
}
|
|
|
|
function xml2xhtml($xml)
|
|
{
|
|
return preg_replace_callback('#<(\w+)([^>]*)\s*/>#s', function($m) {
|
|
$xhtml_tags = array('br', 'hr', 'input', 'frame', 'img', 'area', 'link', 'col', 'base', 'basefont', 'param');
|
|
if (in_array($m[1], $xhtml_tags)) {
|
|
return '<' . $m[1] . $m[2] . ' />';
|
|
} else {
|
|
return '<' . $m[1] . $m[2] . '></' . $m[1] . '>';
|
|
}
|
|
}, $xml);
|
|
}
|
|
|
|
function display_xml_error($error)
|
|
{
|
|
$return = '';
|
|
$return .= str_repeat('-', $error->column) . "^\n";
|
|
|
|
switch ($error->level) {
|
|
case LIBXML_ERR_WARNING:
|
|
$return .= 'Warning ' . $error->code . ': ';
|
|
break;
|
|
case LIBXML_ERR_ERROR:
|
|
$return .= 'Error ' . $error->code . ': ';
|
|
break;
|
|
case LIBXML_ERR_FATAL:
|
|
$return .= 'Fatal Error ' . $error->code . ': ';
|
|
break;
|
|
}
|
|
|
|
$return .= trim($error->message) .
|
|
"\n Line: " . $error->line .
|
|
"\n Column: " . $error->column;
|
|
|
|
if ($error->file) {
|
|
$return .= "\n File: " . $error->file;
|
|
}
|
|
|
|
return "$return\n\n--------------------------------------------\n\n";
|
|
}
|
|
|
|
function are_libxml_errors_ok()
|
|
{
|
|
$errors = libxml_get_errors();
|
|
|
|
foreach ($errors as $error) {
|
|
if ($error->code == 801) return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
function html2xhtml($html)
|
|
{
|
|
$doc = new DOMDocument();
|
|
libxml_use_internal_errors(true);
|
|
|
|
$doc->loadHTML('<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body>' .
|
|
$html . '</body></html>'); // Load the HTML
|
|
$output = $doc->saveXML($doc->documentElement); // Transform to an Ansi xml stream
|
|
$output = xml2xhtml($output);
|
|
if (preg_match ('#<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></meta></head><body>(.*)</body></html>#ms', $output, $matches)) {
|
|
$output = $matches [1]; // Remove <html><body>
|
|
}
|
|
/*
|
|
// In case of error with summary, use it to debug
|
|
$errors = libxml_get_errors();
|
|
|
|
foreach ($errors as $error) {
|
|
$output .= display_xml_error($error);
|
|
}
|
|
*/
|
|
|
|
if (!are_libxml_errors_ok ()) $output = 'HTML code not valid.';
|
|
|
|
libxml_use_internal_errors(false);
|
|
return $output;
|
|
}
|
|
|
|
/**
|
|
* This method is a direct copy-paste from
|
|
* http://tmont.com/blargh/2010/1/string-format-in-php
|
|
*/
|
|
function str_format($format)
|
|
{
|
|
$args = func_get_args();
|
|
$format = array_shift($args);
|
|
|
|
preg_match_all('/(?=\{)\{(\d+)\}(?!\})/', $format, $matches, PREG_OFFSET_CAPTURE);
|
|
$offset = 0;
|
|
foreach ($matches[1] as $data) {
|
|
$i = $data[0];
|
|
$format = substr_replace($format, @$args[$i], $offset + $data[1] - 1, 2 + strlen($i));
|
|
$offset += strlen(@$args[$i]) - 2 - strlen($i);
|
|
}
|
|
|
|
return $format;
|
|
}
|
|
|
|
/**
|
|
* Get all accepted languages from the browser and put them in a sorted array
|
|
* languages id are normalized : fr-fr -> fr_FR
|
|
* @return array of languages
|
|
*/
|
|
function getAcceptLanguages()
|
|
{
|
|
$langs = array();
|
|
|
|
if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
|
|
// break up string into pieces (languages and q factors)
|
|
$accept = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
|
|
if (preg_match('/^(\w{2})-\w{2}$/', $accept, $matches)) {
|
|
// Special fix for IE11 which send fr-FR and nothing else
|
|
$accept = $accept . ',' . $matches[1] . ';q=0.8';
|
|
}
|
|
preg_match_all('/([a-z]{1,8}(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i', $accept, $lang_parse);
|
|
|
|
if (count($lang_parse[1])) {
|
|
$langs = array();
|
|
foreach ($lang_parse[1] as $lang) {
|
|
// Format the language code (not standard among browsers)
|
|
if (strlen($lang) == 5) {
|
|
$lang = str_replace('-', '_', $lang);
|
|
$splitted = preg_split('/_/', $lang);
|
|
$lang = $splitted[0] . '_' . strtoupper($splitted[1]);
|
|
}
|
|
array_push($langs, $lang);
|
|
}
|
|
// create a list like "en" => 0.8
|
|
$langs = array_combine($langs, $lang_parse[4]);
|
|
|
|
// set default to 1 for any without q factor
|
|
foreach ($langs as $lang => $val) {
|
|
if ($val === '') $langs[$lang] = 1;
|
|
}
|
|
|
|
// sort list based on value
|
|
arsort($langs, SORT_NUMERIC);
|
|
}
|
|
}
|
|
|
|
return $langs;
|
|
}
|
|
|
|
/**
|
|
* Find the best translation file possible based on the accepted languages
|
|
* @return array of language and language file
|
|
*/
|
|
function getLangAndTranslationFile()
|
|
{
|
|
global $config;
|
|
$langs = array();
|
|
$lang = 'en';
|
|
if (!empty($config['cops_language'])) {
|
|
$lang = $config['cops_language'];
|
|
}
|
|
elseif (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
|
|
$langs = getAcceptLanguages();
|
|
}
|
|
//echo var_dump($langs);
|
|
$lang_file = NULL;
|
|
foreach ($langs as $language => $val) {
|
|
$temp_file = dirname(__FILE__). '/lang/Localization_' . $language . '.json';
|
|
if (file_exists($temp_file)) {
|
|
$lang = $language;
|
|
$lang_file = $temp_file;
|
|
break;
|
|
}
|
|
}
|
|
if (empty ($lang_file)) {
|
|
$lang_file = dirname(__FILE__). '/lang/Localization_' . $lang . '.json';
|
|
}
|
|
return array($lang, $lang_file);
|
|
}
|
|
|
|
/**
|
|
* This method is based on this page
|
|
* http://www.mind-it.info/2010/02/22/a-simple-approach-to-localization-in-php/
|
|
*/
|
|
function localize($phrase, $count=-1, $reset=false)
|
|
{
|
|
global $config;
|
|
if ($count == 0)
|
|
$phrase .= '.none';
|
|
if ($count == 1)
|
|
$phrase .= '.one';
|
|
if ($count > 1)
|
|
$phrase .= '.many';
|
|
|
|
/* Static keyword is used to ensure the file is loaded only once */
|
|
static $translations = NULL;
|
|
if ($reset) {
|
|
$translations = NULL;
|
|
}
|
|
/* If no instance of $translations has occured load the language file */
|
|
if (is_null($translations)) {
|
|
$lang_file_en = NULL;
|
|
list ($lang, $lang_file) = getLangAndTranslationFile();
|
|
if ($lang != 'en') {
|
|
$lang_file_en = dirname(__FILE__). '/lang/' . 'Localization_en.json';
|
|
}
|
|
|
|
$lang_file_content = file_get_contents($lang_file);
|
|
/* Load the language file as a JSON object and transform it into an associative array */
|
|
$translations = json_decode($lang_file_content, true);
|
|
|
|
/* Clean the array of all unfinished translations */
|
|
foreach (array_keys ($translations) as $key) {
|
|
if (preg_match ('/^##TODO##/', $key)) {
|
|
unset ($translations [$key]);
|
|
}
|
|
}
|
|
if (!is_null($lang_file_en)) {
|
|
$lang_file_content = file_get_contents($lang_file_en);
|
|
$translations_en = json_decode($lang_file_content, true);
|
|
$translations = array_merge ($translations_en, $translations);
|
|
}
|
|
}
|
|
if (array_key_exists ($phrase, $translations)) {
|
|
return $translations[$phrase];
|
|
}
|
|
return $phrase;
|
|
}
|
|
|
|
function addURLParameter($urlParams, $paramName, $paramValue)
|
|
{
|
|
if (empty ($urlParams)) {
|
|
$urlParams = '';
|
|
}
|
|
$start = '';
|
|
if (preg_match ('#^\?(.*)#', $urlParams, $matches)) {
|
|
$start = '?';
|
|
$urlParams = $matches[1];
|
|
}
|
|
$params = array();
|
|
parse_str($urlParams, $params);
|
|
if (empty ($paramValue) && $paramValue != 0) {
|
|
unset ($params[$paramName]);
|
|
} else {
|
|
$params[$paramName] = $paramValue;
|
|
}
|
|
return $start . http_build_query($params);
|
|
}
|
|
|
|
function useNormAndUp()
|
|
{
|
|
global $config;
|
|
return $config ['cops_normalized_search'] == '1';
|
|
}
|
|
|
|
function normalizeUtf8String($s)
|
|
{
|
|
include_once 'transliteration.php';
|
|
return _transliteration_process($s);
|
|
}
|
|
|
|
function normAndUp($s)
|
|
{
|
|
return mb_strtoupper(normalizeUtf8String($s), 'UTF-8');
|
|
}
|