feat: add videodb media index with Docker stack
- Add videodb PHP/MySQL media collection manager (Blu-ray, DVD, CD) - Dockerfile: PHP 8.1 + Apache with GD/mysqli/exif extensions - docker-compose.yml: app on port 6761 + MySQL 8.0 with health checks - docker-entrypoint.sh: auto-generates config.inc.php from env vars, waits for MySQL, initializes DB schema idempotently - init-db.php: CLI schema installer using app's own prefix_query() logic - Persistent volumes for DB, cache, and cover images Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
56
videodb/core/VariableStream.class.php
Normal file
56
videodb/core/VariableStream.class.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
/**
|
||||
* VariableStream class
|
||||
*
|
||||
* @package Core
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @version $Id: VariableStream.class.php,v 1.4 2004/10/30 11:48:36 andig2 Exp $
|
||||
*/
|
||||
|
||||
// stream wrappers require php > 4.3
|
||||
if (version_compare(phpversion(), '4.3') < 0)
|
||||
{
|
||||
errorpage('PHP version mismatch',
|
||||
'At least PHP version 4.3.0 is required to run the VariableStream, please check the documentation!');
|
||||
}
|
||||
|
||||
/**
|
||||
* VariableStream allows XML reading from variables
|
||||
* @package Core
|
||||
*/
|
||||
class VariableStream
|
||||
{
|
||||
var $position;
|
||||
var $varname;
|
||||
var $context;
|
||||
|
||||
function stream_open($path, $mode, $options, &$opened_path) {
|
||||
$url = parse_url($path);
|
||||
$this->varname = $url['host'];
|
||||
$this->position = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
function stream_read($count) {
|
||||
$ret = substr($GLOBALS[$this->varname], $this->position, $count);
|
||||
$this->position += strlen($ret);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function stream_eof() {
|
||||
return $this->position >= strlen($GLOBALS[$this->varname]);
|
||||
}
|
||||
|
||||
function stream_stat() {
|
||||
return array('size' => strlen($GLOBALS[$this->varname]));
|
||||
}
|
||||
|
||||
function url_stat() {
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
// register stream type to allow use in xml->load
|
||||
stream_wrapper_register('var', 'VariableStream');
|
||||
|
||||
?>
|
||||
196
videodb/core/cache.php
Normal file
196
videodb/core/cache.php
Normal file
@@ -0,0 +1,196 @@
|
||||
<?php
|
||||
/**
|
||||
* File caching functions
|
||||
*
|
||||
* @package Core
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @version $Id: cache.php,v 1.11 2013/04/26 15:09:35 andig2 Exp $
|
||||
*/
|
||||
|
||||
// define cache folder
|
||||
if (!defined('CACHE')) define('CACHE', 'cache');
|
||||
|
||||
/**
|
||||
* Get the hashed filename
|
||||
*
|
||||
* @param string url of the item
|
||||
* @param string $cache_folder name ob the sub-cache to adress
|
||||
* @param string ext file extension of the cache file
|
||||
*/
|
||||
function cache_get_filename($url, $cache_folder, $ext = '')
|
||||
{
|
||||
$hash = md5($url) . (($ext) ? '.'.$ext : '');
|
||||
$cache_file = cache_get_folder($cache_folder, $hash) . $hash;
|
||||
|
||||
return $cache_file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name of the cache folder
|
||||
*
|
||||
* @TODO decouple from global config options
|
||||
*
|
||||
* @param string $cache_folder name ob the sub-cache to adress
|
||||
* @param string $cache_filename name of the item to be cached for use with hierarchical caches
|
||||
* @return string cache folder path including trailing /
|
||||
*/
|
||||
function cache_get_folder($cache_folder, $cache_filename = '')
|
||||
{
|
||||
global $config;
|
||||
|
||||
$cache_folder = CACHE.'/' .
|
||||
(($cache_folder) ? $cache_folder.'/' : '');
|
||||
|
||||
if ($cache_filename)
|
||||
$cache_folder .= substr($cache_filename, 0, @(int)$config['hierarchical']).'/';
|
||||
|
||||
return $cache_folder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup a single cache folder
|
||||
*
|
||||
* @param string $cache_folder path to cache folder
|
||||
* @param int $cache_max_age maximum age of cached items in seconds
|
||||
* @param bool $force_prune force cache pruning even if not due according to schedule
|
||||
*/
|
||||
function cache_prune_folder($cache_folder, $cache_max_age, $force_prune = false, $simulate = false, $pattern = '*')
|
||||
{
|
||||
if (!preg_match('#/$#', $cache_folder)) $cache_folder .= '/';
|
||||
$stamp = $cache_folder.'cache_last_purge';
|
||||
$cache_mtime = @filemtime($stamp); // get time the cache was last purged (once a day)
|
||||
|
||||
// if cache was last purged a day or more ago
|
||||
if ($force_prune || ((time() - $cache_mtime) > ($cache_max_age / 24))) # 86400)
|
||||
{
|
||||
foreach (glob($cache_folder.$pattern, GLOB_NOSORT) as $file)
|
||||
{
|
||||
// avoid hidden files and directories
|
||||
if (is_file($file) &! preg_match("/^\./", $file) && time() - filemtime($file) > $cache_max_age)
|
||||
{
|
||||
if ($simulate)
|
||||
$files[] = $file; // add to list of potentially purged files
|
||||
else
|
||||
@unlink($file); // purge cache
|
||||
}
|
||||
}
|
||||
|
||||
if ($simulate) return $files;
|
||||
|
||||
@touch($stamp); // mark purge as having occurred
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup a cache folder hierarchy
|
||||
*
|
||||
* @TODO decouple from global config options
|
||||
*
|
||||
* @param string $cache_folder path to cache folder
|
||||
* @param int $cache_max_age maximum age of cached items in seconds
|
||||
* @param bool $force_prune force cache pruning even if not due according to schedule
|
||||
*/
|
||||
function cache_prune_folders($cache_folder, $cache_max_age, $force_prune = false, $simulate = false, $pattern = '*', $levels = 0)
|
||||
{
|
||||
global $config;
|
||||
|
||||
// root folder
|
||||
cache_prune_folder($cache_folder, $cache_max_age, $force_prune, $simulate, $pattern, $levels);
|
||||
|
||||
// descent hierarchy
|
||||
if ($levels > 0)
|
||||
{
|
||||
if (!isset($error))
|
||||
{
|
||||
$error = '';
|
||||
}
|
||||
for ($i=0; $i<16; $i++)
|
||||
$error .= cache_prune_folders($cache_folder.dechex($i).'/', $cache_max_age, $force_prune, $simulate, $pattern, $levels-1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create cache folders
|
||||
*
|
||||
* Check individual cache folder for existance, check if folder is writable and create folder if it doesn't exist
|
||||
*/
|
||||
function cache_create_folders($dir, $levels = 0)
|
||||
{
|
||||
$error = '';
|
||||
if (!is_dir($dir))
|
||||
{
|
||||
if (!@mkdir($dir, 0700)) $error = 'Directory <code>'.$dir.'</code> does not exist.<br/>';
|
||||
}
|
||||
elseif (!is_writable($dir))
|
||||
{
|
||||
$error = 'Directory <code>'.$dir.'</code> is not writable.<br/>';
|
||||
}
|
||||
|
||||
// check hierarchical folders
|
||||
if (empty($error) && ($levels > 0))
|
||||
{
|
||||
for ($i=0; $i<16; $i++)
|
||||
$error .= cache_create_folders($dir.'/'.dechex($i), $levels-1);
|
||||
}
|
||||
|
||||
return $error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify existance of cached file for given url/ extension
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @param string url of the item
|
||||
* @param string ext file extension of the cache file
|
||||
* @param string file result: URL to the cached image if exists
|
||||
* @return bool result of check
|
||||
*/
|
||||
function cache_file_exists($url, &$cache_file, $cache_folder, $ext = '')
|
||||
{
|
||||
$cache_file = cache_get_filename($url, $cache_folder, $ext);
|
||||
// Small performance fix
|
||||
$result = file_exists($cache_file) && filesize($cache_file);
|
||||
# $result = filesize($cache_file) > 0;
|
||||
|
||||
return($result);
|
||||
}
|
||||
|
||||
function cache_get($url, $cache_folder, $cache_max_age, $serialize = false)
|
||||
{
|
||||
$data = false;
|
||||
|
||||
if ($cache_max_age > 0)
|
||||
{
|
||||
if (cache_file_exists($url, $cache_file, $cache_folder))
|
||||
{
|
||||
if (time() - filemtime($cache_file) < $cache_max_age)
|
||||
{
|
||||
$data = file_get_contents($cache_file);
|
||||
if (($data !== false) && $serialize) $data = unserialize($data);
|
||||
}
|
||||
// TODO Check if outdated cache files should really be auto-deleted
|
||||
else @unlink($cache_file);
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
function cache_put($url, $data, $cache_folder, $cache_max_age, $serialize = false)
|
||||
{
|
||||
// only put file to cache if caching is enabled
|
||||
if ($cache_max_age > 0)
|
||||
{
|
||||
// get the cache file name
|
||||
$cache_file = cache_get_filename($url, $cache_folder);
|
||||
|
||||
// commit to disk
|
||||
if ($serialize) $data = serialize($data);
|
||||
file_put_contents($cache_file, $data);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
312
videodb/core/compatibility.php
Normal file
312
videodb/core/compatibility.php
Normal file
@@ -0,0 +1,312 @@
|
||||
<?php
|
||||
/**
|
||||
* Compatibility functions
|
||||
*
|
||||
* Borrowed simplified functions from PEAR module PHP_Compat
|
||||
*
|
||||
* @package Core
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @link http://pear.php.net PEAR
|
||||
* @version $Id: compatibility.php,v 1.15 2013/03/13 16:38:19 andig2 Exp $
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements file_get_contents introduced in v4.3.0
|
||||
*/
|
||||
if (!function_exists('file_get_contents'))
|
||||
{
|
||||
function file_get_contents($filename)
|
||||
{
|
||||
$fh = @fopen($filename, 'rb');
|
||||
if (!$fh) return false;
|
||||
$content = fread($fh, filesize($filename));
|
||||
fclose($fh);
|
||||
return $content;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements file_put_contents introduced in v5.0.0
|
||||
*/
|
||||
if (!function_exists('file_put_contents'))
|
||||
{
|
||||
function file_put_contents($filename, $content)
|
||||
{
|
||||
$fh = @fopen($filename, 'wb');
|
||||
if (!$fh) return false;
|
||||
if (!fwrite($fh, $content, strlen($content))) return false;
|
||||
fclose($fh);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements html_entity_decode introduced in v4.3.0
|
||||
* @author <martin@swertcw.com>
|
||||
* @param string $string HTML encoded string
|
||||
* @return string HTML decoded string
|
||||
*/
|
||||
if (!function_exists('html_entity_decode'))
|
||||
{
|
||||
function html_entity_decode($string)
|
||||
{
|
||||
// replace numeric entities
|
||||
$string = preg_replace('~&#x([0-9a-f]+);~ei', 'chr(hexdec("\\1"))', $string);
|
||||
$string = preg_replace('~&#([0-9]+);~e', 'chr(\\1)', $string);
|
||||
// replace literal entities
|
||||
$trans_tbl = get_html_translation_table(HTML_ENTITIES);
|
||||
$trans_tbl = array_flip($trans_tbl);
|
||||
return strtr($string, $trans_tbl);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements http_build_query introduced in v5.0.0
|
||||
*/
|
||||
if (!function_exists('http_build_query'))
|
||||
{
|
||||
function http_build_query ($formdata, $numeric_prefix = null)
|
||||
{
|
||||
// Check we have an array to work with
|
||||
if (!is_array($formdata)) {
|
||||
return $formdata;
|
||||
}
|
||||
|
||||
// Start building the query
|
||||
$tmp = array ();
|
||||
foreach ($formdata as $key => $val)
|
||||
{
|
||||
array_push($tmp, urlencode($key).'='.urlencode($val));
|
||||
}
|
||||
|
||||
return implode('&', $tmp);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Multibyte-aware character case conversion
|
||||
*
|
||||
* @author tedemo <tedemo@free.fr>
|
||||
*/
|
||||
if (!function_exists('mb_convert_case'))
|
||||
{
|
||||
function mb_convert_case($str)
|
||||
{
|
||||
return ucwords(strtolower($str));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* iconv alternatives
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
*/
|
||||
if (!function_exists('iconv'))
|
||||
{
|
||||
function iconv($source_encoding, $target_encoding, $str)
|
||||
{
|
||||
// remove transliteration- only available in native iconv
|
||||
$source_encoding = preg_replace('#^(.+?)(//.*)#', '\\1', $source_encoding);
|
||||
$target_encoding = preg_replace('#^(.+?)(//.*)#', '\\1', $target_encoding);
|
||||
|
||||
if (function_exists('mb_convert_encoding'))
|
||||
return mb_convert_encoding($str, $target_encoding, $source_encoding);
|
||||
elseif (function_exists('recode_string'))
|
||||
return recode_string($source_encoding.'..'.$target_encoding, $str);
|
||||
else
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements json_encode introduced in v5.2.0
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
*/
|
||||
if (!function_exists('json_encode'))
|
||||
{
|
||||
function json_encode($data)
|
||||
{
|
||||
require_once('./lib/json.php');
|
||||
$json = new Services_JSON();
|
||||
return($json->encode($data));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements json_decode introduced in v5.2.0
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
*/
|
||||
if (!function_exists('json_decode'))
|
||||
{
|
||||
function json_decode($data)
|
||||
{
|
||||
require_once('./lib/json.php');
|
||||
$json = new Services_JSON();
|
||||
return($json->decode($data));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements json_decode introduced in v5.0.0
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
*/
|
||||
if (!function_exists('http_build_query'))
|
||||
{
|
||||
function http_build_query($formdata, $numeric_prefix = null, $key = null)
|
||||
{
|
||||
$res = array();
|
||||
foreach ((array)$formdata as $k=>$v)
|
||||
{
|
||||
$tmp_key = urlencode(is_int($k) ? $numeric_prefix.$k : $k);
|
||||
if ($key) $tmp_key = $key.'['.$tmp_key.']';
|
||||
|
||||
if ( is_array($v) || is_object($v) ) {
|
||||
$res[] = http_build_query($v, null /* or $numeric_prefix if you want to add numeric_prefix to all indexes in array*/, $tmp_key);
|
||||
} else {
|
||||
$res[] = $tmp_key."=".urlencode($v);
|
||||
}
|
||||
}
|
||||
$separator = ini_get('arg_separator.output');
|
||||
return implode($separator, $res);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Quick image type detection
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
*/
|
||||
if (!function_exists('exif_imagetype'))
|
||||
{
|
||||
function exif_imagetype($filename)
|
||||
{
|
||||
if ((list($width, $height, $type, $attr) = getimagesize($filename )) !== false ) {
|
||||
return $type;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ease PHP 5.3.0 requirement on Windows
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
*/
|
||||
if (!function_exists('linkinfo'))
|
||||
{
|
||||
function linkinfo($path)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Polyfill for PHP 4 - PHP 7
|
||||
* introduced in PHP 8
|
||||
*/
|
||||
if (!function_exists('str_contains'))
|
||||
{
|
||||
function str_contains(string $haystack, string $needle): bool
|
||||
{
|
||||
return strpos($haystack, $needle) !== false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This file is part of the array_column library
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* @copyright Copyright (c) 2013 Ben Ramsey <http://benramsey.com>
|
||||
* @license http://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns the values from a single column of the input array, identified by
|
||||
* the $columnKey.
|
||||
*
|
||||
* Optionally, you may provide an $indexKey to index the values in the returned
|
||||
* array by the values from the $indexKey column in the input array.
|
||||
*
|
||||
* @param array $input A multi-dimensional array (record set) from which to pull
|
||||
* a column of values.
|
||||
* @param mixed $columnKey The column of values to return. This value may be the
|
||||
* integer key of the column you wish to retrieve, or it
|
||||
* may be the string key name for an associative array.
|
||||
* @param mixed $indexKey (Optional.) The column to use as the index/keys for
|
||||
* the returned array. This value may be the integer key
|
||||
* of the column, or it may be the string key name.
|
||||
* @return array
|
||||
*/
|
||||
if (!function_exists('array_column'))
|
||||
{
|
||||
function array_column($input = null, $columnKey = null, $indexKey = null)
|
||||
{
|
||||
// Using func_get_args() in order to check for proper number of
|
||||
// parameters and trigger errors exactly as the built-in array_column()
|
||||
// does in PHP 5.5.
|
||||
$params = func_get_args();
|
||||
if (!isset($params[0])) {
|
||||
trigger_error('array_column() expects at least 2 parameters, 0 given', E_USER_WARNING);
|
||||
return null;
|
||||
} elseif (!isset($params[1])) {
|
||||
trigger_error('array_column() expects at least 2 parameters, 1 given', E_USER_WARNING);
|
||||
return null;
|
||||
}
|
||||
if (!is_array($params[0])) {
|
||||
trigger_error('array_column() expects parameter 1 to be array, ' . gettype($params[0]) . ' given', E_USER_WARNING);
|
||||
return null;
|
||||
}
|
||||
if (!is_int($params[1])
|
||||
&& !is_string($params[1])
|
||||
&& !(is_object($params[1]) && method_exists($params[1], '__toString'))
|
||||
) {
|
||||
trigger_error('array_column(): The column key should be either a string or an integer', E_USER_WARNING);
|
||||
return false;
|
||||
}
|
||||
if (isset($params[2])
|
||||
&& !is_int($params[2])
|
||||
&& !is_string($params[2])
|
||||
&& !(is_object($params[2]) && method_exists($params[2], '__toString'))
|
||||
) {
|
||||
trigger_error('array_column(): The index key should be either a string or an integer', E_USER_WARNING);
|
||||
return false;
|
||||
}
|
||||
$paramsInput = $params[0];
|
||||
$paramsColumnKey = (string) $params[1];
|
||||
$paramsIndexKey = (isset($params[2]) ? (string) $params[2] : null);
|
||||
$resultArray = array();
|
||||
foreach ($paramsInput as $row) {
|
||||
$key = $value = null;
|
||||
$keySet = $valueSet = false;
|
||||
if ($paramsIndexKey !== null && array_key_exists($paramsIndexKey, $row)) {
|
||||
$keySet = true;
|
||||
$key = $row[$paramsIndexKey];
|
||||
}
|
||||
if (is_array($row) && array_key_exists($paramsColumnKey, $row)) {
|
||||
$valueSet = true;
|
||||
$value = $row[$paramsColumnKey];
|
||||
}
|
||||
if ($valueSet) {
|
||||
if ($keySet) {
|
||||
$resultArray[$key] = $value;
|
||||
} else {
|
||||
$resultArray[] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $resultArray;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
76
videodb/core/constants.php
Normal file
76
videodb/core/constants.php
Normal file
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
/**
|
||||
* Constants
|
||||
*
|
||||
* Contains global constants for table names
|
||||
* Must only be loaded after config.inc.php
|
||||
*
|
||||
* @package Core
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @version $Id: constants.php,v 1.65 2013/04/25 15:00:32 andig2 Exp $
|
||||
*/
|
||||
|
||||
// Config file
|
||||
define('CONFIG_FILE', './config.inc.php');
|
||||
define('VERSION', '4.1.0');
|
||||
|
||||
define('LOG_FILE', 'debug.log');
|
||||
|
||||
// User Permission bit masks
|
||||
define('PERM_ADMIN', 1);
|
||||
define('PERM_READ', 2);
|
||||
define('PERM_WRITE', 4);
|
||||
define('PERM_ADULT', 8);
|
||||
define('PERM_ALL', -1); // used to check for "all" permissions only
|
||||
define('PERM_ANY', -2); // used to check for exististance of any cross-user permission
|
||||
|
||||
// Cache folders
|
||||
define('CACHE_IMG', 'img');
|
||||
define('CACHE_HTML', 'imdb');
|
||||
define('CACHE_THUMBS', 'thumbs');
|
||||
define('CACHE_LOCAL', 'local'); // local images for covers and actors
|
||||
|
||||
// Table names
|
||||
define('TBL_DATA', $config['db_prefix'].'videodata');
|
||||
|
||||
define('TBL_CONFIG', $config['db_prefix'].'config');
|
||||
define('TBL_USERCONFIG', $config['db_prefix'].'userconfig');
|
||||
|
||||
define('TBL_USERS', $config['db_prefix'].'users');
|
||||
define('TBL_USERSEEN', $config['db_prefix'].'userseen');
|
||||
define('TBL_PERMISSIONS', $config['db_prefix'].'permissions');
|
||||
|
||||
define('TBL_ACTORS', $config['db_prefix'].'actors');
|
||||
define('TBL_GENRES', $config['db_prefix'].'genres');
|
||||
|
||||
define('TBL_VIDEOGENRE', $config['db_prefix'].'videogenre');
|
||||
define('TBL_MEDIATYPES', $config['db_prefix'].'mediatypes');
|
||||
|
||||
define('TBL_LENT', $config['db_prefix'].'lent');
|
||||
|
||||
define('TBL_CACHE', $config['db_prefix'].'cache');
|
||||
|
||||
// Wishlist
|
||||
define('MEDIA_WISHLIST', 50);
|
||||
|
||||
// Amazon associates token
|
||||
define('AMAZON_ASSOCIATE', 'cpuidle-20');
|
||||
|
||||
// Database character set - only valid values are UTF8, LATIN1 (legacy only) or empty
|
||||
define('DB_CHARSET', 'UTF8');
|
||||
// Database sort order - if empty sorting is defined by language file or db standard.
|
||||
// use UTF8_GENERAL_CI or other valid MySQL collation to override
|
||||
define('DB_COLLATION', '');
|
||||
|
||||
// Required database version
|
||||
define('DB_REQUIRED', 41);
|
||||
|
||||
/**
|
||||
* These used to be defined inside config.sample and therefore config.inc
|
||||
* Removed the need for them inside config.* but since their definition can still
|
||||
* be inside config.inc prefixed here with a check
|
||||
*/
|
||||
if (!defined('TUMB_NO_SCALE')) define('TUMB_NO_SCALE', -1); // no scaling - use of thumbnails is disabled
|
||||
if (!defined('TUMB_REDUCE_ONLY')) define('TUMB_REDUCE_ONLY', 0); // reduce only - create thumbnails when requested image dimensions are smaller than original image
|
||||
if (!defined('TUMB_SCALE')) define('TUMB_SCALE', 1); // always scale - create thumbnails for all images (applies aliasing when scaling)
|
||||
|
||||
492
videodb/core/custom.php
Normal file
492
videodb/core/custom.php
Normal file
@@ -0,0 +1,492 @@
|
||||
<?php
|
||||
/**
|
||||
* Custom handlers
|
||||
*
|
||||
* Defines functions for displaying custom fields.
|
||||
* To add your own type define input and output functions for it here. These
|
||||
* functions will be called in show.php (output) and edit.php (input). You can
|
||||
* get other values from these files by global'ing them into your function. See
|
||||
* ed2k as an example.
|
||||
*
|
||||
* @todo Check if this can be moved to Smarty plugins
|
||||
*
|
||||
* @package Custom
|
||||
* @author Andreas Gohr <a.gohr@web.de>
|
||||
* @version $Id: custom.php,v 1.16 2008/10/03 14:18:04 andig2 Exp $
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
Hint:
|
||||
|
||||
$cn
|
||||
holds the name of the custom field (eg. 'custom2') use this as the name for
|
||||
the input formfield
|
||||
|
||||
$cv
|
||||
holds the current value of that field if any. When you want to use it as
|
||||
value in a formfield quote it with the formvar() function!
|
||||
|
||||
When you add new types send them to me. I will include them here.
|
||||
*/
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/* This array contains all available types - be sure to add your type if
|
||||
you ad a new one */
|
||||
$allcustomtypes=array('',
|
||||
'text',
|
||||
'url',
|
||||
'ed2k',
|
||||
'language',
|
||||
'orgtitle',
|
||||
'movix',
|
||||
'mpaa',
|
||||
'bbfc',
|
||||
'fsk',
|
||||
'barcode',
|
||||
'kijkwijzer'
|
||||
);
|
||||
|
||||
/**
|
||||
* Assigns custom field names and values to input object
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @param hashref $video Reference to video hash structure
|
||||
* @param string $inout Either in or out, determines type of control
|
||||
* returned (html input control or rendered output)
|
||||
*/
|
||||
function customfields(&$video, $inout)
|
||||
{
|
||||
global $config;
|
||||
|
||||
$inout_function = ($inout == 'in') ? '_input' : '_output';
|
||||
for ($i=1; $i < 5; $i++)
|
||||
{
|
||||
if (!empty($config['custom'.$i]))
|
||||
{
|
||||
$video['custom'.$i.'name'] = $config['custom'.$i];
|
||||
$run = 'custom_'.$config['custom'.$i.'type'].$inout_function;
|
||||
$custom_value = null;
|
||||
if (array_key_exists('custom'.$i, $video))
|
||||
{
|
||||
$custom_value = $video['custom'.$i];
|
||||
}
|
||||
$video['custom'.$i.$inout] = $run('custom'.$i,$custom_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom Type:
|
||||
*
|
||||
* Standardinputhandler for custom fields -> just calls text type
|
||||
*/
|
||||
function custom__input($cn,$cv)
|
||||
{
|
||||
return custom_text_input($cn,$cv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom Type:
|
||||
*
|
||||
* Standardoutputhandler for custom fields -> just calls text type
|
||||
*/
|
||||
function custom__output($cn,$cv)
|
||||
{
|
||||
return custom_text_output($cn,$cv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom Type: text
|
||||
*
|
||||
* Standardinputhandler for custom fields
|
||||
*/
|
||||
function custom_text_input($cn,$cv)
|
||||
{
|
||||
return '<input type="text" size="45" maxlength="255" name="'.$cn.'" id="'.$cn.'" value="'.formvar($cv).'" />';
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom Type: text
|
||||
*
|
||||
* Standardouputhandler for custom fields
|
||||
*/
|
||||
function custom_text_output($cn,$cv)
|
||||
{
|
||||
return $cv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom Type: url
|
||||
*
|
||||
* Stores an URL in a custom file and shows a clickable link.
|
||||
*/
|
||||
function custom_url_input($cn,$cv)
|
||||
{
|
||||
return '<input type="text" size="45" maxlength="255" name="'.$cn.'" id="'.$cn.'" value="'.formvar($cv).'" />';
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom Type: url
|
||||
*
|
||||
* Stores an URL in a custom file and shows a clickable link.
|
||||
*/
|
||||
function custom_url_output($cn,$cv)
|
||||
{
|
||||
if (!empty($cv))
|
||||
{
|
||||
return '<a href="'.$cv.'">[ Link ]</a>';
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom Type: ed2k
|
||||
*
|
||||
* Stores the MD4 sum of the File in a custom file and shows a clickable ed2k
|
||||
* Link for the eDonkey2000 client tools.
|
||||
*/
|
||||
function custom_ed2k_input($cn,$cv)
|
||||
{
|
||||
return '<input type="text" size="40" maxlength="255" name="'.$cn.'" id="'.$cn.'" value="'.formvar($cv).'" /> (MD4)';
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom Type: ed2k
|
||||
*
|
||||
* Stores the MD4 sum of the File in a custom file and shows a clickable ed2k
|
||||
* Link for the eDonkey2000 client tools.
|
||||
*/
|
||||
function custom_ed2k_output($cn,$cv)
|
||||
{
|
||||
global $video;
|
||||
|
||||
if (!empty($video[0]['filesize']) && !empty($video[0]['filename']) && !empty($cv)) {
|
||||
return '<a href="ed2k://|file|'.$video[0]['filename'].'|'.$video[0]['filesize'].'|'.$cv.'|">[ Add to eDonkey ]</a>';
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom Type: language
|
||||
*
|
||||
* Language Selection with Quickselectionbuttons configured in
|
||||
* $config['languages']
|
||||
*/
|
||||
function custom_language_input($cn,$cv)
|
||||
{
|
||||
global $config;
|
||||
|
||||
$output = '';
|
||||
$output .= '<input type="text" size="15" maxlength="255" name="'.$cn.'" id="'.$cn.'" value="'.formvar($cv).'" /> ';
|
||||
foreach ($config['languages'] as $flag)
|
||||
{
|
||||
$output .= '<a href="#" title="set to '.$flag.'" onclick="document.edi.'.$cn.'.value=\''.$flag.'\'">';
|
||||
$output .= '<img src="'.img('flags/'.$flag.'.gif').'" border="0" alt="'.formvar($cv).'" /></a> ';
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom Type: language
|
||||
*
|
||||
* Language Selection with Quickselectionbuttons configured in
|
||||
* $config[languages]
|
||||
*/
|
||||
function custom_language_output($cn,$cv)
|
||||
{
|
||||
return custom_text_output($cn,$cv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom Type: FSK
|
||||
*
|
||||
* Allows you to set the FSK Rating of a movie.
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
*/
|
||||
function custom_fsk_input($cn,$cv)
|
||||
{
|
||||
return custom_text_input($cn,$cv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom Type: FSK
|
||||
*
|
||||
* Allows you to display the FSK Rating.
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
*/
|
||||
function custom_fsk_output($cn,$cv)
|
||||
{
|
||||
$allfsktypes = array('0','6','12','16','18');
|
||||
if (!in_array ($cv, $allfsktypes))
|
||||
{
|
||||
return custom_text_output($cn,$cv);
|
||||
}
|
||||
|
||||
return '<a href="search.php?q='.$cv.'&fields='.$cn.'"><img border="0" src="'.img('r_'.$cv.'.gif').'" width="50" height="50" /></a>';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Custom Type: Barcode
|
||||
*
|
||||
* Allows you to input the Barcode of a movie.
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
*/
|
||||
function custom_barcode_input($cn,$cv)
|
||||
{
|
||||
return custom_text_input($cn,$cv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom Type: Barcode
|
||||
*
|
||||
* Allows you to display Barcode.
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
*/
|
||||
function custom_barcode_output($cn,$cv)
|
||||
{
|
||||
return custom_text_output($cn,$cv);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Custom Type: Originaltitle
|
||||
*
|
||||
* Holds the Original title of an movie
|
||||
*
|
||||
* @author Stephan Zalewski <stephan-01@gmx.de>
|
||||
*/
|
||||
function custom_orgtitle_input($cn,$cv)
|
||||
{
|
||||
global $config;
|
||||
global $imdbdata;
|
||||
global $id;
|
||||
|
||||
if (empty($cv)|| $config['lookupdefault_edit'] > 0 || $config['lookupdefault_new'] > 0)
|
||||
{
|
||||
if (!empty($imdbdata['title'])) {$cv .= ' - '.$imdbdata['title'];}
|
||||
if (!empty($imdbdata['subtitle'])) {$cv .= ' - '.$imdbdata['subtitle'];}
|
||||
|
||||
// we need to save our self here!
|
||||
if (!empty($id) && $cv != '')
|
||||
{
|
||||
$qcv = escapeSQL($cv);
|
||||
$UPDATE = "UPDATE ".TBL_DATA." SET $cn = '$qcv' WHERE id = $id";
|
||||
runSQL($UPDATE);
|
||||
}
|
||||
}
|
||||
return custom_text_input($cn,$cv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom Type: Originaltitle
|
||||
*
|
||||
* Holds the Original title of an movie
|
||||
*
|
||||
* @author Stephan Zalewski <stephan-01@gmx.de>
|
||||
*/
|
||||
function custom_orgtitle_output($cn,$cv)
|
||||
{
|
||||
return custom_text_output($cn,$cv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom Type: Movix
|
||||
*
|
||||
* Allows you to indicate if a movie is stored in a cd/dvd
|
||||
* with movix (http://movix.sourceforge.net/)
|
||||
*
|
||||
* @author Antonio Giungato <antonio_giungato@libero.it>
|
||||
*/
|
||||
|
||||
function custom_movix_input($cn,$cv)
|
||||
{
|
||||
$output ='<select name="'.$cn.'">
|
||||
<option selected value=""></option>
|
||||
<option value="eMovix">eMovix</option>
|
||||
<option value="Movix">Movix</option>
|
||||
<option value="Movix²">Movix²</option>
|
||||
</select>';
|
||||
return $output;
|
||||
}
|
||||
|
||||
function custom_movix_output($cn,$cv)
|
||||
{
|
||||
return custom_text_output($cn,$cv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom Type: MPAA
|
||||
*
|
||||
* Show the MPAA rating of a movie
|
||||
*
|
||||
* @author Tim M. Sanders <tsanders@thesanders.org>
|
||||
*/
|
||||
function custom_mpaa_input($cn,$cv)
|
||||
{
|
||||
global $config;
|
||||
global $imdbdata;
|
||||
global $id;
|
||||
|
||||
if (empty($cv)|| $config['lookupdefault_edit'] > 0 || $config['lookupdefault_new'] > 0)
|
||||
{
|
||||
if (!empty($imdbdata['mpaa'])) {$cv .= $imdbdata['mpaa'];}
|
||||
|
||||
//we need to save our self here!
|
||||
if(!empty($id) && $cv != '')
|
||||
{
|
||||
$qcv = escapeSQL($cv);
|
||||
$UPDATE = "UPDATE ".TBL_DATA." SET $cn = '$qcv' WHERE id = $id";
|
||||
runSQL($UPDATE);
|
||||
}
|
||||
}
|
||||
$output = '<input type="text" size="50" maxlength="255" name="'.$cn.'" id="'.$cn.'" value="'.formvar($cv).'" /> ';
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom Type: MPAA
|
||||
*
|
||||
* Show the MPAA rating of a movie
|
||||
*
|
||||
* @author Tim M. Sanders <tsanders@thesanders.org>
|
||||
*/
|
||||
function custom_mpaa_output($cn,$cv)
|
||||
{
|
||||
global $imdbdata;
|
||||
global $id;
|
||||
|
||||
$ratings = array('R' => 'mpaa-R.gif',
|
||||
'NC-17' => 'mpaa-NC-17.gif',
|
||||
'PG-13' => 'mpaa-PG-13.gif',
|
||||
'PG' => 'mpaa-PG.gif',
|
||||
'G' => 'mpaa-G.gif');
|
||||
|
||||
$output = custom_text_output($cn,$cv);
|
||||
foreach ($ratings as $rating => $image)
|
||||
{
|
||||
if (strstr($output, $rating))
|
||||
{
|
||||
$output .= '<br/><img src="'.img($image).'" alt="'.$rating.'"/>';
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom Type: BBFC
|
||||
*
|
||||
* Show the BBFC rating of a movie
|
||||
* Based on the MPAA ratings above
|
||||
*
|
||||
* @author Colin Ogilvie <csogilvie@users.sourceforge.net>
|
||||
*/
|
||||
function custom_bbfc_input($cn,$cv)
|
||||
{
|
||||
global $config;
|
||||
global $imdbdata;
|
||||
global $id;
|
||||
|
||||
if (empty($cv)|| $config['lookupdefault_edit'] > 0 || $config['lookupdefault_new'] > 0)
|
||||
{
|
||||
$cv = $imdbdata['bbfc'];
|
||||
if (!empty($imdbdata['bbfc'])) $cv .= $imdbdata['bbfc'];
|
||||
|
||||
//we need to save our self here!
|
||||
if(!empty($id) && $cv != '')
|
||||
{
|
||||
$qcv = escapeSQL($cv);
|
||||
$UPDATE = "UPDATE ".TBL_DATA." SET $cn = '$qcv' WHERE id = $id";
|
||||
runSQL($UPDATE);
|
||||
}
|
||||
}
|
||||
$output = '<input type="text" size="10" maxlength="4" name="'.$cn.'" id="'.$cn.'" value="'.formvar($cv).'" />';
|
||||
$output .= " <a href='#' onclick='document.edi.".$cn.".value=\"U\"'>U</a>";
|
||||
$output .= " <a href='#' onclick='document.edi.".$cn.".value=\"12\"'>12</a>";
|
||||
$output .= " <a href='#' onclick='document.edi.".$cn.".value=\"12A\"'>12A</a>";
|
||||
$output .= " <a href='#' onclick='document.edi.".$cn.".value=\"15\"'>15</a>";
|
||||
$output .= " <a href='#' onclick='document.edi.".$cn.".value=\"18\"'>18</a>";
|
||||
$output .= " <a href='#' onclick='document.edi.".$cn.".value=\"PG\"'>PG</a>";
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom Type: BBFC
|
||||
*
|
||||
* Show the BBFC rating of a movie
|
||||
* Based on the MPAA ratings above
|
||||
*
|
||||
* @author Colin Ogilvie <csogilvie@users.sourceforge.net>
|
||||
*/
|
||||
function custom_bbfc_output($cn,$cv)
|
||||
{
|
||||
global $imdbdata;
|
||||
global $id;
|
||||
|
||||
$ratings = array('PG' => 'bbfc-PG.gif',
|
||||
'12A' => 'bbfc-12A.gif',
|
||||
'12' => 'bbfc-12.gif',
|
||||
'15' => 'bbfc-15.gif',
|
||||
'18' => 'bbfc-18.gif',
|
||||
'U' => 'bbfc-U.gif');
|
||||
|
||||
$output = custom_text_output($cn,$cv);
|
||||
foreach ($ratings as $rating => $image)
|
||||
{
|
||||
if (strstr($output, (string) $rating))
|
||||
{
|
||||
$output = '<img src="'.img($image).'" alt="'.$rating.'"/>';
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
function custom_kijkwijzer_kijkwijzerdata () {
|
||||
return [
|
||||
'AL' => [1, 'Alle leeftijden', 'kijkwijzer/al.png', ''],
|
||||
'06' => [2, '6 jaar', 'kijkwijzer/6.png', ''],
|
||||
'09' => [4, '9 jaar', 'kijkwijzer/9.png', ''],
|
||||
'12' => [8, '12 jaar', 'kijkwijzer/12.png', ''],
|
||||
'14' => [16, '14 jaar', 'kijkwijzer/14.png', ''],
|
||||
'16' => [32, '16 jaar', 'kijkwijzer/16.png', ''],
|
||||
'18' => [64, '18 jaar', 'kijkwijzer/18.png', ''],
|
||||
'AN' => [128, 'Angst', 'kijkwijzer/angst.png', ''],
|
||||
'DI' => [256, 'Discriminatie', 'kijkwijzer/discriminatie.png', ''],
|
||||
'DA' => [512, 'Roken, alcohol en drugs', 'kijkwijzer/drugs-en-alcohol.png', ''],
|
||||
'GE' => [1024, 'Geweld', 'kijkwijzer/geweld.png', ''],
|
||||
'SE' => [2048, 'Seks', 'kijkwijzer/seks.png', ''],
|
||||
'TA' => [4096, 'Grof taalgebruik', 'kijkwijzer/taal.png', '']
|
||||
];
|
||||
}
|
||||
|
||||
function custom_kijkwijzer_input ($cn, $cv) {
|
||||
$kijkwijzer = custom_kijkwijzer_kijkwijzerdata();
|
||||
$output = '<input type="text" size="10" maxlength="4" name="'.$cn.'" id="'.$cn.'" value="'.formvar($cv).'" />';
|
||||
foreach ($kijkwijzer as $val => $cfg) {
|
||||
$output .= " <a href='#' onclick='document.edi.".$cn.".value+=\"".$val." \"' title='".$cfg[1]."'><img src=\"".img($cfg[2])."\" alt=\"Kijkwijzer: ".$cfg[1]."\" data-desc=\"".$cfg[3]."\" width=\"32\" /></a>";
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
function custom_kijkwijzer_output ($cn, $cv, $sm = false) {
|
||||
$kijkwijzer = custom_kijkwijzer_kijkwijzerdata();
|
||||
$rv = '';
|
||||
$cv = explode(' ', trim($cv));
|
||||
foreach ($cv as $i) {
|
||||
if (isset($kijkwijzer[$i])) {
|
||||
$rv .= '<img src="' . img($kijkwijzer[$i][2]) . '" alt="Kijkwijzer: ' . $kijkwijzer[$i][1] . '" title="' . $kijkwijzer[$i][1] . '" width="' . ($sm ? 24 : 48) . '" />';
|
||||
}
|
||||
}
|
||||
return $rv;
|
||||
}
|
||||
|
||||
263
videodb/core/edit.core.php
Normal file
263
videodb/core/edit.core.php
Normal file
@@ -0,0 +1,263 @@
|
||||
<?php
|
||||
/**
|
||||
* Edit functions. Split into separate file for reuse.
|
||||
*
|
||||
* @package videoDB
|
||||
* @author Andreas Götz <cpuidle@gmx.de>
|
||||
* @author Andreas Gohr <a.gohr@web.de>
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @version $Id: edit.core.php,v 1.9 2009/12/05 13:56:04 andig2 Exp $
|
||||
*/
|
||||
|
||||
require_once './core/security.php';
|
||||
|
||||
// list of fields to be read/written from/to html form
|
||||
$imdb_set_fields = array('md5','title','subtitle','language','diskid','mediatype','comment','disklabel',
|
||||
'imdbID','year','imgurl','director','actors','runtime','country','plot','filename',
|
||||
'filesize','filedate','audio_codec','video_codec','video_width','video_height','istv',
|
||||
'rating', 'custom1','custom2','custom3','custom4');
|
||||
|
||||
// list of fields to be overwritten by refetchAllInfos-Script
|
||||
$imdb_overwrite_fields = array('comment','disklabel','imdbID','year','director','actors','runtime','country','plot',
|
||||
'rating','custom1','custom2','custom3','custom4');
|
||||
|
||||
// special fields for SQL statements
|
||||
$db_null_fields = array('runtime', 'filesize', 'filedate', 'video_width', 'video_height');
|
||||
$db_zero_fields = array('istv', 'year');
|
||||
|
||||
/**
|
||||
* Obtain new disk id
|
||||
*
|
||||
* @return string Generated disk id
|
||||
*/
|
||||
function getDiskId()
|
||||
{
|
||||
global $config;
|
||||
|
||||
/*
|
||||
* change this if you have some fancy naming style
|
||||
*/
|
||||
|
||||
// how many digits have to be used for DiskId?
|
||||
$digits = ($config['diskid_digits']) ? $config['diskid_digits'] : 4;
|
||||
|
||||
/*
|
||||
* Old way automatic DiskID was generated: result was "highest ID + 1"
|
||||
*
|
||||
$NEXTUSERID = "SELECT LPAD(TRIM(LEADING '0' FROM MAX(LPAD(TRIM(LEADING '0' FROM diskid), 10, '0'))) + 1, ".
|
||||
$digits.", '0') AS max FROM ".TBL_DATA.' WHERE diskid NOT REGEXP "[^0-9]"';
|
||||
$result = runSQL($NEXTUSERID);
|
||||
return $result[0]['max'];
|
||||
*/
|
||||
|
||||
// get all DiskIds ordered from DB
|
||||
$SQL = "SELECT LPAD(TRIM(LEADING '0' FROM diskid), 10, '0') AS id
|
||||
FROM ".TBL_DATA.'
|
||||
WHERE diskid NOT REGEXP "[^0-9]" AND
|
||||
owner_id = '.get_current_user_id().'
|
||||
ORDER BY id';
|
||||
// sql looks strange but fixes problems with users who change their
|
||||
// diskid_digits while they have already movies in their DB.
|
||||
// added owner_id as fix for https://github.com/andig/videodb/issues/6
|
||||
$results = runSQL($SQL);
|
||||
|
||||
// find first 'free' diskId
|
||||
$lastid = 0;
|
||||
foreach ($results as $result)
|
||||
{
|
||||
$thisid = preg_replace('/^0+/','',$result['id']);
|
||||
if ($lastid + 1 < $thisid) break;
|
||||
$lastid = $thisid;
|
||||
}
|
||||
|
||||
// return the found id
|
||||
return str_pad($lastid + 1, $digits, '0', STR_PAD_LEFT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Strip leading articles
|
||||
*
|
||||
* @param string $field Input field to be stripped
|
||||
* @return string Input with articles rearranged to end of string
|
||||
*/
|
||||
function removeArticles($field)
|
||||
{
|
||||
$articles = array('the ', 'la ', 'a ', 'der ', 'die ', 'das ', 'des ', 'dem ', 'den ',
|
||||
'ein ', 'eine ', 'eines ', 'le ', 'el ', "l'", 'il ', 'les ', 'i ',
|
||||
'o ', 'un ', 'los ', 'de ', 'an ', 'una ', 'las ', 'gli ', 'het ',
|
||||
'lo ', 'os ', 'az ', 'ha-', 'een ', 'det ', 'oi ', 'ang ', 'ta ',
|
||||
'al-', 'uno ', "un'", 'ett ', 'mga ', 'Ï ', 'Ç ', 'els ', 'Ôï ', 'Ïé ');
|
||||
|
||||
foreach ($articles as $article)
|
||||
{
|
||||
if (preg_match("/^$article+/i", $field))
|
||||
{
|
||||
$field = trim(preg_replace("/(^$article)(.+)/i", "$2, $1", $field));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $field;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare item for display based on input data
|
||||
*/
|
||||
function echoInput($data)
|
||||
{
|
||||
global $imdb_set_fields;
|
||||
|
||||
// error no owner specified
|
||||
$video = array();
|
||||
|
||||
// select all fields according to list, plus id
|
||||
foreach ($imdb_set_fields as $name)
|
||||
{
|
||||
$video[0][$name] = $data[$name];
|
||||
}
|
||||
|
||||
return $video;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare update SQL
|
||||
*
|
||||
* @param array $data key/value pairs of data
|
||||
* @returns string result SQL, suitable for INSERT/UPDATE
|
||||
*/
|
||||
function prepareSQL($data, $setonly = false)
|
||||
{
|
||||
global $config, $imdb_set_fields, $db_null_fields, $db_zero_fields;
|
||||
|
||||
// get global variables into local scope
|
||||
extract($data);
|
||||
|
||||
// Fix for Bugreport [1122052] Automatic DiskID generation problem
|
||||
if ($config['autoid'] && !empty($diskid) && ($diskid == $autoid))
|
||||
{
|
||||
// in case DiskID is already used in meanwhile
|
||||
// -> update to new DiskId
|
||||
$diskid = getDiskId();
|
||||
}
|
||||
|
||||
// set default mediatype
|
||||
if (empty($mediatype)) $mediatype = $config['mediadefault'];
|
||||
|
||||
// set owner
|
||||
if (is_numeric($owner_id)) $SQL = 'owner_id = '.$owner_id;
|
||||
|
||||
// rating up to 10
|
||||
$rating = min($rating, 10);
|
||||
|
||||
// update all fields according to list
|
||||
foreach ($imdb_set_fields as $name)
|
||||
{
|
||||
if ($setonly && !isset($$name)) continue;
|
||||
|
||||
// sanitize input
|
||||
$$name = removeEvilTags($$name);
|
||||
if (!is_null($$name))
|
||||
{
|
||||
$$name = html_entity_decode($$name);
|
||||
}
|
||||
|
||||
// make sure no formatting contained in basic data
|
||||
if (in_array($name, array('title', 'subtitle')))
|
||||
{
|
||||
$$name = trim(strip_tags($$name));
|
||||
|
||||
// string leading articles?
|
||||
if ($config['removearticles'])
|
||||
{
|
||||
$$name = removeArticles($$name);
|
||||
}
|
||||
}
|
||||
|
||||
$SET = "$name = '".escapeSQL($$name)."'";
|
||||
|
||||
// special null/zero handling
|
||||
if (empty($$name))
|
||||
{
|
||||
if (in_array($name, $db_null_fields))
|
||||
$SET = "$name = NULL";
|
||||
elseif (in_array($name, $db_zero_fields))
|
||||
$SET = "$name = 0";
|
||||
}
|
||||
|
||||
if ($SQL) $SQL .= ', ';
|
||||
$SQL .= $SET;
|
||||
}
|
||||
|
||||
return $SQL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $SQL set fields
|
||||
* @param int $id id of item to update, insert if empty
|
||||
* @param boolean $touch true specifies to update created data of item
|
||||
*/
|
||||
function updateDB($SQL, $id, $touch=false)
|
||||
{
|
||||
if ($id)
|
||||
{
|
||||
// update existing record
|
||||
if ($touch)
|
||||
{
|
||||
// if the disk was on the wishlist and is now available, make sure it appears under 'new'
|
||||
$SQL .= ', created = NOW()';
|
||||
}
|
||||
|
||||
$SQL = 'UPDATE '.TBL_DATA.' SET '.$SQL.' WHERE id = '.$id;
|
||||
runSQL($SQL);
|
||||
}
|
||||
else
|
||||
{
|
||||
// insert new record
|
||||
$SQL = 'INSERT INTO '.TBL_DATA.' SET '.$SQL.', created = NOW()';
|
||||
$id = runSQL($SQL);
|
||||
}
|
||||
|
||||
return $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process HTTP file upload
|
||||
*/
|
||||
function processUpload($id, $file, $mime, $name)
|
||||
{
|
||||
if (!(isset($_FILES['coverupload']) && is_uploaded_file($_FILES['coverupload']['tmp_name'])))
|
||||
return;
|
||||
|
||||
// determine file extension
|
||||
if (preg_match('=image/jpe?g=i', $mime))
|
||||
{
|
||||
$ext = 'jpg';
|
||||
}
|
||||
elseif (preg_match('=image/(gif|png)=i', $mime, $m))
|
||||
{
|
||||
$ext = $m[1];
|
||||
}
|
||||
elseif (preg_match('=application/octet-stream=i', $mime))
|
||||
{
|
||||
if (preg_match("/\.(jpe?g|gif|png)$/i", $name, $m))
|
||||
{
|
||||
$ext = $m[1];
|
||||
}
|
||||
}
|
||||
|
||||
// move to cache and update db
|
||||
if (!empty($ext))
|
||||
{
|
||||
$coverfile = 'cache/img/'.$id.'.'.$ext;
|
||||
if (move_uploaded_file($file, $coverfile))
|
||||
{
|
||||
// fix permission issues
|
||||
chmod($coverfile, 0644);
|
||||
|
||||
$sql = "UPDATE ".TBL_DATA." SET imgurl='$coverfile' WHERE id=$id";
|
||||
runSQL($sql);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
282
videodb/core/encoding.php
Normal file
282
videodb/core/encoding.php
Normal file
@@ -0,0 +1,282 @@
|
||||
<?php
|
||||
/**
|
||||
* Encoding functions
|
||||
*
|
||||
* Contains HTML and Unicode conversion functions
|
||||
*
|
||||
* @package Core
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @version $Id: encoding.php,v 1.6 2013/03/10 16:25:35 andig2 Exp $
|
||||
*/
|
||||
|
||||
/**
|
||||
* Check if string contains unicode characters
|
||||
*/
|
||||
function is_utf8($str)
|
||||
{
|
||||
// array handling
|
||||
if (is_array($str)) {
|
||||
foreach($str as $k => $v) {
|
||||
$res = is_utf8($v);
|
||||
if (!$res) return(false);
|
||||
}
|
||||
return(true);
|
||||
}
|
||||
|
||||
// From http://w3.org/International/questions/qa-forms-utf-8.html
|
||||
return preg_match('%^(?:
|
||||
[\x09\x0A\x0D\x20-\x7E] # ASCII
|
||||
| [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
|
||||
| \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
|
||||
| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
|
||||
| \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
|
||||
| \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
|
||||
| [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15
|
||||
| \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
|
||||
)*$%xs', $str);
|
||||
}
|
||||
|
||||
/**
|
||||
* @author "Sebasti<74>n Grignoli" <grignoli@framework2.com.ar>
|
||||
* @package Encoding
|
||||
* @version 1.1
|
||||
* @link http://www.framework2.com.ar/dzone/forceUTF8-es/
|
||||
* @example http://www.framework2.com.ar/dzone/forceUTF8-es/
|
||||
*/
|
||||
function fix_utf8($text)
|
||||
{
|
||||
$utf8ToWin1252 = array(
|
||||
"\xe2\x82\xac" => "\x80",
|
||||
|
||||
"\xe2\x80\x9a" => "\x82",
|
||||
"\xc6\x92" => "\x83",
|
||||
"\xe2\x80\x9e" => "\x84",
|
||||
"\xe2\x80\xa6" => "\x85",
|
||||
"\xe2\x80\xa0" => "\x86",
|
||||
"\xe2\x80\xa1" => "\x87",
|
||||
"\xcb\x86" => "\x88",
|
||||
"\xe2\x80\xb0" => "\x89",
|
||||
"\xc5\xa0" => "\x8a",
|
||||
"\xe2\x80\xb9" => "\x8b",
|
||||
"\xc5\x92" => "\x8c",
|
||||
|
||||
"\xc5\xbd" => "\x8e",
|
||||
|
||||
|
||||
"\xe2\x80\x98" => "\x91",
|
||||
"\xe2\x80\x99" => "\x92",
|
||||
"\xe2\x80\x9c" => "\x93",
|
||||
"\xe2\x80\x9d" => "\x94",
|
||||
"\xe2\x80\xa2" => "\x95",
|
||||
"\xe2\x80\x93" => "\x96",
|
||||
"\xe2\x80\x94" => "\x97",
|
||||
"\xcb\x9c" => "\x98",
|
||||
"\xe2\x84\xa2" => "\x99",
|
||||
"\xc5\xa1" => "\x9a",
|
||||
"\xe2\x80\xba" => "\x9b",
|
||||
"\xc5\x93" => "\x9c",
|
||||
|
||||
"\xc5\xbe" => "\x9e",
|
||||
"\xc5\xb8" => "\x9f"
|
||||
);
|
||||
|
||||
if (is_array($text)) {
|
||||
foreach($text as $k => $v) {
|
||||
$text[$k] = fix_utf8($v);
|
||||
}
|
||||
return $text;
|
||||
}
|
||||
|
||||
$last = "";
|
||||
while ($last <> $text) {
|
||||
$last = $text;
|
||||
$text = utf8_encode(utf8_decode(str_replace(array_keys($utf8ToWin1252), array_values($utf8ToWin1252), $text)));
|
||||
}
|
||||
$text = utf8_encode(utf8_decode(str_replace(array_keys($utf8ToWin1252), array_values($utf8ToWin1252), $text)));
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode string is utf-8. Typically used for later URL encoding of the string
|
||||
*/
|
||||
function utf8_smart_decode($str)
|
||||
{
|
||||
return (is_utf8($str)) ? utf8_decode($str) : $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Like html_entity_decode() but also supports numeric entities.
|
||||
* Output encoding is ISO-8852-1.
|
||||
*
|
||||
* @author www.php.net
|
||||
* @param string $string html entity loaded string
|
||||
* @return string html entity free string
|
||||
*/
|
||||
function html_entity_decode_all($string)
|
||||
{
|
||||
// replace numeric entities
|
||||
$string = preg_replace_callback('~&#x([0-9a-f]+);~i', '_callback_chr_hexdec', $string);
|
||||
$string = preg_replace_callback('~&#([0-9]+);~', '_callback_chr', $string);
|
||||
# utf8 version commented out
|
||||
# $string = preg_replace_callback('~&#x([0-9a-f]+);~i', '_callback_code2utf_hexdec', $string);
|
||||
# $string = preg_replace_callback('~&#([0-9]+);~', '_callback_code2utf', $string);
|
||||
|
||||
// replace literal entities
|
||||
$trans_tbl = get_html_translation_table(HTML_ENTITIES);
|
||||
$trans_tbl = array_flip($trans_tbl);
|
||||
# utf8 version commented out
|
||||
# foreach (get_html_translation_table(HTML_ENTITIES) as $val=>$key) $trans_tbl[$key] = utf8_encode($val);
|
||||
|
||||
return strtr($string, $trans_tbl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Like html_entity_decode() but also supports numeric entities.
|
||||
* Output encoding is UTF-8.
|
||||
*
|
||||
* @author www.php.net
|
||||
* @param string $string html entity loaded string
|
||||
* @return string html entity free string
|
||||
*/
|
||||
function html_entity_decode_all_utf8($string)
|
||||
{
|
||||
// replace numeric entities
|
||||
# non-utf8 version commented out
|
||||
# $string = preg_replace_callback('~&#x([0-9a-f]+);~i', '_callback_chr_hexdec', $string);
|
||||
# $string = preg_replace_callback('~&#([0-9]+);~', '_callback_chr', $string);
|
||||
$string = preg_replace_callback('~&#x([0-9a-f]+);~i', '_callback_code2utf_hexdec', $string);
|
||||
$string = preg_replace_callback('~&#([0-9]+);~', '_callback_code2utf', $string);
|
||||
|
||||
// replace literal entities
|
||||
# non-utf8 version commented out
|
||||
# $trans_tbl = get_html_translation_table(HTML_ENTITIES);
|
||||
# $trans_tbl = array_flip($trans_tbl);
|
||||
foreach (get_html_translation_table(HTML_ENTITIES) as $val=>$key) $trans_tbl[$key] = utf8_encode($val);
|
||||
|
||||
return strtr($string, $trans_tbl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the utf-8 encoding corresponding to the unicode character value
|
||||
* @author from php.net, courtesy - romans@void.lv
|
||||
*/
|
||||
function code2utf($num)
|
||||
{
|
||||
if ($num < 128) return chr($num);
|
||||
if ($num < 2048) return chr(($num >> 6) + 192) . chr(($num & 63) + 128);
|
||||
if ($num < 65536) return chr(($num >> 12) + 224) . chr((($num >> 6) & 63) + 128) . chr(($num & 63) + 128);
|
||||
if ($num < 2097152) return chr(($num >> 18) + 240) . chr((($num >> 12) & 63) + 128) . chr((($num >> 6) & 63) + 128) . chr(($num & 63) + 128);
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean HTML entities and replace special spaces
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @param string $string html entity loaded string
|
||||
* @return string html entity free string
|
||||
*/
|
||||
function html_clean($str)
|
||||
{
|
||||
return trim(str_replace(chr(160), ' ', html_entity_decode_all($str)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean HTML entities, tags and replace special spaces
|
||||
* Output encoding is UTF-8.
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @param string $str html entity loaded string
|
||||
* @return string html entity free string
|
||||
*/
|
||||
function html_clean_utf8($str)
|
||||
{
|
||||
# this replacement breaks unicode enitity encoding as A0 might occor as part of any character
|
||||
# $str = str_replace(chr(160), ' ', $str);
|
||||
$str = html_entity_decode_all_utf8(strip_tags($str));
|
||||
return trim($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Chance character set encoding for hierarchical array
|
||||
*
|
||||
* @param mixed $data string or hierarchical array to convert
|
||||
* @return mixed data in target encoding
|
||||
*/
|
||||
function iconv_array($source_encoding, $target_encoding, $data)
|
||||
{
|
||||
if (is_array($data))
|
||||
{
|
||||
// recursive call for array conversion
|
||||
foreach ($data as $key => $val)
|
||||
{
|
||||
$data[$key] = iconv_array($source_encoding, $target_encoding, $val);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// finally convert string value
|
||||
$data_saved = $data; // save data for output on error page if signalled
|
||||
$data = iconv($source_encoding, $target_encoding."//TRANSLIT", (string)$data);
|
||||
if ($data === FALSE)
|
||||
{
|
||||
errorpage('Character set conversion error', "Error converting from $source_encoding to $target_encoding. <br> String <br> $data_saved");
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert HTML to plain text for some common entities
|
||||
*/
|
||||
function html_to_text($str)
|
||||
{
|
||||
// create list items
|
||||
$str = preg_replace("#<li.*?>#i", "\n-", $str);
|
||||
|
||||
// de-html line breaks
|
||||
$str = preg_replace('#<(br|p).*?>#i', "\n", $str);
|
||||
|
||||
// avoid double line breaks
|
||||
$str = preg_replace("#\n+#", "\n", $str);
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that there is only one match from a preg_replace_callback and return it
|
||||
*/
|
||||
function _get_only_match_from_callback($matches) {
|
||||
assert(sizeof($matches) === 2);
|
||||
return $matches[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* apply chr on the only match of a preg_replace_callback
|
||||
*/
|
||||
function _callback_chr($matches) {
|
||||
return chr(_get_only_match_from_callback($matches));
|
||||
}
|
||||
|
||||
/**
|
||||
* apply hexdec and chr on the only match of a preg_replace_callback
|
||||
*/
|
||||
function _callback_chr_hexdec($matches) {
|
||||
return chr(hexdec(_get_only_match_from_callback($matches)));
|
||||
}
|
||||
|
||||
/**
|
||||
* apply code2utf on the only match of a preg_replace_callback
|
||||
*/
|
||||
function _callback_code2utf($matches) {
|
||||
return code2utf(_get_only_match_from_callback($matches));
|
||||
}
|
||||
|
||||
/**
|
||||
* apply hexdec and code2utf on the only match of a preg_replace_callback
|
||||
*/
|
||||
function _callback_code2utf_hexdec($matches) {
|
||||
return code2utf(hexdec(_get_only_match_from_callback($matches)));
|
||||
}
|
||||
?>
|
||||
81
videodb/core/export.core.php
Normal file
81
videodb/core/export.core.php
Normal file
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
/**
|
||||
* Export functions. Returns standardized data for export.
|
||||
*
|
||||
* @package videoDB
|
||||
* @author Andreas Götz <cpuidle@gmx.de>
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @version $Id: export.core.php,v 1.8 2013/03/15 16:42:46 andig2 Exp $
|
||||
*/
|
||||
|
||||
require_once './core/genres.php';
|
||||
|
||||
function listExports($link, $omit = array('rss'))
|
||||
{
|
||||
global $config;
|
||||
|
||||
$exports = array('xls' => 'Microsoft Excel',
|
||||
'pdf' => 'Adobe PDF',
|
||||
'xml' => 'XML',
|
||||
'rss' => 'RSS Feed');
|
||||
|
||||
$res = array();
|
||||
foreach ($exports as $export => $title)
|
||||
{
|
||||
if ($config[$export] &! in_array($export, $omit))
|
||||
$res[] = array('type' => $export, 'title' => $title, 'link' => $link);
|
||||
}
|
||||
return($res);
|
||||
}
|
||||
|
||||
function exportData($WHERE)
|
||||
{
|
||||
$SQL = 'SELECT '.TBL_DATA.'.*,
|
||||
'.TBL_USERS.'.name AS owner,
|
||||
'.TBL_MEDIATYPES.'.name AS mediatype,
|
||||
'.TBL_LENT.'.who AS lentto,
|
||||
CASE WHEN '.TBL_USERSEEN.'.video_id IS NULL THEN 0 ELSE 1 END AS seen
|
||||
FROM '.TBL_DATA.'
|
||||
LEFT JOIN '.TBL_USERS.' ON '.TBL_DATA.'.owner_id = '.TBL_USERS.'.id
|
||||
LEFT JOIN '.TBL_USERSEEN.' ON '.TBL_DATA.'.id = '.TBL_USERSEEN.'.video_id AND '.TBL_USERSEEN.'.user_id = '.get_current_user_id().'
|
||||
LEFT JOIN '.TBL_LENT.' ON '.TBL_DATA.'.diskid = '.TBL_LENT.'.diskid
|
||||
LEFT JOIN '.TBL_MEDIATYPES.' ON mediatype = '.TBL_MEDIATYPES.'.id '.
|
||||
$WHERE;
|
||||
|
||||
$result = runSQL($SQL);
|
||||
|
||||
// do adultcheck
|
||||
if (is_array($result))
|
||||
{
|
||||
$result = array_filter($result, function($video) {return adultcheck($video["id"]);});
|
||||
}
|
||||
|
||||
// genres
|
||||
for($i=0; $i<count($result); $i++)
|
||||
{
|
||||
$result[$i]['genres'] = getItemGenres($result[$i]['id'], true);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Limit string length while honoring word breaks
|
||||
*
|
||||
* @param string string to trim
|
||||
* @param int target length
|
||||
* @result string trimmed string
|
||||
*/
|
||||
function leftString($plot, $text_length)
|
||||
{
|
||||
if (strlen($plot) > $text_length+3)
|
||||
{
|
||||
$plot = substr($plot, 0, $text_length);
|
||||
$space = strrpos($plot, ' ');
|
||||
if ($space) $plot = substr($plot, 0, $space);
|
||||
$plot .= '...';
|
||||
}
|
||||
return $plot;
|
||||
}
|
||||
|
||||
?>
|
||||
279
videodb/core/functions.core.php
Normal file
279
videodb/core/functions.core.php
Normal file
@@ -0,0 +1,279 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* General functions
|
||||
*
|
||||
* Contains globally available tool functions. It is included in every
|
||||
* page and sets up some defaults like error reporting, environment
|
||||
* setups and config loading
|
||||
*
|
||||
* @package Core
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @author Andreas Gohr <a.gohr@web.de>
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @version $Id: functions.core.php,v 1.1 2013/04/26 15:08:30 andig2 Exp $
|
||||
*/
|
||||
|
||||
if (!function_exists('errorpage')) {
|
||||
function errorpage($title = 'An error occured', $body = '', $stacktrace = false) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Output debug info
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @param mixed $var Variable to dump
|
||||
* @param bool $ret Return result instead of outputting
|
||||
* @param bool $plain Indicate that \n separator is used
|
||||
*/
|
||||
function dump($var, $ret = false, $plain = false)
|
||||
{
|
||||
global $argv;
|
||||
if (isset($argv) && is_array($argv) && count($argv) > 0) $plain = true;
|
||||
|
||||
if (is_array($var) || is_object($var))
|
||||
$var = print_r($var, 1);
|
||||
else if (is_bool($var))
|
||||
$var = ($var) ? 'TRUE' : 'FALSE';
|
||||
|
||||
$var .= (is_array($argv)&&count($argv) > 0 || $plain) ? "\n" : "<br/>\n";
|
||||
|
||||
if ($ret) return $var;
|
||||
echo $var;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write variable to file
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @param string $filename Filename to dump to
|
||||
* @param var $var Variable to dump
|
||||
*/
|
||||
function file_append($filename, $var, $append = true)
|
||||
{
|
||||
$log = fopen($filename, $append ? 'a' : 'w');
|
||||
fwrite($log, dump($var, true, true));
|
||||
fclose($log);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write to debug log
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @param mixed $var Variable to dump
|
||||
*/
|
||||
function dlog($var)
|
||||
{
|
||||
file_append(LOG_FILE, $var);
|
||||
}
|
||||
|
||||
/**
|
||||
* safe formoutputter
|
||||
*
|
||||
* @param string $name The input string
|
||||
* @return string The cleaned string
|
||||
*/
|
||||
function formvar($name)
|
||||
{
|
||||
if (!is_null($name))
|
||||
{
|
||||
return htmlspecialchars($name);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get high resolution time
|
||||
*
|
||||
* @return integer current time in microseconds
|
||||
*/
|
||||
function getmicrotime()
|
||||
{
|
||||
list($usec, $sec) = explode(' ', microtime());
|
||||
return ((float)$usec + (float)$sec);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return mysqli db connection object
|
||||
*
|
||||
* @return mysqli database handle
|
||||
*/
|
||||
function getConnection()
|
||||
{
|
||||
global $config, $dbh;
|
||||
|
||||
$dbh = mysqli_connect('p:'.$config['db_server'], $config['db_user'], $config['db_password'], $config['db_database']);
|
||||
if (mysqli_connect_error())
|
||||
errorpage('DB Connection Error',
|
||||
"<p>Edit the database settings in <code>".CONFIG_FILE."</code>.</p>
|
||||
<p>Alternatively, consider running the <a href='install.php'>installation script</a>.</p>");
|
||||
|
||||
if (DB_CHARSET)
|
||||
{
|
||||
if (mysqli_set_charset($dbh, DB_CHARSET) === false)
|
||||
errorpage('DB Link Error', 'Couldn\'t set encoding to '.DB_CHARSET);
|
||||
}
|
||||
|
||||
return($dbh);
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape SQL string according to current DB charset settings
|
||||
*
|
||||
* @param string $sql_string SQL string to escape
|
||||
* @return string escaped string
|
||||
*/
|
||||
function escapeSQL($sql_string)
|
||||
{
|
||||
global $dbh;
|
||||
|
||||
if (!is_null($sql_string))
|
||||
{
|
||||
if (!is_resource($dbh)) $dbh = getConnection();
|
||||
|
||||
return(mysqli_real_escape_string($dbh, $sql_string));
|
||||
}
|
||||
|
||||
return ("");
|
||||
}
|
||||
|
||||
/**
|
||||
* SQL wrapper for all Database accesses
|
||||
*
|
||||
* @param string $sql_string The SQL-Statement to execute
|
||||
* @return mixed either the resultset as an array with hashes or the insertid
|
||||
*/
|
||||
function runSQL($sql_string, $verify = true)
|
||||
{
|
||||
global $config, $dbh, $SQLtrace;
|
||||
|
||||
if ($config['debug'])
|
||||
{
|
||||
dlog("\n".$_SERVER['REQUEST_URI']);
|
||||
if (function_exists('xdebug_get_function_stack')) dlog(join(' -> ', array_column(xdebug_get_function_stack(), 'function')));
|
||||
dlog($sql_string);
|
||||
$timestamp = getmicrotime();
|
||||
}
|
||||
|
||||
if (!is_resource($dbh)) $dbh = getConnection();
|
||||
$res = mysqli_query($dbh, $sql_string);
|
||||
|
||||
// mysqli_db_query returns either positive result ressource or true/false for an insert/update statement
|
||||
if ($res === false)
|
||||
{
|
||||
$result = false;
|
||||
if ($verify)
|
||||
{
|
||||
// report DB Problem
|
||||
errorpage('Database Problem', mysqli_error($dbh)."\n<br />\n".$sql_string, true);
|
||||
}
|
||||
}
|
||||
elseif ($res === true)
|
||||
{
|
||||
// on insert, return id of created record
|
||||
$result = mysqli_insert_id($dbh);
|
||||
}
|
||||
else
|
||||
{
|
||||
// return associative result array
|
||||
$result = array();
|
||||
|
||||
for ($i=0; $i<mysqli_num_rows($res); $i++)
|
||||
{
|
||||
$result[] = mysqli_fetch_assoc($res);
|
||||
}
|
||||
mysqli_free_result($res);
|
||||
}
|
||||
|
||||
if ($config['debug'])
|
||||
{
|
||||
$timestamp = getmicrotime() - $timestamp;
|
||||
dlog('Time: '.$timestamp);
|
||||
// collect all SQL info for debugging
|
||||
$SQLtrace[] = array('sql' => $sql_string, 'time' => $timestamp);
|
||||
}
|
||||
|
||||
# mysqli_close($dbh);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the page is accessed from within the local net.
|
||||
*
|
||||
* @return bool true if localnet
|
||||
*/
|
||||
function localnet()
|
||||
{
|
||||
global $config;
|
||||
return (preg_match('/'.$config['localnet'].'/', $_SERVER['REMOTE_ADDR']));
|
||||
}
|
||||
|
||||
/**
|
||||
* checks if the page is accessed from within the local net.
|
||||
* If not, displays a simple error page and exits
|
||||
*/
|
||||
function localnet_or_die()
|
||||
{
|
||||
if (!localnet()) errorpage('Forbidden', 'You are not allowed to access this page');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set connection encoding according to config file or language specification
|
||||
*/
|
||||
function db_set_encoding()
|
||||
{
|
||||
global $config, $lang;
|
||||
|
||||
// set connection character set and collation
|
||||
if (DB_CHARSET)
|
||||
{
|
||||
$sql = "SET NAMES '".DB_CHARSET."'";
|
||||
$collation = ($lang['collation']) ? DB_CHARSET.'_'.$lang['collation'] : DB_COLLATION;
|
||||
if ($collation) $sql .= " COLLATE '".$collation."'";
|
||||
|
||||
runSQL($sql);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect to new location
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @param string $dest Redirect destination
|
||||
* @todo Read somewhere that according to RFC redirects need to specify full URI
|
||||
*/
|
||||
function redirect($dest)
|
||||
{
|
||||
header('Location: '.$dest);
|
||||
exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an array of associative arrays (e.g. a database query result) to an associative key=>value array
|
||||
*
|
||||
* Sample: array_associate( 0=>(a=>1a, b=1b) 1=>(a=>2a, b=>2b), "a", "b" ) gives 1a=>1b, 2a=>2b
|
||||
*
|
||||
* If $value is false, the whole array is associated instead of a specific value
|
||||
*
|
||||
* Sample: array_associate( 0=>(a=>1a, b=1b) 1=>(a=>2a, b=>2b), "a", false ) gives 1a=>(b=>1b), 2a=>(b=>2b
|
||||
*
|
||||
* TODO Check if this can be replaced by PHP5.5 array_column() function
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @param $ary SQL result array
|
||||
* @param $key key index name
|
||||
* @param $value value index name
|
||||
* @return array resulting associative array
|
||||
*/
|
||||
function array_associate($ary, $columnKey, $value = false)
|
||||
{
|
||||
$res = array();
|
||||
foreach ($ary as $row)
|
||||
{
|
||||
$res[$row[$columnKey]] = ($value) ? $row[$value] : $row;
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
?>
|
||||
1095
videodb/core/functions.php
Normal file
1095
videodb/core/functions.php
Normal file
File diff suppressed because it is too large
Load Diff
137
videodb/core/genres.php
Normal file
137
videodb/core/genres.php
Normal file
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
/**
|
||||
* Genre functions
|
||||
*
|
||||
* Contains functions for working with video genres
|
||||
* moved from functions.php to genres.php
|
||||
*
|
||||
* @package Core
|
||||
* @author Andreas Gohr <a.gohr@web.de>
|
||||
* @author Andreas Götz <cpuidle@gmx.de>
|
||||
* @version $Id: genres.php,v 1.14 2008/01/29 10:59:52 veal Exp $
|
||||
*/
|
||||
|
||||
/**
|
||||
* Map movie genres to versions existing in db
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @param array $genres A list of input genres
|
||||
* @return array The mapped genres result array
|
||||
*/
|
||||
function mapGenres($genres)
|
||||
{
|
||||
global $dbgenres;
|
||||
|
||||
// load genres from DB once
|
||||
if (empty($dbgenres))
|
||||
{
|
||||
$dbgenres = array();
|
||||
foreach (runSQL('SELECT id, name FROM '.TBL_GENRES.' ORDER BY name') as $row)
|
||||
{
|
||||
$dbgenres[] = $row['name'];
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($genres as $in_genre)
|
||||
{
|
||||
$mapped_genre = '';
|
||||
$mapped_percent = 0;
|
||||
|
||||
$in_genre = trim($in_genre);
|
||||
|
||||
// direct match?
|
||||
if (in_array($in_genre, $dbgenres))
|
||||
{
|
||||
$gens[] = $in_genre;
|
||||
}
|
||||
else
|
||||
{
|
||||
// possible approximate match
|
||||
foreach ($dbgenres as $genre_name)
|
||||
{
|
||||
// calculate similiarity and find best match
|
||||
$chars = similar_text($in_genre, $genre_name, $percent);
|
||||
if ($percent >= 50)
|
||||
{
|
||||
if (stristr($in_genre, $genre_name)) $percent += 10;
|
||||
if ($percent > $mapped_percent)
|
||||
{
|
||||
$mapped_genre = $genre_name;
|
||||
$mapped_percent = $percent;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($mapped_genre) $gens[] = $mapped_genre;
|
||||
}
|
||||
}
|
||||
|
||||
return array_unique($gens);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the genreID for a given name from the 'genres' table
|
||||
*
|
||||
* @todo check if this can be moved to edit.php
|
||||
* @param string $name the name of the genre
|
||||
* @return integer $genre the genre id
|
||||
*/
|
||||
function getGenreId($name)
|
||||
{
|
||||
$name = escapeSQL($name);
|
||||
$result = runSQL("SELECT id FROM ".TBL_GENRES." WHERE LCASE(name) = LCASE('".$name."')");
|
||||
return $result[0]['id'];
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieve genre ids/ genres of a video
|
||||
*
|
||||
* @param integer $id ID of the video
|
||||
* @param boolean $names include genre names in output
|
||||
* @return array genre id's OR
|
||||
* @return array associative array of genre ids and names
|
||||
*/
|
||||
function getItemGenres($id, $names = false)
|
||||
{
|
||||
$genres = array();
|
||||
if (empty($id)) return $genres;
|
||||
|
||||
$SELECT = 'SELECT genres.id, genres.name
|
||||
FROM '.TBL_GENRES.' AS genres, '.TBL_VIDEOGENRE.' AS videogenre
|
||||
WHERE genres.id = videogenre.genre_id
|
||||
AND videogenre.video_id = '.$id;
|
||||
$result = runSQL($SELECT);
|
||||
|
||||
if ($names) return $result;
|
||||
|
||||
foreach ($result as $row)
|
||||
{
|
||||
$genres[] = $row['id'];
|
||||
}
|
||||
|
||||
return $genres;
|
||||
}
|
||||
|
||||
/**
|
||||
* save genres for a movie
|
||||
*
|
||||
* @todo check if this can be moved to edit.php
|
||||
* @param integer $id ID of the video
|
||||
* @param array $genres genre IDs
|
||||
*/
|
||||
function setItemGenres($id, $genres)
|
||||
{
|
||||
// Delete all genres for id
|
||||
runSQL('DELETE FROM '.TBL_VIDEOGENRE.' WHERE video_id = '.$id);
|
||||
|
||||
if (count($genres))
|
||||
{
|
||||
$genres = array_unique($genres);
|
||||
|
||||
foreach($genres as $genre)
|
||||
{
|
||||
runSQL('INSERT INTO '.TBL_VIDEOGENRE.' SET video_id = '.$id.', genre_id = '.$genre);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
111
videodb/core/httpcache.php
Normal file
111
videodb/core/httpcache.php
Normal file
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
/**
|
||||
* HTTP caching functions
|
||||
*
|
||||
* Enable use of HTTP 304 headers for unmodified content to save bandwidth
|
||||
*
|
||||
* @package Core
|
||||
* @author Andreas Götz <cpuidle@gmx.de>
|
||||
* @version $Id: httpcache.php,v 1.5 2010/11/05 10:38:47 andig2 Exp $
|
||||
*/
|
||||
|
||||
/**
|
||||
* Start output buffering
|
||||
*/
|
||||
function httpCacheCaptureStart()
|
||||
{
|
||||
ob_start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop output buffering
|
||||
*
|
||||
* @param string MD5 hash of content
|
||||
*/
|
||||
function httpCacheCaptureEnd()
|
||||
{
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get last modified data for given etag
|
||||
* Checks session for known etag and timestamp
|
||||
*/
|
||||
function httpCacheCheckTag($template, $etag)
|
||||
{
|
||||
if ($etag != $_SESSION['vdb'][$template]['etag'])
|
||||
{
|
||||
$lastmod = time();
|
||||
$_SESSION['vdb'][$template]['etag'] = $etag;
|
||||
$_SESSION['vdb'][$template]['time'] = $lastmod;
|
||||
}
|
||||
else
|
||||
{
|
||||
$lastmod = $_SESSION['vdb'][$template]['time'];
|
||||
}
|
||||
return($lastmod);
|
||||
}
|
||||
|
||||
/**
|
||||
* Output 304 Not Modified header
|
||||
* Require browser to re-check on next request
|
||||
*/
|
||||
function httpCacheHeaders($etag, $expires)
|
||||
{
|
||||
header(php_sapi_name() == 'cgi' ? 'Status: 304 Not Modified' : 'HTTP/1.x 304 Not Modified');
|
||||
header("ETag: {$etag}");
|
||||
header("Cache-Control: private, max-age={$expires}, pre-check=0, post-check=0");
|
||||
header("Content-Length: 0");
|
||||
|
||||
header("Content-Type: !invalid");
|
||||
exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if output was modified since last request
|
||||
* If unmodifed, output 304 Not Modified header
|
||||
* Otherwise add additional ETag and LastModified headers
|
||||
*/
|
||||
function httpCacheOutput($template, $content)
|
||||
{
|
||||
$etag = '"'.md5($content).'"';
|
||||
|
||||
// check if 'sending' is necessary (using cache functions)
|
||||
$sendbody = true;
|
||||
$expires = 0;
|
||||
|
||||
$lastmod = httpCacheCheckTag($template, $etag);
|
||||
|
||||
// check 'If-Modified-Since' header
|
||||
if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && gmdate('D, d M Y H:i:s', $lastmod)." GMT" == trim($_SERVER['HTTP_IF_MODIFIED_SINCE']))
|
||||
{
|
||||
httpCacheHeaders($etag, $expires);
|
||||
}
|
||||
|
||||
// check 'If-None-Match' header (ETag)
|
||||
if ($sendbody && isset($_SERVER['HTTP_IF_NONE_MATCH']))
|
||||
{
|
||||
$inm = explode(',', $_SERVER['HTTP_IF_NONE_MATCH']);
|
||||
foreach ($inm as $i)
|
||||
{
|
||||
if (trim($i) != $etag) continue;
|
||||
httpCacheHeaders($etag, $expires);
|
||||
}
|
||||
}
|
||||
|
||||
// send with caching headers (enable cache for one day)
|
||||
$exp_gmt = gmdate('D, d M Y H:i:s', time() + $expires).' GMT';
|
||||
$mod_gmt = gmdate('D, d M Y H:i:s', $lastmod).' GMT';
|
||||
header("Expires: {$exp_gmt}");
|
||||
header("Last-Modified: {$mod_gmt}");
|
||||
header("Cache-Control: private, max-age={$expires}, pre-check=0, post-check=0");
|
||||
header("Pragma: !invalid");
|
||||
header("ETag: {$etag}");
|
||||
|
||||
echo $content;
|
||||
}
|
||||
|
||||
?>
|
||||
246
videodb/core/httpclient.php
Normal file
246
videodb/core/httpclient.php
Normal file
@@ -0,0 +1,246 @@
|
||||
<?php
|
||||
/**
|
||||
* HTTP client functions
|
||||
*
|
||||
* @todo Encapsulate httpClient and Cache as separate classes
|
||||
*
|
||||
* @package Core
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @author Andreas Gohr <a.gohr@web.de>
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @version $Id: httpclient.php,v 1.21 2013/04/26 15:09:35 andig2 Exp $
|
||||
*/
|
||||
|
||||
require_once 'core/cache.php';
|
||||
require_once 'vendor/autoload.php';
|
||||
|
||||
use GuzzleHttp\Psr7 as Psr7;
|
||||
|
||||
/**
|
||||
* Reads a saved HTTP response from a cachefile.
|
||||
* If caching is globally disabled ($config['IMDBage'] <= 0), file is not loaded.
|
||||
*
|
||||
* @param string $url URL of the cached response
|
||||
* @return mixed HTTP Response, false on errors
|
||||
*/
|
||||
function getHTTPcache($url)
|
||||
{
|
||||
global $config;
|
||||
|
||||
if (@$config['cache_pruning'])
|
||||
{
|
||||
$cache_file = cache_get_filename($url, CACHE_HTML);
|
||||
cache_prune_folder(dirname($cache_file).'/', $config['IMDBage']);
|
||||
}
|
||||
|
||||
return cache_get($url, CACHE_HTML, $config['IMDBage'], true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves a HTTP resonse to a cachefile
|
||||
* If caching is globally disabled ($config['IMDBage'] <= 0), file is not saved.
|
||||
*
|
||||
* @param string $url URL of the response
|
||||
* @param mixed $resp HTTP Response
|
||||
*/
|
||||
function putHTTPcache($url, $data)
|
||||
{
|
||||
global $config;
|
||||
|
||||
// for debugging purposes track there the request originated
|
||||
$data['source'] = $url;
|
||||
|
||||
cache_put($url, $data, CACHE_HTML, $config['IMDBage'], true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract source encoding from HTML code or HTTP header otherwise
|
||||
*/
|
||||
function get_response_encoding($response)
|
||||
{
|
||||
$header = $encoding = null;
|
||||
|
||||
// response array from cache
|
||||
if (is_array($response)) {
|
||||
if (isset($response['header']['Content-Type'])) {
|
||||
$header = $response['header']['Content-Type'];
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Psr response
|
||||
$header = $response->getHeader('Content-Type');
|
||||
}
|
||||
|
||||
if ($header) {
|
||||
$parsed = Psr7\parse_header($header);
|
||||
if (array_key_exists('charset', $parsed[0]))
|
||||
{
|
||||
$encoding = strtolower($parsed[0]['charset']);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$encoding)
|
||||
{
|
||||
$encoding = 'iso-8859-1';
|
||||
}
|
||||
|
||||
return $encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* HTTP Client
|
||||
*
|
||||
* Returns the raw data from the given URL, uses proxy when configured
|
||||
* and follows redirects
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @param string $url URL to fetch
|
||||
* @param bool $cache use caching? defaults to false
|
||||
* @param string $post POST data, if nonempty POST is used instead of GET
|
||||
* @param integer $timeout Timeout in seconds defaults to 15
|
||||
* @return mixed HTTP response
|
||||
*/
|
||||
function httpClient($url, $cache = false, $para = null, $reload = false)
|
||||
{
|
||||
static $referer = 'https://www.imdb.com/search/';
|
||||
global $config;
|
||||
$client = new GuzzleHttp\Client();
|
||||
|
||||
$requestConfig = [];
|
||||
$headers = ''; // additional HTTP headers, used for post data
|
||||
|
||||
if (!empty($para) && array_key_exists('cookies', $para) && $para['cookies'])
|
||||
{
|
||||
$jar = new GuzzleHttp\Cookie\CookieJar();
|
||||
$requestConfig += ['cookies' => $jar];
|
||||
}
|
||||
|
||||
$method = 'GET';
|
||||
|
||||
$post = isset($para['post']) ? $para['post'] : '';
|
||||
if ($post)
|
||||
{
|
||||
$method = 'POST';
|
||||
$requestConfig += ['headers' => ['Content-Type' => 'application/x-www-form-urlencoded']];
|
||||
$requestConfig += ['body' => $post];
|
||||
}
|
||||
|
||||
// get data from cache?
|
||||
if ($cache &! $reload)
|
||||
{
|
||||
$resp = getHTTPcache($url.$post);
|
||||
if ($resp !== false)
|
||||
{
|
||||
$resp['cached'] = true;
|
||||
return $resp;
|
||||
}
|
||||
}
|
||||
|
||||
// proxy setup
|
||||
if (!empty($config['proxy_host']) && !$para['no_proxy'])
|
||||
{
|
||||
$server = $config['proxy_host'];
|
||||
if (!($port = @$config['proxy_port']))
|
||||
{
|
||||
$port = 8080;
|
||||
}
|
||||
$requestConfig += ['proxy' => sprintf('tcp://%s:%d', $server, $port)];
|
||||
}
|
||||
|
||||
// additional request headers
|
||||
if (!empty($para) && array_key_exists('header', $para) && $para['header'])
|
||||
{
|
||||
$requestConfig += ['headers' => $para['header']];
|
||||
}
|
||||
|
||||
if (empty($requestConfig['headers']['Accept'])) $requestConfig['headers']['Accept'] = 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8';
|
||||
if (empty($requestConfig['headers']['Accept-Language'])) $requestConfig['headers']['Accept-Language'] = ((isset($config['acclangbrowser']) && $config['acclangbrowser']) ? filter_input(INPUT_SERVER, 'HTTP_ACCEPT_LANGUAGE') : 'en-US;q=0.7,en;q=0.3');
|
||||
if (empty($requestConfig['headers']['DNT'])) $requestConfig['headers']['DNT'] = '1';
|
||||
if (empty($requestConfig['headers']['User-Agent'])) $requestConfig['headers']['User-Agent'] = filter_input(INPUT_SERVER, 'HTTP_USER_AGENT');
|
||||
if (empty($requestConfig['headers']['Referer'])) $requestConfig['headers']['Referer'] = $referer;
|
||||
|
||||
$resp = $client->request($method, $url, $requestConfig);
|
||||
|
||||
$response['error'] = '';
|
||||
$response['url'] = $url;
|
||||
$response['success'] = false;
|
||||
$response['encoding'] = get_response_encoding($resp);
|
||||
$response['header'] = $resp->getHeaders();
|
||||
$response['data'] = (string) $resp->getBody();
|
||||
|
||||
if ($config['debug']) echoHeaders($response['header'])."<p>";
|
||||
if ($config['debug']) echo "data:<br>".htmlspecialchars($response['data'])."<p>";
|
||||
|
||||
|
||||
// log response
|
||||
if ($config['httpclientlog'])
|
||||
{
|
||||
$log = fopen('httpClient.log', 'a');
|
||||
fwrite($log, headers_to_string($response['header']));
|
||||
fclose($log);
|
||||
}
|
||||
|
||||
// verify status code
|
||||
if ($resp->getStatusCode() != 200)
|
||||
{
|
||||
$response['error'] = 'Server returned wrong status: ' . $resp->getStatusCode();
|
||||
$response['error'] .= " Reason: " . $resp->getReasonPhrase();
|
||||
return $response;
|
||||
}
|
||||
|
||||
$response['success'] = true;
|
||||
// @todo i'm not sure on the side-effects of setting the previous requested URL as referer
|
||||
// for the next, so disabled for now. might be something to investigate...
|
||||
//$referer = $url;
|
||||
|
||||
// commit successful request to cache
|
||||
if ($cache)
|
||||
{
|
||||
putHTTPcache($url.$post, $response);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Print all header info using echo
|
||||
* @param response Object homepage Psr7\Response
|
||||
*/
|
||||
function echoHeaders($headers)
|
||||
{
|
||||
foreach ($headers as $name => $values) {
|
||||
echo $name . ': ' . implode(', ', $values) . "<br>";
|
||||
}
|
||||
}
|
||||
|
||||
function headers_to_string($headers)
|
||||
{
|
||||
$result = '';
|
||||
foreach ($headers as $name => $values) {
|
||||
$result .= $name . ': ' . implode(', ', $values) . "\n";
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Downloads an URL to the given local file
|
||||
*
|
||||
* @param string $url URL to download
|
||||
* @param string $local Full path to save to
|
||||
* @return bool true on succes else false
|
||||
*/
|
||||
function download($url, $local)
|
||||
{
|
||||
$resp = httpClient($url);
|
||||
|
||||
if (!$resp['success'])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return(@file_put_contents($local, $resp['data']) !== false);
|
||||
}
|
||||
|
||||
?>
|
||||
68
videodb/core/ids.php
Normal file
68
videodb/core/ids.php
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* IDS setup
|
||||
*
|
||||
* @package Core
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @version $Id: ids.php,v 1.2 2010/02/01 22:38:42 andig2 Exp $
|
||||
*/
|
||||
|
||||
// set the include path properly for PHPIDS
|
||||
set_include_path(
|
||||
get_include_path()
|
||||
. PATH_SEPARATOR
|
||||
. './lib/'
|
||||
);
|
||||
|
||||
if (!session_id()) {
|
||||
session_start();
|
||||
}
|
||||
|
||||
require_once 'IDS/Init.php';
|
||||
|
||||
try {
|
||||
$init = IDS_Init::init(dirname(__FILE__) . '/../lib/IDS/Config/Config.ini');
|
||||
$init->config['General']['base_path'] = dirname(__FILE__) . '/../lib/IDS/';
|
||||
$init->config['General']['use_base_path'] = true;
|
||||
$init->config['Caching']['caching'] = 'file';
|
||||
|
||||
$request = array(
|
||||
'GET' => $_GET,
|
||||
'POST' => $_POST,
|
||||
'COOKIE' => $_COOKIE
|
||||
);
|
||||
|
||||
$ids = new IDS_Monitor($request, $init);
|
||||
|
||||
$result = $ids->run();
|
||||
if (!$result->isEmpty() && $result->getImpact() > 50)
|
||||
{
|
||||
require_once 'IDS/Log/Database.php';
|
||||
require_once 'IDS/Log/Composite.php';
|
||||
$compositeLog = new IDS_Log_Composite();
|
||||
$compositeLog->addLogger(
|
||||
IDS_Log_Database::getInstance($init)
|
||||
);
|
||||
$compositeLog->execute($result);
|
||||
|
||||
$hta = @file_get_contents('.htaccess');
|
||||
if (preg_match('/(.+?)^(allow from all.*)/ms', $hta, $m))
|
||||
{
|
||||
$addr = $_SERVER['REMOTE_ADDR'];
|
||||
|
||||
// block whole subnet
|
||||
$addr = implode('.', array_slice(explode('.', $addr), 0, 3));
|
||||
|
||||
$hta = $m[1] . 'deny from '.$addr."\n" . $m[2];
|
||||
@file_put_contents('.htaccess', $hta);
|
||||
}
|
||||
|
||||
header("HTTP/1.0 403 Forbidden");
|
||||
die('Your IP has been blocked.<br/>To find out why visit <a href="http://sourceforge.net/mailarchive/forum.php?forum_name=videodb-devel">http://sourceforge.net/mailarchive/forum.php?forum_name=videodb-devel</a>');
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
//this shouldn't happen and if it does you don't want the notification public.
|
||||
}
|
||||
|
||||
?>
|
||||
326
videodb/core/install.core.php
Normal file
326
videodb/core/install.core.php
Normal file
@@ -0,0 +1,326 @@
|
||||
<?php
|
||||
/**
|
||||
* Installer functions
|
||||
*
|
||||
* Create database, tables and config file
|
||||
*
|
||||
* @package Setup
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @version $Id: install.core.php,v 1.11 2010/02/18 15:15:37 andig2 Exp $
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Build formatted message string for html output
|
||||
*
|
||||
* @param string $msg Message to print
|
||||
* @param string $color Color code for <div> tag
|
||||
* @param boolean $print If true, output directly, else append to message string
|
||||
*/
|
||||
function showmessage($msg, $color, $print = false)
|
||||
{
|
||||
global $message;
|
||||
|
||||
if ($msg) $msg = "<span style='color: $color'>$msg</span><br/><br/>\n";
|
||||
if ($print)
|
||||
{
|
||||
// print directly
|
||||
echo $msg;
|
||||
}
|
||||
else
|
||||
{
|
||||
// return
|
||||
$message .= $msg;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare formatted error message for output
|
||||
*
|
||||
* @param string $msg Message to print
|
||||
* @param boolean $print If true, output directly, else append to message string
|
||||
*/
|
||||
function error($msg, $print = false)
|
||||
{
|
||||
showmessage($msg, 'red', $print);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare formatted warning message for output
|
||||
*
|
||||
* @param string $msg Message to print
|
||||
* @param boolean $print If true, output directly, else append to message string
|
||||
*/
|
||||
function warn($msg, $print = false)
|
||||
{
|
||||
showmessage($msg, 'orange', $print);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare formatted info message for output
|
||||
*
|
||||
* @param string $msg Message to print
|
||||
* @param boolean $print If true, output directly, else append to message string
|
||||
*/
|
||||
function info($msg, $print = false)
|
||||
{
|
||||
showmessage($msg, 'green', $print);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Recursively delete files from directory
|
||||
* used for Smarty cache cleanup during installation
|
||||
*
|
||||
* @param string $dir Directory name
|
||||
* @param boolean $recursive Recurse into subfolders
|
||||
*/
|
||||
function delete_files($dir, $recursive = false)
|
||||
{
|
||||
if ($dh = @opendir($dir))
|
||||
{
|
||||
while (($file = readdir($dh)) !== false)
|
||||
{
|
||||
// next if . or ..
|
||||
if (preg_match("/^\.\.?$/", $file)) continue;
|
||||
|
||||
// recursion?
|
||||
if (is_dir("$dir/$file"))
|
||||
{
|
||||
if ($recursive) delete_files("$dir/$file", $recursive);
|
||||
}
|
||||
else
|
||||
{
|
||||
// delete file
|
||||
unlink("$dir/$file");
|
||||
}
|
||||
}
|
||||
closedir($dh);
|
||||
|
||||
if ($recursive) rmdir($dir);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse config file and replace settings according
|
||||
* to associate array parameter
|
||||
*
|
||||
* @param array new parameter values
|
||||
*/
|
||||
function parse_config($vars)
|
||||
{
|
||||
$raw = null;
|
||||
|
||||
if ($file = @file_get_contents(CONFIG_FILE)) {
|
||||
$raw = explode("\n", $file);
|
||||
|
||||
for ($i = 0; $i < count($raw); $i++)
|
||||
{
|
||||
foreach ($vars as $name => $val)
|
||||
{
|
||||
if (preg_match("/^(.*?'$name'.*?=\s*)(.*?)(\s*;.*?)$/", $raw[$i], $matches))
|
||||
{
|
||||
# quoted?
|
||||
if (preg_match("/^[\"'].*[\"']$/", $matches[2])) $val = "'$val'";
|
||||
$matches[2] = $val;
|
||||
$raw[$i] = join('', array_slice($matches,1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fallback if config file is empty or invalid
|
||||
if (count($raw) < 4)
|
||||
{
|
||||
$raw = array('<?php');
|
||||
foreach ($vars as $name => $val)
|
||||
{
|
||||
$line = "\$config['$name'] = ";
|
||||
$line .= (is_numeric($val)) ? "$val;" : "'$val';";
|
||||
$raw[] = $line;
|
||||
}
|
||||
$raw[] = '?>';
|
||||
}
|
||||
|
||||
return join("\n", $raw);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse database upgrade SQL file and
|
||||
* build associate array of upgrade sql steps per version
|
||||
*
|
||||
* @return array associative array of upgrade steps
|
||||
*/
|
||||
function parse_upgrades($upgrade_file)
|
||||
{
|
||||
$cfg = file_get_contents($upgrade_file);
|
||||
$raw = preg_split('/# changes in DB version /i', $cfg);
|
||||
|
||||
// loop through list of db upgrades split by comments
|
||||
foreach ($raw as $str)
|
||||
{
|
||||
// upgrade version comment found?
|
||||
if (preg_match('/(\d+)\s*#\s*(.+)/s', $str, $m))
|
||||
{
|
||||
$key = $m[1];
|
||||
$str = $m[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (empty($upgrades['3']))
|
||||
{
|
||||
// this is the first supported version
|
||||
$key = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
// unexpected first db upgrade version found
|
||||
trigger_error('Could not parse <a href="'.$upgrade_file.'">'.$upgrade_file.'</a>, please fix!', E_USER_ERROR);
|
||||
}
|
||||
}
|
||||
$upgrades["$key"] = $str;
|
||||
}
|
||||
return $upgrades;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback function for adding prefix to table name in FROM clauses- extended to include sub queries
|
||||
*
|
||||
* $match[2] is table
|
||||
*/
|
||||
function sql_add_prefix($match)
|
||||
{
|
||||
global $db_prefix;
|
||||
|
||||
$match[2] = preg_replace('/(\'?\w+\'?)(\s*\w*)(,?)/', "`$db_prefix$1`$2$3", $match[2]);
|
||||
return join(array_slice($match, 1, 3));
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefix table names with table name prefix
|
||||
* This will only work for simple queries with known structure (createtables.sql, updatedb.sql)
|
||||
*
|
||||
* @param string SQL command
|
||||
* @return string SQL command with new table names
|
||||
*/
|
||||
function prefix_query($query)
|
||||
{
|
||||
global $db_prefix;
|
||||
|
||||
$query = preg_replace('/((CREATE|ALTER)\s+TABLE\s+(IF\s+NOT\s+EXISTS\s+)?)`?(\w+)`?/', "$1`$db_prefix$4`", $query);
|
||||
$query = preg_replace('/((INSERT(\s+IGNORE)?|REPLACE)\s+INTO\s+)`?(\w+)`?/', "$1`$db_prefix$4`", $query);
|
||||
|
||||
$query = preg_replace('/(DROP\s+TABLE\s+(IF\s+EXISTS\s+)?)`?(\w+)`?(;?)/', "$1`$db_prefix$3`$4", $query);
|
||||
// changed to allow only replace if sql update to row
|
||||
$query = preg_replace('/(UPDATE\s+)`?(\w+)`?(\s+SET\s+)`?/', "$1`$db_prefix$2`$3", $query);
|
||||
|
||||
// FROM matches at beginning of string or subquery opened by left bracket
|
||||
$query = preg_replace_callback( "/(\s+FROM\s+)(.*?)((\s+WHERE|ORDER|LEFT|RIGHT|OUTER|JOIN)|\)|$)/msi", 'sql_add_prefix', $query);
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run multiple comma-separated queries
|
||||
*
|
||||
* @todo Split SQL queries more cleverly (currently not needed)
|
||||
*
|
||||
* @param string SQL commands
|
||||
* @param ressource database handle
|
||||
* @return mixed result array or false
|
||||
*/
|
||||
function runSQL($sql, $dbh, $verify = false)
|
||||
{
|
||||
$result = true;
|
||||
foreach (explode(';', $sql) as $query)
|
||||
{
|
||||
$query = trim($query);
|
||||
if (empty($query)) continue;
|
||||
|
||||
$query = prefix_query($query);
|
||||
$result = mysqli_query($dbh, $query);
|
||||
|
||||
// error running SQL?
|
||||
if ($result === false)
|
||||
{
|
||||
$sql = $query;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// error running SQL?
|
||||
if ($result === false)
|
||||
{
|
||||
if ($verify)
|
||||
{
|
||||
error("Error in SQL statement:<br/>".
|
||||
"<code>$sql</code><br/>".mysqli_error($dbh));
|
||||
}
|
||||
}
|
||||
|
||||
// result set returned?
|
||||
elseif ($result !== true)
|
||||
{
|
||||
$res = array();
|
||||
|
||||
for ($i=0; $i < mysqli_num_rows($result); $i++)
|
||||
{
|
||||
$res[] = mysqli_fetch_assoc($result);
|
||||
}
|
||||
mysqli_free_result($result);
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run all upgrade scripts passed as array step by step
|
||||
*
|
||||
* @param array $upgrade_steps Associative array of upgrade sql steps
|
||||
*/
|
||||
function db_upgrade($upgrade_steps)
|
||||
{
|
||||
global $dbh, $version;
|
||||
global $step;
|
||||
|
||||
foreach ($upgrade_steps as $ver => $sql)
|
||||
{
|
||||
#info("Upgrading to database version: $ver");
|
||||
$sql = preg_replace('/#.*\n/m','',$sql);
|
||||
|
||||
if (runSQL($sql, $dbh) === false)
|
||||
{
|
||||
error('Error upgrading database, try full install instead of upgrade:<br/>'.mysqli_error($dbh).
|
||||
'<br/><br/><pre>'.$sql.'</pre>');
|
||||
return false;
|
||||
}
|
||||
|
||||
// perform additional upgrade steps
|
||||
$upgrade_file = "./install/upgrade_v$ver.php";
|
||||
if (file_exists($upgrade_file))
|
||||
{
|
||||
$result = include_once($upgrade_file);
|
||||
if (!$result) return($false);
|
||||
}
|
||||
|
||||
// add DB version information- this will make the separate update statement in upgrade.sql obsolete
|
||||
runSQL("REPLACE INTO config (opt,value) VALUES ('dbversion', ".$ver.");", $dbh);
|
||||
# runSQL("update config set value=25 where opt='dbversion'");
|
||||
|
||||
$version = $ver;
|
||||
}
|
||||
|
||||
// perform generic upgrade validation
|
||||
$upgrade_file = "./install/upgrade.php";
|
||||
if (file_exists($upgrade_file))
|
||||
{
|
||||
$result = include_once($upgrade_file);
|
||||
if (!$result) return($false);
|
||||
}
|
||||
|
||||
return $version;
|
||||
}
|
||||
|
||||
?>
|
||||
278
videodb/core/output.php
Normal file
278
videodb/core/output.php
Normal file
@@ -0,0 +1,278 @@
|
||||
<?php
|
||||
/**
|
||||
* Output functions
|
||||
*
|
||||
* Functions for HTML output generation (Not templates!)
|
||||
*
|
||||
* @todo Check if this can be moved to smarty plugins
|
||||
*
|
||||
* @package Core
|
||||
* @author Andreas Gohr <a.gohr@web.de>
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @version $Id: output.php,v 1.29 2013/04/19 07:55:58 andig2 Exp $
|
||||
*/
|
||||
|
||||
require_once './core/functions.php';
|
||||
|
||||
/**
|
||||
* Return list of valid genres from db
|
||||
*/
|
||||
function getGenres()
|
||||
{
|
||||
$SELECT = 'SELECT id, name
|
||||
FROM '.TBL_GENRES.'
|
||||
ORDER BY name';
|
||||
$result = runSQL($SELECT);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display genre checkboxes
|
||||
*
|
||||
* @param array $selected selected genre IDs
|
||||
* @return string HTML for genre checkboxes
|
||||
*/
|
||||
function out_genres($selected)
|
||||
{
|
||||
global $config;
|
||||
|
||||
$result = getGenres();
|
||||
$out = '<table class="genreselect"><tr>';
|
||||
|
||||
// get list of adult genres
|
||||
$adultgenres = array();
|
||||
if ($config['multiuser'] && !check_permission(PERM_ADULT))
|
||||
{
|
||||
$adultgenres = get_adult_genres();
|
||||
}
|
||||
|
||||
$row = 0;
|
||||
foreach ($result as $res)
|
||||
{
|
||||
// don't show adult genres if no permissions
|
||||
if (in_array($res['id'], $adultgenres)) continue;
|
||||
|
||||
$out .= '<td nowrap="nowrap">';
|
||||
$out .= '<input type="checkbox" name="genres[]" id="genreid'.$res['id'].'" value="'.$res['id'].'"';
|
||||
if (@in_array ($res['id'], $selected))
|
||||
{
|
||||
$out .= ' checked="checked"';
|
||||
}
|
||||
$out .= '/>';
|
||||
$out .= '<label for="genreid'.$res['id'].'">'.$res['name'].'</label>';
|
||||
$out .= '</td>';
|
||||
if ((++$row % 5) == 0)
|
||||
{
|
||||
$out .= '</tr><tr>';
|
||||
}
|
||||
}
|
||||
$out .= '</tr></table>';
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate genres array for use with genre checkboxes
|
||||
*
|
||||
* @param array $selected selected genre IDs
|
||||
* @return string HTML for genre checkboxes
|
||||
*/
|
||||
function out_genres2($item_genres = null)
|
||||
{
|
||||
global $config;
|
||||
// get detailed genres
|
||||
$all_genres = getGenres();
|
||||
$adultgenres = array();
|
||||
if ($config['multiuser'] && !check_permission(PERM_ADULT)) {
|
||||
$adultgenres = get_adult_genres();
|
||||
}
|
||||
|
||||
$genres = array();
|
||||
foreach ($all_genres as $gen) {
|
||||
// don't show adult genres if no permissions
|
||||
if (in_array($gen['id'], $adultgenres)) continue;
|
||||
|
||||
// selected?
|
||||
if ($item_genres) $gen['checked'] = (@in_array($gen['id'], $item_genres)) ? 1 : 0;
|
||||
|
||||
$genres[] = $gen;
|
||||
}
|
||||
|
||||
return($genres);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display selectbox with available Mediatypes
|
||||
*
|
||||
* @todo is this still used? can it be replaced by template code?
|
||||
* @author <rob@robvonk.com>
|
||||
* @return string HTML of selectbox
|
||||
*/
|
||||
function out_mediatypes($prefix = null)
|
||||
{
|
||||
global $config;
|
||||
|
||||
// select mediatypes
|
||||
$SELECT = 'SELECT id, name
|
||||
FROM '.TBL_MEDIATYPES.'
|
||||
ORDER BY name';
|
||||
$result = runSQL($SELECT);
|
||||
|
||||
// build associative array
|
||||
# array('0' => '') +
|
||||
$mediatypes = is_array($prefix) ? $prefix : array();
|
||||
$mediatypes = $mediatypes + array_associate($result, 'id', 'name');
|
||||
|
||||
return $mediatypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* All available language flags for config screen
|
||||
*
|
||||
* @param array $flags selected flags
|
||||
* @return string HTML of Languageflags
|
||||
*/
|
||||
function out_languageflags($flags)
|
||||
{
|
||||
global $config;
|
||||
|
||||
$out = '';
|
||||
$count = 1;
|
||||
|
||||
if (($dh = @opendir('./'.$config['templatedir'].'images/flags')) || ($dh = opendir('./images/flags')))
|
||||
{
|
||||
while (($file = readdir($dh)) !== false)
|
||||
{
|
||||
if (preg_match("/(.*)\.gif$/", $file, $matches))
|
||||
{
|
||||
$CHECK= (in_array($matches[1], $flags)) ? 'checked="checked"' : '';
|
||||
$out .= '<input type="checkbox" name="languages[]" '.$CHECK.' id="flag_'.$matches[1].'" value="'.$matches[1].'" />';
|
||||
$out .= '<label for="flag_'.$matches[1].'">';
|
||||
$out .= '<img src="'.img('flags/'.$matches[1].'.gif').'" width="30" height="15" alt="'.ucwords($matches[1]).'" title="'.ucwords($matches[1]).'" />';
|
||||
$out .= '</label> ';
|
||||
if ($count++%4 == 0) $out.='<br />';
|
||||
}
|
||||
}
|
||||
closedir($dh);
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* List of owners names/ids with valid permissions for use in edit/index/search templates
|
||||
*
|
||||
* @author <cpuidle@gmx.de>
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @param string $prefix Predefined additional Array entries
|
||||
* @param string $permission Honor permissions for selectbox
|
||||
* @return array Array with keys=ownernames and values=ownerids
|
||||
*/
|
||||
function out_owners($prefix = null, $permission = false, $keyIsId = false)
|
||||
{
|
||||
global $config;
|
||||
|
||||
// all permissions available if admin
|
||||
if (check_permission(PERM_ADMIN)) $permission = false;
|
||||
|
||||
// hide guest if he/she can't login
|
||||
$WHERES = ($config['denyguest']) ? " AND B.id != ".$config['guestid'] : '';
|
||||
|
||||
// select user ids- if permissions are required and no all access given, this is done against xrefs
|
||||
if ($permission && !check_permission($permission))
|
||||
{
|
||||
// xref permissions
|
||||
// TODO use cached permission table instead
|
||||
$SELECT = 'SELECT DISTINCT(B.name) AS name, B.id
|
||||
FROM '.TBL_PERMISSIONS.' A, '.TBL_USERS.' B
|
||||
WHERE A.to_uid = B.id
|
||||
AND A.from_uid = '.get_current_user_id().'
|
||||
AND (A.permissions & '.$permission.') = '.$permission.$WHERES.'
|
||||
ORDER BY name';
|
||||
}
|
||||
else
|
||||
{
|
||||
// all users +/- guest
|
||||
$SELECT = 'SELECT B.id, B.name
|
||||
FROM '.TBL_USERS.' B
|
||||
WHERE 1=1 '.$WHERES.'
|
||||
ORDER BY B.name';
|
||||
}
|
||||
$result = runSQL($SELECT);
|
||||
|
||||
$key = ($keyIsId) ? 'id' : 'name';
|
||||
|
||||
// build associative array
|
||||
$owners = is_array($prefix) ? $prefix : array();
|
||||
$owners = $owners + array_unique(array_associate($result, $key, 'name'));
|
||||
|
||||
return $owners;
|
||||
}
|
||||
|
||||
/**
|
||||
* MySQL-compatible list of owner ids with required access permission
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
*/
|
||||
function get_owner_ids($permission)
|
||||
{
|
||||
foreach($_SESSION['vdb']['permissions']['to_uid'] as $to_uid => $perm)
|
||||
{
|
||||
if ($permission & $perm) $ids[] = $to_uid;
|
||||
}
|
||||
|
||||
return (count($ids)) ? join(',', $ids) : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Present a size (in bytes) as a human-readable value
|
||||
*
|
||||
* @author http://php.net
|
||||
*
|
||||
* @param int $size size (in bytes)
|
||||
* @param int $precision number of digits after the decimal point
|
||||
* @return string
|
||||
*/
|
||||
function sizetostring($size, $precision = 0)
|
||||
{
|
||||
$sizes = array('YB', 'ZB', 'EB', 'PB', 'TB', 'GB', 'MB', 'kB', 'B');
|
||||
$total = count($sizes);
|
||||
|
||||
while($total-- && $size > 1024) $size /= 1024;
|
||||
return round($size, $precision).$sizes[$total];
|
||||
}
|
||||
|
||||
// @todo unused
|
||||
function img_avg_color($filename, $format=0)
|
||||
{
|
||||
// networked file
|
||||
if (preg_match('/^http/i', $imgurl)) return(FALSE);
|
||||
|
||||
// not a valid image
|
||||
if (!list($width, $height) = @getimagesize($filename)) return(FALSE);
|
||||
|
||||
// resample
|
||||
switch (exif_imagetype($filename)) {
|
||||
case 2:
|
||||
$img = imagecreatefromjpeg($filename);
|
||||
break;
|
||||
case 3:
|
||||
$img = imagecreatefrompng($filename);
|
||||
break;
|
||||
case 1:
|
||||
$img = imagecreatefromgif($filename);
|
||||
break;
|
||||
}
|
||||
|
||||
$tmp = imagecreatetruecolor(1, 1);
|
||||
if (!imagecopyresampled($tmp, $img, 0, 0, 0, 0, 1, 1, $width, $height)) return(FALSE);
|
||||
|
||||
$rgb = imagecolorat($tmp, 0, 0);
|
||||
$r = dechex($rgb >> 16);
|
||||
$g = dechex($rgb >> 8 & 0xFF);
|
||||
$b = dechex($rgb & 0xFF);
|
||||
|
||||
return('#'.$r.$g.$b);
|
||||
}
|
||||
|
||||
?>
|
||||
457
videodb/core/pdf.php
Normal file
457
videodb/core/pdf.php
Normal file
@@ -0,0 +1,457 @@
|
||||
<?php
|
||||
/**
|
||||
* PDF Export functions
|
||||
*
|
||||
* Allows exporting movies to PDF
|
||||
* Requires FPDF libaray (http://www.fpdf.org)
|
||||
*
|
||||
* @package Core
|
||||
* @link http://www.fpdf.org
|
||||
* @author Andreas Götz <cpuidle@gmx.de>
|
||||
* @version $Id: pdf.php,v 1.36 2013/03/15 16:42:46 andig2 Exp $
|
||||
*/
|
||||
|
||||
require_once './core/functions.php';
|
||||
require_once './core/cache.php';
|
||||
require_once './core/export.core.php';
|
||||
require_once './engines/engines.php';
|
||||
require_once './core/VariableStream.class.php';
|
||||
|
||||
define('FPDF', './vendor/setasign/fpdf');
|
||||
define('FPDF_FONTPATH', FPDF.'/font/');
|
||||
|
||||
require_once FPDF.'/fpdf.php';
|
||||
require_once './lib/fpdf2file/fpdf2file.php';
|
||||
|
||||
/**
|
||||
* Copied from FPDF tutorial 3
|
||||
* enhanced with memory image creation for gif->png conversion
|
||||
*
|
||||
* @link http://www.fpdf.org/?go=script&id=45
|
||||
*/
|
||||
class PDF extends FPDF2File
|
||||
{
|
||||
var $B;
|
||||
var $I;
|
||||
var $U;
|
||||
var $HREF;
|
||||
var $GDCount = 0;
|
||||
var $Scale = 0; // dont rescale images
|
||||
|
||||
function FPDF2File($orientation='P', $unit='mm', $format='A4')
|
||||
{
|
||||
//Call parent constructor
|
||||
$this->FPDF($orientation,$unit,$format);
|
||||
//Initialization
|
||||
$this->B=0;
|
||||
$this->I=0;
|
||||
$this->U=0;
|
||||
$this->HREF='';
|
||||
}
|
||||
|
||||
function GDImage($file, $x, $y, $im, $w=0, $h=0, $link='', $type='png')
|
||||
{
|
||||
// ouput the GD image $im
|
||||
ob_start();
|
||||
$func = 'image'.$type; // image creation function according to type
|
||||
$func($im);
|
||||
$data = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
// create file-unique variable name to not duplicate images for pdf
|
||||
$file = (empty($file)) ? $this->GDCount++ : preg_replace('/[\s\/\.]/', '_', $file);
|
||||
$name = 'pdf_image_'.$file;
|
||||
$GLOBALS[$name] = $data;
|
||||
|
||||
// call Image using in-memory PNG file
|
||||
parent::Image('var://'.$name, $x, $y, $w, $h, $type, $link);
|
||||
}
|
||||
|
||||
function Image($file, $x=null, $y=null, $w=0, $h=0, $ext='', $link='')
|
||||
{
|
||||
global $config;
|
||||
|
||||
$image_types = array(1 => 'gif', 2 => 'jpg', 3 => 'png', 6 => 'bmp');
|
||||
|
||||
list($width, $height, $ext, $attr) = getimagesize($file);
|
||||
$ext = $image_types[$ext];
|
||||
|
||||
// find image loading function
|
||||
switch($ext)
|
||||
{
|
||||
case 'jpg': $func = 'jpeg'; break;
|
||||
case 'bmp': $func = 'wbmp'; break;
|
||||
default: $func = $ext;
|
||||
}
|
||||
$func = 'imagecreatefrom'.$func;
|
||||
|
||||
// check if loading functions exists (especially for gif support)
|
||||
$im = (function_exists($func)) ? $func($file) : imagecreatetruecolor(1,1);
|
||||
|
||||
// scaling requested?
|
||||
if ($this->Scale)
|
||||
{
|
||||
$this->max_width = round($this->Scale * $config['pdf_image_max_width']);
|
||||
$this->max_height = round($this->Scale * $config['pdf_image_max_height']);
|
||||
|
||||
$scale = min($this->max_width/$width, $this->max_height/$height);
|
||||
$thumb_x = round($width * $scale);
|
||||
$thumb_y = round($height * $scale);
|
||||
}
|
||||
|
||||
// scaling requied?
|
||||
if (($this->Scale) && (($thumb_x != $width) || ($thumb_y != $height)))
|
||||
{
|
||||
// create white truecolor image (in case original is transparent)
|
||||
$target = imagecreatetruecolor($thumb_x, $thumb_y);
|
||||
$white = imagecolorallocate($target, 255, 255, 255);
|
||||
imagefilledrectangle($target, 0, 0, $thumb_x, $thumb_y, $white);
|
||||
imagecopyresampled($target, $im, 0,0, 0,0, $thumb_x,$thumb_y, $width,$height);
|
||||
$this->GDImage($file, $x, $y, $target, $w, $h, $link, 'jpeg'); // change to png if you receive acrobat errors
|
||||
imagedestroy($target);
|
||||
}
|
||||
elseif ($ext == 'gif') {
|
||||
// pdf doesn't support interlaced images
|
||||
if (imageinterlace($im))
|
||||
{
|
||||
// claim non-interlaced image
|
||||
imageinterlace($im, false);
|
||||
}
|
||||
|
||||
$this->GDImage($file, $x, $y, $im, $w, $h, $link);
|
||||
}
|
||||
else {
|
||||
parent::Image($file, $x, $y, $w, $h, $ext, $link);
|
||||
}
|
||||
|
||||
imagedestroy($im);
|
||||
}
|
||||
|
||||
function VerifyFont($font, $mode = '')
|
||||
{
|
||||
$default_fonts = array('Arial', 'Courier', 'Helvetica', 'Times');
|
||||
|
||||
if (!in_array($font, $default_fonts))
|
||||
{
|
||||
if ($mode)
|
||||
$this->AddFont($font, 'B', strtolower($font).'b.php');
|
||||
else
|
||||
$this->AddFont($font);
|
||||
}
|
||||
}
|
||||
|
||||
function WriteHTML($html)
|
||||
{
|
||||
global $config;
|
||||
|
||||
//HTML parser
|
||||
$html = str_replace("\n",' ',$html);
|
||||
$a = preg_split('/<(.*)>/U',$html,-1,PREG_SPLIT_DELIM_CAPTURE);
|
||||
foreach($a as $i=>$e)
|
||||
{
|
||||
if($i%2==0)
|
||||
{
|
||||
//Text
|
||||
if($this->HREF)
|
||||
$this->PutLink($this->HREF,$e);
|
||||
else
|
||||
$this->Write((int)$config['pdf_font_size'] / 2.5, $e);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Tag
|
||||
if($e[0]=='/')
|
||||
$this->CloseTag(strtoupper(substr($e,1)));
|
||||
else
|
||||
{
|
||||
//Extract attributes
|
||||
$a2=explode(' ',$e);
|
||||
$tag=strtoupper(array_shift($a2));
|
||||
$attr=array();
|
||||
foreach($a2 as $v)
|
||||
if(ereg('^([^=]*)=["\']?([^"\']*)["\']?$',$v,$a3))
|
||||
$attr[strtoupper($a3[1])]=$a3[2];
|
||||
$this->OpenTag($tag,$attr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function OpenTag($tag, $attr)
|
||||
{
|
||||
global $config;
|
||||
|
||||
//Opening tag
|
||||
if($tag=='B' or $tag=='I' or $tag=='U')
|
||||
$this->SetStyle($tag,true);
|
||||
if($tag=='A')
|
||||
$this->HREF=$attr['HREF'];
|
||||
if($tag=='BR')
|
||||
$this->Ln((int)$config['pdf_font_size'] / 2);
|
||||
}
|
||||
|
||||
function CloseTag($tag)
|
||||
{
|
||||
//Closing tag
|
||||
if($tag=='B' or $tag=='I' or $tag=='U')
|
||||
$this->SetStyle($tag,false);
|
||||
if($tag=='A')
|
||||
$this->HREF='';
|
||||
}
|
||||
|
||||
function SetStyle($tag, $enable)
|
||||
{
|
||||
//Modify style and select corresponding font
|
||||
$this->$tag+=($enable ? 1 : -1);
|
||||
$style='';
|
||||
foreach(array('B','I','U') as $s)
|
||||
if($this->$s>0)
|
||||
$style.=$s;
|
||||
$this->SetFont('',$style);
|
||||
}
|
||||
|
||||
function PutLink($URL, $txt)
|
||||
{
|
||||
global $config;
|
||||
|
||||
//Put a hyperlink
|
||||
$this->SetTextColor(0,0,255);
|
||||
$this->SetStyle('U',true);
|
||||
$this->Write((int)$config['pdf_font_size'] / 2, $txt, $URL);
|
||||
$this->SetStyle('U',false);
|
||||
$this->SetTextColor(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Olivier <oliver@fpdf.org>
|
||||
* @license Freeware
|
||||
*/
|
||||
function WordWrap(&$text, $maxwidth)
|
||||
{
|
||||
$text = trim($text);
|
||||
if ($text==='')
|
||||
return 0;
|
||||
$space = $this->GetStringWidth(' ');
|
||||
$lines = explode("\n", $text);
|
||||
$text = '';
|
||||
$count = 0;
|
||||
|
||||
foreach ($lines as $line)
|
||||
{
|
||||
$words = preg_split('/ +/', $line);
|
||||
$width = 0;
|
||||
|
||||
foreach ($words as $word)
|
||||
{
|
||||
$wordwidth = $this->GetStringWidth($word);
|
||||
if ($width + $wordwidth <= $maxwidth)
|
||||
{
|
||||
$width += $wordwidth + $space;
|
||||
$text .= $word.' ';
|
||||
}
|
||||
else
|
||||
{
|
||||
$width = $wordwidth + $space;
|
||||
$text = rtrim($text)."\n".$word.' ';
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
$text = rtrim($text)."\n";
|
||||
$count++;
|
||||
}
|
||||
$text = rtrim($text);
|
||||
return $count;
|
||||
}
|
||||
|
||||
function SaveFile($filename)
|
||||
{
|
||||
FPDF::Output('D', 'videoDB.pdf', $isUTF8=false);
|
||||
readfile($filename);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return image name for representing the media type
|
||||
*/
|
||||
function getMediaImage($mediatype)
|
||||
{
|
||||
if (preg_match("/^(DVD([+-]R)?|DivX|CD|VCD|SVCD|VHS|BLU-RAY|AVCHD|HDD|HD-DVD)/i", $mediatype, $matches))
|
||||
{
|
||||
$type_image = strtolower($matches[1]).'.png';
|
||||
}
|
||||
else $type_image = '';
|
||||
|
||||
return $type_image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Export PDF document
|
||||
*
|
||||
* @param string $where WHERE clause for SQL statement
|
||||
*/
|
||||
function pdfexport($WHERE)
|
||||
{
|
||||
global $config;
|
||||
|
||||
$ypos = $config['pdf_font_size']; // Match the font size for proper vertical offset
|
||||
$page_width = $config['pdf_page_width'];
|
||||
$margin = $config['pdf_margin'];
|
||||
$left_margin = $config['pdf_left_margin'];
|
||||
$right_margin = $config['pdf_right_margin'];
|
||||
$mediaimg_width = $config['pdf_image_media_width'];
|
||||
$font_size = $config['pdf_font_size'];
|
||||
|
||||
$image_height = $config['pdf_image_height'];
|
||||
$image_width = $config['pdf_image_width'];
|
||||
|
||||
$font_title = $config['pdf_font_title'];
|
||||
$font_plot = $config['pdf_font_plot'];
|
||||
|
||||
$text_length = $config['pdf_text_length'];
|
||||
|
||||
$tempfolder = cache_get_folder('');
|
||||
if ($config['cache_pruning']) cache_prune_folder($tempfolder, 3600, false, false, 'videodb*.pdf');
|
||||
$filename = $tempfolder.'videodb'.date('His',time()).'.pdf';
|
||||
|
||||
// setup pdf class
|
||||
$pdf = new PDF();
|
||||
$pdf->Open($filename);
|
||||
$pdf->VerifyFont($font_title);
|
||||
$pdf->VerifyFont($font_title, 'B');
|
||||
$pdf->VerifyFont($font_plot);
|
||||
$pdf->AddPage();
|
||||
$pdf->SetRightMargin($right_margin);
|
||||
|
||||
// add downscaling
|
||||
if (array_key_exists('pdf_scale', $config) && $config['pdf_scale'])
|
||||
{
|
||||
$pdf->Scale = $config['pdf_scale'];
|
||||
$pdf->max_width = $config['pdf_image_max_width'];
|
||||
$pdf->max_height= $config['pdf_image_max_height'];
|
||||
}
|
||||
|
||||
// get data
|
||||
$result = iconv_array('utf-8', 'iso-8859-1', exportData($WHERE));
|
||||
|
||||
$tech = array();
|
||||
|
||||
foreach ($result as $row)
|
||||
{
|
||||
set_time_limit(300); // rise per movie execution timeout limit if safe_mode is not set in php.ini
|
||||
|
||||
$title = $row['title'];
|
||||
if ($row['subtitle']) $title .= ' - '.$row['subtitle'];
|
||||
if ($row['diskid'] || $row['mediatype'])
|
||||
{
|
||||
$title .= ' [';
|
||||
if ($row['mediatype']) $title .= $row['mediatype'] . ', ';
|
||||
if ($row['diskid']) $title .= $row['diskid'];
|
||||
$title = preg_replace('/, $/', '', $title) . ']';
|
||||
}
|
||||
|
||||
// get drilldown url for image
|
||||
$imdb = $row['imdbID'];
|
||||
$link = ($imdb) ? engineGetContentUrl($imdb, engineGetEngine($imdb)) : '';
|
||||
|
||||
// title
|
||||
$pdf->SetFont($font_title, 'B', $font_size);
|
||||
$pdf->SetXY($left_margin + $image_width + $margin, $ypos);
|
||||
$pdf->Cell(0, 0, $title, 0,1, 'L',0,$link);
|
||||
|
||||
// [muddle] technical details
|
||||
unset($tech['Y']);
|
||||
if ($row['year']) {
|
||||
$tech['Y'] = "Year: ".$row['year'];
|
||||
}
|
||||
|
||||
unset($tech['V']);
|
||||
if ($row['video_width'] and $row['video_height'])
|
||||
{
|
||||
$vw = $row['video_width'];
|
||||
$vh = $row['video_height'];
|
||||
$tech['V'] = "Video: ";
|
||||
|
||||
if ($vw>1920) {
|
||||
$tech['V'] .= "UHD ".$vw."x".$vh;
|
||||
} elseif ($vw>1280) {
|
||||
$tech['V'] .= "HD 1080p";
|
||||
} elseif ($vw==1280 or $vh==720) {
|
||||
$tech['V'] .= "HD 720p";
|
||||
} elseif ($vw==720 or $vw==704) {
|
||||
$tech['V'] .= "SD ";
|
||||
if ($vh==480) {
|
||||
$tech['V'] .= "NTSC";
|
||||
} elseif ($vh==576) {
|
||||
$tech['V'] .= "PAL";
|
||||
} else {
|
||||
$tech['V'] .= $vw."x".$vh;
|
||||
}
|
||||
} else {
|
||||
$tech['V'] .= "LORES ".$vw."x".$vh;
|
||||
}
|
||||
}
|
||||
|
||||
unset($tech['A']);
|
||||
if ($row['audio_codec']) {
|
||||
$tech['A'] = "Audio: ".$row['audio_codec'];
|
||||
}
|
||||
|
||||
unset($tech['D']);
|
||||
if ($row['created']) {
|
||||
$tech['D'] = "Date: ".$row['created'];
|
||||
}
|
||||
|
||||
$techinfo = implode(", ", $tech);
|
||||
|
||||
$pdf->SetFont($font_title, 'B', $font_size-3);
|
||||
$pdf->SetXY($left_margin + $image_width + $margin, $ypos+ 4);
|
||||
$pdf->Cell(0, 0, $techinfo, 0,1, 'L',0);
|
||||
|
||||
// plot
|
||||
$plot = leftString($row['plot'], $text_length);
|
||||
$pdf->SetFont($font_plot, '', $font_size-1);
|
||||
$pdf->SetXY($left_margin + $image_width + $margin, $ypos+3 +3);
|
||||
$pdf->SetLeftMargin($left_margin + $image_width + $margin);
|
||||
$pdf->WriteHTML($plot);
|
||||
|
||||
// image
|
||||
$file = getThumbnail($row['imgurl']);
|
||||
if (preg_match('/^img.php/', $file)) $file = img();
|
||||
|
||||
// image file present?
|
||||
if ($file)
|
||||
{
|
||||
$pdf->Image($file, $left_margin, $ypos-2, $image_width, $image_height, '', $link);
|
||||
}
|
||||
|
||||
// add mediatype image
|
||||
if ($type_image = getMediaImage($row['mediatype']))
|
||||
{
|
||||
$pdf->Image('./images/media/'.$type_image, $page_width - $mediaimg_width - $right_margin, $ypos - 2, $mediaimg_width, 0, '', '');
|
||||
}
|
||||
|
||||
// new position
|
||||
$ypos += $margin;
|
||||
if ($file or $plot)
|
||||
{
|
||||
$ypos += max($image_height, $font_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
$ypos += $font_size;
|
||||
}
|
||||
|
||||
if ($ypos > 250)
|
||||
{
|
||||
$ypos = $config['pdf_font_size'];
|
||||
$pdf->AddPage();
|
||||
}
|
||||
}
|
||||
|
||||
$pdf->SaveFile($filename);
|
||||
|
||||
// get rid of temp file
|
||||
@unlink($filename);
|
||||
}
|
||||
|
||||
?>
|
||||
182
videodb/core/queryparser.php
Normal file
182
videodb/core/queryparser.php
Normal file
@@ -0,0 +1,182 @@
|
||||
<?php
|
||||
/**
|
||||
* Searchquerystring Parser
|
||||
*
|
||||
* Parses a search query into it's tokens kann detect + - AND OR NOT Operators
|
||||
* and Phrases.
|
||||
*
|
||||
* @todo remove german errorstrings, maybe handle umlauts and stuff...
|
||||
*
|
||||
* @package Search
|
||||
* @author Andreas Gohr <a.gohr@web.de>
|
||||
* @author Andreas Götz <cpuidle@gmx.de>
|
||||
* @version $Id: queryparser.php,v 1.9 2007/12/19 18:42:11 andig2 Exp $
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Querystringparser
|
||||
*
|
||||
* Parses a querystring into a datastructure
|
||||
*
|
||||
* @param string $query Querystring
|
||||
* @param string &$errors Stringreference to write errors back
|
||||
* @return array parsed querytokens
|
||||
*/
|
||||
function queryparser($query, &$errors)
|
||||
{
|
||||
$query = trim($query);
|
||||
/*
|
||||
// filter forbidden characters
|
||||
if (preg_match('/[^\w \.\(\)"\'*]/',$query))
|
||||
{
|
||||
$errors .= "Nicht erlaubte Zeichen wurden ignoriert\n";
|
||||
$query = preg_replace('/[^\w \.\(\)"\'*]/','',$query);
|
||||
}
|
||||
*/
|
||||
|
||||
$ops = array();
|
||||
$struct = array();
|
||||
$tokens = tokenizer($query);
|
||||
|
||||
// look through tokens
|
||||
while ($current = array_shift($tokens))
|
||||
{
|
||||
if (preg_match('/^(AND|OR|NOT)$/i', $current))
|
||||
{
|
||||
// token is operator
|
||||
$ops[] = strtoupper($current);
|
||||
}
|
||||
else
|
||||
{
|
||||
// token is searchword
|
||||
if (!count($ops))
|
||||
{
|
||||
// empty operator counts as AND
|
||||
$ops[] = 'AND';
|
||||
}
|
||||
|
||||
// clean invalid operators
|
||||
$cleanops = cleanoperators($ops, $errors);
|
||||
|
||||
// check wildcards
|
||||
$wild = '';
|
||||
if (substr($current,0,1) == '*') $wild .= 'l';
|
||||
if (substr($current, -1) == '*') $wild .= 'r';
|
||||
|
||||
$current = str_replace('*', '', $current);
|
||||
$struct[] = array('ops' => $cleanops,
|
||||
'token' => $current,
|
||||
'wildcard' => $wild);
|
||||
$ops = array();
|
||||
}
|
||||
}
|
||||
return $struct;
|
||||
}
|
||||
|
||||
/**
|
||||
* Querystring tokenizer
|
||||
*
|
||||
* Parse string into array of tokens.
|
||||
* Honors literal expressions enclosed by "",
|
||||
* converts +/- to AND and NOT
|
||||
*
|
||||
* @param string Querystring
|
||||
* @return array All tokens of the Strings
|
||||
*/
|
||||
function tokenizer($qstring)
|
||||
{
|
||||
// replace +/- with AND and NOT
|
||||
$qstring = ' '.$qstring; // for following regexps
|
||||
$qstring = preg_replace('/(\s)-(\S)/', '\1NOT \2', $qstring);
|
||||
$qstring = preg_replace('/(\s)\+(\S)/', '\1AND \2', $qstring);
|
||||
$qstring = trim($qstring);
|
||||
|
||||
$tokens = array();
|
||||
$current = '';
|
||||
$sep = '\s';
|
||||
|
||||
for ($i=0; $i < strlen($qstring); $i++)
|
||||
{
|
||||
$char = $qstring[$i];
|
||||
|
||||
// match current separator?
|
||||
if (preg_match("/$sep/", $char))
|
||||
{
|
||||
$current = trim($current);
|
||||
if (!empty($current) AND ((str_replace('*', '', $current)) != ''))
|
||||
{
|
||||
// add non-empty token
|
||||
$tokens[] = $current;
|
||||
}
|
||||
$current = '';
|
||||
$sep = '\s';
|
||||
}
|
||||
|
||||
// begin literal expression?
|
||||
elseif ($char == '"')
|
||||
{
|
||||
$sep = '"';
|
||||
}
|
||||
|
||||
// normal token character
|
||||
else
|
||||
{
|
||||
$current .= $char;
|
||||
}
|
||||
}
|
||||
|
||||
// add remaining token
|
||||
$current = trim($current);
|
||||
if (!empty($current) AND ((str_replace('*','',$current))!=''))
|
||||
{
|
||||
$tokens[] = $current;
|
||||
}
|
||||
|
||||
return $tokens;
|
||||
}
|
||||
|
||||
/**
|
||||
* Operator cleaning
|
||||
*
|
||||
* removes illogical operator combinations...
|
||||
*
|
||||
* @param array Operators
|
||||
* @param string Stringreference to write errors back
|
||||
* @return string cleaned Operators
|
||||
*/
|
||||
function cleanoperators($ops, &$errors)
|
||||
{
|
||||
$newops = array();
|
||||
|
||||
// make unique
|
||||
$ops = array_unique($ops);
|
||||
|
||||
// sort
|
||||
if (in_array('AND', $ops)) $newops[] = 'AND';
|
||||
if (in_array('OR', $ops)) $newops[] = 'OR';
|
||||
if (in_array('NOT', $ops)) $newops[] = 'NOT';
|
||||
|
||||
// join
|
||||
$opstr = join(' ', $newops);
|
||||
|
||||
// clean unnormal conditions
|
||||
if (strstr($opstr, 'AND OR'))
|
||||
{
|
||||
$errors .= "Die logische Verknüpfung 'AND OR' ist nicht erlaubt und wurde in 'OR' umgewandelt.\n";
|
||||
$opstr = str_replace('AND OR', 'OR', $opstr);
|
||||
}
|
||||
if (strstr($opstr, 'OR NOT'))
|
||||
{
|
||||
$errors .= "Die logische Verknüpfung 'OR NOT' ist nicht erlaubt und wurde in 'AND' umgewandelt.\n";
|
||||
$opstr = str_replace('OR NOT', 'AND', $opstr);
|
||||
}
|
||||
if ($opstr == 'NOT')
|
||||
{
|
||||
$opstr = 'AND NOT';
|
||||
}
|
||||
|
||||
return $opstr;
|
||||
}
|
||||
|
||||
|
||||
59
videodb/core/security.php
Normal file
59
videodb/core/security.php
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
/**
|
||||
* Security functions
|
||||
*
|
||||
* @package Core
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @author tREXX <www.trexx.ch>
|
||||
* @version $Id: security.php,v 1.2 2008/01/05 13:50:58 andig2 Exp $
|
||||
*/
|
||||
|
||||
/**
|
||||
* Allow these tags
|
||||
*/
|
||||
$allowedTags = '<h1><h2><h3><h4><b><strong><i><a><ol><ul><li><pre><hr><blockquote>';
|
||||
|
||||
/**
|
||||
* Disallow these attributes/prefix within a tag
|
||||
*/
|
||||
$stripAttrib = 'javascript:|onclick|ondblclick|onmousedown|onmouseup|onmouseover|'.
|
||||
'onmousemove|onmouseout|onkeypress|onkeydown|onkeyup';
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @param string
|
||||
* @desc Strip forbidden attributes from a tag
|
||||
*/
|
||||
function removeEvilAttributes($tagSource)
|
||||
{
|
||||
global $stripAttrib;
|
||||
return stripslashes(preg_replace("/$stripAttrib/i", 'forbidden', $tagSource));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @param string
|
||||
* @desc Strip forbidden attributes from an array of matches for an expression like (<)(.*?)(>)
|
||||
*/
|
||||
function _callbackRemoveEvilAttributes($matches)
|
||||
{
|
||||
return $matches[1] . removeEvilAttributes($matches[2]) . $matches[3];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @param string
|
||||
* @desc Strip forbidden tags and delegate tag-source check to removeEvilAttributes()
|
||||
*/
|
||||
function removeEvilTags($source)
|
||||
{
|
||||
global $allowedTags;
|
||||
if (!is_null($source))
|
||||
{
|
||||
$source = strip_tags($source, $allowedTags);
|
||||
return preg_replace_callback('/(<)(.*?)(>)/i', "_callbackRemoveEvilAttributes", $source);
|
||||
}
|
||||
return $source;
|
||||
}
|
||||
|
||||
?>
|
||||
69
videodb/core/session.php
Normal file
69
videodb/core/session.php
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
/**
|
||||
* Session functions
|
||||
*
|
||||
* Moved all session functions into one file,
|
||||
* include this where session starting might be required
|
||||
*
|
||||
* @package Core
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @version $Id: session.php,v 1.13 2008/02/28 20:01:17 andig2 Exp $
|
||||
*/
|
||||
|
||||
// start session
|
||||
session_start();
|
||||
|
||||
/**
|
||||
* Get session value or specified default
|
||||
*/
|
||||
function session_get($varname, $default=null)
|
||||
{
|
||||
if (isset($_SESSION['vdb'][$varname]))
|
||||
{
|
||||
return $_SESSION['vdb'][$varname];
|
||||
}
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set session value or specified default
|
||||
*/
|
||||
function session_set($varname, $value)
|
||||
{
|
||||
$_SESSION['vdb'][$varname] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Upsert session value with current value of global variable or specified default
|
||||
*/
|
||||
function session_default($varname, $default=null)
|
||||
{
|
||||
global $$varname;
|
||||
|
||||
if (!isset($$varname))
|
||||
{
|
||||
$$varname = (isset($_SESSION['vdb'][$varname])) ? $_SESSION['vdb'][$varname] : $default;
|
||||
}
|
||||
$_SESSION['vdb'][$varname] = $$varname;
|
||||
}
|
||||
|
||||
/**
|
||||
* get session_default for owner
|
||||
*
|
||||
* basically this only executes the extra query when the global $owner is not set and also
|
||||
* not available in session data. only then we need the hasAny check. if the global is set
|
||||
* or the global is not set but the session is then session_default() will fix both those
|
||||
* cases. put into a single function because it gets called from multiple files.
|
||||
*/
|
||||
function session_default_owner()
|
||||
{
|
||||
global $owner, $lang;
|
||||
if (!isset($owner) && !isset($_SESSION['vdb']['owner'])) {
|
||||
$hasAny = runSQL('SELECT COUNT(*) AS num FROM '.TBL_DATA.' WHERE '.TBL_DATA.'.owner_id = ' . get_current_user_id());
|
||||
$hasAny = ($hasAny && isset($hasAny[0]['num']) && $hasAny[0]['num'] > 0);
|
||||
$default = ($hasAny ? get_username(get_current_user_id()) : $lang['filter_any']);
|
||||
return session_default('owner', $default);
|
||||
}
|
||||
return session_default('owner');
|
||||
}
|
||||
|
||||
356
videodb/core/setup.core.php
Normal file
356
videodb/core/setup.core.php
Normal file
@@ -0,0 +1,356 @@
|
||||
<?php
|
||||
/**
|
||||
* Functions for config options
|
||||
*
|
||||
* @package Core
|
||||
* @author Andreas Gohr <a.gohr@web.de>
|
||||
* @author Andreas Götz <cpuidle@gmx.de>
|
||||
* @version $Id: setup.core.php,v 1.12 2013/03/16 10:10:07 andig2 Exp $
|
||||
*/
|
||||
|
||||
require_once './core/functions.php';
|
||||
require_once './core/custom.php';
|
||||
require_once './core/output.php';
|
||||
|
||||
$SETUP_GLOBAL = array('language', 'autoid', 'mediadefault', 'langdefault', 'acclangbrowser',
|
||||
'filterdefault', 'showtv', 'orderallbydisk', 'removearticles',
|
||||
'localnet', 'IMDBage', 'thumbnail',
|
||||
'castcolumns', 'template', 'languageflags', 'custom1',
|
||||
'custom2', 'custom3', 'custom4', 'custom1type',
|
||||
'custom2type', 'custom3type', 'custom4type', 'enginedefault',
|
||||
'proxy_host', 'proxy_port', 'actorpics', 'thumbAge', 'listcolumns',
|
||||
'shownew', 'imdbBrowser', 'multiuser', 'denyguest', 'adultgenres',
|
||||
'pageno', 'showtools', 'showcasttoggle', 'browse_include_title');
|
||||
|
||||
$SETUP_QUICK = array('template');
|
||||
|
||||
$SETUP_USER = array('language', 'mediadefault', 'langdefault', 'acclangbrowser', 'filterdefault',
|
||||
'showtv', 'orderallbydisk', 'template', 'languageflags',
|
||||
'listcolumns', 'castcolumns', 'shownew', 'pageno', 'removearticles',
|
||||
'showcasttoggle', 'browse_include_title');
|
||||
|
||||
/**
|
||||
* Build config options array
|
||||
*
|
||||
* @param boolean $isprofile Determines if user-specific options are to be displayed
|
||||
*
|
||||
* @return array associative array of config options
|
||||
*/
|
||||
function setup_mkOptions($isprofile = false)
|
||||
{
|
||||
global $config, $lang;
|
||||
|
||||
// built list of setup options
|
||||
$setup = array();
|
||||
|
||||
// isprofile, name, type (text|boolean|dropdown|special|link), data, set, helphl, helptxt
|
||||
$setup[] = setup_addSection('opt_general');
|
||||
$setup[] = setup_addOption($isprofile, 'language', 'dropdown', setup_getLanguages(), null, $lang['help_langn'], $lang['help_lang']);
|
||||
$option = setup_addOption($isprofile, 'template', 'dropdown', setup_getTemplates($thumbs));
|
||||
$option['thumbs'] = $thumbs;
|
||||
$setup[] = $option;
|
||||
|
||||
$setup[] = setup_addOption($isprofile, 'listcolumns', 'text');
|
||||
$setup[] = setup_addOption($isprofile, 'castcolumns', 'text');
|
||||
|
||||
$setup[] = setup_addOption($isprofile, 'autoid', 'boolean');
|
||||
$setup[] = setup_addOption($isprofile, 'orderallbydisk', 'boolean');
|
||||
|
||||
$setup[] = setup_addOption($isprofile, 'mediadefault', 'dropdown', setup_getMediatypes());
|
||||
$setup[] = setup_addOption($isprofile, 'langdefault', 'text');
|
||||
$setup[] = setup_addOption($isprofile, 'acclangbrowser', 'boolean');
|
||||
$setup[] = setup_addOption($isprofile, 'filterdefault', 'dropdown', array('all'=>$lang['radio_all'], 'unseen'=>$lang['radio_unseen'], 'new'=>$lang['radio_new'], 'wanted'=>$lang['radio_wanted']));
|
||||
$setup[] = setup_addOption($isprofile, 'showtv', 'boolean');
|
||||
$setup[] = setup_addOption($isprofile, 'shownew', 'text');
|
||||
$setup[] = setup_addOption($isprofile, 'pageno', 'text');
|
||||
$setup[] = setup_addOption($isprofile, 'languageflags', 'special', out_languageflags($config['languages']));
|
||||
$setup[] = setup_addOption($isprofile, 'removearticles', 'boolean');
|
||||
$setup[] = setup_addOption($isprofile, 'adultgenres', 'multi', setup_getGenres(), @explode('::', $config['adultgenres']));
|
||||
$setup[] = setup_addOption($isprofile, 'showtools', 'boolean');
|
||||
$setup[] = setup_addOption($isprofile, 'showcasttoggle', 'boolean');
|
||||
$setup[] = setup_addOption($isprofile, 'browse_include_title', 'dropdown', array('none' => $lang['none'], 'top' => $lang['top'], 'bottom' => $lang['bottom'], 'both' => $lang['both']));
|
||||
|
||||
if (!$isprofile) $setup[] = setup_addSection('opt_custom');
|
||||
$setup[] = setup_addOption($isprofile, 'custom', 'special', setup_mkCustoms(), 'custom', $lang['help_customn'], $lang['help_custom']);
|
||||
|
||||
if (!$isprofile) $setup[] = setup_addSection('opt_engines');
|
||||
$setup[] = setup_addOption($isprofile, 'enginedefault', 'dropdown', setup_getEngines($config['engines']), null , $lang['help_defaultenginen'], $lang['help_defaultengine']);
|
||||
|
||||
foreach ($config['engines'] as $engine => $meta)
|
||||
{
|
||||
$title = $meta['name'];
|
||||
if (array_key_exists($engine,$config['engine'])) {$enabled = $config['engine'][$engine];} else {$enabled = null;}
|
||||
$helptext = sprintf($lang['help_engine'], $title);
|
||||
if (array_key_exists('help_engine' . $engine, $lang)) {$helptext .= ' ' . $lang['help_engine' . $engine];}
|
||||
if (!array_key_exists('stable', $meta) || $meta['stable'] == 0) {$helptext .= ' ' . $lang['help_engexperimental'];}
|
||||
|
||||
$setup[] = setup_addOption($isprofile, 'engine'.$engine, 'boolean', null, $enabled, $title, $helptext);
|
||||
|
||||
// add engine-specific options
|
||||
if (array_key_exists('config', $meta) && is_array($meta['config']))
|
||||
{
|
||||
foreach ($meta['config'] as $setting)
|
||||
{
|
||||
// NOTE: check setup_additionalSettings if you change the option naming
|
||||
if (is_array($setting['values']))
|
||||
$setup[] = setup_addOption($isprofile, $engine.$setting['opt'],
|
||||
'dropdown', $setting['values'], null, $setting['name'], $setting['desc']);
|
||||
else
|
||||
$setup[] = setup_addOption($isprofile, $engine.$setting['opt'],
|
||||
'text', null, null, $setting['name'], $setting['desc']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$isprofile) {$setup[] = setup_addSection('opt_security');}
|
||||
$setup[] = setup_addOption($isprofile, 'localnet', 'text');
|
||||
$setup[] = setup_addOption($isprofile, 'multiuser', 'boolean');
|
||||
$setup[] = setup_addOption($isprofile, 'denyguest', 'boolean');
|
||||
$setup[] = setup_addOption($isprofile, 'usermanager', 'link', 'users.php', 'usermanager');
|
||||
$setup[] = setup_addOption($isprofile, 'proxy_host', 'text');
|
||||
$setup[] = setup_addOption($isprofile, 'proxy_port', 'text');
|
||||
|
||||
if (!$isprofile) {$setup[] = setup_addSection('opt_caching');}
|
||||
$setup[] = setup_addOption($isprofile, 'thumbnail', 'boolean');
|
||||
$setup[] = setup_addOption($isprofile, 'imdbBrowser', 'boolean');
|
||||
$setup[] = setup_addOption($isprofile, 'IMDBage', 'text');
|
||||
$setup[] = setup_addOption($isprofile, 'actorpics', 'boolean');
|
||||
$setup[] = setup_addOption($isprofile, 'thumbAge', 'text');
|
||||
|
||||
// clean empty entries
|
||||
for ($i = count($setup); $i > 0; $i--)
|
||||
{
|
||||
if (empty($setup[$i]['name']) && empty($setup[$i]['group'])) unset($setup[$i]);
|
||||
}
|
||||
|
||||
return $setup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add engine-specific config options for saving
|
||||
*/
|
||||
function setup_additionalSettings()
|
||||
{
|
||||
global $config, $SETUP_GLOBAL;
|
||||
|
||||
foreach ($config['engines'] as $engine => $meta)
|
||||
{
|
||||
// add engine-specific options
|
||||
if (array_key_exists('config', $meta) && is_array($meta['config']))
|
||||
{
|
||||
foreach ($meta['config'] as $setting)
|
||||
{
|
||||
$SETUP_GLOBAL[] = $engine.$setting['opt'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new section to the config options array
|
||||
*
|
||||
* @param array $setup The config array
|
||||
* @param string $section Name of the new section
|
||||
*/
|
||||
function setup_addSection($section)
|
||||
{
|
||||
$option['group'] = $section;
|
||||
return $option;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an entry for the config option array
|
||||
*
|
||||
* returns NULL on global options if $isprofile is true
|
||||
* so global options will not be added to user profile settings
|
||||
*
|
||||
* @param array $setup The config array
|
||||
* @param boolean $isprofile Do we prepare a profile array?
|
||||
* @param string $name Name of the config option
|
||||
* @param string $type Type of option (text|boolean|dropdown|special|link)
|
||||
* @param string $data Current value of this option
|
||||
* @param string $set Default value of this option
|
||||
* @param string $hl Help text headline
|
||||
* @param string $help Help text
|
||||
*/
|
||||
function setup_addOption($isprofile, $name, $type,
|
||||
$data='', $set=NULL, $hl=NULL, $help=NULL)
|
||||
{
|
||||
global $config, $lang;
|
||||
global $SETUP_USER;
|
||||
|
||||
// user-specific setting?
|
||||
$isuser = in_array($name, $SETUP_USER);
|
||||
|
||||
if ($isprofile and !$isuser) return;
|
||||
|
||||
$option['isuser'] = $isuser;
|
||||
$option['name'] = $name;
|
||||
$option['type'] = $type;
|
||||
$option['data'] = $data;
|
||||
|
||||
$option['set'] = ($set) ? $set : $config[$name];
|
||||
$option['hl'] = ($hl) ? $hl : $lang['help_'.$name.'n'];
|
||||
$option['help'] = ($help) ? $help : $lang['help_'.$name];
|
||||
|
||||
return $option;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find available languages
|
||||
*/
|
||||
function setup_getLanguages()
|
||||
{
|
||||
if ($dh = opendir('language'))
|
||||
{
|
||||
while (($file = readdir($dh)) !== false)
|
||||
{
|
||||
if (preg_match("/(.*)\.php$/", $file, $matches))
|
||||
{
|
||||
$languages[$matches[1]] = $matches[1];
|
||||
}
|
||||
}
|
||||
closedir($dh);
|
||||
}
|
||||
return $languages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find available templates/styles
|
||||
* Extended to search for template screenshots
|
||||
*
|
||||
* @author Andreas Götz <cpuidle@gmx.de>
|
||||
*/
|
||||
function setup_getTemplates(&$screenshots)
|
||||
{
|
||||
$screenshots = array();
|
||||
|
||||
if ($dh = @opendir('templates'))
|
||||
{
|
||||
while (($file = readdir($dh)) !== false)
|
||||
{
|
||||
if (preg_match("/^\./", $file)) continue;
|
||||
if (is_dir('templates/'.$file))
|
||||
{
|
||||
$template = 'templates/'.$file;
|
||||
if ($dh2 = opendir($template))
|
||||
{
|
||||
$style_name = '';
|
||||
|
||||
while (($style = readdir($dh2)) !== false)
|
||||
{
|
||||
if (preg_match("/(.*)\.css$/", $style, $matches))
|
||||
{
|
||||
$thumb = $template.'/screenshot_'.$matches[1].'.jpg';
|
||||
if (file_exists($thumb))
|
||||
{
|
||||
$screenshots[] = array('name' => "$file::".$matches[1], 'img' => $thumb);
|
||||
}
|
||||
elseif (empty($style_name))
|
||||
{
|
||||
// remember first style found
|
||||
$style_name = $matches[1];
|
||||
}
|
||||
$templates[$file.'::'.$matches[1]] = $file.' ('.$matches[1].')';
|
||||
}
|
||||
}
|
||||
closedir($dh2);
|
||||
|
||||
if ($style_name)
|
||||
{
|
||||
$thumb = $template.'/screenshot.jpg';
|
||||
if (file_exists($thumb))
|
||||
{
|
||||
$screenshots[] = array('name' => "$file::$style_name", 'img' => $thumb);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir($dh);
|
||||
}
|
||||
return $templates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mediatypes
|
||||
*/
|
||||
function setup_getMediatypes()
|
||||
{
|
||||
$SELECT = 'SELECT id, name
|
||||
FROM '.TBL_MEDIATYPES.'
|
||||
ORDER BY name';
|
||||
$result = runSQL($SELECT);
|
||||
|
||||
return array_associate($result, 'id', 'name');
|
||||
}
|
||||
|
||||
/**
|
||||
* Genres
|
||||
*/
|
||||
function setup_getGenres()
|
||||
{
|
||||
$SELECT = 'SELECT id, name
|
||||
FROM '.TBL_GENRES.'
|
||||
ORDER BY name';
|
||||
$result = runSQL($SELECT);
|
||||
|
||||
return array_associate($result, 'id', 'name');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of engines for default engine selection
|
||||
*/
|
||||
function setup_getEngines($engines_ary)
|
||||
{
|
||||
$engines = array();
|
||||
|
||||
foreach ($engines_ary as $engine => $meta)
|
||||
{
|
||||
if (engine_get_capability($engine, 'movie')) $engines[$engine] = $meta['name'];
|
||||
}
|
||||
|
||||
return $engines;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare customfields
|
||||
*/
|
||||
function setup_mkCustoms()
|
||||
{
|
||||
global $config;
|
||||
global $allcustomtypes;
|
||||
|
||||
$setup_custom = '';
|
||||
|
||||
for ($i=1; $i<5; $i++)
|
||||
{
|
||||
$setup_custom .= $i.'. <input type="text" size="20" name="custom'.$i.'" id="custom'.$i.'" value="'.formvar($config['custom'.$i]).'"/>';
|
||||
$setup_custom .= '<select name="custom'.$i.'type">';
|
||||
|
||||
foreach($allcustomtypes as $ctype)
|
||||
{
|
||||
$selected = ($ctype == $config['custom'.$i.'type']) ? ' selected="selected"' : '';
|
||||
$setup_custom .= '<option value="'.$ctype.'"'.$selected.'>'.$ctype.'</option>';
|
||||
}
|
||||
$setup_custom .= '</select>';
|
||||
$setup_custom .= "<br />\n";
|
||||
}
|
||||
|
||||
return $setup_custom;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update session variables with configuration values
|
||||
*
|
||||
* @author Andreas Goetz
|
||||
*/
|
||||
function update_session()
|
||||
{
|
||||
global $listcolumns, $showtv;
|
||||
|
||||
if ($listcolumns) $_SESSION['vdb']['listcolumns'] = $listcolumns;
|
||||
if ($showtv) $_SESSION['vdb']['showtv'] = $showtv;
|
||||
}
|
||||
|
||||
612
videodb/core/template.php
Normal file
612
videodb/core/template.php
Normal file
@@ -0,0 +1,612 @@
|
||||
<?php
|
||||
/**
|
||||
* Template functions
|
||||
*
|
||||
* These functions prepare the data for assignment to the template engine
|
||||
*
|
||||
* @todo replace additional assignments of config options by using $config
|
||||
*
|
||||
* @package Core
|
||||
* @author Andreas Gohr <a.gohr@web.de>
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @version $Id: template.php,v 1.70 2013/03/21 16:27:57 andig2 Exp $
|
||||
*/
|
||||
|
||||
require_once './core/session.php';
|
||||
require_once './core/output.php';
|
||||
require_once './core/genres.php';
|
||||
require_once './core/functions.php';
|
||||
require_once './engines/engines.php';
|
||||
|
||||
/**
|
||||
* Display template with standard header and footer
|
||||
*/
|
||||
function tpl_display_show($template, $flush = true)
|
||||
{
|
||||
smarty_display('header.tpl');
|
||||
|
||||
if ($flush) flush();
|
||||
smarty_display($template);
|
||||
smarty_display('footer.tpl');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display page using templates
|
||||
* If page content is unmodified, return HTTP 304 Not modified
|
||||
*
|
||||
* @param string $template Template name for main content
|
||||
*/
|
||||
function tpl_display($template)
|
||||
{
|
||||
global $config;
|
||||
|
||||
// caching enabled?
|
||||
if ($config['http_caching'])
|
||||
{
|
||||
require_once('./core/httpcache.php');
|
||||
httpCacheCaptureStart();
|
||||
}
|
||||
|
||||
tpl_display_show($template, !$config['http_caching']);
|
||||
|
||||
if ($config['http_caching'])
|
||||
{
|
||||
httpCacheOutput($template, httpCacheCaptureEnd());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare standard page templates
|
||||
*/
|
||||
function tpl_page($help = '', $title = '')
|
||||
{
|
||||
tpl_language();
|
||||
tpl_header($help, $title);
|
||||
tpl_footer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns language strings and config options to the smarty engine
|
||||
*/
|
||||
function tpl_language()
|
||||
{
|
||||
global $smarty, $lang, $config;
|
||||
|
||||
$smarty->assign('lang', $lang);
|
||||
$smarty->assign('config', $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns the header urls to the smarty engine
|
||||
*
|
||||
* @param string $help The helpfile to display (optional, without extension)
|
||||
* @param string $title The text to add to html <title> tag (optional, will be html-encoded)
|
||||
*/
|
||||
function tpl_header($help = '', $title = '')
|
||||
{
|
||||
global $smarty, $lang, $config;
|
||||
global $id, $diskid;
|
||||
|
||||
// viewing is only availble if autorized or public access
|
||||
if (auth_check(false))
|
||||
{
|
||||
$header['browse'] = 'index.php';
|
||||
if (check_permission(PERM_READ, PERM_ANY))
|
||||
{
|
||||
$header['random'] = 'show.php';
|
||||
$header['search'] = 'search.php';
|
||||
}
|
||||
$header['stats'] = 'stats.php';
|
||||
if ($config['imdbBrowser']) $header['trace'] = 'trace.php';
|
||||
$header['help'] = 'help.php';
|
||||
if ($help) $header['help'] .= '?page='.$help.'.html';
|
||||
}
|
||||
|
||||
// editing is only available in local network
|
||||
if (localnet())
|
||||
{
|
||||
if (check_permission(PERM_WRITE, PERM_ANY))
|
||||
{
|
||||
$header['new'] = 'edit.php';
|
||||
if ($config['showtools']) $header['contrib'] = 'contrib.php';
|
||||
}
|
||||
if (check_permission(PERM_ADMIN)) $header['setup'] = 'setup.php';
|
||||
|
||||
// edit or show?
|
||||
if ($id)
|
||||
{
|
||||
if (check_videopermission(PERM_WRITE, $id)) $header['edit'] = 'edit.php?id='.$id;
|
||||
if (!preg_match('/show.php$/', $_SERVER['PHP_SELF']))
|
||||
{
|
||||
$header['view'] = 'show.php?id='.$id;
|
||||
}
|
||||
if (check_videopermission(PERM_WRITE, $id)) $header['del'] = 'delete.php?id='.$id;
|
||||
}
|
||||
if (check_permission(PERM_WRITE, PERM_ANY))
|
||||
{
|
||||
$header['borrow'] = 'borrow.php';
|
||||
if (isset($diskid)) $header['borrow'] .= '?diskid='.$diskid;
|
||||
}
|
||||
}
|
||||
|
||||
// multiuser settings
|
||||
if ($config['multiuser'])
|
||||
{
|
||||
$header['login'] = 'login.php';
|
||||
|
||||
// logged in?
|
||||
if (!empty($_COOKIE['VDBusername']) && $_COOKIE['VDBuserid'] != $config['guestid'])
|
||||
{
|
||||
$header['profile'] = 'profile.php';
|
||||
$smarty->assign('loggedin', $_COOKIE['VDBusername']);
|
||||
}
|
||||
else
|
||||
{
|
||||
// make sure anonymous users don't get access to trace for security reasons
|
||||
unset($header['trace']);
|
||||
}
|
||||
|
||||
if (check_permission(PERM_ADMIN)) $header['users'] = 'users.php';
|
||||
}
|
||||
|
||||
// determine active tab
|
||||
if (preg_match('/(\w+)\.php/', $_SERVER['PHP_SELF'], $m))
|
||||
{
|
||||
$tab = strtolower($m[1]);
|
||||
switch ($tab)
|
||||
{
|
||||
case 'show':
|
||||
$header['request_uri'] = $_SERVER['REQUEST_URI'];
|
||||
case 'edit':
|
||||
if (!empty($id)) $header['active'] = $tab;
|
||||
// uncomment this if you want the 'Browse' tab to remember last visited movie
|
||||
// { ... $smarty->assign('browseid', $_REQUEST['id']); }
|
||||
else $header['active'] = ($tab == 'show') ? 'random' : 'new';
|
||||
break;
|
||||
default:
|
||||
/* legacy version
|
||||
$translate = array('index' => 'browse', 'users' => 'setup', 'permissions' => 'setup', 'delete' => 'show');
|
||||
*/
|
||||
$translate = array('index' => 'browse', 'permissions' => 'users', 'delete' => 'show');
|
||||
if (in_array($tab, array_keys($translate)))
|
||||
{
|
||||
$tab = $translate[$tab];
|
||||
}
|
||||
$header['active'] = $tab;
|
||||
}
|
||||
}
|
||||
|
||||
// breadcrumbs
|
||||
$breadcrumbs = session_get('breadcrumbs', array());
|
||||
$smarty->assign('breadcrumbs', $breadcrumbs);
|
||||
|
||||
if (!is_null($title))
|
||||
{
|
||||
$smarty->assign('title', htmlspecialchars($title));
|
||||
}
|
||||
else
|
||||
{
|
||||
$smarty->assign('title', "");
|
||||
}
|
||||
$smarty->assign('header', $header);
|
||||
$smarty->assign('style', $config['style']);
|
||||
$smarty->assign('langcode', $config['language']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns the filter options to the smarty engine
|
||||
*/
|
||||
function tpl_filters($filter, $showtv)
|
||||
{
|
||||
global $smarty, $lang;
|
||||
global $filter_expr;
|
||||
global $owner, $mediatype;
|
||||
global $config;
|
||||
|
||||
// build filter array
|
||||
foreach ($filter_expr as $flt => $regex)
|
||||
{
|
||||
$filters[$flt] = ($flt == "NUM") ? "#" : $flt;
|
||||
}
|
||||
$filters['all'] = $lang['radio_all'];
|
||||
$filters['unseen'] = $lang['radio_unseen'];
|
||||
$filters['new'] = $lang['radio_new'];
|
||||
/*
|
||||
# removed as of 4.0 in favour of media type filter
|
||||
$filters['wanted'] = $lang['radio_wanted'];
|
||||
*/
|
||||
$smarty->assign('filters', $filters);
|
||||
$smarty->assign('filter', $filter);
|
||||
$smarty->assign('showtv', $showtv);
|
||||
|
||||
// create owner selectbox
|
||||
$smarty->assign('owners', out_owners(array($lang['filter_any'] => $lang['filter_any']), PERM_READ));
|
||||
if (!$owner) $owner = $lang['filter_any']; //!! default owner hack
|
||||
$smarty->assign('owner', $owner);
|
||||
|
||||
// create mediatype selectbox
|
||||
$smarty->assign('mediafilter', out_mediatypes(array(-2 => $lang['filter_any'], -1 => $lang['filter_available'])));
|
||||
if (!$mediatype) $mediatype = session_get('mediafilter'); //!! default media type hack
|
||||
$smarty->assign('mediatype', $mediatype);
|
||||
|
||||
// create sorting selectbox
|
||||
// Sorting is disabled when ordering by diskid is enabled
|
||||
if(!$config['orderallbydisk']) {
|
||||
$smarty->assign('order_options', array(-1 => $lang['title'], 1 => $lang['rating'], 2 => $lang['date']));
|
||||
if(!isset($order)) $order = session_get('order');
|
||||
$smarty->assign('order', $order);
|
||||
}
|
||||
|
||||
|
||||
// enable dynamic columns in list view
|
||||
$smarty->assign('listcolumns', session_get('listcolumns'));
|
||||
}
|
||||
|
||||
function adultcheck_for_video($video)
|
||||
{
|
||||
return adultcheck($video["id"]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns the searchresults/browselist to the smarty engine
|
||||
*
|
||||
* @param array indexed array containing the item data
|
||||
*/
|
||||
function tpl_list($list)
|
||||
{
|
||||
global $smarty, $config;
|
||||
global $listcolumns;
|
||||
if(!$list)
|
||||
{
|
||||
$smarty->assign('totalresults', 0);
|
||||
return;
|
||||
}
|
||||
for ($i=0; $i < count($list); $i++)
|
||||
{
|
||||
// setup imgurls
|
||||
$list[$i]['imgurl'] = ($config['thumbnail']) ? getThumbnail($list[$i]['imgurl']) : '';
|
||||
|
||||
// check for flagfile
|
||||
$languages = $list[$i]['language'];
|
||||
$flagfile = img('flags/'.$languages.'.gif');
|
||||
if (file_exists($flagfile))
|
||||
{
|
||||
// one langage
|
||||
$list[$i]['flagfile'][$languages] = $flagfile;
|
||||
$list[$i]['language'] = array($list[$i]['language']);
|
||||
}
|
||||
else
|
||||
{
|
||||
// multiple languages
|
||||
$langary = preg_split('/,\s*/', $languages);
|
||||
$list[$i]['language'] = $langary;
|
||||
|
||||
// assign them all
|
||||
foreach ($langary as $languagepart)
|
||||
{
|
||||
$flagfile = img('flags/'.$languagepart.'.gif');
|
||||
if (file_exists($flagfile))
|
||||
{
|
||||
$list[$i]['flagfile'][$languagepart] = $flagfile;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// is this file editable?
|
||||
if (localnet())
|
||||
{
|
||||
$list[$i]['editable'] = ($config['multiuser']) ?
|
||||
check_permission(PERM_WRITE, $list[$i]['owner_id']) : true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$list[$i]['editable'] = false;
|
||||
}
|
||||
/*
|
||||
uncomment this to allow display of rating in the 'Browse' tab
|
||||
require_once 'custom.php';
|
||||
customfields($list[$i], 'out');
|
||||
*/
|
||||
}
|
||||
|
||||
// do adultcheck
|
||||
if (is_array($list))
|
||||
{
|
||||
$list = array_filter($list, "adultcheck_for_video");
|
||||
}
|
||||
|
||||
// enable dynamic columns in list view
|
||||
$smarty->assign('listcolumns', session_get('listcolumns'));
|
||||
$smarty->assign('list', $list);
|
||||
|
||||
// show total number of movies in footer
|
||||
$smarty->assign('totalresults', count($list));
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns debug infos and version to the smarty engine
|
||||
*/
|
||||
function tpl_footer()
|
||||
{
|
||||
global $smarty, $config, $SQLtrace;
|
||||
|
||||
if ($config['debug'])
|
||||
{
|
||||
$out = $config;
|
||||
$out['db_password'] = '***';
|
||||
$session = $_SESSION['vdb'];
|
||||
$session['db_password'] = '***';
|
||||
|
||||
ob_start();
|
||||
print '<pre>';
|
||||
dump($SQLtrace);
|
||||
dump($out);
|
||||
dump($session);
|
||||
print '</pre>';
|
||||
# phpinfo();
|
||||
$debug = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
$smarty->assign('DEBUG', $debug);
|
||||
}
|
||||
$smarty->assign('version', VERSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function combines multiple actor thumbnail queries into single SQL query
|
||||
*/
|
||||
function get_actor_thumbnails_batched(&$actors)
|
||||
{
|
||||
if (!count($actors)) return;
|
||||
|
||||
$ids = "'".join("','", array_map('escapeSQL', array_column($actors, 'id')))."'";
|
||||
|
||||
$SQL = 'SELECT actorid, name, imgurl, UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(checked) AS cacheage
|
||||
FROM '.TBL_ACTORS.' WHERE actorid IN ('.$ids.')';
|
||||
$result = runSQL($SQL);
|
||||
|
||||
$result = array_associate($result, 'actorid');
|
||||
|
||||
// loop over actors from full-text field
|
||||
foreach ($actors as $idx => $actor)
|
||||
{
|
||||
// check for actor thumbnail
|
||||
$batch_result = null;
|
||||
if (array_key_exists($actor['id'], $result))
|
||||
{
|
||||
$batch_result = $result[$actor['id']];
|
||||
}
|
||||
|
||||
if ($batch_result)
|
||||
{
|
||||
$actors[$idx]['imgurl'] = get_actor_image_from_cache($batch_result, $actor['name'], $actor['id']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$actors[$idx]['imgurl'] = getActorThumbnail($actor['name'], $actor['id'], false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert textbox/db presentation into actors array
|
||||
*/
|
||||
function split_cast_array(&$actor, $key)
|
||||
{
|
||||
$ary = explode('::', $actor);
|
||||
|
||||
$actor = array();
|
||||
$actor['name'] = $ary[0];
|
||||
$actor['id'] = $ary[2];
|
||||
$actor['roles'] = preg_split('[^</]', $ary[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts plain cast data into array of actors with thumbnails
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
*/
|
||||
function prepare_cast($cast)
|
||||
{
|
||||
global $config;
|
||||
|
||||
// convert text represenatation into array
|
||||
$actors = array_filter(preg_split("/\r?\n/", trim($cast)));
|
||||
|
||||
// reformat roles
|
||||
$actors = preg_replace('/\((.*?)\)/', '<small>($1)</small>', $actors);
|
||||
|
||||
array_walk($actors, 'split_cast_array');
|
||||
|
||||
// check for actor thumbnails
|
||||
if ($config['actorpics']) get_actor_thumbnails_batched($actors);
|
||||
|
||||
// loop over actors from full-text field
|
||||
foreach ($actors as $idx => $actor)
|
||||
{
|
||||
$actors[$idx]['imdburl'] = engineGetActorUrl($actor['name'], $actor['id'], engineGetActorEngine($actor['id']));
|
||||
|
||||
// check for actor thumbnail
|
||||
# if ($config['actorpics']) $actor['imgurl'] = getActorThumbnail($actor['name'], $actor['id']);
|
||||
}
|
||||
|
||||
return $actors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns the videoinfos to the smarty engine
|
||||
*
|
||||
* @param array associative array containing the item data
|
||||
*/
|
||||
function tpl_show($video)
|
||||
{
|
||||
global $smarty, $config;
|
||||
|
||||
// imageurl
|
||||
$video['imgurl'] = getThumbnail($video['imgurl'], $video['title']);
|
||||
|
||||
// make soft linebreaks:
|
||||
$video['filename'] = preg_replace('/(_|\.|-)/', '$1<wbr />', $video['filename']);
|
||||
|
||||
// split comma-separated countries, prevent empty array
|
||||
$video['country'] = preg_split('/,\s*/', $video['country'], -1, PREG_SPLIT_NO_EMPTY);
|
||||
|
||||
// split comma-separated multiple languages, prevent empty array
|
||||
$video['language'] = preg_split('/,\s*/', $video['language'], -1, PREG_SPLIT_NO_EMPTY);
|
||||
|
||||
// humanreadable filesize:
|
||||
$video['filesize'] = round($video['filesize']/(1024*1024), 2);
|
||||
|
||||
// break plot and comment
|
||||
$video['plot'] = nl2br($video['plot']);
|
||||
$video['comment'] = nl2br($video['comment']);
|
||||
|
||||
// cast
|
||||
$smarty->assign('cast_toggle', $config['showcasttoggle']);
|
||||
$show_cast = true;
|
||||
if ($config['showcasttoggle'])
|
||||
{
|
||||
$show_cast = (isset($_GET['show_cast']) && $_GET['show_cast'] == '1');
|
||||
}
|
||||
$smarty->assign('show_cast', $show_cast);
|
||||
$video['cast'] = [];
|
||||
if ($show_cast)
|
||||
{
|
||||
$video['cast'] = prepare_cast($video['actors']);
|
||||
}
|
||||
|
||||
// prepare the custom fields
|
||||
customfields($video, 'out');
|
||||
|
||||
// hide owner if not using multi-user
|
||||
if (!$config['multiuser']) unset($video['owner']);
|
||||
|
||||
// get drilldown url for image
|
||||
if ($video['imdbID'])
|
||||
{
|
||||
require_once './engines/engines.php';
|
||||
$smarty->assign('link', engineGetContentUrl($video['imdbID'], engineGetEngine($video['imdbID'])));
|
||||
}
|
||||
|
||||
// add episodes information
|
||||
if (array_key_exists('episodes', $video) && is_array($video['episodes']))
|
||||
{
|
||||
// allow multiple columns
|
||||
$smarty->assign('listcolumns', session_get('listcolumns'));
|
||||
}
|
||||
|
||||
$smarty->assign('castcolumns', $config['castcolumns']);
|
||||
$smarty->assign('video', $video);
|
||||
|
||||
// get genre ids and names
|
||||
$smarty->assign('genres', getItemGenres($video['id'], true));
|
||||
|
||||
// make engines available
|
||||
$smarty->assign('engines', $config['engine']);
|
||||
|
||||
// allow XML export
|
||||
foreach (array('xls','pdf','xml') as $export)
|
||||
{
|
||||
if ($config[$export]) $smarty->assign($export, 'show.php?id='.$video['id'].'&');
|
||||
}
|
||||
// new-style way of exporting
|
||||
// $smarty->assign('exports', listExports('show.php?id='.$video['id'].'&'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns the videoinfos to the smarty engine
|
||||
*/
|
||||
function tpl_edit($video)
|
||||
{
|
||||
global $smarty, $config, $lang;
|
||||
|
||||
// create a form ready quoted version for each value
|
||||
foreach (array_keys($video) as $key)
|
||||
{
|
||||
$video['q_'.$key] = formvar($video[$key]);
|
||||
}
|
||||
|
||||
// use custom function for language
|
||||
$video['f_language'] = custom_language_input('language', $video['language']);
|
||||
|
||||
// create mediatype selectbox
|
||||
$smarty->assign('mediatypes', out_mediatypes());
|
||||
if (!isset($video['mediatype'])) $video['mediatype'] = $config['mediadefault'];
|
||||
|
||||
// prepare the custom fields
|
||||
customfields($video, 'in');
|
||||
|
||||
if ($config['multiuser'])
|
||||
{
|
||||
$smarty->assign('owners', out_owners(array('0' => ''), (check_permission(PERM_ADMIN)) ? false : PERM_WRITE, true));
|
||||
}
|
||||
|
||||
// item genres
|
||||
if (array_key_exists('id', $video))
|
||||
{
|
||||
$item_genres = getItemGenres($video['id']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$item_genres = array();
|
||||
}
|
||||
// new-style
|
||||
$smarty->assign('genres', out_genres2($item_genres));
|
||||
#dlog(out_genres2($item_genres));
|
||||
#dlog($item_genres);
|
||||
// classic
|
||||
$smarty->assign('genreselect', out_genres($item_genres));
|
||||
|
||||
// assign data
|
||||
$smarty->assign('video', $video);
|
||||
|
||||
// get drilldown url for visit link
|
||||
if (array_key_exists('imdbID', $video))
|
||||
{
|
||||
require_once './engines/engines.php';
|
||||
$engine = engineGetEngine($video['imdbID']);
|
||||
$smarty->assign('link', engineGetContentUrl($video['imdbID'], $engine));
|
||||
$smarty->assign('engine', $engine);
|
||||
}
|
||||
|
||||
/*
|
||||
// populate autocomplete boxes
|
||||
$smarty->assign('audio_codecs', array_column(runSQL('SELECT DISTINCT audio_codec FROM '.TBL_DATA.' WHERE audio_codec IS NOT NULL'), 'audio_codec'));
|
||||
$smarty->assign('video_codecs', array_column(runSQL('SELECT DISTINCT video_codec FROM '.TBL_DATA.' WHERE video_codec IS NOT NULL'), 'video_codec'));
|
||||
*/
|
||||
$smarty->assign('lookup', array('0' => $lang['radio_look_ignore'],
|
||||
'1' => $lang['radio_look_lookup'],
|
||||
'2' => $lang['radio_look_overwrite']));
|
||||
|
||||
// needed for ajax image lookup
|
||||
$smarty->assign('engines', $config['engines']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare lookup template
|
||||
*/
|
||||
function tpl_lookup($find, $engine, $searchtype)
|
||||
{
|
||||
global $smarty, $config;
|
||||
|
||||
$find = trim($find);
|
||||
$smarty->assign('find', $find);
|
||||
$smarty->assign('q_find', formvar($find));
|
||||
|
||||
$smarty->assign('engine', $engine);
|
||||
|
||||
$tpl = array();
|
||||
foreach (engine_get_capable_engines($searchtype) as $eng => $enabled)
|
||||
{
|
||||
// url- make sure this is non-unicode
|
||||
$tpl[$eng]['url'] = 'lookup.php?find='.urlencode(utf8_smart_decode($find)).'&engine='.$eng.'&searchtype='.$searchtype;
|
||||
|
||||
// title
|
||||
$tpl[$eng]['name'] = $config['engines'][$eng]['name'];
|
||||
}
|
||||
|
||||
$smarty->assign('engines', $tpl);
|
||||
}
|
||||
|
||||
?>
|
||||
459
videodb/core/xls.php
Normal file
459
videodb/core/xls.php
Normal file
@@ -0,0 +1,459 @@
|
||||
<?php
|
||||
/**
|
||||
* XLS Export functions
|
||||
*
|
||||
* Allows exporting movies to an Excel list
|
||||
* Requires Spreadsheet_Excel_Writer libaray (http://pear.php.net)
|
||||
*
|
||||
* @package Core
|
||||
* @link http://pear.php.net/package/Spreadsheet_Excel_Writer
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @author Andreas Götz <cpuidle@gmx.de>
|
||||
* @version $Id: xls.php,v 1.8 2008/01/05 13:50:29 andig2 Exp $
|
||||
*/
|
||||
|
||||
require_once './core/functions.php';
|
||||
require_once './core/export.core.php';
|
||||
require_once './engines/engines.php';
|
||||
|
||||
#error_reporting(E_ALL^E_NOTICE);
|
||||
require_once 'vendor/autoload.php';
|
||||
|
||||
/**
|
||||
* Export PDF document
|
||||
*
|
||||
* @param string $where WHERE clause for SQL statement
|
||||
*/
|
||||
function xlsexport($WHERE)
|
||||
{
|
||||
global $config, $lang;
|
||||
|
||||
$text_length = 256-3;
|
||||
|
||||
// videodb context dir
|
||||
$context_dir = preg_replace('/^(.*)\/.*?$/','\\1',$_SERVER["SCRIPT_FILENAME"]);
|
||||
|
||||
// array of temp files wich have to be deleted if workbook is closed
|
||||
$del_list = array();
|
||||
|
||||
// make shure we have list with extra fields, even if empty
|
||||
$extra_fields = array_map('trim', explode(",", $config['xls_extra_fields']));
|
||||
|
||||
// Creating a workbook
|
||||
$workbook = new Spreadsheet_Excel_Writer();
|
||||
$workbook->setCustomColor(12, 192,192,192); // Headline
|
||||
$workbook->setCustomColor(13, 255,255,200); // Seen
|
||||
$workbook->setCustomColor(14, 255,220,220); // Lent
|
||||
//$workbook->setCustomColor(15, 0,0,0); // Test
|
||||
|
||||
// sending HTTP headers
|
||||
$outputFilename = ($config['xls_output_filename']) ? $config['xls_output_filename'] : 'VideoDB';
|
||||
$workbook->send($outputFilename.'.xls');
|
||||
|
||||
// Creating a worksheet
|
||||
$sheetTitle = ($config['xls_sheet_title']) ? $config['xls_sheet_title'] : 'VideoDB';
|
||||
$worksheet =& $workbook->addWorksheet($sheetTitle);
|
||||
|
||||
// format templates
|
||||
$alignLeftFormatNormal =& $workbook->addFormat();
|
||||
$alignLeftFormatLent =& $workbook->addFormat(array('Pattern' => 1));
|
||||
$alignLeftFormatLent -> setFGColor(14);
|
||||
$alignRightFormatNormal =& $workbook->addFormat(array('Align' => 'right'));
|
||||
$alignRightFormatLent =& $workbook->addFormat(array('Align' => 'right', 'Pattern' => 1));
|
||||
$alignRightFormatLent -> setFgColor(14);
|
||||
$alignCenterFormatNormal =& $workbook->addFormat(array('Align' => 'center'));
|
||||
$alignCenterFormatLent =& $workbook->addFormat(array('Align' => 'center', 'Pattern' => 1));
|
||||
$alignCenterFormatLent -> setFgColor(14);
|
||||
$titleFormatNormal =& $workbook->addFormat(array('Bold' => 1));
|
||||
$titleFormatUnseen =& $workbook->addFormat(array('Bold' => 1, 'Pattern' => 1));
|
||||
$titleFormatUnseen -> setFgColor(13);
|
||||
$titleFormatLent =& $workbook->addFormat(array('Bold' => 1, 'Pattern' => 1));
|
||||
$titleFormatLent -> setFgColor(14);
|
||||
|
||||
$plotFormatNormal =& $workbook->addFormat(array('Align' => 'top'));
|
||||
$plotFormatNormal -> setTextWrap();
|
||||
$plotFormatLent =& $workbook->addFormat(array('Align' => 'top','Pattern' => 1));
|
||||
$plotFormatLent -> setTextWrap();
|
||||
$plotFormatLent -> setFgColor(14);
|
||||
|
||||
$headlineFormat =& $workbook->addFormat(array('Bold' => 1, 'Align' => 'center', 'Pattern' => 1));
|
||||
$headlineFormat ->setFgColor(12);
|
||||
|
||||
$rowindex = 0;
|
||||
$columnindex = 0;
|
||||
|
||||
if ($config['xls_show_headline'])
|
||||
{
|
||||
$worksheet->setRow(0, 30);
|
||||
$rowindex++;
|
||||
}
|
||||
|
||||
// get data (see http://pear.php.net/bugs/bug.php?id=1572)
|
||||
$result = iconv_array('utf-8', 'iso-8859-1', exportData($WHERE));
|
||||
|
||||
foreach ($result as $row)
|
||||
{
|
||||
$columnindex = 0;
|
||||
set_time_limit(300); // rise per movie execution timeout limit if safe_mode is not set in php.ini
|
||||
|
||||
if (!empty($row['lentto']) && $config['xls_mark_lent']) {
|
||||
$alignLeftFormat = $alignLeftFormatLent;
|
||||
$alignCenterFormat = $alignLeftFormatLent;
|
||||
$alignRightFormat = $alignLeftFormatLent;
|
||||
}
|
||||
else
|
||||
{
|
||||
$alignLeftFormat = $alignLeftFormatNormal;
|
||||
$alignCenterFormat = $alignLeftFormatNormal;
|
||||
$alignRightFormat = $alignLeftFormatNormal;
|
||||
}
|
||||
$worksheet->setRow($rowindex, 15, $alignLeftFormat);
|
||||
|
||||
foreach ($extra_fields as $field)
|
||||
{
|
||||
$isNote = false;
|
||||
$walks = 1;
|
||||
if (preg_match('/(.+)\((.+)\)/',$field,$matches))
|
||||
{
|
||||
$field = trim($matches[1]);
|
||||
$note = trim($matches[2]);
|
||||
$walks = 2;
|
||||
}
|
||||
|
||||
for ($walk = 0;$walk < $walks; $walk++)
|
||||
{
|
||||
if ($walk == 1)
|
||||
{
|
||||
$isNote = true;
|
||||
$field = $note;
|
||||
$columnindex--;
|
||||
}
|
||||
|
||||
// title
|
||||
if ($field == "title")
|
||||
{
|
||||
// headline
|
||||
if ($config['xls_show_headline'] && $rowindex == 1 && !$isNote)
|
||||
$worksheet->writeString( 0, $columnindex, $lang['title'], $headlineFormat);
|
||||
|
||||
$title = $row['title'];
|
||||
if ($row['subtitle']) $title .= ' - '.$row['subtitle'];
|
||||
|
||||
if ($isNote) $worksheet->writeNote($rowindex, $columnindex++, $lang['title'].":\n".html_entity_decode($title));
|
||||
else {
|
||||
if ($row['seen'] == '0' && $config['xls_mark_unseen']) $format = $titleFormatUnseen;
|
||||
elseif (!empty($row['lentto']) && $config['xls_mark_lent']) $format = $titleFormatLent;
|
||||
else $format = $titleFormatNormal;
|
||||
if ($rowindex == 1) $worksheet->setColumn($columnindex, $columnindex, 50);
|
||||
$imdb = $row['imdbID'];
|
||||
$link = ($imdb) ? engineGetContentUrl($imdb, engineGetEngine($imdb)) : '';
|
||||
if($link <> '') $worksheet->writeUrl($rowindex, $columnindex, $link, html_entity_decode($title), $format);
|
||||
else $worksheet->writeString($rowindex, $columnindex, leftString(html_entity_decode($row['title']),$text_length), $format);
|
||||
}
|
||||
$columnindex++;
|
||||
}
|
||||
|
||||
// plot
|
||||
elseif ($field == "plot")
|
||||
{
|
||||
// headline
|
||||
if ($config['xls_show_headline'] && $rowindex == 1 && !$isNote)
|
||||
$worksheet->writeString( 0, $columnindex, $lang['plot'], $headlineFormat);
|
||||
|
||||
if ($isNote) $worksheet->writeNote($rowindex, $columnindex++, leftString(html_entity_decode($row['plot']),$text_length));
|
||||
else
|
||||
{
|
||||
if (!empty($row['lentto']) && $config['xls_mark_lent']) $format = $plotFormatLent;
|
||||
else $format = $plotFormatNormal;
|
||||
if ($rowindex == 1) $worksheet->setColumn($columnindex, $columnindex, 50);
|
||||
$worksheet->writeString($rowindex, $columnindex++, leftString(html_entity_decode($row['plot']),$text_length), $format);
|
||||
}
|
||||
}
|
||||
|
||||
// DiskId
|
||||
elseif ($field == "diskid")
|
||||
{
|
||||
// headline
|
||||
if ($config['xls_show_headline'] && $rowindex == 1 && !$isNote)
|
||||
$worksheet->writeString( 0, $columnindex, $lang['diskid'], $headlineFormat);
|
||||
|
||||
if ($isNote) $worksheet->writeNote($rowindex, $columnindex++, $lang['diskid'].":\n".html_entity_decode($row['diskid']));
|
||||
else
|
||||
{
|
||||
if ($rowindex == 1) $worksheet->setColumn($columnindex, $columnindex, 7);
|
||||
$worksheet->writeString($rowindex, $columnindex++, html_entity_decode($row['diskid']), $alignCenterFormat);
|
||||
}
|
||||
}
|
||||
|
||||
// add language
|
||||
elseif ($field == "language")
|
||||
{
|
||||
// headline
|
||||
if ($config['xls_show_headline'] && $rowindex == 1 && !$isNote)
|
||||
$worksheet->writeString( 0, $columnindex, $lang['language'], $headlineFormat);
|
||||
|
||||
if ($isNote) $worksheet->writeNote($rowindex, $columnindex++, $lang['language'].":\n".html_entity_decode($row['language']));
|
||||
else
|
||||
{
|
||||
if ($rowindex == 1) $worksheet->setColumn($columnindex, $columnindex, 30);
|
||||
$worksheet->writeString($rowindex, $columnindex++, html_entity_decode($row['language']), $alignLeftFormat);
|
||||
}
|
||||
}
|
||||
|
||||
// add mediatype
|
||||
elseif ($field == "mediatype")
|
||||
{
|
||||
// headline
|
||||
if ($config['xls_show_headline'] && $rowindex == 1 && !$isNote)
|
||||
$worksheet->writeString( 0, $columnindex, $lang['mediatype'], $headlineFormat);
|
||||
|
||||
if ($isNote) $worksheet->writeNote($rowindex, $columnindex++, $lang['mediatype'].":\n".html_entity_decode($row['mediatype']));
|
||||
else
|
||||
{
|
||||
if ($rowindex == 1) $worksheet->setColumn($columnindex, $columnindex, 7);
|
||||
$worksheet->writeString($rowindex, $columnindex++, html_entity_decode($row['mediatype']), $alignLeftFormat);
|
||||
}
|
||||
}
|
||||
|
||||
// genres
|
||||
elseif ($field == "genres")
|
||||
{
|
||||
// headline
|
||||
if ($config['xls_show_headline'] && $rowindex == 1 && !$isNote)
|
||||
$worksheet->writeString( 0, $columnindex, $lang['genres'], $headlineFormat);
|
||||
|
||||
if (count($row['genres']))
|
||||
{
|
||||
$output_genres = array();
|
||||
foreach ($row['genres'] as $genre)
|
||||
{
|
||||
$output_genres[]= html_entity_decode($genre['name']);
|
||||
}
|
||||
|
||||
if ($isNote) $worksheet->writeNote($rowindex, $columnindex++, $lang['genres'].":\n".join(", ", $output_genres));
|
||||
else
|
||||
{
|
||||
if ($rowindex == 1) $worksheet->setColumn($columnindex, $columnindex, 20);
|
||||
$worksheet->writeString($rowindex, $columnindex, join(", ", $output_genres), $alignCenterFormat);
|
||||
}
|
||||
}
|
||||
$columnindex++;
|
||||
}
|
||||
|
||||
// runtime
|
||||
elseif ($field == "runtime")
|
||||
{
|
||||
// headline
|
||||
if ($config['xls_show_headline'] && $rowindex == 1 && !$isNote)
|
||||
$worksheet->writeString( 0, $columnindex, $lang['runtime'], $headlineFormat);
|
||||
|
||||
if ($row['runtime'])
|
||||
{
|
||||
if ($isNote) $worksheet->writeNote($rowindex, $columnindex++, $lang['runtime'].":\n".html_entity_decode($row['runtime']).' min');
|
||||
else
|
||||
{
|
||||
if ($rowindex == 1) $worksheet->setColumn($columnindex, $columnindex, 7);
|
||||
$worksheet->writeString($rowindex, $columnindex, html_entity_decode($row['runtime']).' min', $alignRightFormat);
|
||||
}
|
||||
}
|
||||
$columnindex++;
|
||||
}
|
||||
|
||||
// year
|
||||
elseif ($field == "year")
|
||||
{
|
||||
// headline
|
||||
if ($config['xls_show_headline'] && $rowindex == 1 && !$isNote)
|
||||
$worksheet->writeString( 0, $columnindex, $lang['year'], $headlineFormat);
|
||||
|
||||
if ($row['year'] != '0000')
|
||||
{
|
||||
if ($isNote) $worksheet->writeNote($rowindex, $columnindex++, $lang['year'].":\n".html_entity_decode($row['year']));
|
||||
else
|
||||
{
|
||||
if ($rowindex == 1) $worksheet->setColumn($columnindex, $columnindex, 7);
|
||||
$worksheet->writeNumber($rowindex, $columnindex, html_entity_decode($row['year']), $alignCenterFormat);
|
||||
}
|
||||
}
|
||||
$columnindex++;
|
||||
}
|
||||
|
||||
// owner
|
||||
elseif ($field == "owner")
|
||||
{
|
||||
// headline
|
||||
if ($config['xls_show_headline'] && $rowindex == 1 && !$isNote)
|
||||
$worksheet->writeString( 0, $columnindex, $lang['owner'], $headlineFormat);
|
||||
|
||||
if ($isNote) $worksheet->writeNote($rowindex, $columnindex++, $lang['owner'].":\n".html_entity_decode($row['owner']));
|
||||
else
|
||||
{
|
||||
if ($rowindex == 1) $worksheet->setColumn($columnindex, $columnindex, 15);
|
||||
$worksheet->writeString($rowindex, $columnindex++, html_entity_decode($row['owner']), $alignCenterFormat);
|
||||
}
|
||||
}
|
||||
|
||||
// lent
|
||||
elseif ($field == "lent")
|
||||
{
|
||||
// headline
|
||||
if ($config['xls_show_headline'] && $rowindex == 1 && !$isNote)
|
||||
$worksheet->writeString( 0, $columnindex, $lang['lentto'], $headlineFormat);
|
||||
|
||||
if ($isNote) $worksheet->writeNote($rowindex, $columnindex++, $lang['lentto'].":\n".html_entity_decode($row['lentto']));
|
||||
else
|
||||
{
|
||||
if ($rowindex == 1) $worksheet->setColumn($columnindex, $columnindex, 15);
|
||||
$worksheet->writeString($rowindex, $columnindex++, html_entity_decode($row['lentto']), $alignCenterFormat);
|
||||
}
|
||||
}
|
||||
// seen
|
||||
elseif ($field == "seen")
|
||||
{
|
||||
// headline
|
||||
if ($config['xls_show_headline'] && $rowindex == 1 && !$isNote)
|
||||
$worksheet->writeString( 0, $columnindex, $lang['seen'], $headlineFormat);
|
||||
|
||||
if ($isNote) {
|
||||
if ($row['seen'] == 1) $worksheet->writeNote($rowindex, $columnindex++, html_entity_decode($lang['seen']));
|
||||
else $columnindex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($rowindex == 1) $worksheet->setColumn($columnindex, $columnindex, 2);
|
||||
if ($row['seen'] == 1) $worksheet->writeString($rowindex, $columnindex++, "X", $alignCenterFormat); else $columnindex++;
|
||||
}
|
||||
}
|
||||
// insertdate
|
||||
elseif ($field == "insertdate")
|
||||
{
|
||||
// headline
|
||||
if ($config['xls_show_headline'] && $rowindex == 1 && !$isNote)
|
||||
$worksheet->writeString( 0, $columnindex, $lang['date'], $headlineFormat);
|
||||
|
||||
if ($isNote) $worksheet->writeNote($rowindex, $columnindex++, $lang['date'].":\n".html_entity_decode(preg_replace('/^([0-9]{4}\-[0-9]{2}\-[0-9]{2}).*/','$1',$row['created'])));
|
||||
else
|
||||
{
|
||||
if ($rowindex == 1) $worksheet->setColumn($columnindex, $columnindex, 10);
|
||||
$worksheet->write($rowindex, $columnindex++, html_entity_decode(preg_replace('/^([0-9]{4}\-[0-9]{2}\-[0-9]{2}).*/','$1',$row['created'])), $alignCenterFormat);
|
||||
}
|
||||
}
|
||||
|
||||
// custom fields
|
||||
elseif(preg_match("/^custom[0-4]$/",$field))
|
||||
{
|
||||
// headline
|
||||
if ($config['xls_show_headline'] && $rowindex == 1 && !$isNote)
|
||||
$worksheet->writeString( 0, $columnindex, $config[$field], $headlineFormat);
|
||||
|
||||
//$row[$field] = html_entity_decode($row[$field]);
|
||||
|
||||
switch ($config[$field.'type'])
|
||||
{
|
||||
case 'ed2k':
|
||||
if ($isNote) $worksheet->writeNote($rowindex, $columnindex++, $config[$field].":\n".html_entity_decode($row[$field]));
|
||||
else
|
||||
{
|
||||
if ($rowindex == 1) $worksheet->setColumn($columnindex, $columnindex, 12);
|
||||
$worksheet->writeUrl($rowindex, $columnindex++, html_entity_decode($row[$field]), 'ED2K-Link', $alignCenterFormat);
|
||||
}
|
||||
break;
|
||||
case 'language':
|
||||
if ($isNote) $worksheet->writeNote($rowindex, $columnindex++, $config[$field].":\n".html_entity_decode($row[$field]));
|
||||
else
|
||||
{
|
||||
if ($rowindex == 1) $worksheet->setColumn($columnindex, $columnindex, 30);
|
||||
$worksheet->writeString($rowindex, $columnindex++, html_entity_decode($row[$field]), $alignLeftFormat);
|
||||
}
|
||||
break;
|
||||
case 'rating':
|
||||
if ($row[$field]) $rating = html_entity_decode($row[$field]).'/10'; else $rating = "";
|
||||
if ($isNote)
|
||||
{
|
||||
if ($row[$field]) $worksheet->writeNote($rowindex, $columnindex, $config[$field].":\n".$rating);
|
||||
$columnindex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($rowindex == 1) $worksheet->setColumn($columnindex, $columnindex, 7);
|
||||
if ($row[$field]) $worksheet->writeString($rowindex, $columnindex, $rating,$alignCenterFormat);
|
||||
$columnindex++;
|
||||
}
|
||||
break;
|
||||
case 'fsk':
|
||||
if (preg_match("/[0-9]+/",$row[$field]) && !preg_match("/[^0-9]+/",$row[$field]))
|
||||
{
|
||||
$fskstr = 'FSK'.html_entity_decode($row[$field]);
|
||||
}
|
||||
else $fskstr = html_entity_decode($row[$field]);
|
||||
|
||||
if ($isNote) $worksheet->writeNote($rowindex, $columnindex++, $config[$field].":\n".$fskstr);
|
||||
else
|
||||
{
|
||||
if ($rowindex == 1) $worksheet->setColumn($columnindex, $columnindex, 7);
|
||||
$worksheet->writeString($rowindex, $columnindex++, $fskstr, $alignCenterFormat);
|
||||
}
|
||||
break;
|
||||
case 'barcode':
|
||||
if ($isNote) $worksheet->writeNote($rowindex, $columnindex++, $config[$field].":\n".html_entity_decode($row[$field]));
|
||||
else
|
||||
{
|
||||
if ($rowindex == 1) $worksheet->setColumn($columnindex, $columnindex, 15);
|
||||
$worksheet->writeString($rowindex, $columnindex++, html_entity_decode($row[$field]), $alignCenterFormat);
|
||||
}
|
||||
break;
|
||||
case 'orgtitle':
|
||||
if ($isNote)
|
||||
{
|
||||
if (!empty($row[$field])) $worksheet->writeNote($rowindex, $columnindex, $config[$field]. ":\n".html_entity_decode($row[$field]));
|
||||
$columnindex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($rowindex == 1) $worksheet->setColumn($columnindex, $columnindex, 50);
|
||||
$worksheet->writeString($rowindex, $columnindex++, html_entity_decode($row[$field]), $alignLeftFormat);
|
||||
}
|
||||
break;
|
||||
case 'movix':
|
||||
if ($isNote) $worksheet->writeNote($rowindex, $columnindex++, $config[$field].":\n ".html_entity_decode($row[$field]));
|
||||
else
|
||||
{
|
||||
if ($rowindex == 1) $worksheet->setColumn($columnindex, $columnindex, 7);
|
||||
$worksheet->writeString($rowindex, $columnindex++, html_entity_decode($row[$field]), $alignCenterFormat);
|
||||
}
|
||||
break;
|
||||
case 'mpaa':
|
||||
if ($isNote) $worksheet->writeNote($rowindex, $columnindex++, $config[$field].":\n".html_entity_decode($row[$field]), $alignCenterFormat);
|
||||
else
|
||||
{
|
||||
if ($rowindex == 1) $worksheet->setColumn($columnindex, $columnindex, 12);
|
||||
$worksheet->writeString($rowindex, $columnindex++, html_entity_decode($row[$field]), $alignCenterFormat);
|
||||
}
|
||||
break;
|
||||
case 'bbfc':
|
||||
if ($isNote) $worksheet->writeNote($rowindex, $columnindex++, $config[$field].":\n".html_entity_decode($row[$field]));
|
||||
else
|
||||
{
|
||||
if ($rowindex == 1) $worksheet->setColumn($columnindex, $columnindex, 7);
|
||||
$worksheet->writeString($rowindex, $columnindex++, html_entity_decode($row[$field]), $alignCenterFormat);
|
||||
}
|
||||
break;
|
||||
default: // unknown
|
||||
if ($isNote) $worksheet->writeNote($rowindex, $columnindex++, $config[$field].":\n".html_entity_decode($row[$field]));
|
||||
else
|
||||
{
|
||||
$worksheet->writeString($rowindex, $columnindex++, html_entity_decode($row[$field]), $alignLeftFormat);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} //End of walk
|
||||
|
||||
}
|
||||
$rowindex++;
|
||||
}
|
||||
// Let's send the file
|
||||
$workbook->close();
|
||||
}
|
||||
?>
|
||||
107
videodb/core/xml.core.php
Normal file
107
videodb/core/xml.core.php
Normal file
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
/**
|
||||
* XML support functions
|
||||
*
|
||||
* @package Core
|
||||
* @author Andreas Götz <cpuidle@gmx.de>
|
||||
* @version $Id: xml.core.php,v 1.8 2013/04/26 15:09:35 andig2 Exp $
|
||||
*/
|
||||
|
||||
/**
|
||||
* See http://feedvalidator.org/docs/error/InvalidRFC2822Date.html
|
||||
*/
|
||||
$GLOBALS['rss_timestamp_format'] = 'D, j M Y H:i:s O';
|
||||
|
||||
/**
|
||||
* Encodes HTML entities into XML character entities
|
||||
* this avoids problems with unknown entities in XML
|
||||
*
|
||||
* @param string $string HTML string to encode
|
||||
* @return string encoded string containing XML character entities
|
||||
*/
|
||||
function encode_character_entities($string)
|
||||
{
|
||||
return strtr($string, get_html_translation_table(HTML_SPECIALCHARS));
|
||||
# return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an XML tag
|
||||
*
|
||||
* @param string $tag XML tag name
|
||||
* @param string $value value for XML tag
|
||||
* @param boolean $encode require encoding of tag value
|
||||
* @return string XML tag
|
||||
*/
|
||||
function createTag($tag, $value, $encode = true)
|
||||
{
|
||||
if ($encode) $value = encode_character_entities($value);
|
||||
return "<$tag>".$value."</$tag>\n";
|
||||
}
|
||||
|
||||
function createContainer($tag, $value = '')
|
||||
{
|
||||
return createTag($tag, $value, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert MySQL Date to RSS timestamp
|
||||
*
|
||||
* @return string RFC 2822 Date (http://feedvalidator.org/docs/error/InvalidRFC2822Date.html)
|
||||
*/
|
||||
function rss_timestamp($timestamp)
|
||||
{
|
||||
global $rss_timestamp_format;
|
||||
|
||||
// Lets sort this nasty timestamp nonsense out ;D
|
||||
$y = substr($timestamp, 0, 4);
|
||||
$m = substr($timestamp, 5, 2);
|
||||
$d = substr($timestamp, 8, 2);
|
||||
$h = substr($timestamp, 11, 2);
|
||||
$min = substr($timestamp, 14, 2);
|
||||
$s = substr($timestamp, 17, 2);
|
||||
|
||||
$timestamp = mktime($h, $min, $s, $m, $d, $y);
|
||||
|
||||
return date($rss_timestamp_format, $timestamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load XML into SimpleXML object
|
||||
* Fixes potential encoding issue
|
||||
*/
|
||||
function load_xml($data)
|
||||
{
|
||||
$xml = simplexml_load_string($data, $root = 'SimpleXMLElement', LIBXML_NOCDATA);
|
||||
|
||||
// character encoding warning- hack
|
||||
if ($xml === false)
|
||||
{
|
||||
$error = error_get_last();
|
||||
# dump($error);
|
||||
|
||||
// this is nasty- sometimes simplexml_load_string fails but doesn't raise an error
|
||||
if (preg_match('/simplexml_load_string/i', $error['message']))
|
||||
{
|
||||
$xml = simplexml_load_string(utf8_encode($data), $root, LIBXML_NOCDATA);
|
||||
}
|
||||
}
|
||||
|
||||
return $xml;
|
||||
}
|
||||
|
||||
/**
|
||||
* Concatenate string-converted xml entities
|
||||
*/
|
||||
function xml_join($items, $str = "\n")
|
||||
{
|
||||
foreach ($items as $item)
|
||||
{
|
||||
if ($data) $data .= $str;
|
||||
$data .= (string) $item;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
?>
|
||||
186
videodb/core/xml.php
Normal file
186
videodb/core/xml.php
Normal file
@@ -0,0 +1,186 @@
|
||||
<?php
|
||||
/**
|
||||
* XML export functions
|
||||
*
|
||||
* Lets you browse through your movie collection
|
||||
*
|
||||
* @package Core
|
||||
* @author Andreas Götz <cpuidle@gmx.de>
|
||||
* @author Kokanovic Branko <branko.kokanovic@gmail.com>
|
||||
* @version $Id: xml.php,v 1.34 2013/03/10 16:25:35 andig2 Exp $
|
||||
*/
|
||||
|
||||
require_once './core/functions.php';
|
||||
require_once './core/export.core.php';
|
||||
require_once './core/xml.core.php';
|
||||
|
||||
/**
|
||||
* Export XML data
|
||||
*
|
||||
* @param string $where WHERE clause for SQL statement
|
||||
*/
|
||||
function xmlexport($WHERE)
|
||||
{
|
||||
global $config;
|
||||
|
||||
// get data
|
||||
$result = exportData($WHERE);
|
||||
|
||||
// do adultcheck
|
||||
// this may not be needed as same check is done in exportData in previous statement
|
||||
if (is_array($result))
|
||||
{
|
||||
$result = array_filter($result, function($video) {return adultcheck($video["id"]);});
|
||||
}
|
||||
|
||||
$xml = '';
|
||||
|
||||
// loop over items
|
||||
foreach ($result as $item)
|
||||
{
|
||||
$xml_item = '';
|
||||
|
||||
// loop over attributes
|
||||
foreach ($item as $key => $value)
|
||||
{
|
||||
if (!empty($value))
|
||||
{
|
||||
if (($key != 'owner_id') && ($key != 'actors') && ($key != 'genres'))
|
||||
{
|
||||
$tag = strtolower($key);
|
||||
$xml_item .= createTag($tag, trim(html_entity_decode_all($value)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// this is a hack for exporting thumbnail URLs
|
||||
if ($item['imgurl'] && $config['xml_thumbnails'])
|
||||
{
|
||||
$thumb = getThumbnail($item['imgurl']);
|
||||
if (preg_match('/cache/', $thumb))
|
||||
$xml_item .= createTag('thumbnail', trim($thumb));
|
||||
}
|
||||
|
||||
// genres
|
||||
if (count($item['genres']))
|
||||
{
|
||||
$xml_genres = '';
|
||||
foreach ($item['genres'] as $genre)
|
||||
{
|
||||
$xml_genres .= createTag('genre', $genre['name']);
|
||||
}
|
||||
$xml_item .= createContainer('genres', $xml_genres);
|
||||
}
|
||||
|
||||
// actors
|
||||
$actors = explode ("\n",$item['actors']);
|
||||
if (count($actors))
|
||||
{
|
||||
$xml_actors = '';
|
||||
foreach ($actors as $actor)
|
||||
{
|
||||
$xml_actor_data = '';
|
||||
$actor_data = explode("::",$actor);
|
||||
if (array_key_exists('1', $actor_data))
|
||||
{
|
||||
$xml_actor_data .= createTag('name', $actor_data[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
$xml_actor_data .= createTag('name', '');
|
||||
}
|
||||
if (array_key_exists('1', $actor_data))
|
||||
{
|
||||
$xml_actor_data .= createTag('role', $actor_data[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
$xml_actor_data .= createTag('role', '');
|
||||
}
|
||||
if (array_key_exists('2', $actor_data))
|
||||
{
|
||||
$xml_actor_data .= createTag('imdbid', $actor_data[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
$xml_actor_data .= createTag('imdbid', '');
|
||||
}
|
||||
$xml_actors .= createContainer('actor', $xml_actor_data);
|
||||
}
|
||||
$xml_item .= createContainer('actors', $xml_actors);
|
||||
}
|
||||
$xml .= createContainer('item', $xml_item);
|
||||
}
|
||||
|
||||
$xml = '<?xml version="1.0" encoding="utf-8"?>'.
|
||||
"\n".createContainer('catalog', $xml);
|
||||
|
||||
// header('Content-type: text/xml');
|
||||
$mime = (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE')) ? 'application/force-download' : 'application/octet-stream';
|
||||
header('Content-type: '.$mime);
|
||||
header('Content-length: '.strlen($xml));
|
||||
header('Content-disposition: attachment; filename=videoDB.xml');
|
||||
|
||||
echo $xml;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update RSS File
|
||||
*
|
||||
* @author Mike Clark <mike.clark@cinven.com>
|
||||
*/
|
||||
function rssexport($WHERE)
|
||||
{
|
||||
global $config, $rss_timestamp_format, $filter;
|
||||
|
||||
// make sure server doesn't specify something else
|
||||
header('Content-type: text/xml; charset=utf-8');
|
||||
|
||||
if ($filter)
|
||||
{
|
||||
$result = exportData($WHERE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// get the latest items from the DB according to config setting
|
||||
$SQL = 'SELECT id, title, plot, created
|
||||
FROM '.TBL_DATA.'
|
||||
ORDER BY created DESC LIMIT '.$config['shownew'];
|
||||
$result = runSQL($SQL);
|
||||
}
|
||||
|
||||
// script root
|
||||
$base = 'http://'.$_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF']);
|
||||
|
||||
// setup the RSS Feed
|
||||
$rssfeed = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
|
||||
$rssfeed .= '<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">';
|
||||
$rssfeed .= '<channel>';
|
||||
$rssfeed .= '<atom:link href="'.$base.'/index.php?export=rss" rel="self" type="application/rss+xml" />';
|
||||
$rssfeed .= createTag('title', 'VideoDB');
|
||||
$rssfeed .= createTag('link', $base.'/index.php?export=rss');
|
||||
$rssfeed .= createTag('description', 'New items posted on VideoDB');
|
||||
$rssfeed .= createTag('language', 'en-us');
|
||||
$rssfeed .= createTag('lastBuildDate', date($rss_timestamp_format));
|
||||
|
||||
// build the <item></item> section of the Feed
|
||||
foreach ($result as $item)
|
||||
{
|
||||
$xml_item = createTag('title', $item['title']);
|
||||
$xml_item .= createTag('link', $base.'/show.php?id='.$item['id']);
|
||||
$xml_item .= createTag('description', $item['plot']);
|
||||
$xml_item .= createTag('guid', $base.'/show.php?id='.$item['id']);
|
||||
$xml_item .= createTag('pubDate', rss_timestamp($item['created']));
|
||||
|
||||
$rssfeed .= createTag('item', $xml_item, false);
|
||||
}
|
||||
$rssfeed .= '</channel>';
|
||||
$rssfeed .= '</rss>';
|
||||
|
||||
header('Content-type: text/xml');
|
||||
# header('Content-length: '.rssfeed($xml));
|
||||
# header('Content-disposition: filename=rss.xml');
|
||||
echo $rssfeed;
|
||||
}
|
||||
|
||||
?>
|
||||
Reference in New Issue
Block a user