Initial commit: Backup der Webseiten
- zoesch.de - blitzkiste.net - gruene-hassberge (norbert.zoesch.de) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
489
zoesch.de/galerie/include/Logger.class.php
Normal file
489
zoesch.de/galerie/include/Logger.class.php
Normal file
@@ -0,0 +1,489 @@
|
||||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Piwigo - a PHP based photo gallery |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright(C) 2008-2016 Piwigo Team http://piwigo.org |
|
||||
// | Copyright(C) 2003-2008 PhpWebGallery Team http://phpwebgallery.net |
|
||||
// | Copyright(C) 2002-2003 Pierrick LE GALL http://le-gall.net/pierrick |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
* Modified version of KLogger 0.2.0
|
||||
*
|
||||
* @author Kenny Katzgrau <katzgrau@gmail.com>
|
||||
*
|
||||
* @package logger
|
||||
*/
|
||||
|
||||
class Logger
|
||||
{
|
||||
/**
|
||||
* Error severity, from low to high. From BSD syslog RFC, section 4.1.1
|
||||
* @link http://www.faqs.org/rfcs/rfc3164.html
|
||||
*/
|
||||
const EMERGENCY = 0; // Emergency: system is unusable
|
||||
const ALERT = 1; // Alert: action must be taken immediately
|
||||
const CRITICAL = 2; // Critical: critical conditions
|
||||
const ERROR = 3; // Error: error conditions
|
||||
const WARNING = 4; // Warning: warning conditions
|
||||
const NOTICE = 5; // Notice: normal but significant condition
|
||||
const INFO = 6; // Informational: informational messages
|
||||
const DEBUG = 7; // Debug: debug messages
|
||||
|
||||
/**
|
||||
* Custom "disable" level.
|
||||
*/
|
||||
const OFF = -1; // Log nothing at all
|
||||
|
||||
/**
|
||||
* Internal status codes.
|
||||
*/
|
||||
const STATUS_LOG_OPEN = 1;
|
||||
const STATUS_OPEN_FAILED = 2;
|
||||
const STATUS_LOG_CLOSED = 3;
|
||||
|
||||
/**
|
||||
* Disable archive purge.
|
||||
*/
|
||||
const ARCHIVE_NO_PURGE = -1;
|
||||
|
||||
/**
|
||||
* Standard messages produced by the class.
|
||||
* @var array
|
||||
*/
|
||||
private static $_messages = array(
|
||||
'writefail' => 'The file could not be written to. Check that appropriate permissions have been set.',
|
||||
'opensuccess' => 'The log file was opened successfully.',
|
||||
'openfail' => 'The file could not be opened. Check permissions.',
|
||||
);
|
||||
|
||||
/**
|
||||
* Instance options.
|
||||
* @var array
|
||||
*/
|
||||
private $options = array(
|
||||
'directory' => null, // Log files directory
|
||||
'filename' => null, // Path to the log file
|
||||
'globPattern' => 'log_*.txt', // Pattern to select all log files with glob()
|
||||
'severity' => self::DEBUG, // Current minimum logging threshold
|
||||
'dateFormat' => 'Y-m-d G:i:s', // Date format
|
||||
'archiveDays' => self::ARCHIVE_NO_PURGE, // Number of files to keep
|
||||
);
|
||||
|
||||
/**
|
||||
* Current status of the logger.
|
||||
* @var integer
|
||||
*/
|
||||
private $_logStatus = self::STATUS_LOG_CLOSED;
|
||||
/**
|
||||
* File handle for this instance's log file.
|
||||
* @var resource
|
||||
*/
|
||||
private $_fileHandle = null;
|
||||
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param array $options
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($options)
|
||||
{
|
||||
$this->options = array_merge($this->options, $options);
|
||||
|
||||
if (is_string($this->options['severity']))
|
||||
{
|
||||
$this->options['severity'] = self::codeToLevel($this->options['severity']);
|
||||
}
|
||||
|
||||
if ($this->options['severity'] === self::OFF)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$this->options['directory'] = rtrim($this->options['directory'], '\\/') . DIRECTORY_SEPARATOR;
|
||||
|
||||
if ($this->options['filename'] == null)
|
||||
{
|
||||
$this->options['filename'] = 'log_' . date('Y-m-d') . '.txt';
|
||||
}
|
||||
|
||||
$this->options['filePath'] = $this->options['directory'] . $this->options['filename'];
|
||||
|
||||
if ($this->options['archiveDays'] != self::ARCHIVE_NO_PURGE && rand() % 97 == 0)
|
||||
{
|
||||
$this->purge();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the log file if not already oppenned
|
||||
*/
|
||||
private function open()
|
||||
{
|
||||
if ($this->status() == self::STATUS_LOG_CLOSED)
|
||||
{
|
||||
if (!file_exists($this->options['directory']))
|
||||
{
|
||||
mkgetdir($this->options['directory'], MKGETDIR_DEFAULT|MKGETDIR_PROTECT_HTACCESS);
|
||||
}
|
||||
|
||||
if (file_exists($this->options['filePath']) && !is_writable($this->options['filePath']))
|
||||
{
|
||||
$this->_logStatus = self::STATUS_OPEN_FAILED;
|
||||
throw new RuntimeException(self::$_messages['writefail']);
|
||||
return;
|
||||
}
|
||||
|
||||
if (($this->_fileHandle = fopen($this->options['filePath'], 'a')) != false)
|
||||
{
|
||||
$this->_logStatus = self::STATUS_LOG_OPEN;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->_logStatus = self::STATUS_OPEN_FAILED;
|
||||
throw new RuntimeException(self::$_messages['openfail']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class destructor.
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
if ($this->_fileHandle)
|
||||
{
|
||||
fclose($this->_fileHandle);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns logger status.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function status()
|
||||
{
|
||||
return $this->_logStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns logger severity threshold.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function severity()
|
||||
{
|
||||
return $this->options['severity'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a $line to the log with a severity level of DEBUG.
|
||||
*
|
||||
* @param string $line
|
||||
* @param string $cat
|
||||
* @param array $args
|
||||
*/
|
||||
public function debug($line, $cat = null, $args = array())
|
||||
{
|
||||
$this->log(self::DEBUG, $line, $cat, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a $line to the log with a severity level of INFO.
|
||||
*
|
||||
* @param string $line
|
||||
* @param string $cat
|
||||
* @param array $args
|
||||
*/
|
||||
public function info($line, $cat = null, $args = array())
|
||||
{
|
||||
$this->log(self::INFO, $line, $cat, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a $line to the log with a severity level of NOTICE.
|
||||
*
|
||||
* @param string $line
|
||||
* @param string $cat
|
||||
* @param array $args
|
||||
*/
|
||||
public function notice($line, $cat = null, $args = array())
|
||||
{
|
||||
$this->log(self::NOTICE, $line, $cat, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a $line to the log with a severity level of WARNING.
|
||||
*
|
||||
* @param string $line
|
||||
* @param string $cat
|
||||
* @param array $args
|
||||
*/
|
||||
public function warn($line, $cat = null, $args = array())
|
||||
{
|
||||
$this->log(self::WARNING, $line, $cat, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a $line to the log with a severity level of ERROR.
|
||||
*
|
||||
* @param string $line
|
||||
* @param string $cat
|
||||
* @param array $args
|
||||
*/
|
||||
public function error($line, $cat = null, $args = array())
|
||||
{
|
||||
$this->log(self::ERROR, $line, $cat, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a $line to the log with a severity level of ALERT.
|
||||
*
|
||||
* @param string $line
|
||||
* @param string $cat
|
||||
* @param array $args
|
||||
*/
|
||||
public function alert($line, $cat = null, $args = array())
|
||||
{
|
||||
$this->log(self::ALERT, $line, $cat, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a $line to the log with a severity level of CRITICAL.
|
||||
*
|
||||
* @param string $line
|
||||
* @param string $cat
|
||||
* @param array $args
|
||||
*/
|
||||
public function critical($line, $cat = null, $args = array())
|
||||
{
|
||||
$this->log(self::CRITICAL, $line, $cat, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a $line to the log with a severity level of EMERGENCY.
|
||||
*
|
||||
* @param string $line
|
||||
* @param string $cat
|
||||
* @param array $args
|
||||
*/
|
||||
public function emergency($line, $cat = null, $args = array())
|
||||
{
|
||||
$this->log(self::EMERGENCY, $line, $cat, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a $line to the log with the given severity.
|
||||
*
|
||||
* @param integer $severity
|
||||
* @param string $line
|
||||
* @param string $cat
|
||||
* @param array $args
|
||||
*/
|
||||
public function log($severity, $message, $cat = null, $args = array())
|
||||
{
|
||||
if ($this->severity() >= $severity)
|
||||
{
|
||||
if (is_array($cat))
|
||||
{
|
||||
$args = $cat;
|
||||
$cat = null;
|
||||
}
|
||||
$line = $this->formatMessage($severity, $message, $cat, $args);
|
||||
$this->write($line);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Directly writes a line to the log without adding level and time.
|
||||
*
|
||||
* @param string $line
|
||||
*/
|
||||
public function write($line)
|
||||
{
|
||||
$this->open();
|
||||
if ($this->status() == self::STATUS_LOG_OPEN)
|
||||
{
|
||||
if (fwrite($this->_fileHandle, $line) === false)
|
||||
{
|
||||
throw new RuntimeException(self::$_messages['writefail']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Purges files matching 'globPattern' older than 'archiveDays'.
|
||||
*/
|
||||
public function purge()
|
||||
{
|
||||
$files = glob($this->options['directory'] . $this->options['globPattern']);
|
||||
$limit = time() - $this->options['archiveDays'] * 86400;
|
||||
|
||||
foreach ($files as $file)
|
||||
{
|
||||
if (@filemtime($file) < $limit)
|
||||
{
|
||||
@unlink($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the message for logging.
|
||||
*
|
||||
* @param string $level
|
||||
* @param string $message
|
||||
* @param array $context
|
||||
* @return string
|
||||
*/
|
||||
private function formatMessage($level, $message, $cat, $context)
|
||||
{
|
||||
if (!empty($context))
|
||||
{
|
||||
$message.= "\n" . $this->indent($this->contextToString($context));
|
||||
}
|
||||
$line = "[" . $this->getTimestamp() . "]\t[" . self::levelToCode($level) . "]\t";
|
||||
if ($cat != null)
|
||||
{
|
||||
$line.= "[" . $cat . "]\t";
|
||||
}
|
||||
return $line . $message . "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the formatted Date/Time for the log entry.
|
||||
*
|
||||
* PHP DateTime is dumb, and you have to resort to trickery to get microseconds
|
||||
* to work correctly, so here it is.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getTimestamp()
|
||||
{
|
||||
$originalTime = microtime(true);
|
||||
$micro = sprintf('%06d', ($originalTime - floor($originalTime)) * 1000000);
|
||||
$date = new DateTime(date('Y-m-d H:i:s.'.$micro, $originalTime));
|
||||
return $date->format($this->options['dateFormat']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes the given context and converts it to a string.
|
||||
*
|
||||
* @param array $context
|
||||
* @return string
|
||||
*/
|
||||
private function contextToString($context)
|
||||
{
|
||||
$export = '';
|
||||
foreach ($context as $key => $value)
|
||||
{
|
||||
$export.= $key . ': ';
|
||||
$export.= preg_replace(array(
|
||||
'/=>\s+([a-zA-Z])/im',
|
||||
'/array\(\s+\)/im',
|
||||
'/^ |\G /m'
|
||||
),
|
||||
array(
|
||||
'=> $1',
|
||||
'array()',
|
||||
' '
|
||||
),
|
||||
str_replace('array (', 'array(', var_export($value, true))
|
||||
);
|
||||
$export.= PHP_EOL;
|
||||
}
|
||||
return str_replace(array('\\\\', '\\\''), array('\\', '\''), rtrim($export));
|
||||
}
|
||||
|
||||
/**
|
||||
* Indents the given string with the given indent.
|
||||
*
|
||||
* @param string $string The string to indent
|
||||
* @param string $indent What to use as the indent.
|
||||
* @return string
|
||||
*/
|
||||
private function indent($string, $indent = ' ')
|
||||
{
|
||||
return $indent . str_replace("\n", "\n" . $indent, $string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts level constants to string name.
|
||||
*
|
||||
* @param int $level
|
||||
* @return string
|
||||
*/
|
||||
static function levelToCode($level)
|
||||
{
|
||||
switch ($level)
|
||||
{
|
||||
case self::EMERGENCY:
|
||||
return 'EMERGENCY';
|
||||
case self::ALERT:
|
||||
return 'ALERT';
|
||||
case self::CRITICAL:
|
||||
return 'CRITICAL';
|
||||
case self::NOTICE:
|
||||
return 'NOTICE';
|
||||
case self::INFO:
|
||||
return 'INFO';
|
||||
case self::WARNING:
|
||||
return 'WARNING';
|
||||
case self::DEBUG:
|
||||
return 'DEBUG';
|
||||
case self::ERROR:
|
||||
return 'ERROR';
|
||||
default:
|
||||
throw new RuntimeException('Unknown severity level ' . $level);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts level names to constant.
|
||||
*
|
||||
* @param string $code
|
||||
* @return int
|
||||
*/
|
||||
static function codeToLevel($code)
|
||||
{
|
||||
switch (strtoupper($code))
|
||||
{
|
||||
case 'EMERGENCY':
|
||||
return self::EMERGENCY;
|
||||
case 'ALERT':
|
||||
return self::ALERT;
|
||||
case 'CRITICAL':
|
||||
return self::CRITICAL;
|
||||
case 'NOTICE':
|
||||
return self::NOTICE;
|
||||
case 'INFO':
|
||||
return self::INFO;
|
||||
case 'WARNING':
|
||||
return self::WARNING;
|
||||
case 'DEBUG':
|
||||
return self::DEBUG;
|
||||
case 'ERROR':
|
||||
return self::ERROR;
|
||||
default:
|
||||
throw new RuntimeException('Unknown severity code ' . $code);
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
335
zoesch.de/galerie/include/block.class.php
Normal file
335
zoesch.de/galerie/include/block.class.php
Normal file
@@ -0,0 +1,335 @@
|
||||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Piwigo - a PHP based photo gallery |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright(C) 2008-2016 Piwigo Team http://piwigo.org |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
* @package functions\menubar
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Manages a set of RegisteredBlock and DisplayBlock.
|
||||
*/
|
||||
class BlockManager
|
||||
{
|
||||
/** @var string */
|
||||
protected $id;
|
||||
/** @var RegisteredBlock[] */
|
||||
protected $registered_blocks = array();
|
||||
/** @var DisplayBlock[] */
|
||||
protected $display_blocks = array();
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
*/
|
||||
public function __construct($id)
|
||||
{
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers a notice that allows plugins of menu blocks to register the blocks.
|
||||
*/
|
||||
public function load_registered_blocks()
|
||||
{
|
||||
trigger_notify('blockmanager_register_blocks', array($this));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_id()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return RegisteredBlock[]
|
||||
*/
|
||||
public function get_registered_blocks()
|
||||
{
|
||||
return $this->registered_blocks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a block with the menu. Usually called in 'blockmanager_register_blocks' event.
|
||||
*
|
||||
* @param RegisteredBlock $block
|
||||
*/
|
||||
public function register_block($block)
|
||||
{
|
||||
if (isset($this->registered_blocks[$block->get_id()]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
$this->registered_blocks[$block->get_id()] = $block;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs one time preparation of registered blocks for display.
|
||||
* Triggers 'blockmanager_prepare_display' event where plugins can
|
||||
* reposition or hide blocks
|
||||
*/
|
||||
public function prepare_display()
|
||||
{
|
||||
global $conf;
|
||||
$conf_id = 'blk_'.$this->id;
|
||||
$mb_conf = isset($conf[$conf_id]) ? $conf[$conf_id] : array();
|
||||
if (!is_array($mb_conf))
|
||||
{
|
||||
$mb_conf = @unserialize($mb_conf);
|
||||
}
|
||||
|
||||
$idx = 1;
|
||||
foreach ($this->registered_blocks as $id => $block)
|
||||
{
|
||||
$pos = isset($mb_conf[$id]) ? $mb_conf[$id] : $idx*50;
|
||||
if ($pos>0)
|
||||
{
|
||||
$this->display_blocks[$id] = new DisplayBlock($block);
|
||||
$this->display_blocks[$id]->set_position($pos);
|
||||
}
|
||||
$idx++;
|
||||
}
|
||||
$this->sort_blocks();
|
||||
trigger_notify('blockmanager_prepare_display', array($this));
|
||||
$this->sort_blocks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the block is hidden.
|
||||
*
|
||||
* @param string $block_id
|
||||
* @return bool
|
||||
*/
|
||||
public function is_hidden($block_id)
|
||||
{
|
||||
return !isset($this->display_blocks[$block_id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a block from the displayed blocks.
|
||||
*
|
||||
* @param string $block_id
|
||||
*/
|
||||
public function hide_block($block_id)
|
||||
{
|
||||
unset($this->display_blocks[$block_id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a visible block.
|
||||
*
|
||||
* @param string $block_id
|
||||
* @return DisplayBlock|null
|
||||
*/
|
||||
public function get_block($block_id)
|
||||
{
|
||||
if (isset($this->display_blocks[$block_id]))
|
||||
{
|
||||
return $this->display_blocks[$block_id];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the position of a block.
|
||||
*
|
||||
* @param string $block_id
|
||||
* @param int $position
|
||||
*/
|
||||
public function set_block_position($block_id, $position)
|
||||
{
|
||||
if (isset($this->display_blocks[$block_id]))
|
||||
{
|
||||
$this->display_blocks[$block_id]->set_position($position);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the blocks.
|
||||
*/
|
||||
protected function sort_blocks()
|
||||
{
|
||||
uasort($this->display_blocks, array('BlockManager', 'cmp_by_position'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for blocks sorting.
|
||||
*/
|
||||
static protected function cmp_by_position($a, $b)
|
||||
{
|
||||
return $a->get_position() - $b->get_position();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the menu and assign the result in a template variable.
|
||||
*
|
||||
* @param string $var
|
||||
* @param string $file
|
||||
*/
|
||||
public function apply($var, $file)
|
||||
{
|
||||
global $template;
|
||||
|
||||
$template->set_filename('menubar', $file);
|
||||
trigger_notify('blockmanager_apply', array($this) );
|
||||
|
||||
foreach ($this->display_blocks as $id=>$block)
|
||||
{
|
||||
if (empty($block->raw_content) and empty($block->template))
|
||||
{
|
||||
$this->hide_block($id);
|
||||
}
|
||||
}
|
||||
$this->sort_blocks();
|
||||
$template->assign('blocks', $this->display_blocks);
|
||||
$template->assign_var_from_handle($var, 'menubar');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Represents a menu block registered in a BlockManager object.
|
||||
*/
|
||||
class RegisteredBlock
|
||||
{
|
||||
/** @var string */
|
||||
protected $id;
|
||||
/** @var string */
|
||||
protected $name;
|
||||
/** @var string */
|
||||
protected $owner;
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
* @param string $name
|
||||
* @param string $owner
|
||||
*/
|
||||
public function __construct($id, $name, $owner)
|
||||
{
|
||||
$this->id = $id;
|
||||
$this->name = $name;
|
||||
$this->owner = $owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_id()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_name()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_owner()
|
||||
{
|
||||
return $this->owner;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Represents a menu block ready for display in the BlockManager object.
|
||||
*/
|
||||
class DisplayBlock
|
||||
{
|
||||
/** @var RegisteredBlock */
|
||||
protected $_registeredBlock;
|
||||
/** @var int */
|
||||
protected $_position;
|
||||
/** @var string */
|
||||
protected $_title;
|
||||
|
||||
/** @var mixed */
|
||||
public $data;
|
||||
/** @var string */
|
||||
public $template;
|
||||
/** @var string */
|
||||
public $raw_content;
|
||||
|
||||
/**
|
||||
* @param RegisteredBlock $block
|
||||
*/
|
||||
public function __construct($block)
|
||||
{
|
||||
$this->_registeredBlock = $block;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return RegisteredBlock
|
||||
*/
|
||||
public function get_block()
|
||||
{
|
||||
return $this->_registeredBlock;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function get_position()
|
||||
{
|
||||
return $this->_position;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $position
|
||||
*/
|
||||
public function set_position($position)
|
||||
{
|
||||
$this->_position = $position;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_title()
|
||||
{
|
||||
if (isset($this->_title))
|
||||
{
|
||||
return $this->_title;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->_registeredBlock->get_name();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string
|
||||
*/
|
||||
public function set_title($title)
|
||||
{
|
||||
$this->_title = $title;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
143
zoesch.de/galerie/include/cache.class.php
Normal file
143
zoesch.de/galerie/include/cache.class.php
Normal file
@@ -0,0 +1,143 @@
|
||||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Piwigo - a PHP based photo gallery |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright(C) 2008-2016 Piwigo Team http://piwigo.org |
|
||||
// | Copyright(C) 2003-2008 PhpWebGallery Team http://phpwebgallery.net |
|
||||
// | Copyright(C) 2002-2003 Pierrick LE GALL http://le-gall.net/pierrick |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
Provides a persistent cache mechanism across multiple page loads/sessions etc...
|
||||
*/
|
||||
abstract class PersistentCache
|
||||
{
|
||||
var $default_lifetime = 86400;
|
||||
protected $instance_key = PHPWG_VERSION;
|
||||
|
||||
/**
|
||||
@return a key that can be safely be used with get/set methods
|
||||
*/
|
||||
function make_key($key)
|
||||
{
|
||||
if ( is_array($key) )
|
||||
{
|
||||
$key = implode('&', $key);
|
||||
}
|
||||
$key .= $this->instance_key;
|
||||
return md5($key);
|
||||
}
|
||||
|
||||
/**
|
||||
Searches for a key in the persistent cache and fills corresponding value.
|
||||
@param string $key
|
||||
@param out mixed $value
|
||||
@return false if the $key is not found in cache ($value is not modified in this case)
|
||||
*/
|
||||
abstract function get($key, &$value);
|
||||
|
||||
/**
|
||||
Sets a key/value pair in the persistent cache.
|
||||
@param string $key - it should be the return value of make_key function
|
||||
@param mixed $value
|
||||
@param int $lifetime
|
||||
@return false on error
|
||||
*/
|
||||
abstract function set($key, $value, $lifetime=null);
|
||||
|
||||
/**
|
||||
Purge the persistent cache.
|
||||
@param boolean $all - if false only expired items will be purged
|
||||
*/
|
||||
abstract function purge($all);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Implementation of a persistent cache using files.
|
||||
*/
|
||||
class PersistentFileCache extends PersistentCache
|
||||
{
|
||||
private $dir;
|
||||
|
||||
function __construct()
|
||||
{
|
||||
global $conf;
|
||||
$this->dir = PHPWG_ROOT_PATH.$conf['data_location'].'cache/';
|
||||
}
|
||||
|
||||
function get($key, &$value)
|
||||
{
|
||||
$loaded = @file_get_contents($this->dir.$key.'.cache');
|
||||
if ($loaded !== false && ($loaded=unserialize($loaded)) !== false)
|
||||
{
|
||||
if ($loaded['expire'] > time())
|
||||
{
|
||||
$value = $loaded['data'];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function set($key, $value, $lifetime=null)
|
||||
{
|
||||
if ($lifetime === null)
|
||||
{
|
||||
$lifetime = $this->default_lifetime;
|
||||
}
|
||||
|
||||
if (rand() % 97 == 0)
|
||||
{
|
||||
$this->purge(false);
|
||||
}
|
||||
|
||||
$serialized = serialize( array(
|
||||
'expire' => time() + $lifetime,
|
||||
'data' => $value
|
||||
));
|
||||
|
||||
if (false === @file_put_contents($this->dir.$key.'.cache', $serialized))
|
||||
{
|
||||
mkgetdir($this->dir, MKGETDIR_DEFAULT&~MKGETDIR_DIE_ON_ERROR);
|
||||
if (false === @file_put_contents($this->dir.$key.'.cache', $serialized))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function purge($all)
|
||||
{
|
||||
$files = glob($this->dir.'*.cache');
|
||||
if (empty($files))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$limit = time() - $this->default_lifetime;
|
||||
foreach ($files as $file)
|
||||
{
|
||||
if ($all || @filemtime($file) < $limit)
|
||||
@unlink($file);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
376
zoesch.de/galerie/include/calendar_base.class.php
Normal file
376
zoesch.de/galerie/include/calendar_base.class.php
Normal file
@@ -0,0 +1,376 @@
|
||||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Piwigo - a PHP based photo gallery |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright(C) 2008-2016 Piwigo Team http://piwigo.org |
|
||||
// | Copyright(C) 2003-2008 PhpWebGallery Team http://phpwebgallery.net |
|
||||
// | Copyright(C) 2002-2003 Pierrick LE GALL http://le-gall.net/pierrick |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
* @package functions\calendar
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Base class for monthly and weekly calendar styles
|
||||
*/
|
||||
abstract class CalendarBase
|
||||
{
|
||||
/** db column on which this calendar works */
|
||||
var $date_field;
|
||||
/** used for queries (INNER JOIN or normal) */
|
||||
var $inner_sql;
|
||||
/** used to store db fields */
|
||||
var $calendar_levels;
|
||||
|
||||
/**
|
||||
* Generate navigation bars for category page.
|
||||
*
|
||||
* @return boolean false indicates that thumbnails where not included
|
||||
*/
|
||||
abstract function generate_category_content();
|
||||
|
||||
/**
|
||||
* Returns a sql WHERE subquery for the date field.
|
||||
*
|
||||
* @param int $max_levels (e.g. 2=only year and month)
|
||||
* @return string
|
||||
*/
|
||||
abstract function get_date_where($max_levels=3);
|
||||
|
||||
/**
|
||||
* Initialize the calendar.
|
||||
*
|
||||
* @param string $inner_sql
|
||||
*/
|
||||
function initialize($inner_sql)
|
||||
{
|
||||
global $page;
|
||||
if ($page['chronology_field']=='posted')
|
||||
{
|
||||
$this->date_field = 'date_available';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->date_field = 'date_creation';
|
||||
}
|
||||
$this->inner_sql = $inner_sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the calendar title (with HTML).
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function get_display_name()
|
||||
{
|
||||
global $conf, $page;
|
||||
$res = '';
|
||||
|
||||
for ($i=0; $i<count($page['chronology_date']); $i++)
|
||||
{
|
||||
$res .= $conf['level_separator'];
|
||||
if ( isset($page['chronology_date'][$i+1]) )
|
||||
{
|
||||
$chronology_date = array_slice($page['chronology_date'],0, $i+1);
|
||||
$url = duplicate_index_url(
|
||||
array( 'chronology_date'=>$chronology_date ),
|
||||
array( 'start' )
|
||||
);
|
||||
$res .=
|
||||
'<a href="'.$url.'">'
|
||||
.$this->get_date_component_label($i, $page['chronology_date'][$i])
|
||||
.'</a>';
|
||||
}
|
||||
else
|
||||
{
|
||||
$res .=
|
||||
'<span class="calInHere">'
|
||||
.$this->get_date_component_label($i, $page['chronology_date'][$i])
|
||||
.'</span>';
|
||||
}
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a display name for a date component optionally using labels.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function get_date_component_label($level, $date_component)
|
||||
{
|
||||
$label = $date_component;
|
||||
if (isset($this->calendar_levels[$level]['labels'][$date_component]))
|
||||
{
|
||||
$label = $this->calendar_levels[$level]['labels'][$date_component];
|
||||
}
|
||||
elseif ('any' === $date_component )
|
||||
{
|
||||
$label = l10n('All');
|
||||
}
|
||||
return $label;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a nice display name for a date to be shown in previous/next links
|
||||
*
|
||||
* @param string $date
|
||||
* @return string
|
||||
*/
|
||||
protected function get_date_nice_name($date)
|
||||
{
|
||||
$date_components = explode('-', $date);
|
||||
$res = '';
|
||||
for ($i=count($date_components)-1; $i>=0; $i--)
|
||||
{
|
||||
if ('any' !== $date_components[$i])
|
||||
{
|
||||
$label = $this->get_date_component_label($i, $date_components[$i] );
|
||||
if ( $res!='' )
|
||||
{
|
||||
$res .= ' ';
|
||||
}
|
||||
$res .= $label;
|
||||
}
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a calendar navigation bar.
|
||||
*
|
||||
* @param array $date_components
|
||||
* @param array $items - hash of items to put in the bar (e.g. 2005,2006)
|
||||
* @param bool $show_any - adds any link to the end of the bar
|
||||
* @param bool $show_empty - shows all labels even those without items
|
||||
* @param array $labels - optional labels for items (e.g. Jan,Feb,...)
|
||||
* @return string
|
||||
*/
|
||||
protected function get_nav_bar_from_items($date_components, $items,
|
||||
$show_any,
|
||||
$show_empty=false, $labels=null)
|
||||
{
|
||||
global $conf, $page, $template;
|
||||
|
||||
$nav_bar_datas=array();
|
||||
|
||||
if ($conf['calendar_show_empty'] and $show_empty and !empty($labels) )
|
||||
{
|
||||
foreach ($labels as $item => $label)
|
||||
{
|
||||
if ( ! isset($items[$item]) )
|
||||
{
|
||||
$items[$item] = -1;
|
||||
}
|
||||
}
|
||||
ksort($items);
|
||||
}
|
||||
|
||||
foreach ($items as $item => $nb_images)
|
||||
{
|
||||
$label = $item;
|
||||
if (isset($labels[$item]))
|
||||
{
|
||||
$label = $labels[$item];
|
||||
}
|
||||
if ($nb_images==-1)
|
||||
{
|
||||
$tmp_datas=array(
|
||||
'LABEL'=> $label
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$url = duplicate_index_url(
|
||||
array('chronology_date'=>array_merge($date_components,array($item))),
|
||||
array( 'start' )
|
||||
);
|
||||
$tmp_datas=array(
|
||||
'LABEL'=> $label,
|
||||
'URL' => $url
|
||||
);
|
||||
}
|
||||
if ($nb_images > 0)
|
||||
{
|
||||
$tmp_datas['NB_IMAGES']=$nb_images;
|
||||
}
|
||||
$nav_bar_datas[]=$tmp_datas;
|
||||
|
||||
}
|
||||
|
||||
if ($conf['calendar_show_any'] and $show_any and count($items)>1 and
|
||||
count($date_components)<count($this->calendar_levels)-1 )
|
||||
{
|
||||
$url = duplicate_index_url(
|
||||
array('chronology_date'=>array_merge($date_components,array('any'))),
|
||||
array( 'start' )
|
||||
);
|
||||
$nav_bar_datas[]=array(
|
||||
'LABEL' => l10n('All'),
|
||||
'URL' => $url
|
||||
);
|
||||
}
|
||||
|
||||
return $nav_bar_datas;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a calendar navigation bar for a given level.
|
||||
*
|
||||
* @param int $level - 0-year, 1-month/week, 2-day
|
||||
*/
|
||||
protected function build_nav_bar($level, $labels=null)
|
||||
{
|
||||
global $template, $conf, $page;
|
||||
|
||||
$query = '
|
||||
SELECT DISTINCT('.$this->calendar_levels[$level]['sql'].') as period,
|
||||
COUNT(DISTINCT id) as nb_images'.
|
||||
$this->inner_sql.
|
||||
$this->get_date_where($level).'
|
||||
GROUP BY period;';
|
||||
|
||||
$level_items = query2array($query, 'period', 'nb_images');
|
||||
|
||||
if ( count($level_items)==1 and
|
||||
count($page['chronology_date'])<count($this->calendar_levels)-1)
|
||||
{
|
||||
if ( ! isset($page['chronology_date'][$level]) )
|
||||
{
|
||||
list($key) = array_keys($level_items);
|
||||
$page['chronology_date'][$level] = (int)$key;
|
||||
|
||||
if ( $level<count($page['chronology_date']) and
|
||||
$level!=count($this->calendar_levels)-1 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$dates = $page['chronology_date'];
|
||||
while ($level<count($dates))
|
||||
{
|
||||
array_pop($dates);
|
||||
}
|
||||
|
||||
$nav_bar = $this->get_nav_bar_from_items(
|
||||
$dates,
|
||||
$level_items,
|
||||
true,
|
||||
true,
|
||||
isset($labels) ? $labels : $this->calendar_levels[$level]['labels']
|
||||
);
|
||||
|
||||
$template->append(
|
||||
'chronology_navigation_bars',
|
||||
array(
|
||||
'items' => $nav_bar,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns the next/previous link to the template with regards to
|
||||
* the currently choosen date.
|
||||
*/
|
||||
protected function build_next_prev()
|
||||
{
|
||||
global $template, $page;
|
||||
|
||||
$prev = $next =null;
|
||||
if ( empty($page['chronology_date']) )
|
||||
return;
|
||||
|
||||
$sub_queries = array();
|
||||
$nb_elements = count($page['chronology_date']);
|
||||
for ($i=0; $i<$nb_elements; $i++)
|
||||
{
|
||||
if ( 'any' === $page['chronology_date'][$i] )
|
||||
{
|
||||
$sub_queries[] = '\'any\'';
|
||||
}
|
||||
else
|
||||
{
|
||||
$sub_queries[] = pwg_db_cast_to_text($this->calendar_levels[$i]['sql']);
|
||||
}
|
||||
}
|
||||
$query = 'SELECT '.pwg_db_concat_ws($sub_queries, '-').' AS period';
|
||||
$query .= $this->inner_sql .'
|
||||
AND ' . $this->date_field . ' IS NOT NULL
|
||||
GROUP BY period';
|
||||
|
||||
$current = implode('-', $page['chronology_date'] );
|
||||
$upper_items = query2array($query,null, 'period');
|
||||
|
||||
usort($upper_items, 'version_compare');
|
||||
$upper_items_rank = array_flip($upper_items);
|
||||
if ( !isset($upper_items_rank[$current]) )
|
||||
{
|
||||
$upper_items[] = $current;// just in case (external link)
|
||||
usort($upper_items, 'version_compare');
|
||||
$upper_items_rank = array_flip($upper_items);
|
||||
}
|
||||
$current_rank = $upper_items_rank[$current];
|
||||
|
||||
$tpl_var = array();
|
||||
|
||||
if ( $current_rank>0 )
|
||||
{ // has previous
|
||||
$prev = $upper_items[$current_rank-1];
|
||||
$chronology_date = explode('-', $prev);
|
||||
$tpl_var['previous'] =
|
||||
array(
|
||||
'LABEL' => $this->get_date_nice_name($prev),
|
||||
'URL' => duplicate_index_url(
|
||||
array('chronology_date'=>$chronology_date), array('start')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ( $current_rank < count($upper_items)-1 )
|
||||
{ // has next
|
||||
$next = $upper_items[$current_rank+1];
|
||||
$chronology_date = explode('-', $next);
|
||||
$tpl_var['next'] =
|
||||
array(
|
||||
'LABEL' => $this->get_date_nice_name($next),
|
||||
'URL' => duplicate_index_url(
|
||||
array('chronology_date'=>$chronology_date), array('start')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ( !empty($tpl_var) )
|
||||
{
|
||||
$existing = $template->smarty->getVariable('chronology_navigation_bars');
|
||||
if (! ($existing instanceof Smarty_Undefined_Variable))
|
||||
{
|
||||
$existing->value[ sizeof($existing->value)-1 ] =
|
||||
array_merge( $existing->value[ sizeof($existing->value)-1 ], $tpl_var);
|
||||
}
|
||||
else
|
||||
{
|
||||
$template->append( 'chronology_navigation_bars', $tpl_var );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
497
zoesch.de/galerie/include/calendar_monthly.class.php
Normal file
497
zoesch.de/galerie/include/calendar_monthly.class.php
Normal file
@@ -0,0 +1,497 @@
|
||||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Piwigo - a PHP based photo gallery |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright(C) 2008-2016 Piwigo Team http://piwigo.org |
|
||||
// | Copyright(C) 2003-2008 PhpWebGallery Team http://phpwebgallery.net |
|
||||
// | Copyright(C) 2002-2003 Pierrick LE GALL http://le-gall.net/pierrick |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
* @package functions\calendar
|
||||
*/
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'include/calendar_base.class.php');
|
||||
|
||||
/** level of year view */
|
||||
define('CYEAR', 0);
|
||||
/** level of month view */
|
||||
define('CMONTH', 1);
|
||||
/** level of day view */
|
||||
define('CDAY', 2);
|
||||
|
||||
|
||||
/**
|
||||
* Monthly calendar style (composed of years/months and days)
|
||||
*/
|
||||
class CalendarMonthly extends CalendarBase
|
||||
{
|
||||
/**
|
||||
* Initialize the calendar.
|
||||
* @param string $inner_sql
|
||||
*/
|
||||
function initialize($inner_sql)
|
||||
{
|
||||
parent::initialize($inner_sql);
|
||||
global $lang;
|
||||
$this->calendar_levels = array(
|
||||
array(
|
||||
'sql'=> pwg_db_get_year($this->date_field),
|
||||
'labels' => null
|
||||
),
|
||||
array(
|
||||
'sql'=> pwg_db_get_month($this->date_field),
|
||||
'labels' => $lang['month']
|
||||
),
|
||||
array(
|
||||
'sql'=> pwg_db_get_dayofmonth($this->date_field),
|
||||
'labels' => null
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate navigation bars for category page.
|
||||
*
|
||||
* @return boolean false indicates that thumbnails where not included
|
||||
*/
|
||||
function generate_category_content()
|
||||
{
|
||||
global $conf, $page;
|
||||
|
||||
$view_type = $page['chronology_view'];
|
||||
if ($view_type==CAL_VIEW_CALENDAR)
|
||||
{
|
||||
global $template;
|
||||
$tpl_var = array();
|
||||
if ( count($page['chronology_date'])==0 )
|
||||
{//case A: no year given - display all years+months
|
||||
if ($this->build_global_calendar($tpl_var))
|
||||
{
|
||||
$template->assign('chronology_calendar', $tpl_var);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( count($page['chronology_date'])==1 )
|
||||
{//case B: year given - display all days in given year
|
||||
if ($this->build_year_calendar($tpl_var))
|
||||
{
|
||||
$template->assign('chronology_calendar', $tpl_var);
|
||||
$this->build_nav_bar(CYEAR); // years
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( count($page['chronology_date'])==2 )
|
||||
{//case C: year+month given - display a nice month calendar
|
||||
if ( $this->build_month_calendar($tpl_var) )
|
||||
{
|
||||
$template->assign('chronology_calendar', $tpl_var);
|
||||
}
|
||||
$this->build_next_prev();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($view_type==CAL_VIEW_LIST or count($page['chronology_date'])==3)
|
||||
{
|
||||
if ( count($page['chronology_date'])==0 )
|
||||
{
|
||||
$this->build_nav_bar(CYEAR); // years
|
||||
}
|
||||
if ( count($page['chronology_date'])==1)
|
||||
{
|
||||
$this->build_nav_bar(CMONTH); // month
|
||||
}
|
||||
if ( count($page['chronology_date'])==2 )
|
||||
{
|
||||
$day_labels = range( 1, $this->get_all_days_in_month(
|
||||
$page['chronology_date'][CYEAR] ,$page['chronology_date'][CMONTH] ) );
|
||||
array_unshift($day_labels, 0);
|
||||
unset( $day_labels[0] );
|
||||
$this->build_nav_bar( CDAY, $day_labels ); // days
|
||||
}
|
||||
$this->build_next_prev();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a sql WHERE subquery for the date field.
|
||||
*
|
||||
* @param int $max_levels (e.g. 2=only year and month)
|
||||
* @return string
|
||||
*/
|
||||
function get_date_where($max_levels=3)
|
||||
{
|
||||
global $page;
|
||||
|
||||
$date = $page['chronology_date'];
|
||||
while (count($date)>$max_levels)
|
||||
{
|
||||
array_pop($date);
|
||||
}
|
||||
$res = '';
|
||||
if (isset($date[CYEAR]) and $date[CYEAR]!=='any')
|
||||
{
|
||||
$b = $date[CYEAR] . '-';
|
||||
$e = $date[CYEAR] . '-';
|
||||
if (isset($date[CMONTH]) and $date[CMONTH]!=='any')
|
||||
{
|
||||
$b .= sprintf('%02d-', $date[CMONTH]);
|
||||
$e .= sprintf('%02d-', $date[CMONTH]);
|
||||
if (isset($date[CDAY]) and $date[CDAY]!=='any')
|
||||
{
|
||||
$b .= sprintf('%02d', $date[CDAY]);
|
||||
$e .= sprintf('%02d', $date[CDAY]);
|
||||
}
|
||||
else
|
||||
{
|
||||
$b .= '01';
|
||||
$e .= $this->get_all_days_in_month($date[CYEAR], $date[CMONTH]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$b .= '01-01';
|
||||
$e .= '12-31';
|
||||
if (isset($date[CMONTH]) and $date[CMONTH]!=='any')
|
||||
{
|
||||
$res .= ' AND '.$this->calendar_levels[CMONTH]['sql'].'='.$date[CMONTH];
|
||||
}
|
||||
if (isset($date[CDAY]) and $date[CDAY]!=='any')
|
||||
{
|
||||
$res .= ' AND '.$this->calendar_levels[CDAY]['sql'].'='.$date[CDAY];
|
||||
}
|
||||
}
|
||||
$res = " AND $this->date_field BETWEEN '$b' AND '$e 23:59:59'" . $res;
|
||||
}
|
||||
else
|
||||
{
|
||||
$res = ' AND '.$this->date_field.' IS NOT NULL';
|
||||
if (isset($date[CMONTH]) and $date[CMONTH]!=='any')
|
||||
{
|
||||
$res .= ' AND '.$this->calendar_levels[CMONTH]['sql'].'='.$date[CMONTH];
|
||||
}
|
||||
if (isset($date[CDAY]) and $date[CDAY]!=='any')
|
||||
{
|
||||
$res .= ' AND '.$this->calendar_levels[CDAY]['sql'].'='.$date[CDAY];
|
||||
}
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array with all the days in a given month.
|
||||
*
|
||||
* @param int $year
|
||||
* @param int $month
|
||||
* @return int[]
|
||||
*/
|
||||
protected function get_all_days_in_month($year, $month)
|
||||
{
|
||||
$md= array(1=>31,28,31,30,31,30,31,31,30,31,30,31);
|
||||
|
||||
if ( is_numeric($year) and $month==2)
|
||||
{
|
||||
$nb_days = $md[2];
|
||||
if ( ($year%4==0) and ( ($year%100!=0) or ($year%400!=0) ) )
|
||||
{
|
||||
$nb_days++;
|
||||
}
|
||||
}
|
||||
elseif ( is_numeric($month) )
|
||||
{
|
||||
$nb_days = $md[ $month ];
|
||||
}
|
||||
else
|
||||
{
|
||||
$nb_days = 31;
|
||||
}
|
||||
return $nb_days;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build global calendar and assign the result in _$tpl_var_
|
||||
*
|
||||
* @param array $tpl_var
|
||||
* @return bool
|
||||
*/
|
||||
protected function build_global_calendar(&$tpl_var)
|
||||
{
|
||||
global $page;
|
||||
|
||||
assert( count($page['chronology_date']) == 0 );
|
||||
$query='
|
||||
SELECT '.pwg_db_get_date_YYYYMM($this->date_field).' as period,
|
||||
COUNT(distinct id) as count';
|
||||
$query.= $this->inner_sql;
|
||||
$query.= $this->get_date_where();
|
||||
$query.= '
|
||||
GROUP BY period
|
||||
ORDER BY '.pwg_db_get_year($this->date_field).' DESC, '.pwg_db_get_month($this->date_field).' ASC';
|
||||
|
||||
$result = pwg_query($query);
|
||||
$items=array();
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
$y = substr($row['period'], 0, 4);
|
||||
$m = (int)substr($row['period'], 4, 2);
|
||||
if ( ! isset($items[$y]) )
|
||||
{
|
||||
$items[$y] = array('nb_images'=>0, 'children'=>array() );
|
||||
}
|
||||
$items[$y]['children'][$m] = $row['count'];
|
||||
$items[$y]['nb_images'] += $row['count'];
|
||||
}
|
||||
//echo ('<pre>'. var_export($items, true) . '</pre>');
|
||||
if (count($items)==1)
|
||||
{// only one year exists so bail out to year view
|
||||
list($y) = array_keys($items);
|
||||
$page['chronology_date'][CYEAR] = $y;
|
||||
return false;
|
||||
}
|
||||
|
||||
global $lang;
|
||||
foreach ( $items as $year=>$year_data)
|
||||
{
|
||||
$chronology_date = array( $year );
|
||||
$url = duplicate_index_url( array('chronology_date'=>$chronology_date) );
|
||||
|
||||
$nav_bar = $this->get_nav_bar_from_items( $chronology_date,
|
||||
$year_data['children'], false, false, $lang['month'] );
|
||||
|
||||
$tpl_var['calendar_bars'][] =
|
||||
array(
|
||||
'U_HEAD' => $url,
|
||||
'NB_IMAGES' => $year_data['nb_images'],
|
||||
'HEAD_LABEL' => $year,
|
||||
'items' => $nav_bar,
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build year calendar and assign the result in _$tpl_var_
|
||||
*
|
||||
* @param array $tpl_var
|
||||
* @return bool
|
||||
*/
|
||||
protected function build_year_calendar(&$tpl_var)
|
||||
{
|
||||
global $page;
|
||||
|
||||
assert( count($page['chronology_date']) == 1 );
|
||||
$query='SELECT '.pwg_db_get_date_MMDD($this->date_field).' as period,
|
||||
COUNT(DISTINCT id) as count';
|
||||
$query.= $this->inner_sql;
|
||||
$query.= $this->get_date_where();
|
||||
$query.= '
|
||||
GROUP BY period
|
||||
ORDER BY period ASC';
|
||||
|
||||
$result = pwg_query($query);
|
||||
$items=array();
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
$m = (int)substr($row['period'], 0, 2);
|
||||
$d = substr($row['period'], 2, 2);
|
||||
if ( ! isset($items[$m]) )
|
||||
{
|
||||
$items[$m] = array('nb_images'=>0, 'children'=>array() );
|
||||
}
|
||||
$items[$m]['children'][$d] = $row['count'];
|
||||
$items[$m]['nb_images'] += $row['count'];
|
||||
}
|
||||
if (count($items)==1)
|
||||
{ // only one month exists so bail out to month view
|
||||
list($m) = array_keys($items);
|
||||
$page['chronology_date'][CMONTH] = $m;
|
||||
return false;
|
||||
}
|
||||
global $lang;
|
||||
foreach ( $items as $month=>$month_data)
|
||||
{
|
||||
$chronology_date = array( $page['chronology_date'][CYEAR], $month );
|
||||
$url = duplicate_index_url( array('chronology_date'=>$chronology_date) );
|
||||
|
||||
$nav_bar = $this->get_nav_bar_from_items( $chronology_date,
|
||||
$month_data['children'], false );
|
||||
|
||||
$tpl_var['calendar_bars'][] =
|
||||
array(
|
||||
'U_HEAD' => $url,
|
||||
'NB_IMAGES' => $month_data['nb_images'],
|
||||
'HEAD_LABEL' => $lang['month'][$month],
|
||||
'items' => $nav_bar,
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build month calendar and assign the result in _$tpl_var_
|
||||
*
|
||||
* @param array $tpl_var
|
||||
* @return bool
|
||||
*/
|
||||
protected function build_month_calendar(&$tpl_var)
|
||||
{
|
||||
global $page, $lang, $conf;
|
||||
|
||||
$query='SELECT '.pwg_db_get_dayofmonth($this->date_field).' as period,
|
||||
COUNT(DISTINCT id) as count';
|
||||
$query.= $this->inner_sql;
|
||||
$query.= $this->get_date_where();
|
||||
$query.= '
|
||||
GROUP BY period
|
||||
ORDER BY period ASC';
|
||||
|
||||
$items=array();
|
||||
$result = pwg_query($query);
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
$d = (int)$row['period'];
|
||||
$items[$d] = array('nb_images'=>$row['count']);
|
||||
}
|
||||
|
||||
foreach ( $items as $day=>$data)
|
||||
{
|
||||
$page['chronology_date'][CDAY]=$day;
|
||||
$query = '
|
||||
SELECT id, file,representative_ext,path,width,height,rotation, '.pwg_db_get_dayofweek($this->date_field).'-1 as dow';
|
||||
$query.= $this->inner_sql;
|
||||
$query.= $this->get_date_where();
|
||||
$query.= '
|
||||
ORDER BY '.DB_RANDOM_FUNCTION.'()
|
||||
LIMIT 1';
|
||||
unset ( $page['chronology_date'][CDAY] );
|
||||
|
||||
$row = pwg_db_fetch_assoc(pwg_query($query));
|
||||
$derivative = new DerivativeImage(IMG_SQUARE, new SrcImage($row));
|
||||
$items[$day]['derivative'] = $derivative;
|
||||
$items[$day]['file'] = $row['file'];
|
||||
$items[$day]['dow'] = $row['dow'];
|
||||
}
|
||||
|
||||
if ( !empty($items) )
|
||||
{
|
||||
list($known_day) = array_keys($items);
|
||||
$known_dow = $items[$known_day]['dow'];
|
||||
$first_day_dow = ($known_dow-($known_day-1))%7;
|
||||
if ($first_day_dow<0)
|
||||
{
|
||||
$first_day_dow += 7;
|
||||
}
|
||||
//first_day_dow = week day corresponding to the first day of this month
|
||||
$wday_labels = $lang['day'];
|
||||
|
||||
if ('monday' == $conf['week_starts_on'])
|
||||
{
|
||||
if ($first_day_dow==0)
|
||||
{
|
||||
$first_day_dow = 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
$first_day_dow -= 1;
|
||||
}
|
||||
|
||||
$wday_labels[] = array_shift($wday_labels);
|
||||
}
|
||||
|
||||
list($cell_width, $cell_height) = ImageStdParams::get_by_type(IMG_SQUARE)->sizing->ideal_size;
|
||||
|
||||
$tpl_weeks = array();
|
||||
$tpl_crt_week = array();
|
||||
|
||||
//fill the empty days in the week before first day of this month
|
||||
for ($i=0; $i<$first_day_dow; $i++)
|
||||
{
|
||||
$tpl_crt_week[] = array();
|
||||
}
|
||||
|
||||
for ( $day = 1;
|
||||
$day <= $this->get_all_days_in_month(
|
||||
$page['chronology_date'][CYEAR], $page['chronology_date'][CMONTH]
|
||||
);
|
||||
$day++)
|
||||
{
|
||||
$dow = ($first_day_dow + $day-1)%7;
|
||||
if ($dow==0 and $day!=1)
|
||||
{
|
||||
$tpl_weeks[] = $tpl_crt_week; // add finished week to week list
|
||||
$tpl_crt_week = array(); // start new week
|
||||
}
|
||||
|
||||
if ( !isset($items[$day]) )
|
||||
{// empty day
|
||||
$tpl_crt_week[] =
|
||||
array(
|
||||
'DAY' => $day
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$url = duplicate_index_url(
|
||||
array(
|
||||
'chronology_date' =>
|
||||
array(
|
||||
$page['chronology_date'][CYEAR],
|
||||
$page['chronology_date'][CMONTH],
|
||||
$day
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
$tpl_crt_week[] =
|
||||
array(
|
||||
'DAY' => $day,
|
||||
'DOW' => $dow,
|
||||
'NB_ELEMENTS' => $items[$day]['nb_images'],
|
||||
'IMAGE' => $items[$day]['derivative']->get_url(),
|
||||
'U_IMG_LINK' => $url,
|
||||
'IMAGE_ALT' => $items[$day]['file'],
|
||||
);
|
||||
}
|
||||
}
|
||||
//fill the empty days in the week after the last day of this month
|
||||
while ( $dow<6 )
|
||||
{
|
||||
$tpl_crt_week[] = array();
|
||||
$dow++;
|
||||
}
|
||||
$tpl_weeks[] = $tpl_crt_week;
|
||||
|
||||
$tpl_var['month_view'] =
|
||||
array(
|
||||
'CELL_WIDTH' => $cell_width,
|
||||
'CELL_HEIGHT' => $cell_height,
|
||||
'wday_labels' => $wday_labels,
|
||||
'weeks' => $tpl_weeks,
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
144
zoesch.de/galerie/include/calendar_weekly.class.php
Normal file
144
zoesch.de/galerie/include/calendar_weekly.class.php
Normal file
@@ -0,0 +1,144 @@
|
||||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Piwigo - a PHP based photo gallery |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright(C) 2008-2016 Piwigo Team http://piwigo.org |
|
||||
// | Copyright(C) 2003-2008 PhpWebGallery Team http://phpwebgallery.net |
|
||||
// | Copyright(C) 2002-2003 Pierrick LE GALL http://le-gall.net/pierrick |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
* @package functions\calendar
|
||||
*/
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'include/calendar_base.class.php');
|
||||
|
||||
/** level of year view */
|
||||
define('CYEAR', 0);
|
||||
/** level of week view */
|
||||
define('CWEEK', 1);
|
||||
/** level of day view */
|
||||
define('CDAY', 2);
|
||||
|
||||
|
||||
/**
|
||||
* Weekly calendar style (composed of years/week in years and days in week)
|
||||
*/
|
||||
class CalendarWeekly extends CalendarBase
|
||||
{
|
||||
/**
|
||||
* Initialize the calendar
|
||||
* @param string $inner_sql
|
||||
*/
|
||||
function initialize($inner_sql)
|
||||
{
|
||||
parent::initialize($inner_sql);
|
||||
global $lang, $conf;
|
||||
$week_no_labels=array();
|
||||
for ($i=1; $i<=53; $i++)
|
||||
{
|
||||
$week_no_labels[$i] = l10n('Week %d', $i);
|
||||
//$week_no_labels[$i] = $i;
|
||||
}
|
||||
|
||||
$this->calendar_levels = array(
|
||||
array(
|
||||
'sql'=> pwg_db_get_year($this->date_field),
|
||||
'labels' => null
|
||||
),
|
||||
array(
|
||||
'sql'=> pwg_db_get_week($this->date_field).'+1',
|
||||
'labels' => $week_no_labels,
|
||||
),
|
||||
array(
|
||||
'sql'=> pwg_db_get_dayofweek($this->date_field).'-1',
|
||||
'labels' => $lang['day']
|
||||
),
|
||||
);
|
||||
//Comment next lines for week starting on Sunday or if MySQL version<4.0.17
|
||||
//WEEK(date,5) = "0-53 - Week 1=the first week with a Monday in this year"
|
||||
if ('monday' == $conf['week_starts_on'])
|
||||
{
|
||||
$this->calendar_levels[CWEEK]['sql'] = pwg_db_get_week($this->date_field, 5).'+1';
|
||||
$this->calendar_levels[CDAY]['sql'] = pwg_db_get_weekday($this->date_field);
|
||||
$this->calendar_levels[CDAY]['labels'][] = array_shift($this->calendar_levels[CDAY]['labels']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate navigation bars for category page.
|
||||
*
|
||||
* @return boolean false indicates that thumbnails where not included
|
||||
*/
|
||||
function generate_category_content()
|
||||
{
|
||||
global $conf, $page;
|
||||
|
||||
if ( count($page['chronology_date'])==0 )
|
||||
{
|
||||
$this->build_nav_bar(CYEAR); // years
|
||||
}
|
||||
if ( count($page['chronology_date'])==1 )
|
||||
{
|
||||
$this->build_nav_bar(CWEEK, array()); // week nav bar 1-53
|
||||
}
|
||||
if ( count($page['chronology_date'])==2 )
|
||||
{
|
||||
$this->build_nav_bar(CDAY); // days nav bar Mon-Sun
|
||||
}
|
||||
$this->build_next_prev();
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a sql WHERE subquery for the date field.
|
||||
*
|
||||
* @param int $max_levels (e.g. 2=only year and month)
|
||||
* @return string
|
||||
*/
|
||||
function get_date_where($max_levels=3)
|
||||
{
|
||||
global $page;
|
||||
$date = $page['chronology_date'];
|
||||
while (count($date)>$max_levels)
|
||||
{
|
||||
array_pop($date);
|
||||
}
|
||||
$res = '';
|
||||
if (isset($date[CYEAR]) and $date[CYEAR]!=='any')
|
||||
{
|
||||
$y = $date[CYEAR];
|
||||
$res = " AND $this->date_field BETWEEN '$y-01-01' AND '$y-12-31 23:59:59'";
|
||||
}
|
||||
|
||||
if (isset($date[CWEEK]) and $date[CWEEK]!=='any')
|
||||
{
|
||||
$res .= ' AND '.$this->calendar_levels[CWEEK]['sql'].'='.$date[CWEEK];
|
||||
}
|
||||
if (isset($date[CDAY]) and $date[CDAY]!=='any')
|
||||
{
|
||||
$res .= ' AND '.$this->calendar_levels[CDAY]['sql'].'='.$date[CDAY];
|
||||
}
|
||||
if (empty($res))
|
||||
{
|
||||
$res = ' AND '.$this->date_field.' IS NOT NULL';
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
383
zoesch.de/galerie/include/category_cats.inc.php
Normal file
383
zoesch.de/galerie/include/category_cats.inc.php
Normal file
@@ -0,0 +1,383 @@
|
||||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Piwigo - a PHP based photo gallery |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright(C) 2008-2016 Piwigo Team http://piwigo.org |
|
||||
// | Copyright(C) 2003-2008 PhpWebGallery Team http://phpwebgallery.net |
|
||||
// | Copyright(C) 2002-2003 Pierrick LE GALL http://le-gall.net/pierrick |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
* This file is included by the main page to show subcategories of a category
|
||||
* or to show recent categories or main page categories list
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
// $user['forbidden_categories'] including with USER_CACHE_CATEGORIES_TABLE
|
||||
$query = '
|
||||
SELECT
|
||||
c.*,
|
||||
user_representative_picture_id,
|
||||
nb_images,
|
||||
date_last,
|
||||
max_date_last,
|
||||
count_images,
|
||||
nb_categories,
|
||||
count_categories
|
||||
FROM '.CATEGORIES_TABLE.' c
|
||||
INNER JOIN '.USER_CACHE_CATEGORIES_TABLE.' ucc
|
||||
ON id = cat_id
|
||||
AND user_id = '.$user['id'];
|
||||
|
||||
if ('recent_cats' == $page['section'])
|
||||
{
|
||||
$query.= '
|
||||
WHERE '.get_recent_photos_sql('date_last');
|
||||
}
|
||||
else
|
||||
{
|
||||
$query.= '
|
||||
WHERE id_uppercat '.(!isset($page['category']) ? 'is NULL' : '= '.$page['category']['id']);
|
||||
}
|
||||
|
||||
$query.= '
|
||||
'.get_sql_condition_FandF(
|
||||
array('visible_categories' => 'id'),
|
||||
'AND'
|
||||
);
|
||||
|
||||
if ('recent_cats' != $page['section'])
|
||||
{
|
||||
$query.= '
|
||||
ORDER BY rank';
|
||||
}
|
||||
|
||||
$result = pwg_query($query);
|
||||
$categories = array();
|
||||
$category_ids = array();
|
||||
$image_ids = array();
|
||||
$user_representative_updates_for = array();
|
||||
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
$row['is_child_date_last'] = @$row['max_date_last']>@$row['date_last'];
|
||||
|
||||
if (!empty($row['user_representative_picture_id']))
|
||||
{
|
||||
$image_id = $row['user_representative_picture_id'];
|
||||
}
|
||||
elseif (!empty($row['representative_picture_id']))
|
||||
{ // if a representative picture is set, it has priority
|
||||
$image_id = $row['representative_picture_id'];
|
||||
}
|
||||
elseif ($conf['allow_random_representative'])
|
||||
{ // searching a random representant among elements in sub-categories
|
||||
$image_id = get_random_image_in_category($row);
|
||||
}
|
||||
elseif ($row['count_categories']>0 and $row['count_images']>0)
|
||||
{ // searching a random representant among representant of sub-categories
|
||||
$query = '
|
||||
SELECT representative_picture_id
|
||||
FROM '.CATEGORIES_TABLE.' INNER JOIN '.USER_CACHE_CATEGORIES_TABLE.'
|
||||
ON id = cat_id and user_id = '.$user['id'].'
|
||||
WHERE uppercats LIKE \''.$row['uppercats'].',%\'
|
||||
AND representative_picture_id IS NOT NULL'
|
||||
.get_sql_condition_FandF
|
||||
(
|
||||
array
|
||||
(
|
||||
'visible_categories' => 'id',
|
||||
),
|
||||
"\n AND"
|
||||
).'
|
||||
ORDER BY '.DB_RANDOM_FUNCTION.'()
|
||||
LIMIT 1
|
||||
;';
|
||||
$subresult = pwg_query($query);
|
||||
if (pwg_db_num_rows($subresult) > 0)
|
||||
{
|
||||
list($image_id) = pwg_db_fetch_row($subresult);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (isset($image_id))
|
||||
{
|
||||
if ($conf['representative_cache_on_subcats'] and $row['user_representative_picture_id'] != $image_id)
|
||||
{
|
||||
$user_representative_updates_for[ $row['id'] ] = $image_id;
|
||||
}
|
||||
|
||||
$row['representative_picture_id'] = $image_id;
|
||||
$image_ids[] = $image_id;
|
||||
$categories[] = $row;
|
||||
$category_ids[] = $row['id'];
|
||||
}
|
||||
unset($image_id);
|
||||
}
|
||||
|
||||
if ($conf['display_fromto'])
|
||||
{
|
||||
if (count($category_ids) > 0)
|
||||
{
|
||||
$query = '
|
||||
SELECT
|
||||
category_id,
|
||||
MIN(date_creation) AS `from`,
|
||||
MAX(date_creation) AS `to`
|
||||
FROM '.IMAGE_CATEGORY_TABLE.'
|
||||
INNER JOIN '.IMAGES_TABLE.' ON image_id = id
|
||||
WHERE category_id IN ('.implode(',', $category_ids).')
|
||||
'.get_sql_condition_FandF
|
||||
(
|
||||
array
|
||||
(
|
||||
'visible_categories' => 'category_id',
|
||||
'visible_images' => 'id'
|
||||
),
|
||||
'AND'
|
||||
).'
|
||||
GROUP BY category_id
|
||||
;';
|
||||
$dates_of_category = query2array($query, 'category_id');
|
||||
}
|
||||
}
|
||||
|
||||
if ($page['section']=='recent_cats')
|
||||
{
|
||||
usort($categories, 'global_rank_compare');
|
||||
}
|
||||
|
||||
if (count($categories) > 0)
|
||||
{
|
||||
$infos_of_image = array();
|
||||
$new_image_ids = array();
|
||||
|
||||
$query = '
|
||||
SELECT *
|
||||
FROM '.IMAGES_TABLE.'
|
||||
WHERE id IN ('.implode(',', $image_ids).')
|
||||
;';
|
||||
$result = pwg_query($query);
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
if ($row['level'] <= $user['level'])
|
||||
{
|
||||
$infos_of_image[$row['id']] = $row;
|
||||
}
|
||||
else
|
||||
{
|
||||
// problem: we must not display the thumbnail of a photo which has a
|
||||
// higher privacy level than user privacy level
|
||||
//
|
||||
// * what is the represented category?
|
||||
// * find a random photo matching user permissions
|
||||
// * register it at user_representative_picture_id
|
||||
// * set it as the representative_picture_id for the category
|
||||
|
||||
foreach ($categories as &$category)
|
||||
{
|
||||
if ($row['id'] == $category['representative_picture_id'])
|
||||
{
|
||||
// searching a random representant among elements in sub-categories
|
||||
$image_id = get_random_image_in_category($category);
|
||||
|
||||
if (isset($image_id) and !in_array($image_id, $image_ids))
|
||||
{
|
||||
$new_image_ids[] = $image_id;
|
||||
}
|
||||
|
||||
if ($conf['representative_cache_on_level'])
|
||||
{
|
||||
$user_representative_updates_for[ $category['id'] ] = $image_id;
|
||||
}
|
||||
|
||||
$category['representative_picture_id'] = $image_id;
|
||||
}
|
||||
}
|
||||
unset($category);
|
||||
}
|
||||
}
|
||||
|
||||
if (count($new_image_ids) > 0)
|
||||
{
|
||||
$query = '
|
||||
SELECT *
|
||||
FROM '.IMAGES_TABLE.'
|
||||
WHERE id IN ('.implode(',', $new_image_ids).')
|
||||
;';
|
||||
$result = pwg_query($query);
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
$infos_of_image[$row['id']] = $row;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($infos_of_image as &$info)
|
||||
{
|
||||
$info['src_image'] = new SrcImage($info);
|
||||
}
|
||||
unset($info);
|
||||
}
|
||||
|
||||
if (count($user_representative_updates_for))
|
||||
{
|
||||
$updates = array();
|
||||
|
||||
foreach ($user_representative_updates_for as $cat_id => $image_id)
|
||||
{
|
||||
$updates[] =
|
||||
array(
|
||||
'user_id' => $user['id'],
|
||||
'cat_id' => $cat_id,
|
||||
'user_representative_picture_id' => $image_id,
|
||||
);
|
||||
}
|
||||
|
||||
mass_updates(
|
||||
USER_CACHE_CATEGORIES_TABLE,
|
||||
array(
|
||||
'primary' => array('user_id', 'cat_id'),
|
||||
'update' => array('user_representative_picture_id')
|
||||
),
|
||||
$updates
|
||||
);
|
||||
}
|
||||
|
||||
if (count($categories) > 0)
|
||||
{
|
||||
// Update filtered data
|
||||
if (function_exists('update_cats_with_filtered_data'))
|
||||
{
|
||||
update_cats_with_filtered_data($categories);
|
||||
}
|
||||
|
||||
$template->set_filename('index_category_thumbnails', 'mainpage_categories.tpl');
|
||||
|
||||
trigger_notify('loc_begin_index_category_thumbnails', $categories);
|
||||
|
||||
$tpl_thumbnails_var = array();
|
||||
|
||||
foreach ($categories as $category)
|
||||
{
|
||||
if (0 == $category['count_images'])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$category['name'] = trigger_change(
|
||||
'render_category_name',
|
||||
$category['name'],
|
||||
'subcatify_category_name'
|
||||
);
|
||||
|
||||
if ($page['section']=='recent_cats')
|
||||
{
|
||||
$name = get_cat_display_name_cache($category['uppercats'], null);
|
||||
}
|
||||
else
|
||||
{
|
||||
$name = $category['name'];
|
||||
}
|
||||
|
||||
$representative_infos = $infos_of_image[ $category['representative_picture_id'] ];
|
||||
|
||||
$tpl_var = array_merge( $category, array(
|
||||
'ID' => $category['id'] /*obsolete*/,
|
||||
'representative' => $representative_infos,
|
||||
'TN_ALT' => strip_tags($category['name']),
|
||||
|
||||
'URL' => make_index_url(
|
||||
array(
|
||||
'category' => $category
|
||||
)
|
||||
),
|
||||
'CAPTION_NB_IMAGES' => get_display_images_count
|
||||
(
|
||||
$category['nb_images'],
|
||||
$category['count_images'],
|
||||
$category['count_categories'],
|
||||
true,
|
||||
'<br>'
|
||||
),
|
||||
'DESCRIPTION' =>
|
||||
trigger_change('render_category_literal_description',
|
||||
trigger_change('render_category_description',
|
||||
@$category['comment'],
|
||||
'subcatify_category_description')),
|
||||
'NAME' => $name,
|
||||
) );
|
||||
if ($conf['index_new_icon'])
|
||||
{
|
||||
$tpl_var['icon_ts'] = get_icon($category['max_date_last'], $category['is_child_date_last']);
|
||||
}
|
||||
|
||||
if ($conf['display_fromto'])
|
||||
{
|
||||
if (isset($dates_of_category[ $category['id'] ]))
|
||||
{
|
||||
$from = $dates_of_category[ $category['id'] ]['from'];
|
||||
$to = $dates_of_category[ $category['id'] ]['to'];
|
||||
|
||||
if (!empty($from))
|
||||
{
|
||||
$tpl_var['INFO_DATES'] = format_fromto($from, $to);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$tpl_thumbnails_var[] = $tpl_var;
|
||||
}
|
||||
|
||||
// pagination
|
||||
$page['total_categories'] = count($tpl_thumbnails_var);
|
||||
|
||||
$tpl_thumbnails_var_selection = array_slice(
|
||||
$tpl_thumbnails_var,
|
||||
$page['startcat'],
|
||||
$conf['nb_categories_page']
|
||||
);
|
||||
|
||||
$derivative_params = trigger_change('get_index_album_derivative_params', ImageStdParams::get_by_type(IMG_THUMB) );
|
||||
$tpl_thumbnails_var_selection = trigger_change('loc_end_index_category_thumbnails', $tpl_thumbnails_var_selection);
|
||||
$template->assign( array(
|
||||
'maxRequests' =>$conf['max_requests'],
|
||||
'category_thumbnails' => $tpl_thumbnails_var_selection,
|
||||
'derivative_params' => $derivative_params,
|
||||
) );
|
||||
|
||||
$template->assign_var_from_handle('CATEGORIES', 'index_category_thumbnails');
|
||||
|
||||
// navigation bar
|
||||
$page['cats_navigation_bar'] = array();
|
||||
if ($page['total_categories'] > $conf['nb_categories_page'])
|
||||
{
|
||||
$page['cats_navigation_bar'] = create_navigation_bar(
|
||||
duplicate_index_url(array(), array('startcat')),
|
||||
$page['total_categories'],
|
||||
$page['startcat'],
|
||||
$conf['nb_categories_page'],
|
||||
true, 'startcat'
|
||||
);
|
||||
}
|
||||
|
||||
$template->assign('cats_navbar', $page['cats_navigation_bar'] );
|
||||
}
|
||||
|
||||
pwg_debug('end include/category_cats.inc.php');
|
||||
?>
|
||||
166
zoesch.de/galerie/include/category_default.inc.php
Normal file
166
zoesch.de/galerie/include/category_default.inc.php
Normal file
@@ -0,0 +1,166 @@
|
||||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Piwigo - a PHP based photo gallery |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright(C) 2008-2016 Piwigo Team http://piwigo.org |
|
||||
// | Copyright(C) 2003-2008 PhpWebGallery Team http://phpwebgallery.net |
|
||||
// | Copyright(C) 2002-2003 Pierrick LE GALL http://le-gall.net/pierrick |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
* This file is included by the main page to show thumbnails for the default
|
||||
* case
|
||||
*
|
||||
*/
|
||||
|
||||
$pictures = array();
|
||||
|
||||
$selection = array_slice(
|
||||
$page['items'],
|
||||
$page['start'],
|
||||
$page['nb_image_page']
|
||||
);
|
||||
|
||||
$selection = trigger_change('loc_index_thumbnails_selection', $selection);
|
||||
|
||||
if (count($selection) > 0)
|
||||
{
|
||||
$rank_of = array_flip($selection);
|
||||
|
||||
$query = '
|
||||
SELECT *
|
||||
FROM '.IMAGES_TABLE.'
|
||||
WHERE id IN ('.implode(',', $selection).')
|
||||
;';
|
||||
$result = pwg_query($query);
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
$row['rank'] = $rank_of[ $row['id'] ];
|
||||
$pictures[] = $row;
|
||||
}
|
||||
|
||||
usort($pictures, 'rank_compare');
|
||||
unset($rank_of);
|
||||
}
|
||||
|
||||
if (count($pictures) > 0)
|
||||
{
|
||||
// define category slideshow url
|
||||
$row = reset($pictures);
|
||||
$page['cat_slideshow_url'] =
|
||||
add_url_params(
|
||||
duplicate_picture_url(
|
||||
array(
|
||||
'image_id' => $row['id'],
|
||||
'image_file' => $row['file']
|
||||
),
|
||||
array('start')
|
||||
),
|
||||
array('slideshow' =>
|
||||
(isset($_GET['slideshow']) ? $_GET['slideshow']
|
||||
: '' ))
|
||||
);
|
||||
|
||||
if ($conf['activate_comments'] and $user['show_nb_comments'])
|
||||
{
|
||||
$query = '
|
||||
SELECT image_id, COUNT(*) AS nb_comments
|
||||
FROM '.COMMENTS_TABLE.'
|
||||
WHERE validated = \'true\'
|
||||
AND image_id IN ('.implode(',', $selection).')
|
||||
GROUP BY image_id
|
||||
;';
|
||||
$nb_comments_of = query2array($query, 'image_id', 'nb_comments');
|
||||
}
|
||||
}
|
||||
|
||||
// template thumbnail initialization
|
||||
$template->set_filenames( array( 'index_thumbnails' => 'thumbnails.tpl',));
|
||||
|
||||
trigger_notify('loc_begin_index_thumbnails', $pictures);
|
||||
$tpl_thumbnails_var = array();
|
||||
|
||||
foreach ($pictures as $row)
|
||||
{
|
||||
// link on picture.php page
|
||||
$url = duplicate_picture_url(
|
||||
array(
|
||||
'image_id' => $row['id'],
|
||||
'image_file' => $row['file']
|
||||
),
|
||||
array('start')
|
||||
);
|
||||
|
||||
if (isset($nb_comments_of))
|
||||
{
|
||||
$row['NB_COMMENTS'] = $row['nb_comments'] = (int)@$nb_comments_of[$row['id']];
|
||||
}
|
||||
|
||||
$name = render_element_name($row);
|
||||
$desc = render_element_description($row, 'main_page_element_description');
|
||||
|
||||
$tpl_var = array_merge( $row, array(
|
||||
'TN_ALT' => htmlspecialchars(strip_tags($name)),
|
||||
'TN_TITLE' => get_thumbnail_title($row, $name, $desc),
|
||||
'URL' => $url,
|
||||
'DESCRIPTION' => $desc,
|
||||
'src_image' => new SrcImage($row),
|
||||
) );
|
||||
|
||||
if ($conf['index_new_icon'])
|
||||
{
|
||||
$tpl_var['icon_ts'] = get_icon($row['date_available']);
|
||||
}
|
||||
|
||||
if ($user['show_nb_hits'])
|
||||
{
|
||||
$tpl_var['NB_HITS'] = $row['hit'];
|
||||
}
|
||||
|
||||
switch ($page['section'])
|
||||
{
|
||||
case 'best_rated' :
|
||||
{
|
||||
$name = '('.$row['rating_score'].') '.$name;
|
||||
break;
|
||||
}
|
||||
case 'most_visited' :
|
||||
{
|
||||
if ( !$user['show_nb_hits'])
|
||||
{
|
||||
$name = '('.$row['hit'].') '.$name;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
$tpl_var['NAME'] = $name;
|
||||
$tpl_thumbnails_var[] = $tpl_var;
|
||||
}
|
||||
|
||||
$template->assign( array(
|
||||
'derivative_params' => trigger_change('get_index_derivative_params', ImageStdParams::get_by_type( pwg_get_session_var('index_deriv', IMG_THUMB) ) ),
|
||||
'maxRequests' =>$conf['max_requests'],
|
||||
'SHOW_THUMBNAIL_CAPTION' =>$conf['show_thumbnail_caption'],
|
||||
) );
|
||||
$tpl_thumbnails_var = trigger_change('loc_end_index_thumbnails', $tpl_thumbnails_var, $pictures);
|
||||
$template->assign('thumbnails', $tpl_thumbnails_var);
|
||||
|
||||
$template->assign_var_from_handle('THUMBNAILS', 'index_thumbnails');
|
||||
unset($pictures, $selection, $tpl_thumbnails_var);
|
||||
$template->clear_assign( 'thumbnails' );
|
||||
pwg_debug('end include/category_default.inc.php');
|
||||
?>
|
||||
309
zoesch.de/galerie/include/common.inc.php
Normal file
309
zoesch.de/galerie/include/common.inc.php
Normal file
@@ -0,0 +1,309 @@
|
||||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Piwigo - a PHP based photo gallery |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright(C) 2008-2016 Piwigo Team http://piwigo.org |
|
||||
// | Copyright(C) 2003-2008 PhpWebGallery Team http://phpwebgallery.net |
|
||||
// | Copyright(C) 2002-2003 Pierrick LE GALL http://le-gall.net/pierrick |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
defined('PHPWG_ROOT_PATH') or trigger_error('Hacking attempt!', E_USER_ERROR);
|
||||
|
||||
// determine the initial instant to indicate the generation time of this page
|
||||
$t2 = microtime(true);
|
||||
|
||||
// @set_magic_quotes_runtime(0); // Disable magic_quotes_runtime
|
||||
|
||||
//
|
||||
// addslashes to vars if magic_quotes_gpc is off this is a security
|
||||
// precaution to prevent someone trying to break out of a SQL statement.
|
||||
//
|
||||
if( !@get_magic_quotes_gpc() )
|
||||
{
|
||||
function sanitize_mysql_kv(&$v, $k)
|
||||
{
|
||||
$v = addslashes($v);
|
||||
}
|
||||
if( is_array( $_GET ) )
|
||||
{
|
||||
array_walk_recursive( $_GET, 'sanitize_mysql_kv' );
|
||||
}
|
||||
if( is_array( $_POST ) )
|
||||
{
|
||||
array_walk_recursive( $_POST, 'sanitize_mysql_kv' );
|
||||
}
|
||||
if( is_array( $_COOKIE ) )
|
||||
{
|
||||
array_walk_recursive( $_COOKIE, 'sanitize_mysql_kv' );
|
||||
}
|
||||
}
|
||||
if ( !empty($_SERVER["PATH_INFO"]) )
|
||||
{
|
||||
$_SERVER["PATH_INFO"] = addslashes($_SERVER["PATH_INFO"]);
|
||||
}
|
||||
|
||||
//
|
||||
// Define some basic configuration arrays this also prevents malicious
|
||||
// rewriting of language and otherarray values via URI params
|
||||
//
|
||||
$conf = array();
|
||||
$page = array(
|
||||
'infos' => array(),
|
||||
'errors' => array(),
|
||||
'warnings' => array(),
|
||||
'messages' => array(),
|
||||
);
|
||||
$user = array();
|
||||
$lang = array();
|
||||
$header_msgs = array();
|
||||
$header_notes = array();
|
||||
$filter = array();
|
||||
|
||||
foreach(
|
||||
array(
|
||||
'gzopen'
|
||||
) as $func)
|
||||
{
|
||||
if (!function_exists($func))
|
||||
{
|
||||
include_once(PHPWG_ROOT_PATH . 'include/php_compat/'.$func.'.php');
|
||||
}
|
||||
}
|
||||
|
||||
include(PHPWG_ROOT_PATH . 'include/config_default.inc.php');
|
||||
@include(PHPWG_ROOT_PATH. 'local/config/config.inc.php');
|
||||
|
||||
defined('PWG_LOCAL_DIR') or define('PWG_LOCAL_DIR', 'local/');
|
||||
|
||||
@include(PHPWG_ROOT_PATH.PWG_LOCAL_DIR .'config/database.inc.php');
|
||||
if (!defined('PHPWG_INSTALLED'))
|
||||
{
|
||||
header('Location: install.php');
|
||||
exit;
|
||||
}
|
||||
include(PHPWG_ROOT_PATH .'include/dblayer/functions_'.$conf['dblayer'].'.inc.php');
|
||||
|
||||
if(isset($conf['show_php_errors']) && !empty($conf['show_php_errors']))
|
||||
{
|
||||
@ini_set('error_reporting', $conf['show_php_errors']);
|
||||
@ini_set('display_errors', true);
|
||||
}
|
||||
|
||||
if ($conf['session_gc_probability'] > 0)
|
||||
{
|
||||
@ini_set('session.gc_divisor', 100);
|
||||
@ini_set('session.gc_probability', min((int)$conf['session_gc_probability'], 100));
|
||||
}
|
||||
|
||||
include(PHPWG_ROOT_PATH . 'include/constants.php');
|
||||
include(PHPWG_ROOT_PATH . 'include/functions.inc.php');
|
||||
include(PHPWG_ROOT_PATH . 'include/template.class.php');
|
||||
include(PHPWG_ROOT_PATH . 'include/cache.class.php');
|
||||
include(PHPWG_ROOT_PATH . 'include/Logger.class.php');
|
||||
|
||||
$persistent_cache = new PersistentFileCache();
|
||||
|
||||
// Database connection
|
||||
try
|
||||
{
|
||||
pwg_db_connect($conf['db_host'], $conf['db_user'],
|
||||
$conf['db_password'], $conf['db_base']);
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
my_error(l10n($e->getMessage()), true);
|
||||
}
|
||||
|
||||
pwg_db_check_charset();
|
||||
|
||||
load_conf_from_db();
|
||||
|
||||
$logger = new Logger(array(
|
||||
'directory' => PHPWG_ROOT_PATH . $conf['data_location'] . $conf['log_dir'],
|
||||
'severity' => $conf['log_level'],
|
||||
// we use an hashed filename to prevent direct file access, and we salt with
|
||||
// the db_password instead of secret_key because the log must be usable in i.php
|
||||
// (secret_key is in the database)
|
||||
'filename' => 'log_' . date('Y-m-d') . '_' . sha1(date('Y-m-d') . $conf['db_password']) . '.txt',
|
||||
'globPattern' => 'log_*.txt',
|
||||
'archiveDays' => $conf['log_archive_days'],
|
||||
));
|
||||
|
||||
if (!$conf['check_upgrade_feed'])
|
||||
{
|
||||
if (!isset($conf['piwigo_db_version']) or $conf['piwigo_db_version'] != get_branch_from_version(PHPWG_VERSION))
|
||||
{
|
||||
redirect(get_root_url().'upgrade.php');
|
||||
}
|
||||
}
|
||||
|
||||
ImageStdParams::load_from_db();
|
||||
|
||||
session_start();
|
||||
load_plugins();
|
||||
|
||||
// users can have defined a custom order pattern, incompatible with GUI form
|
||||
if (isset($conf['order_by_custom']))
|
||||
{
|
||||
$conf['order_by'] = $conf['order_by_custom'];
|
||||
}
|
||||
if (isset($conf['order_by_inside_category_custom']))
|
||||
{
|
||||
$conf['order_by_inside_category'] = $conf['order_by_inside_category_custom'];
|
||||
}
|
||||
|
||||
include(PHPWG_ROOT_PATH.'include/user.inc.php');
|
||||
|
||||
if (in_array( substr($user['language'],0,2), array('fr','it','de','es','pl','hu','ru','nl','tr','da') ) )
|
||||
{
|
||||
define('PHPWG_DOMAIN', substr($user['language'],0,2).'.piwigo.org');
|
||||
}
|
||||
elseif ('zh_CN' == $user['language']) {
|
||||
define('PHPWG_DOMAIN', 'cn.piwigo.org');
|
||||
}
|
||||
elseif ('pt_BR' == $user['language']) {
|
||||
define('PHPWG_DOMAIN', 'br.piwigo.org');
|
||||
}
|
||||
else {
|
||||
define('PHPWG_DOMAIN', 'piwigo.org');
|
||||
}
|
||||
define('PHPWG_URL', 'http://'.PHPWG_DOMAIN);
|
||||
|
||||
if(isset($conf['alternative_pem_url']) and $conf['alternative_pem_url']!='')
|
||||
{
|
||||
define('PEM_URL', $conf['alternative_pem_url']);
|
||||
}
|
||||
else
|
||||
{
|
||||
define('PEM_URL', 'http://'.PHPWG_DOMAIN.'/ext');
|
||||
}
|
||||
|
||||
// language files
|
||||
load_language('common.lang');
|
||||
if ( is_admin() || (defined('IN_ADMIN') and IN_ADMIN) )
|
||||
{
|
||||
load_language('admin.lang');
|
||||
}
|
||||
trigger_notify('loading_lang');
|
||||
load_language('lang', PHPWG_ROOT_PATH.PWG_LOCAL_DIR, array('no_fallback'=>true, 'local'=>true) );
|
||||
|
||||
// only now we can set the localized username of the guest user (and not in
|
||||
// include/user.inc.php)
|
||||
if (is_a_guest())
|
||||
{
|
||||
$user['username'] = l10n('guest');
|
||||
}
|
||||
|
||||
// in case an auth key was provided and is no longer valid, we must wait to
|
||||
// be here, with language loaded, to prepare the message
|
||||
if (isset($page['auth_key_invalid']) and $page['auth_key_invalid'])
|
||||
{
|
||||
$page['errors'][] =
|
||||
l10n('Your authentication key is no longer valid.')
|
||||
.sprintf(' <a href="%s">%s</a>', get_root_url().'identification.php', l10n('Login'))
|
||||
;
|
||||
}
|
||||
|
||||
// template instance
|
||||
if (defined('IN_ADMIN') and IN_ADMIN )
|
||||
{// Admin template
|
||||
$template = new Template(PHPWG_ROOT_PATH.'admin/themes', $conf['admin_theme']);
|
||||
}
|
||||
else
|
||||
{ // Classic template
|
||||
$theme = $user['theme'];
|
||||
if (script_basename() != 'ws' and mobile_theme())
|
||||
{
|
||||
$theme = $conf['mobile_theme'];
|
||||
}
|
||||
$template = new Template(PHPWG_ROOT_PATH.'themes', $theme );
|
||||
}
|
||||
|
||||
if ( !isset($conf['no_photo_yet']) )
|
||||
{
|
||||
include(PHPWG_ROOT_PATH.'include/no_photo_yet.inc.php');
|
||||
}
|
||||
|
||||
if (isset($user['internal_status']['guest_must_be_guest'])
|
||||
and
|
||||
$user['internal_status']['guest_must_be_guest'] === true)
|
||||
{
|
||||
$header_msgs[] = l10n('Bad status for user "guest", using default status. Please notify the webmaster.');
|
||||
}
|
||||
|
||||
if ($conf['gallery_locked'])
|
||||
{
|
||||
$header_msgs[] = l10n('The gallery is locked for maintenance. Please, come back later.');
|
||||
|
||||
if ( script_basename() != 'identification' and !is_admin() )
|
||||
{
|
||||
set_status_header(503, 'Service Unavailable');
|
||||
@header('Retry-After: 900');
|
||||
header('Content-Type: text/html; charset='.get_pwg_charset());
|
||||
echo '<a href="'.get_absolute_root_url(false).'identification.php">'.l10n('The gallery is locked for maintenance. Please, come back later.').'</a>';
|
||||
echo str_repeat( ' ', 512); //IE6 doesn't error output if below a size
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
if ($conf['check_upgrade_feed'])
|
||||
{
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions_upgrade.php');
|
||||
if (check_upgrade_feed())
|
||||
{
|
||||
$header_msgs[] = 'Some database upgrades are missing, '
|
||||
.'<a href="'.get_absolute_root_url(false).'upgrade_feed.php">upgrade now</a>';
|
||||
}
|
||||
}
|
||||
|
||||
if (count($header_msgs) > 0)
|
||||
{
|
||||
$template->assign('header_msgs', $header_msgs);
|
||||
$header_msgs=array();
|
||||
}
|
||||
|
||||
if (!empty($conf['filter_pages']) and get_filter_page_value('used'))
|
||||
{
|
||||
include(PHPWG_ROOT_PATH.'include/filter.inc.php');
|
||||
}
|
||||
else
|
||||
{
|
||||
$filter['enabled'] = false;
|
||||
}
|
||||
|
||||
if (isset($conf['header_notes']))
|
||||
{
|
||||
$header_notes = array_merge($header_notes, $conf['header_notes']);
|
||||
}
|
||||
|
||||
// default event handlers
|
||||
add_event_handler('render_category_literal_description', 'render_category_literal_description');
|
||||
if ( !$conf['allow_html_descriptions'] )
|
||||
{
|
||||
add_event_handler('render_category_description', 'nl2br');
|
||||
}
|
||||
add_event_handler('render_comment_content', 'render_comment_content');
|
||||
add_event_handler('render_comment_author', 'strip_tags');
|
||||
add_event_handler('render_tag_url', 'str2url');
|
||||
add_event_handler('blockmanager_register_blocks', 'register_default_menubar_blocks', EVENT_HANDLER_PRIORITY_NEUTRAL-1);
|
||||
if ( !empty($conf['original_url_protection']) )
|
||||
{
|
||||
add_event_handler('get_element_url', 'get_element_url_protection_handler');
|
||||
add_event_handler('get_src_image_url', 'get_src_image_url_protection_handler');
|
||||
}
|
||||
trigger_notify('init');
|
||||
?>
|
||||
881
zoesch.de/galerie/include/config_default.inc.php
Normal file
881
zoesch.de/galerie/include/config_default.inc.php
Normal file
@@ -0,0 +1,881 @@
|
||||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Piwigo - a PHP based photo gallery |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright(C) 2008-2016 Piwigo Team http://piwigo.org |
|
||||
// | Copyright(C) 2003-2008 PhpWebGallery Team http://phpwebgallery.net |
|
||||
// | Copyright(C) 2002-2003 Pierrick LE GALL http://le-gall.net/pierrick |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
* configuration page
|
||||
*
|
||||
* Set configuration parameters that are not in the table config. In the
|
||||
* application, configuration parameters are considered in the same way
|
||||
* coming from config table or config_default.inc.php.
|
||||
*
|
||||
* It is recommended to let config_default.inc.php as provided and to
|
||||
* overwrite configuration in your local configuration file
|
||||
* local/config/config.inc.php. See tools/config.inc.php as an example.
|
||||
*
|
||||
* Why having some parameters in config table and others in
|
||||
* config_*.inc.php? Modifying config_*.inc.php is a "hard" task for low
|
||||
* skilled users, they need a GUI for this : admin/configuration. But only
|
||||
* parameters that might be modified by low skilled users are in config
|
||||
* table, other parameters are in config_*.inc.php
|
||||
*/
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | misc |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
// order_by_custom and order_by_inside_category_custom : for non common pattern
|
||||
// you can define special ORDER configuration
|
||||
//
|
||||
// $conf['order_by_custom'] = ' ORDER BY date_available DESC, file ASC, id ASC';
|
||||
|
||||
// order_by_inside_category : inside a category, images can also be ordered
|
||||
// by rank. A manually defined rank on each image for the category.
|
||||
//
|
||||
// $conf['order_by_inside_category_custom'] = $conf['order_by_custom'];
|
||||
|
||||
// picture_ext : file extensions for picture file, must be a subset of
|
||||
// file_ext
|
||||
$conf['picture_ext'] = array('jpg','jpeg','png','gif');
|
||||
|
||||
// file_ext : file extensions (case sensitive) authorized
|
||||
$conf['file_ext'] = array_merge(
|
||||
$conf['picture_ext'],
|
||||
array('tiff', 'tif', 'mpg','zip','avi','mp3','ogg','pdf')
|
||||
);
|
||||
|
||||
// enable_formats: should Piwigo search for multiple formats?
|
||||
$conf['enable_formats'] = false;
|
||||
|
||||
// format_ext : file extensions for formats, ie additional versions of a
|
||||
// photo (or nay other file). Formats are in sub-directory pwg_format.
|
||||
$conf['format_ext'] = array('cr2', 'tif', 'tiff', 'nef', 'dng', 'ai', 'psd');
|
||||
|
||||
// top_number : number of element to display for "best rated" and "most
|
||||
// visited" categories
|
||||
$conf['top_number'] = 15;
|
||||
|
||||
// anti-flood_time : number of seconds between 2 comments : 0 to disable
|
||||
$conf['anti-flood_time'] = 60;
|
||||
|
||||
// qualified spam comments are not registered (false will register them
|
||||
// but they will require admin validation)
|
||||
$conf['comment_spam_reject'] = true;
|
||||
|
||||
// maximum number of links in a comment before it is qualified spam
|
||||
$conf['comment_spam_max_links'] = 3;
|
||||
|
||||
// calendar_datefield : date field of table "images" used for calendar
|
||||
// catgory
|
||||
$conf['calendar_datefield'] = 'date_creation';
|
||||
|
||||
// calendar_show_any : the calendar shows an additional 'any' button in the
|
||||
// year/month/week/day navigation bars
|
||||
$conf['calendar_show_any'] = true;
|
||||
|
||||
// calendar_show_empty : the calendar shows month/weeks/days even if there are
|
||||
//no elements for these
|
||||
$conf['calendar_show_empty'] = true;
|
||||
|
||||
// newcat_default_commentable : at creation, must a category be commentable
|
||||
// or not ?
|
||||
$conf['newcat_default_commentable'] = true;
|
||||
|
||||
// newcat_default_visible : at creation, must a category be visible or not ?
|
||||
// Warning : if the parent category is invisible, the category is
|
||||
// automatically create invisible. (invisible = locked)
|
||||
$conf['newcat_default_visible'] = true;
|
||||
|
||||
// newcat_default_status : at creation, must a category be public or private
|
||||
// ? Warning : if the parent category is private, the category is
|
||||
// automatically create private.
|
||||
$conf['newcat_default_status'] = 'public';
|
||||
|
||||
// newcat_default_position : at creation, should the album appear at the first or last position ?
|
||||
$conf['newcat_default_position'] = 'first';
|
||||
|
||||
// level_separator : character string used for separating a category level
|
||||
// to the sub level. Suggestions : ' / ', ' » ', ' → ', ' - ',
|
||||
// ' >'
|
||||
$conf['level_separator'] = ' / ';
|
||||
|
||||
// paginate_pages_around : on paginate navigation bar, how many pages
|
||||
// display before and after the current page ?
|
||||
$conf['paginate_pages_around'] = 2;
|
||||
|
||||
// show_version : shall the version of Piwigo be displayed at the
|
||||
// bottom of each page ?
|
||||
$conf['show_version'] = false;
|
||||
|
||||
// meta_ref to reference multiple sets of incorporated pages or elements
|
||||
// Set it false to avoid referencing in Google, and other search engines.
|
||||
$conf['meta_ref'] = true;
|
||||
|
||||
// links : list of external links to add in the menu. An example is the best
|
||||
// than a long explanation :
|
||||
//
|
||||
// Simple use:
|
||||
// for each link is associated a label
|
||||
// $conf['links'] = array(
|
||||
// 'http://piwigo.org' => 'PWG website',
|
||||
// 'http://piwigo.org/forum' => 'PWG forum',
|
||||
// );
|
||||
//
|
||||
// Advanced use:
|
||||
// You can also used special options. Instead to pass a string like parameter value
|
||||
// you can pass a array with different optional parameter values
|
||||
// $conf['links'] = array(
|
||||
// 'http://piwigo.org' => array('label' => 'PWG website', 'new_window' => false, 'eval_visible' => 'return true;'),
|
||||
// 'http://piwigo.org/forum' => array('label' => 'For ADMIN', 'new_window' => true, 'eval_visible' => 'return is_admin();'),
|
||||
// 'http://piwigo.org/ext' => array('label' => 'For Guest', 'new_window' => true, 'eval_visible' => 'return is_a_guest();'),
|
||||
// 'http://piwigo.org/downloads' =>
|
||||
// array('label' => 'PopUp', 'new_window' => true,
|
||||
// 'nw_name' => 'PopUp', 'nw_features' => 'width=800,height=450,location=no,status=no,toolbar=no,scrollbars=no,menubar=no'),
|
||||
// );
|
||||
// Parameters:
|
||||
// 'label':
|
||||
// Label to display for the link, must be defined
|
||||
// 'new_window':
|
||||
// If true open link on tab/window
|
||||
// [Default value is true if it's not defined]
|
||||
// 'nw_name':
|
||||
// Name use when new_window is true
|
||||
// [Default value is '' if it's not defined]
|
||||
// 'nw_features':
|
||||
// features use when new_window is true
|
||||
// [Default value is '' if it's not defined]
|
||||
// 'eval_visible':
|
||||
// It's php code witch must return if the link is visible or not
|
||||
// [Default value is true if it's not defined]
|
||||
//
|
||||
// Equivalence:
|
||||
// $conf['links'] = array(
|
||||
// 'http://piwigo.org' => 'PWG website',
|
||||
// );
|
||||
// $conf['links'] = array(
|
||||
// 'http://piwigo.org' => array('label' => 'PWG website', 'new_window' => false, 'visible' => 'return true;'),
|
||||
// );
|
||||
//
|
||||
// If the array is empty, the "Links" box won't be displayed on the main
|
||||
// page.
|
||||
$conf['links'] = array();
|
||||
|
||||
// random_index_redirect: list of 'internal' links to use when no section is defined on index.php.
|
||||
// An example is the best than a long explanation :
|
||||
//
|
||||
// for each link is associated a php condition
|
||||
// '' condition is equivalent to 'return true;'
|
||||
// $conf['random_index_redirect'] = array(
|
||||
// PHPWG_ROOT_PATH.'index.php?/best_rated' => 'return true;',
|
||||
// PHPWG_ROOT_PATH.'index.php?/recent_pics' => 'return is_a_guest();',
|
||||
// PHPWG_ROOT_PATH.'random.php' => '',
|
||||
// PHPWG_ROOT_PATH.'index.php?/categories' => '',
|
||||
// );
|
||||
$conf['random_index_redirect'] = array();
|
||||
|
||||
// List of notes to display on all header page
|
||||
// example $conf['header_notes'] = array('Test', 'Hello');
|
||||
$conf['header_notes'] = array();
|
||||
|
||||
// show_thumbnail_caption : on thumbnails page, show thumbnail captions ?
|
||||
$conf['show_thumbnail_caption'] = true;
|
||||
|
||||
// display_fromto: display the date creation bounds of a
|
||||
// category.
|
||||
$conf['display_fromto'] = false;
|
||||
|
||||
// allow_random_representative : do you wish Piwigo to search among
|
||||
// categories elements a new representative at each reload ?
|
||||
//
|
||||
// If false, an element is randomly or manually chosen to represent its
|
||||
// category and remains the representative as long as an admin does not
|
||||
// change it.
|
||||
//
|
||||
// Warning : setting this parameter to true is CPU consuming. Each time you
|
||||
// change the value of this parameter from false to true, an administrator
|
||||
// must update categories informations in screen [Admin > General >
|
||||
// Maintenance].
|
||||
$conf['allow_random_representative'] = false;
|
||||
|
||||
// representative_cache_on_level: if a thumbnail is chosen as representative
|
||||
// but has higher privacy level than current user, Piwigo randomly selects
|
||||
// another thumbnail. Should be store this thumbnail in cache to avoid
|
||||
// another consuming SQL query on next page refresh?
|
||||
$conf['representative_cache_on_level'] = true;
|
||||
|
||||
// representative_cache_on_subcats: if a category (= album) only contains
|
||||
// sub-categories, Piwigo randomly selects a thumbnail among sub-categories
|
||||
// representative. Should we store this thumbnail in cache to avoid another
|
||||
// "slightly" consuming SQL query on next page refresh?
|
||||
$conf['representative_cache_on_subcats'] = true;
|
||||
|
||||
// allow_html_descriptions : authorize administrators to use HTML in
|
||||
// category and element description.
|
||||
$conf['allow_html_descriptions'] = true;
|
||||
|
||||
// image level permissions available in the admin interface
|
||||
$conf['available_permission_levels'] = array(0,1,2,4,8);
|
||||
|
||||
// check_upgrade_feed: check if there are database upgrade required. Set to
|
||||
// true, a message will strongly encourage you to upgrade your database if
|
||||
// needed.
|
||||
//
|
||||
// This configuration parameter is set to true in BSF branch and to false
|
||||
// elsewhere.
|
||||
$conf['check_upgrade_feed'] = false;
|
||||
|
||||
// rate_items: available rates for a picture
|
||||
$conf['rate_items'] = array(0,1,2,3,4,5);
|
||||
|
||||
// Define default method to use ('http' or 'html' in order to do redirect)
|
||||
$conf['default_redirect_method'] = 'http';
|
||||
|
||||
// Define using double password type in admin's users management panel
|
||||
$conf['double_password_type_in_admin'] = false;
|
||||
|
||||
// Define if logins must be case sensitive or not of user's registration. ie :
|
||||
// If set true, the login "user" will equal "User" or "USER" or "user",
|
||||
// etc. ... And it will be impossible to use such login variation to create a
|
||||
// new user account.
|
||||
$conf['insensitive_case_logon'] = false;
|
||||
|
||||
// how should we check for unicity when adding a photo. Can be 'md5sum' or
|
||||
// 'filename'
|
||||
$conf['uniqueness_mode'] = 'md5sum';
|
||||
|
||||
// Library used for image resizing. Value could be 'auto', 'imagick',
|
||||
// 'ext_imagick' or 'gd'. If value is 'auto', library will be chosen in this
|
||||
// order. If chosen library is not available, another one will be picked up.
|
||||
$conf['graphics_library'] = 'auto';
|
||||
|
||||
// If library used is external installation of ImageMagick ('ext_imagick'),
|
||||
// you can define imagemagick directory.
|
||||
$conf['ext_imagick_dir'] = '';
|
||||
|
||||
// how many user comments to display by default on comments.php. Use 'all'
|
||||
// to display all user comments without pagination. Default available values
|
||||
// are array(5,10,20,50,'all') but you can set any other numeric value.
|
||||
$conf['comments_page_nb_comments'] = 10;
|
||||
|
||||
// how often should we check for new versions of Piwigo on piwigo.org? In
|
||||
// seconds. The check is made only if there are visits on Piwigo.
|
||||
// 0 to disable.
|
||||
$conf['update_notify_check_period'] = 24*60*60;
|
||||
|
||||
// how often should be remind of new versions available? For example a first
|
||||
// notification was sent on May 5th 2017 for 2.9.1, after how many seconds
|
||||
// we send it again? 0 to disable.
|
||||
$conf['update_notify_reminder_period'] = 7*24*60*60;
|
||||
|
||||
// should the album description be displayed on all pages (value=true) or
|
||||
// only the first page (value=false)
|
||||
$conf['album_description_on_all_pages'] = false;
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | email |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
// send_bcc_mail_webmaster: send bcc mail to webmaster. Set true for debug
|
||||
// or test.
|
||||
$conf['send_bcc_mail_webmaster'] = false;
|
||||
|
||||
// define the name of sender mail: if value is empty, gallery title is used
|
||||
$conf['mail_sender_name'] = '';
|
||||
|
||||
// define the email of sender mail: if value is empty, webmaster email is used
|
||||
$conf['mail_sender_email'] = '';
|
||||
|
||||
// set true to allow text/html emails
|
||||
$conf['mail_allow_html'] = true;
|
||||
|
||||
// smtp configuration (work if fsockopen function is allowed for smtp port)
|
||||
// smtp_host: smtp server host
|
||||
// if null, regular mail function is used
|
||||
// format: hoststring[:port]
|
||||
// exemple: smtp.pwg.net:21
|
||||
// smtp_user/smtp_password: user & password for smtp authentication
|
||||
$conf['smtp_host'] = '';
|
||||
$conf['smtp_user'] = '';
|
||||
$conf['smtp_password'] = '';
|
||||
|
||||
// 'ssl' or 'tls'
|
||||
$conf['smtp_secure'] = null;
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | metadata |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
// show_iptc: Show IPTC metadata on picture.php if asked by user
|
||||
$conf['show_iptc'] = false;
|
||||
|
||||
// show_iptc_mapping : is used for showing IPTC metadata on picture.php
|
||||
// page. For each key of the array, you need to have the same key in the
|
||||
// $lang array. For example, if my first key is 'iptc_keywords' (associated
|
||||
// to '2#025') then you need to have $lang['iptc_keywords'] set in
|
||||
// language/$user['language']/common.lang.php. If you don't have the lang
|
||||
// var set, the key will be simply displayed
|
||||
//
|
||||
// To know how to associated iptc_field with their meaning, use
|
||||
// tools/metadata.php
|
||||
$conf['show_iptc_mapping'] = array(
|
||||
'iptc_keywords' => '2#025',
|
||||
'iptc_caption_writer' => '2#122',
|
||||
'iptc_byline_title' => '2#085',
|
||||
'iptc_caption' => '2#120'
|
||||
);
|
||||
|
||||
// use_iptc: Use IPTC data during database synchronization with files
|
||||
// metadata
|
||||
$conf['use_iptc'] = false;
|
||||
|
||||
// use_iptc_mapping : in which IPTC fields will Piwigo find image
|
||||
// information ? This setting is used during metadata synchronisation. It
|
||||
// associates a piwigo_images column name to a IPTC key
|
||||
$conf['use_iptc_mapping'] = array(
|
||||
'keywords' => '2#025',
|
||||
'date_creation' => '2#055',
|
||||
'author' => '2#122',
|
||||
'name' => '2#005',
|
||||
'comment' => '2#120'
|
||||
);
|
||||
|
||||
// show_exif: Show EXIF metadata on picture.php (table or line presentation
|
||||
// available)
|
||||
$conf['show_exif'] = true;
|
||||
|
||||
// show_exif_fields : in EXIF fields, you can choose to display fields in
|
||||
// sub-arrays, for example ['COMPUTED']['ApertureFNumber']. for this, add
|
||||
// 'COMPUTED;ApertureFNumber' in $conf['show_exif_fields']
|
||||
//
|
||||
// The key displayed in picture.php will be $lang['exif_field_Make'] for
|
||||
// example and if it exists. For compound fields, only take into account the
|
||||
// last part : for key 'COMPUTED;ApertureFNumber', you need
|
||||
// $lang['exif_field_ApertureFNumber']
|
||||
//
|
||||
// for PHP version newer than 4.1.2 :
|
||||
// $conf['show_exif_fields'] = array('CameraMake','CameraModel','DateTime');
|
||||
//
|
||||
$conf['show_exif_fields'] = array(
|
||||
'Make',
|
||||
'Model',
|
||||
'DateTimeOriginal',
|
||||
'COMPUTED;ApertureFNumber'
|
||||
);
|
||||
|
||||
// use_exif: Use EXIF data during database synchronization with files
|
||||
// metadata
|
||||
$conf['use_exif'] = true;
|
||||
|
||||
// use_exif_mapping: same behaviour as use_iptc_mapping
|
||||
$conf['use_exif_mapping'] = array(
|
||||
'date_creation' => 'DateTimeOriginal'
|
||||
);
|
||||
|
||||
// allow_html_in_metadata: in case the origin of the photo is unsecure (user
|
||||
// upload), we remove HTML tags to avoid XSS (malicious execution of
|
||||
// javascript)
|
||||
$conf['allow_html_in_metadata'] = false;
|
||||
|
||||
// decide which characters can be used as keyword separators (works in EXIF
|
||||
// and IPTC). Coma "," cannot be removed from this list.
|
||||
$conf['metadata_keyword_separator_regex'] = '/[.,;]/';
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | sessions |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
// session_use_cookies: specifies to use cookie to store
|
||||
// the session id on client side
|
||||
$conf['session_use_cookies'] = true;
|
||||
|
||||
// session_use_only_cookies: specifies to only use cookie to store
|
||||
// the session id on client side
|
||||
$conf['session_use_only_cookies'] = true;
|
||||
|
||||
// session_use_trans_sid: do not use transparent session id support
|
||||
$conf['session_use_trans_sid'] = false;
|
||||
|
||||
// session_name: specifies the name of the session which is used as cookie name
|
||||
$conf['session_name'] = 'pwg_id';
|
||||
|
||||
// session_save_handler: comment the line below
|
||||
// to use file handler for sessions.
|
||||
$conf['session_save_handler'] = 'db';
|
||||
|
||||
// authorize_remembering : permits user to stay logged for a long time. It
|
||||
// creates a cookie on client side.
|
||||
$conf['authorize_remembering'] = true;
|
||||
|
||||
// remember_me_name: specifies the name of the cookie used to stay logged
|
||||
$conf['remember_me_name'] = 'pwg_remember';
|
||||
|
||||
// remember_me_length : time of validity for "remember me" cookies, in
|
||||
// seconds.
|
||||
$conf['remember_me_length'] = 5184000;
|
||||
|
||||
// session_length : time of validity for normal session, in seconds.
|
||||
$conf['session_length'] = 3600;
|
||||
|
||||
// session_use_ip_address: avoid session hijacking by using a part of the IP
|
||||
// address
|
||||
$conf['session_use_ip_address'] = true;
|
||||
|
||||
// Probability, on each page generated, to launch session garbage
|
||||
// collector. Integer value between 1 and 100, in %. 0 to disable and let
|
||||
// the system default behavior (on Debian-like, it's "never delete
|
||||
// session").
|
||||
$conf['session_gc_probability'] = 1;
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | debug/performance |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
// show_queries : for debug purpose, show queries and execution times
|
||||
$conf['show_queries'] = false;
|
||||
|
||||
// show_gt : display generation time at the bottom of each page
|
||||
$conf['show_gt'] = false;
|
||||
|
||||
// debug_l10n : display a warning message each time an unset language key is
|
||||
// accessed
|
||||
$conf['debug_l10n'] = false;
|
||||
|
||||
// activate template debugging - a new window will appear
|
||||
$conf['debug_template'] = false;
|
||||
|
||||
// save copies of sent mails into local data dir
|
||||
$conf['debug_mail'] = false;
|
||||
|
||||
// die_on_sql_error: if an SQL query fails, should everything stop?
|
||||
$conf['die_on_sql_error'] = false;
|
||||
|
||||
// if true, some language strings are replaced during template compilation
|
||||
// (instead of template output). this results in better performance. however
|
||||
// any change in the language file will not be propagated until you purge
|
||||
// the compiled templates from the admin / maintenance menu
|
||||
$conf['compiled_template_cache_language'] = false;
|
||||
|
||||
// This tells Smarty whether to check for recompiling or not. Recompiling
|
||||
// does not need to happen unless a template is changed. false results in
|
||||
// better performance.
|
||||
$conf['template_compile_check'] = true;
|
||||
|
||||
// This forces Smarty to (re)compile templates on every invocation. This is
|
||||
// handy for development and debugging. It should never be used in a
|
||||
// production environment.
|
||||
$conf['template_force_compile'] = false;
|
||||
|
||||
// activate merging of javascript / css files
|
||||
$conf['template_combine_files'] = true;
|
||||
|
||||
// this permit to show the php errors reporting (see INI 'error_reporting'
|
||||
// for possible values)
|
||||
// gives an empty value '' to deactivate
|
||||
$conf['show_php_errors'] = E_ALL;
|
||||
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | authentication |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
// apache_authentication : use Apache authentication as reference instead of
|
||||
// users table ?
|
||||
$conf['apache_authentication'] = false;
|
||||
|
||||
// users_table: which table is the reference for users? Can be a different
|
||||
// table than Piwigo table
|
||||
//
|
||||
// If you decide to use another table than the default one, you need to
|
||||
// prepare your database by deleting some datas :
|
||||
//
|
||||
// delete from piwigo_user_access;
|
||||
// delete from piwigo_user_cache;
|
||||
// delete from piwigo_user_feed;
|
||||
// delete from piwigo_user_group;
|
||||
// delete from piwigo_user_infos;
|
||||
// delete from piwigo_sessions;
|
||||
// delete from piwigo_rate;
|
||||
// update piwigo_images set rating_score = null, added_by = <webmaster_id>;
|
||||
// delete from piwigo_caddie;
|
||||
// delete from piwigo_favorites;
|
||||
//
|
||||
// All informations contained in these tables and column are related to
|
||||
// piwigo_users table.
|
||||
$conf['users_table'] = null;
|
||||
|
||||
// If you decide to use external authentication
|
||||
// change conf below by $conf['external_authentification'] = true;
|
||||
$conf['external_authentification'] = false;
|
||||
|
||||
// Other tables can be changed, if you define associated constants
|
||||
// Example:
|
||||
// define('USER_INFOS_TABLE', 'pwg_main'.'user_infos');
|
||||
|
||||
// user_fields : mapping between generic field names and table specific
|
||||
// field names. For example, in PWG, the mail address is names
|
||||
// "mail_address" and in punbb, it's called "email".
|
||||
$conf['user_fields'] = array(
|
||||
'id' => 'id',
|
||||
'username' => 'username',
|
||||
'password' => 'password',
|
||||
'email' => 'mail_address'
|
||||
);
|
||||
|
||||
// password_hash: function hash the clear user password to store it in the
|
||||
// database. The function takes only one parameter: the clear password.
|
||||
$conf['password_hash'] = 'pwg_password_hash';
|
||||
|
||||
// password_verify: function that checks the password against its hash. The
|
||||
// function takes 2 mandatory parameter : clear password, hashed password +
|
||||
// an optional parameter user_id. The user_id is used to update the password
|
||||
// with the new hash introduced in Piwigo 2.5. See function
|
||||
// pwg_password_verify in include/functions_user.inc.php
|
||||
$conf['password_verify'] = 'pwg_password_verify';
|
||||
|
||||
// guest_id : id of the anonymous user
|
||||
$conf['guest_id'] = 2;
|
||||
|
||||
// default_user_id : id of user used for default value
|
||||
$conf['default_user_id'] = $conf['guest_id'];
|
||||
|
||||
// Registering process and guest/generic members get language from the browser
|
||||
// if language isn't available PHPWG_DEFAULT_LANGUAGE is used as previously
|
||||
$conf['browser_language'] = true;
|
||||
|
||||
// webmaster_id : webmaster'id.
|
||||
$conf['webmaster_id'] = 1;
|
||||
|
||||
// does the guest have access ?
|
||||
// (not a security feature, set your categories "private" too)
|
||||
// If false it'll be redirected from index.php to identification.php
|
||||
$conf['guest_access'] = true;
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | history |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
// nb_logs_page : how many logs to display on a page
|
||||
$conf['nb_logs_page'] = 300;
|
||||
|
||||
// Every X new line in history, perform an automatic purge. The more often,
|
||||
// the fewer lines to delete. 0 to disable.
|
||||
$conf['history_autopurge_every'] = 1021;
|
||||
|
||||
// How many lines to keep in history on autopurge? 0 to disable.
|
||||
$conf['history_autopurge_keep_lines'] = 1000000;
|
||||
|
||||
// On history autopurge, how many lines should to deleted at once, maximum?
|
||||
$conf['history_autopurge_blocksize'] = 50000;
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | urls |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
// gallery_url : you can set a specific URL for the home page of your
|
||||
// gallery. This is for very specific use and you don't need to change this
|
||||
// setting when move your gallery to a new directory or a new domain name.
|
||||
$conf['gallery_url'] = null;
|
||||
|
||||
// question_mark_in_urls : the generated urls contain a ? sign. This can be
|
||||
// changed to false only if the server translates PATH_INFO variable
|
||||
// (depends on the server AcceptPathInfo directive configuration)
|
||||
$conf['question_mark_in_urls'] = true;
|
||||
|
||||
// php_extension_in_urls : if true, the urls generated for picture and
|
||||
// category will not contain the .php extension. This will work only if
|
||||
// .htaccess defines Options +MultiViews parameter or url rewriting rules
|
||||
// are active.
|
||||
$conf['php_extension_in_urls'] = true;
|
||||
|
||||
// category_url_style : one of 'id' (default) or 'id-name'. 'id-name'
|
||||
// means that an simplified ascii representation of the category name will
|
||||
// appear in the url
|
||||
$conf['category_url_style'] = 'id';
|
||||
|
||||
// picture_url_style : one of 'id' (default), 'id-file' or 'file'. 'id-file'
|
||||
// or 'file' mean that the file name (without extension will appear in the
|
||||
// url). Note that one additional sql query will occur if 'file' is chosen.
|
||||
// Note that you might experience navigation issues if you choose 'file'
|
||||
// and your file names are not unique
|
||||
$conf['picture_url_style'] = 'id';
|
||||
|
||||
// tag_url_style : one of 'id-tag' (default), 'id' or 'tag'.
|
||||
// Note that if you choose 'tag' and the url (ascii) representation of your
|
||||
// tags is not unique, all tags with the same url representation will be shown
|
||||
$conf['tag_url_style'] = 'id-tag';
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | tags |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
// full_tag_cloud_items_number: number of tags to show in the full tag
|
||||
// cloud. Only the most represented tags will be shown
|
||||
$conf['full_tag_cloud_items_number'] = 200;
|
||||
|
||||
// menubar_tag_cloud_items_number: number of tags to show in the tag
|
||||
// cloud in the menubar. Only the most represented tags will be shown
|
||||
$conf['menubar_tag_cloud_items_number'] = 20;
|
||||
|
||||
// content_tag_cloud_items_number: number of related tags to show in the tag
|
||||
// cloud on the content page, when the current section is not a set of
|
||||
// tags. Only the most represented tags will be shown
|
||||
$conf['content_tag_cloud_items_number'] = 12;
|
||||
|
||||
// tags_levels: number of levels to use for display. Each level is bind to a
|
||||
// CSS class tagLevelX.
|
||||
$conf['tags_levels'] = 5;
|
||||
|
||||
// tags_default_display_mode: group tags by letter or display a tag cloud by
|
||||
// default? 'letters' or 'cloud'.
|
||||
$conf['tags_default_display_mode'] = 'cloud';
|
||||
|
||||
// tag_letters_column_number: how many columns to display tags by letter
|
||||
$conf['tag_letters_column_number'] = 4;
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Notification by mail |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
// Default Value for nbm user
|
||||
$conf['nbm_default_value_user_enabled'] = false;
|
||||
|
||||
// Search list user to send quickly (List all without to check news)
|
||||
// More quickly but less fun to use
|
||||
$conf['nbm_list_all_enabled_users_to_send'] = false;
|
||||
|
||||
// Max time used on one pass in order to send mails.
|
||||
// Timeout delay ratio.
|
||||
$conf['nbm_max_treatment_timeout_percent'] = 0.8;
|
||||
|
||||
// If timeout cannot be combined with nbm_max_treatment_timeout_percent,
|
||||
// nbm_treatment_timeout_default is used by default
|
||||
$conf['nbm_treatment_timeout_default'] = 20;
|
||||
|
||||
// Parameters used in get_recent_post_dates for the 2 kind of notification
|
||||
$conf['recent_post_dates'] = array(
|
||||
'RSS' => array('max_dates' => 5, 'max_elements' => 6, 'max_cats' => 6),
|
||||
'NBM' => array('max_dates' => 7, 'max_elements' => 3, 'max_cats' => 9)
|
||||
);
|
||||
|
||||
// the author shown in the RSS feed <author> element
|
||||
$conf['rss_feed_author'] = 'Piwigo notifier';
|
||||
|
||||
// how long does the authentication key stays valid, in seconds. 3 days by
|
||||
// default. 0 to disable.
|
||||
$conf['auth_key_duration'] = 3*24*60*60;
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Set admin layout |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$conf['admin_theme'] = 'clear';
|
||||
|
||||
// should we load the active plugins ? true=Yes, false=No
|
||||
$conf['enable_plugins']=true;
|
||||
|
||||
// Web services are allowed (true) or completely forbidden (false)
|
||||
$conf['allow_web_services'] = true;
|
||||
|
||||
// Maximum number of images to be returned foreach call to the web service
|
||||
$conf['ws_max_images_per_page'] = 500;
|
||||
|
||||
// Maximum number of users to be returned foreach call to the web service
|
||||
$conf['ws_max_users_per_page'] = 1000;
|
||||
|
||||
// Display a link to subscribe to Piwigo Announcements Newsletter
|
||||
$conf['show_newsletter_subscription'] = true;
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Filter |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// $conf['filter_pages'] contains configuration for each pages
|
||||
// o If values are not defined for a specific page, default value are used
|
||||
// o Array is composed by the basename of each page without extension
|
||||
// o List of value names:
|
||||
// - used: filter function are used
|
||||
// (if false nothing is done [start, cancel, stop, ...]
|
||||
// - cancel: cancel current started filter
|
||||
// - add_notes: add notes about current started filter on the header
|
||||
// o Empty configuration in order to disable completely filter functions
|
||||
// No filter, No icon,...
|
||||
// $conf['filter_pages'] = array();
|
||||
$conf['filter_pages'] = array
|
||||
(
|
||||
// Default page
|
||||
'default' => array(
|
||||
'used' => true, 'cancel' => false, 'add_notes' => false),
|
||||
// Real pages
|
||||
'index' => array('add_notes' => true),
|
||||
'tags' => array('add_notes' => true),
|
||||
'search' => array('add_notes' => true),
|
||||
'comments' => array('add_notes' => true),
|
||||
'admin' => array('used' => false),
|
||||
'feed' => array('used' => false),
|
||||
'notification' => array('used' => false),
|
||||
'nbm' => array('used' => false),
|
||||
'popuphelp' => array('used' => false),
|
||||
'profile' => array('used' => false),
|
||||
'ws' => array('used' => false),
|
||||
'identification' => array('cancel' => true),
|
||||
'install' => array('cancel' => true),
|
||||
'password' => array('cancel' => true),
|
||||
'register' => array('cancel' => true),
|
||||
);
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Slideshow |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// slideshow_period : waiting time in seconds before loading a new page
|
||||
// during automated slideshow
|
||||
// slideshow_period_min, slideshow_period_max are bounds of slideshow_period
|
||||
// slideshow_period_step is the step of navigation between min and max
|
||||
$conf['slideshow_period_min'] = 1;
|
||||
$conf['slideshow_period_max'] = 10;
|
||||
$conf['slideshow_period_step'] = 1;
|
||||
$conf['slideshow_period'] = 4;
|
||||
|
||||
// slideshow_repeat : slideshow loops on pictures
|
||||
$conf['slideshow_repeat'] = true;
|
||||
|
||||
// $conf['light_slideshow'] indicates to use slideshow.tpl in state of
|
||||
// picture.tpl for slideshow
|
||||
// Take care to have slideshow.tpl in all available templates
|
||||
// Or set it false.
|
||||
// Check if Picture's plugins are compliant with it
|
||||
// Every plugin from 1.7 would be design to manage light_slideshow case.
|
||||
$conf['light_slideshow'] = true;
|
||||
|
||||
// the local data directory is used to store data such as compiled templates,
|
||||
// plugin variables, combined css/javascript or resized images. Beware of
|
||||
// mandatory trailing slash.
|
||||
$conf['data_location'] = '_data/';
|
||||
|
||||
// where should the API/UploadForm add photos? This path must be relative to
|
||||
// the Piwigo installation directory (but can be outside, as long as it's
|
||||
// reachable from your webserver).
|
||||
$conf['upload_dir'] = './upload';
|
||||
|
||||
// where should the user be guided when there is no photo in his gallery yet?
|
||||
$conf['no_photo_yet_url'] = 'admin.php?page=photos_add';
|
||||
|
||||
// directory with themes inside
|
||||
$conf['themes_dir'] = PHPWG_ROOT_PATH.'themes';
|
||||
|
||||
// enable the synchronization method for adding photos
|
||||
$conf['enable_synchronization'] = true;
|
||||
|
||||
// permitted characters for files/directories during synchronization
|
||||
$conf['sync_chars_regex'] = '/^[a-zA-Z0-9-_.]+$/';
|
||||
|
||||
// folders name excluded during synchronization
|
||||
$conf['sync_exclude_folders'] = array();
|
||||
|
||||
// PEM url (default is http://piwigo.org/ext)
|
||||
$conf['alternative_pem_url'] = '';
|
||||
|
||||
// categories ID on PEM
|
||||
$conf['pem_plugins_category'] = 12;
|
||||
$conf['pem_themes_category'] = 10;
|
||||
$conf['pem_languages_category'] = 8;
|
||||
|
||||
// based on the EXIF "orientation" tag, should we rotate photos added in the
|
||||
// upload form or through pwg.images.addSimple web API method?
|
||||
$conf['upload_form_automatic_rotation'] = true;
|
||||
|
||||
// 0-'auto', 1-'derivative' 2-'script'
|
||||
$conf['derivative_url_style']=0;
|
||||
|
||||
$conf['chmod_value']= substr_compare(PHP_SAPI, 'apa', 0, 3)==0 ? 0777 : 0755;
|
||||
|
||||
// 'small', 'medium' or 'large'
|
||||
$conf['derivative_default_size'] = 'medium';
|
||||
|
||||
// below which size (in pixels, ie width*height) do we remove metadata
|
||||
// EXIF/IPTC... from derivative?
|
||||
$conf['derivatives_strip_metadata_threshold'] = 256000;
|
||||
|
||||
//Maximum Ajax requests at once, for thumbnails on-the-fly generation
|
||||
$conf['max_requests']=3;
|
||||
|
||||
// one of '', 'images', 'all'
|
||||
//TODO: Put this in admin and also manage .htaccess in #sites and upload folders
|
||||
$conf['original_url_protection'] = '';
|
||||
|
||||
|
||||
// Default behaviour when a new album is created: should the new album inherit the group/user
|
||||
// permissions from its parent? Note that config is only used for Ftp synchro,
|
||||
// and if that option is not explicitly transmit when the album is created.
|
||||
$conf['inheritance_by_default'] = false;
|
||||
|
||||
// 'png' or 'jpg': your uploaded TIF photos will have a representative in
|
||||
// JPEG or PNG file format
|
||||
$conf['tiff_representative_ext'] = 'png';
|
||||
|
||||
// in the upload form, let users upload only picture_exts or all file_exts?
|
||||
// for some file types, Piwigo will try to generate a pwg_representative
|
||||
// (TIFF, videos, PDF)
|
||||
$conf['upload_form_all_types'] = false;
|
||||
|
||||
// Size of chunks, in kilobytes. Fast connections will have better
|
||||
// performances with high values, such as 5000.
|
||||
$conf['upload_form_chunk_size'] = 500;
|
||||
|
||||
// If we try to generate a pwg_representative for a video we use ffmpeg. If
|
||||
// "ffmpeg" is not visible by the web user, you can define the full path of
|
||||
// the directory where "ffmpeg" executable is.
|
||||
$conf['ffmpeg_dir'] = '';
|
||||
|
||||
// batch manager: how many images should Piwigo display by default on the
|
||||
// global mode. Must be among values {20,50,100}
|
||||
$conf['batch_manager_images_per_page_global'] = 20;
|
||||
|
||||
// batch manager: how many images should Piwigo display by default on the
|
||||
// unit mode. Must be among values {5, 10, 50}
|
||||
$conf['batch_manager_images_per_page_unit'] = 5;
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | log |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// Logs directory, relative to $conf['data_location']
|
||||
$conf['log_dir'] = '/logs';
|
||||
|
||||
// Log level (OFF, CRITICAL, ERROR, WARNING, NOTICE, INFO, DEBUG)
|
||||
// development = DEBUG, production = ERROR
|
||||
$conf['log_level'] = 'DEBUG';
|
||||
|
||||
// Keep logs file during X days
|
||||
$conf['log_archive_days'] = 30;
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Proxy Settings |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
// If piwigo needs a http-proxy to connect to the internet, set this to true
|
||||
$conf['use_proxy'] = false;
|
||||
|
||||
// Connection string of the proxy
|
||||
$conf['proxy_server'] = 'proxy.domain.org:port';
|
||||
|
||||
// If the http-proxy requires authentication, set username and password here
|
||||
// e.g. username:password
|
||||
$conf['proxy_auth'] = '';
|
||||
?>
|
||||
113
zoesch.de/galerie/include/constants.php
Normal file
113
zoesch.de/galerie/include/constants.php
Normal file
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Piwigo - a PHP based photo gallery |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright(C) 2008-2016 Piwigo Team http://piwigo.org |
|
||||
// | Copyright(C) 2003-2008 PhpWebGallery Team http://phpwebgallery.net |
|
||||
// | Copyright(C) 2002-2003 Pierrick LE GALL http://le-gall.net/pierrick |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
// Default settings
|
||||
define('PHPWG_VERSION', '2.9.2');
|
||||
define('PHPWG_DEFAULT_LANGUAGE', 'en_UK');
|
||||
define('PHPWG_DEFAULT_TEMPLATE', 'elegant');
|
||||
|
||||
define('PHPWG_THEMES_PATH', $conf['themes_dir'].'/');
|
||||
defined('PWG_COMBINED_DIR') or define('PWG_COMBINED_DIR', $conf['data_location'].'combined/');
|
||||
defined('PWG_DERIVATIVE_DIR') or define('PWG_DERIVATIVE_DIR', $conf['data_location'].'i/');
|
||||
|
||||
// Required versions
|
||||
define('REQUIRED_PHP_VERSION', '5.2.0');
|
||||
|
||||
// Access codes
|
||||
define('ACCESS_FREE', 0);
|
||||
define('ACCESS_GUEST', 1);
|
||||
define('ACCESS_CLASSIC', 2);
|
||||
define('ACCESS_ADMINISTRATOR', 3);
|
||||
define('ACCESS_WEBMASTER', 4);
|
||||
define('ACCESS_CLOSED', 5);
|
||||
|
||||
// Sanity checks
|
||||
define('PATTERN_ID', '/^\d+$/');
|
||||
|
||||
// Table names
|
||||
if (!defined('CATEGORIES_TABLE'))
|
||||
define('CATEGORIES_TABLE', $prefixeTable.'categories');
|
||||
if (!defined('COMMENTS_TABLE'))
|
||||
define('COMMENTS_TABLE', $prefixeTable.'comments');
|
||||
if (!defined('CONFIG_TABLE'))
|
||||
define('CONFIG_TABLE', $prefixeTable.'config');
|
||||
if (!defined('FAVORITES_TABLE'))
|
||||
define('FAVORITES_TABLE', $prefixeTable.'favorites');
|
||||
if (!defined('GROUP_ACCESS_TABLE'))
|
||||
define('GROUP_ACCESS_TABLE', $prefixeTable.'group_access');
|
||||
if (!defined('GROUPS_TABLE'))
|
||||
define('GROUPS_TABLE', $prefixeTable.'groups');
|
||||
if (!defined('HISTORY_TABLE'))
|
||||
define('HISTORY_TABLE', $prefixeTable.'history');
|
||||
if (!defined('HISTORY_SUMMARY_TABLE'))
|
||||
define('HISTORY_SUMMARY_TABLE', $prefixeTable.'history_summary');
|
||||
if (!defined('IMAGE_CATEGORY_TABLE'))
|
||||
define('IMAGE_CATEGORY_TABLE', $prefixeTable.'image_category');
|
||||
if (!defined('IMAGES_TABLE'))
|
||||
define('IMAGES_TABLE', $prefixeTable.'images');
|
||||
if (!defined('SESSIONS_TABLE'))
|
||||
define('SESSIONS_TABLE', $prefixeTable.'sessions');
|
||||
if (!defined('SITES_TABLE'))
|
||||
define('SITES_TABLE', $prefixeTable.'sites');
|
||||
if (!defined('USER_ACCESS_TABLE'))
|
||||
define('USER_ACCESS_TABLE', $prefixeTable.'user_access');
|
||||
if (!defined('USER_GROUP_TABLE'))
|
||||
define('USER_GROUP_TABLE', $prefixeTable.'user_group');
|
||||
if (!defined('USERS_TABLE'))
|
||||
define('USERS_TABLE', isset($conf['users_table']) ? $conf['users_table'] : $prefixeTable.'users' );
|
||||
if (!defined('USER_INFOS_TABLE'))
|
||||
define('USER_INFOS_TABLE', $prefixeTable.'user_infos');
|
||||
if (!defined('USER_FEED_TABLE'))
|
||||
define('USER_FEED_TABLE', $prefixeTable.'user_feed');
|
||||
if (!defined('RATE_TABLE'))
|
||||
define('RATE_TABLE', $prefixeTable.'rate');
|
||||
if (!defined('USER_AUTH_KEYS_TABLE'))
|
||||
define('USER_AUTH_KEYS_TABLE', $prefixeTable.'user_auth_keys');
|
||||
if (!defined('USER_CACHE_TABLE'))
|
||||
define('USER_CACHE_TABLE', $prefixeTable.'user_cache');
|
||||
if (!defined('USER_CACHE_CATEGORIES_TABLE'))
|
||||
define('USER_CACHE_CATEGORIES_TABLE', $prefixeTable.'user_cache_categories');
|
||||
if (!defined('CADDIE_TABLE'))
|
||||
define('CADDIE_TABLE', $prefixeTable.'caddie');
|
||||
if (!defined('UPGRADE_TABLE'))
|
||||
define('UPGRADE_TABLE', $prefixeTable.'upgrade');
|
||||
if (!defined('SEARCH_TABLE'))
|
||||
define('SEARCH_TABLE', $prefixeTable.'search');
|
||||
if (!defined('USER_MAIL_NOTIFICATION_TABLE'))
|
||||
define('USER_MAIL_NOTIFICATION_TABLE', $prefixeTable.'user_mail_notification');
|
||||
if (!defined('TAGS_TABLE'))
|
||||
define('TAGS_TABLE', $prefixeTable.'tags');
|
||||
if (!defined('IMAGE_TAG_TABLE'))
|
||||
define('IMAGE_TAG_TABLE', $prefixeTable.'image_tag');
|
||||
if (!defined('PLUGINS_TABLE'))
|
||||
define('PLUGINS_TABLE', $prefixeTable.'plugins');
|
||||
if (!defined('OLD_PERMALINKS_TABLE'))
|
||||
define('OLD_PERMALINKS_TABLE', $prefixeTable.'old_permalinks');
|
||||
if (!defined('THEMES_TABLE'))
|
||||
define('THEMES_TABLE', $prefixeTable.'themes');
|
||||
if (!defined('LANGUAGES_TABLE'))
|
||||
define('LANGUAGES_TABLE', $prefixeTable.'languages');
|
||||
if (!defined('IMAGE_FORMAT_TABLE'))
|
||||
define('IMAGE_FORMAT_TABLE', $prefixeTable.'image_format');
|
||||
|
||||
?>
|
||||
35
zoesch.de/galerie/include/cssmin.class.php
Normal file
35
zoesch.de/galerie/include/cssmin.class.php
Normal file
File diff suppressed because one or more lines are too long
833
zoesch.de/galerie/include/dblayer/functions_mysql.inc.php
Normal file
833
zoesch.de/galerie/include/dblayer/functions_mysql.inc.php
Normal file
@@ -0,0 +1,833 @@
|
||||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Piwigo - a PHP based photo gallery |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright(C) 2008-2016 Piwigo Team http://piwigo.org |
|
||||
// | Copyright(C) 2003-2008 PhpWebGallery Team http://phpwebgallery.net |
|
||||
// | Copyright(C) 2002-2003 Pierrick LE GALL http://le-gall.net/pierrick |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
define('DB_ENGINE', 'MySQL');
|
||||
define('REQUIRED_MYSQL_VERSION', '5.0.0');
|
||||
|
||||
define('DB_REGEX_OPERATOR', 'REGEXP');
|
||||
define('DB_RANDOM_FUNCTION', 'RAND');
|
||||
|
||||
/**
|
||||
*
|
||||
* simple functions
|
||||
*
|
||||
*/
|
||||
|
||||
function pwg_db_connect($host, $user, $password, $database)
|
||||
{
|
||||
$link = @mysql_connect($host, $user, $password);
|
||||
if (!$link)
|
||||
{
|
||||
throw new Exception("Can't connect to server");
|
||||
}
|
||||
if (!mysql_select_db($database, $link))
|
||||
{
|
||||
throw new Exception('Connection to server succeed, but it was impossible to connect to database');
|
||||
}
|
||||
}
|
||||
|
||||
function pwg_db_check_charset()
|
||||
{
|
||||
$db_charset = 'utf8';
|
||||
if (defined('DB_CHARSET') and DB_CHARSET != '')
|
||||
{
|
||||
$db_charset = DB_CHARSET;
|
||||
}
|
||||
mysql_set_charset($db_charset);
|
||||
}
|
||||
|
||||
function pwg_db_check_version()
|
||||
{
|
||||
$current_mysql = pwg_get_db_version();
|
||||
if (version_compare($current_mysql, REQUIRED_MYSQL_VERSION, '<'))
|
||||
{
|
||||
fatal_error(
|
||||
sprintf(
|
||||
'your MySQL version is too old, you have "%s" and you need at least "%s"',
|
||||
$current_mysql,
|
||||
REQUIRED_MYSQL_VERSION
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function pwg_get_db_version()
|
||||
{
|
||||
return mysql_get_server_info();
|
||||
}
|
||||
|
||||
function pwg_query($query)
|
||||
{
|
||||
global $conf,$page,$debug,$t2;
|
||||
|
||||
$start = microtime(true);
|
||||
($result = mysql_query($query)) or my_error($query, $conf['die_on_sql_error']);
|
||||
|
||||
$time = microtime(true) - $start;
|
||||
|
||||
if (!isset($page['count_queries']))
|
||||
{
|
||||
$page['count_queries'] = 0;
|
||||
$page['queries_time'] = 0;
|
||||
}
|
||||
|
||||
$page['count_queries']++;
|
||||
$page['queries_time']+= $time;
|
||||
|
||||
if ($conf['show_queries'])
|
||||
{
|
||||
$output = '';
|
||||
$output.= '<pre>['.$page['count_queries'].'] ';
|
||||
$output.= "\n".$query;
|
||||
$output.= "\n".'(this query time : ';
|
||||
$output.= '<b>'.number_format($time, 3, '.', ' ').' s)</b>';
|
||||
$output.= "\n".'(total SQL time : ';
|
||||
$output.= number_format($page['queries_time'], 3, '.', ' ').' s)';
|
||||
$output.= "\n".'(total time : ';
|
||||
$output.= number_format( ($time+$start-$t2), 3, '.', ' ').' s)';
|
||||
if ( $result!=null and preg_match('/\s*SELECT\s+/i',$query) )
|
||||
{
|
||||
$output.= "\n".'(num rows : ';
|
||||
$output.= mysql_num_rows($result).' )';
|
||||
}
|
||||
elseif ( $result!=null
|
||||
and preg_match('/\s*INSERT|UPDATE|REPLACE|DELETE\s+/i',$query) )
|
||||
{
|
||||
$output.= "\n".'(affected rows : ';
|
||||
$output.= mysql_affected_rows().' )';
|
||||
}
|
||||
$output.= "</pre>\n";
|
||||
|
||||
$debug .= $output;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
function pwg_db_nextval($column, $table)
|
||||
{
|
||||
$query = '
|
||||
SELECT IF(MAX('.$column.')+1 IS NULL, 1, MAX('.$column.')+1)
|
||||
FROM '.$table;
|
||||
list($next) = pwg_db_fetch_row(pwg_query($query));
|
||||
|
||||
return $next;
|
||||
}
|
||||
|
||||
function pwg_db_changes()
|
||||
{
|
||||
return mysql_affected_rows();
|
||||
}
|
||||
|
||||
function pwg_db_num_rows($result)
|
||||
{
|
||||
return mysql_num_rows($result);
|
||||
}
|
||||
|
||||
function pwg_db_fetch_array($result)
|
||||
{
|
||||
return mysql_fetch_array($result);
|
||||
}
|
||||
|
||||
function pwg_db_fetch_assoc($result)
|
||||
{
|
||||
return mysql_fetch_assoc($result);
|
||||
}
|
||||
|
||||
function pwg_db_fetch_row($result)
|
||||
{
|
||||
return mysql_fetch_row($result);
|
||||
}
|
||||
|
||||
function pwg_db_fetch_object($result)
|
||||
{
|
||||
return mysql_fetch_object($result);
|
||||
}
|
||||
|
||||
function pwg_db_free_result($result)
|
||||
{
|
||||
return mysql_free_result($result);
|
||||
}
|
||||
|
||||
function pwg_db_real_escape_string($s)
|
||||
{
|
||||
return mysql_real_escape_string($s);
|
||||
}
|
||||
|
||||
function pwg_db_insert_id()
|
||||
{
|
||||
return mysql_insert_id();
|
||||
}
|
||||
|
||||
function pwg_db_errno()
|
||||
{
|
||||
return mysql_errno();
|
||||
}
|
||||
|
||||
function pwg_db_error()
|
||||
{
|
||||
return mysql_error();
|
||||
}
|
||||
|
||||
function pwg_db_close()
|
||||
{
|
||||
return mysql_close();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* complex functions
|
||||
*
|
||||
*/
|
||||
|
||||
define('MASS_UPDATES_SKIP_EMPTY', 1);
|
||||
/**
|
||||
* updates multiple lines in a table
|
||||
*
|
||||
* @param string table_name
|
||||
* @param array dbfields
|
||||
* @param array datas
|
||||
* @param int flags - if MASS_UPDATES_SKIP_EMPTY - empty values do not overwrite existing ones
|
||||
* @return void
|
||||
*/
|
||||
function mass_updates($tablename, $dbfields, $datas, $flags=0)
|
||||
{
|
||||
if (count($datas) == 0)
|
||||
return;
|
||||
|
||||
// depending on the MySQL version, we use the multi table update or N update queries
|
||||
if (count($datas) < 10)
|
||||
{
|
||||
foreach ($datas as $data)
|
||||
{
|
||||
$query = '
|
||||
UPDATE '.$tablename.'
|
||||
SET ';
|
||||
$is_first = true;
|
||||
foreach ($dbfields['update'] as $key)
|
||||
{
|
||||
$separator = $is_first ? '' : ",\n ";
|
||||
|
||||
if (isset($data[$key]) and $data[$key] != '')
|
||||
{
|
||||
$query.= $separator.$key.' = \''.$data[$key].'\'';
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( $flags & MASS_UPDATES_SKIP_EMPTY )
|
||||
continue; // next field
|
||||
$query.= "$separator$key = NULL";
|
||||
}
|
||||
$is_first = false;
|
||||
}
|
||||
if (!$is_first)
|
||||
{// only if one field at least updated
|
||||
$query.= '
|
||||
WHERE ';
|
||||
$is_first = true;
|
||||
foreach ($dbfields['primary'] as $key)
|
||||
{
|
||||
if (!$is_first)
|
||||
{
|
||||
$query.= ' AND ';
|
||||
}
|
||||
if ( isset($data[$key]) )
|
||||
{
|
||||
$query.= $key.' = \''.$data[$key].'\'';
|
||||
}
|
||||
else
|
||||
{
|
||||
$query.= $key.' IS NULL';
|
||||
}
|
||||
$is_first = false;
|
||||
}
|
||||
pwg_query($query);
|
||||
}
|
||||
} // foreach update
|
||||
} // if mysql_ver or count<X
|
||||
else
|
||||
{
|
||||
// creation of the temporary table
|
||||
$query = '
|
||||
SHOW FULL COLUMNS FROM '.$tablename;
|
||||
$result = pwg_query($query);
|
||||
$columns = array();
|
||||
$all_fields = array_merge($dbfields['primary'], $dbfields['update']);
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
if (in_array($row['Field'], $all_fields))
|
||||
{
|
||||
$column = $row['Field'];
|
||||
$column.= ' '.$row['Type'];
|
||||
|
||||
$nullable = true;
|
||||
if (!isset($row['Null']) or $row['Null'] == '' or $row['Null']=='NO')
|
||||
{
|
||||
$column.= ' NOT NULL';
|
||||
$nullable = false;
|
||||
}
|
||||
if (isset($row['Default']))
|
||||
{
|
||||
$column.= " default '".$row['Default']."'";
|
||||
}
|
||||
elseif ($nullable)
|
||||
{
|
||||
$column.= " default NULL";
|
||||
}
|
||||
if (isset($row['Collation']) and $row['Collation'] != 'NULL')
|
||||
{
|
||||
$column.= " collate '".$row['Collation']."'";
|
||||
}
|
||||
$columns[] = $column;
|
||||
}
|
||||
}
|
||||
|
||||
$temporary_tablename = $tablename.'_'.micro_seconds();
|
||||
|
||||
$query = '
|
||||
CREATE TABLE '.$temporary_tablename.'
|
||||
(
|
||||
'.implode(",\n ", $columns).',
|
||||
UNIQUE KEY the_key ('.implode(',', $dbfields['primary']).')
|
||||
)';
|
||||
|
||||
pwg_query($query);
|
||||
mass_inserts($temporary_tablename, $all_fields, $datas);
|
||||
if ( $flags & MASS_UPDATES_SKIP_EMPTY )
|
||||
$func_set = create_function('$s', 'return "t1.$s = IFNULL(t2.$s, t1.$s)";');
|
||||
else
|
||||
$func_set = create_function('$s', 'return "t1.$s = t2.$s";');
|
||||
|
||||
// update of images table by joining with temporary table
|
||||
$query = '
|
||||
UPDATE '.$tablename.' AS t1, '.$temporary_tablename.' AS t2
|
||||
SET '.
|
||||
implode(
|
||||
"\n , ",
|
||||
array_map($func_set,$dbfields['update'])
|
||||
).'
|
||||
WHERE '.
|
||||
implode(
|
||||
"\n AND ",
|
||||
array_map(
|
||||
create_function('$s', 'return "t1.$s = t2.$s";'),
|
||||
$dbfields['primary']
|
||||
)
|
||||
);
|
||||
pwg_query($query);
|
||||
$query = '
|
||||
DROP TABLE '.$temporary_tablename;
|
||||
pwg_query($query);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* updates one line in a table
|
||||
*
|
||||
* @param string table_name
|
||||
* @param array set_fields
|
||||
* @param array where_fields
|
||||
* @param int flags - if MASS_UPDATES_SKIP_EMPTY - empty values do not overwrite existing ones
|
||||
* @return void
|
||||
*/
|
||||
function single_update($tablename, $set_fields, $where_fields, $flags=0)
|
||||
{
|
||||
if (count($set_fields) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$query = '
|
||||
UPDATE '.$tablename.'
|
||||
SET ';
|
||||
$is_first = true;
|
||||
foreach ($set_fields as $key => $value)
|
||||
{
|
||||
$separator = $is_first ? '' : ",\n ";
|
||||
|
||||
if (isset($value) and $value !== '')
|
||||
{
|
||||
$query.= $separator.$key.' = \''.$value.'\'';
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( $flags & MASS_UPDATES_SKIP_EMPTY )
|
||||
continue; // next field
|
||||
$query.= "$separator$key = NULL";
|
||||
}
|
||||
$is_first = false;
|
||||
}
|
||||
if (!$is_first)
|
||||
{// only if one field at least updated
|
||||
$query.= '
|
||||
WHERE ';
|
||||
$is_first = true;
|
||||
foreach ($where_fields as $key => $value)
|
||||
{
|
||||
if (!$is_first)
|
||||
{
|
||||
$query.= ' AND ';
|
||||
}
|
||||
if ( isset($value) )
|
||||
{
|
||||
$query.= $key.' = \''.$value.'\'';
|
||||
}
|
||||
else
|
||||
{
|
||||
$query.= $key.' IS NULL';
|
||||
}
|
||||
$is_first = false;
|
||||
}
|
||||
pwg_query($query);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* inserts multiple lines in a table
|
||||
*
|
||||
* @param string table_name
|
||||
* @param array dbfields
|
||||
* @param array inserts
|
||||
* @return void
|
||||
*/
|
||||
function mass_inserts($table_name, $dbfields, $datas, $options=array())
|
||||
{
|
||||
$ignore = '';
|
||||
if (isset($options['ignore']) and $options['ignore'])
|
||||
{
|
||||
$ignore = 'IGNORE';
|
||||
}
|
||||
|
||||
if (count($datas) != 0)
|
||||
{
|
||||
$first = true;
|
||||
|
||||
$query = 'SHOW VARIABLES LIKE \'max_allowed_packet\'';
|
||||
list(, $packet_size) = pwg_db_fetch_row(pwg_query($query));
|
||||
$packet_size = $packet_size - 2000; // The last list of values MUST not exceed 2000 character*/
|
||||
$query = '';
|
||||
|
||||
foreach ($datas as $insert)
|
||||
{
|
||||
if (strlen($query) >= $packet_size)
|
||||
{
|
||||
pwg_query($query);
|
||||
$first = true;
|
||||
}
|
||||
|
||||
if ($first)
|
||||
{
|
||||
$query = '
|
||||
INSERT '.$ignore.' INTO '.$table_name.'
|
||||
('.implode(',', $dbfields).')
|
||||
VALUES';
|
||||
$first = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$query .= '
|
||||
, ';
|
||||
}
|
||||
|
||||
$query .= '(';
|
||||
foreach ($dbfields as $field_id => $dbfield)
|
||||
{
|
||||
if ($field_id > 0)
|
||||
{
|
||||
$query .= ',';
|
||||
}
|
||||
|
||||
if (!isset($insert[$dbfield]) or $insert[$dbfield] === '')
|
||||
{
|
||||
$query .= 'NULL';
|
||||
}
|
||||
else
|
||||
{
|
||||
$query .= "'".$insert[$dbfield]."'";
|
||||
}
|
||||
}
|
||||
$query .= ')';
|
||||
}
|
||||
pwg_query($query);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* inserts one line in a table
|
||||
*
|
||||
* @param string table_name
|
||||
* @param array dbfields
|
||||
* @param array insert
|
||||
* @return void
|
||||
*/
|
||||
function single_insert($table_name, $data)
|
||||
{
|
||||
if (count($data) != 0)
|
||||
{
|
||||
$query = '
|
||||
INSERT INTO '.$table_name.'
|
||||
('.implode(',', array_keys($data)).')
|
||||
VALUES';
|
||||
|
||||
$query .= '(';
|
||||
$is_first = true;
|
||||
foreach ($data as $key => $value)
|
||||
{
|
||||
if (!$is_first)
|
||||
{
|
||||
$query .= ',';
|
||||
}
|
||||
else
|
||||
{
|
||||
$is_first = false;
|
||||
}
|
||||
|
||||
if ($value === '' || is_null($value))
|
||||
{
|
||||
$query .= 'NULL';
|
||||
}
|
||||
else
|
||||
{
|
||||
$query .= "'".$value."'";
|
||||
}
|
||||
}
|
||||
$query .= ')';
|
||||
|
||||
pwg_query($query);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Do maintenance on all PWG tables
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
function do_maintenance_all_tables()
|
||||
{
|
||||
global $prefixeTable, $page;
|
||||
|
||||
$all_tables = array();
|
||||
|
||||
// List all tables
|
||||
$query = 'SHOW TABLES LIKE \''.$prefixeTable.'%\'';
|
||||
$result = pwg_query($query);
|
||||
while ($row = pwg_db_fetch_row($result))
|
||||
{
|
||||
$all_tables[] = $row[0];
|
||||
}
|
||||
|
||||
// Repair all tables
|
||||
$query = 'REPAIR TABLE '.implode(', ', $all_tables);
|
||||
$mysql_rc = pwg_query($query);
|
||||
|
||||
// Re-Order all tables
|
||||
foreach ($all_tables as $table_name)
|
||||
{
|
||||
$all_primary_key = array();
|
||||
|
||||
$query = 'DESC '.$table_name.';';
|
||||
$result = pwg_query($query);
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
if ($row['Key'] == 'PRI')
|
||||
{
|
||||
$all_primary_key[] = $row['Field'];
|
||||
}
|
||||
}
|
||||
|
||||
if (count($all_primary_key) != 0)
|
||||
{
|
||||
$query = 'ALTER TABLE '.$table_name.' ORDER BY '.implode(', ', $all_primary_key).';';
|
||||
$mysql_rc = $mysql_rc && pwg_query($query);
|
||||
}
|
||||
}
|
||||
|
||||
// Optimize all tables
|
||||
$query = 'OPTIMIZE TABLE '.implode(', ', $all_tables);
|
||||
$mysql_rc = $mysql_rc && pwg_query($query);
|
||||
if ($mysql_rc)
|
||||
{
|
||||
$page['infos'][] = l10n('All optimizations have been successfully completed.');
|
||||
}
|
||||
else
|
||||
{
|
||||
$page['errors'][] = l10n('Optimizations have been completed with some errors.');
|
||||
}
|
||||
}
|
||||
|
||||
function pwg_db_concat($array)
|
||||
{
|
||||
$string = implode($array, ',');
|
||||
return 'CONCAT('. $string.')';
|
||||
}
|
||||
|
||||
function pwg_db_concat_ws($array, $separator)
|
||||
{
|
||||
$string = implode($array, ',');
|
||||
return 'CONCAT_WS(\''.$separator.'\','. $string.')';
|
||||
}
|
||||
|
||||
function pwg_db_cast_to_text($string)
|
||||
{
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns an array containing the possible values of an enum field
|
||||
*
|
||||
* @param string tablename
|
||||
* @param string fieldname
|
||||
*/
|
||||
function get_enums($table, $field)
|
||||
{
|
||||
// retrieving the properties of the table. Each line represents a field :
|
||||
// columns are 'Field', 'Type'
|
||||
$result = pwg_query('desc '.$table);
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
// we are only interested in the the field given in parameter for the
|
||||
// function
|
||||
if ($row['Field'] == $field)
|
||||
{
|
||||
// retrieving possible values of the enum field
|
||||
// enum('blue','green','black')
|
||||
$options = explode(',', substr($row['Type'], 5, -1));
|
||||
foreach ($options as $i => $option)
|
||||
{
|
||||
$options[$i] = str_replace("'", '',$option);
|
||||
}
|
||||
}
|
||||
}
|
||||
pwg_db_free_result($result);
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Smartly checks if a variable is equivalent to true or false
|
||||
*
|
||||
* @param mixed input
|
||||
* @return bool
|
||||
*/
|
||||
function get_boolean($input)
|
||||
{
|
||||
if ('false' === strtolower($input))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return (bool)$input;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns boolean string 'true' or 'false' if the given var is boolean
|
||||
*
|
||||
* @param mixed $var
|
||||
* @return mixed
|
||||
*/
|
||||
function boolean_to_string($var)
|
||||
{
|
||||
if (is_bool($var))
|
||||
{
|
||||
return $var ? 'true' : 'false';
|
||||
}
|
||||
else
|
||||
{
|
||||
return $var;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* interval and date functions
|
||||
*
|
||||
*/
|
||||
|
||||
function pwg_db_get_recent_period_expression($period, $date='CURRENT_DATE')
|
||||
{
|
||||
if ($date!='CURRENT_DATE')
|
||||
{
|
||||
$date = '\''.$date.'\'';
|
||||
}
|
||||
|
||||
return 'SUBDATE('.$date.',INTERVAL '.$period.' DAY)';
|
||||
}
|
||||
|
||||
function pwg_db_get_recent_period($period, $date='CURRENT_DATE')
|
||||
{
|
||||
$query = '
|
||||
SELECT '.pwg_db_get_recent_period_expression($period);
|
||||
list($d) = pwg_db_fetch_row(pwg_query($query));
|
||||
|
||||
return $d;
|
||||
}
|
||||
|
||||
function pwg_db_get_flood_period_expression($seconds)
|
||||
{
|
||||
return 'SUBDATE(now(), INTERVAL '.$seconds.' SECOND)';
|
||||
}
|
||||
|
||||
function pwg_db_get_hour($date)
|
||||
{
|
||||
return 'hour('.$date.')';
|
||||
}
|
||||
|
||||
function pwg_db_get_date_YYYYMM($date)
|
||||
{
|
||||
return 'DATE_FORMAT('.$date.', \'%Y%m\')';
|
||||
}
|
||||
|
||||
function pwg_db_get_date_MMDD($date)
|
||||
{
|
||||
return 'DATE_FORMAT('.$date.', \'%m%d\')';
|
||||
}
|
||||
|
||||
function pwg_db_get_year($date)
|
||||
{
|
||||
return 'YEAR('.$date.')';
|
||||
}
|
||||
|
||||
function pwg_db_get_month($date)
|
||||
{
|
||||
return 'MONTH('.$date.')';
|
||||
}
|
||||
|
||||
function pwg_db_get_week($date, $mode=null)
|
||||
{
|
||||
if ($mode)
|
||||
{
|
||||
return 'WEEK('.$date.', '.$mode.')';
|
||||
}
|
||||
else
|
||||
{
|
||||
return 'WEEK('.$date.')';
|
||||
}
|
||||
}
|
||||
|
||||
function pwg_db_get_dayofmonth($date)
|
||||
{
|
||||
return 'DAYOFMONTH('.$date.')';
|
||||
}
|
||||
|
||||
function pwg_db_get_dayofweek($date)
|
||||
{
|
||||
return 'DAYOFWEEK('.$date.')';
|
||||
}
|
||||
|
||||
function pwg_db_get_weekday($date)
|
||||
{
|
||||
return 'WEEKDAY('.$date.')';
|
||||
}
|
||||
|
||||
function pwg_db_date_to_ts($date)
|
||||
{
|
||||
return 'UNIX_TIMESTAMP('.$date.')';
|
||||
}
|
||||
|
||||
// my_error returns (or send to standard output) the message concerning the
|
||||
// error occured for the last mysql query.
|
||||
function my_error($header, $die)
|
||||
{
|
||||
$error = "[mysql error ".mysql_errno().'] '.mysql_error()."\n";
|
||||
$error .= $header;
|
||||
|
||||
if ($die)
|
||||
{
|
||||
fatal_error($error);
|
||||
}
|
||||
echo("<pre>");
|
||||
trigger_error($error, E_USER_WARNING);
|
||||
echo("</pre>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds an data array from a SQL query.
|
||||
* Depending on $key_name and $value_name it can return :
|
||||
*
|
||||
* - an array of arrays of all fields (key=null, value=null)
|
||||
* array(
|
||||
* array('id'=>1, 'name'=>'DSC8956', ...),
|
||||
* array('id'=>2, 'name'=>'DSC8957', ...),
|
||||
* ...
|
||||
* )
|
||||
*
|
||||
* - an array of a single field (key=null, value='...')
|
||||
* array('DSC8956', 'DSC8957', ...)
|
||||
*
|
||||
* - an associative array of array of all fields (key='...', value=null)
|
||||
* array(
|
||||
* 'DSC8956' => array('id'=>1, 'name'=>'DSC8956', ...),
|
||||
* 'DSC8957' => array('id'=>2, 'name'=>'DSC8957', ...),
|
||||
* ...
|
||||
* )
|
||||
*
|
||||
* - an associative array of a single field (key='...', value='...')
|
||||
* array(
|
||||
* 'DSC8956' => 1,
|
||||
* 'DSC8957' => 2,
|
||||
* ...
|
||||
* )
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param string $query
|
||||
* @param string $key_name
|
||||
* @param string $value_name
|
||||
* @return array
|
||||
*/
|
||||
function query2array($query, $key_name=null, $value_name=null)
|
||||
{
|
||||
$result = pwg_query($query);
|
||||
$data = array();
|
||||
|
||||
if (isset($key_name))
|
||||
{
|
||||
if (isset($value_name))
|
||||
{
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
$data[ $row[$key_name] ] = $row[$value_name];
|
||||
}
|
||||
else
|
||||
{
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
$data[ $row[$key_name] ] = $row;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isset($value_name))
|
||||
{
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
$data[] = $row[$value_name];
|
||||
}
|
||||
else
|
||||
{
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
$data[] = $row;
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
?>
|
||||
919
zoesch.de/galerie/include/dblayer/functions_mysqli.inc.php
Normal file
919
zoesch.de/galerie/include/dblayer/functions_mysqli.inc.php
Normal file
@@ -0,0 +1,919 @@
|
||||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Piwigo - a PHP based photo gallery |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright(C) 2008-2016 Piwigo Team http://piwigo.org |
|
||||
// | Copyright(C) 2003-2008 PhpWebGallery Team http://phpwebgallery.net |
|
||||
// | Copyright(C) 2002-2003 Pierrick LE GALL http://le-gall.net/pierrick |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
* @package functions\mysql
|
||||
*/
|
||||
|
||||
define('DB_ENGINE', 'MySQL');
|
||||
define('REQUIRED_MYSQL_VERSION', '5.0.0');
|
||||
|
||||
define('DB_REGEX_OPERATOR', 'REGEXP');
|
||||
define('DB_RANDOM_FUNCTION', 'RAND');
|
||||
|
||||
|
||||
/**
|
||||
* Connect to database and store MySQLi resource in __$mysqli__ global variable.
|
||||
*
|
||||
* @param string $host
|
||||
* - localhost
|
||||
* - 1.2.3.4:3405
|
||||
* - /path/to/socket
|
||||
* @param string $user
|
||||
* @param string $password
|
||||
* @param string $database
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
function pwg_db_connect($host, $user, $password, $database)
|
||||
{
|
||||
global $mysqli;
|
||||
|
||||
$port = null;
|
||||
$socket = null;
|
||||
|
||||
if (strpos($host, '/') === 0)
|
||||
{
|
||||
$socket = $host;
|
||||
$host = null;
|
||||
}
|
||||
elseif (strpos($host, ':') !== false)
|
||||
{
|
||||
list($host, $port) = explode(':', $host);
|
||||
}
|
||||
|
||||
$dbname = null;
|
||||
|
||||
$mysqli = new mysqli($host, $user, $password, $dbname, $port, $socket);
|
||||
if (mysqli_connect_error())
|
||||
{
|
||||
throw new Exception("Can't connect to server");
|
||||
}
|
||||
if (!$mysqli->select_db($database))
|
||||
{
|
||||
throw new Exception('Connection to server succeed, but it was impossible to connect to database');
|
||||
}
|
||||
|
||||
// MySQL 5.7 default settings forbid to select a colum that is not in the
|
||||
// group by. We've used that in Piwigo, for years. As an immediate solution
|
||||
// we can remove this constraint in the current MySQL session.
|
||||
list($sql_mode_current) = pwg_db_fetch_row(pwg_query('SELECT @@SESSION.sql_mode'));
|
||||
|
||||
// remove ONLY_FULL_GROUP_BY from the list
|
||||
$sql_mode_altered = implode(',', array_diff(explode(',', $sql_mode_current), array('ONLY_FULL_GROUP_BY')));
|
||||
|
||||
if ($sql_mode_altered != $sql_mode_current)
|
||||
{
|
||||
pwg_query("SET SESSION sql_mode='".$sql_mode_altered."'");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set charset for database connection.
|
||||
*/
|
||||
function pwg_db_check_charset()
|
||||
{
|
||||
global $mysqli;
|
||||
|
||||
$db_charset = 'utf8';
|
||||
if (defined('DB_CHARSET') and DB_CHARSET != '')
|
||||
{
|
||||
$db_charset = DB_CHARSET;
|
||||
}
|
||||
$mysqli->set_charset($db_charset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check MySQL version. Can call fatal_error().
|
||||
*/
|
||||
function pwg_db_check_version()
|
||||
{
|
||||
$current_mysql = pwg_get_db_version();
|
||||
if (version_compare($current_mysql, REQUIRED_MYSQL_VERSION, '<'))
|
||||
{
|
||||
fatal_error(
|
||||
sprintf(
|
||||
'your MySQL version is too old, you have "%s" and you need at least "%s"',
|
||||
$current_mysql,
|
||||
REQUIRED_MYSQL_VERSION
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Mysql Version.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function pwg_get_db_version()
|
||||
{
|
||||
global $mysqli;
|
||||
|
||||
return $mysqli->server_info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a query
|
||||
*
|
||||
* @param string $query
|
||||
* @return mysqli_result|bool
|
||||
*/
|
||||
function pwg_query($query)
|
||||
{
|
||||
global $mysqli, $conf, $page, $debug, $t2;
|
||||
|
||||
$start = microtime(true);
|
||||
($result = $mysqli->query($query)) or my_error($query, $conf['die_on_sql_error']);
|
||||
|
||||
$time = microtime(true) - $start;
|
||||
|
||||
if (!isset($page['count_queries']))
|
||||
{
|
||||
$page['count_queries'] = 0;
|
||||
$page['queries_time'] = 0;
|
||||
}
|
||||
|
||||
$page['count_queries']++;
|
||||
$page['queries_time']+= $time;
|
||||
|
||||
if ($conf['show_queries'])
|
||||
{
|
||||
$output = '';
|
||||
$output.= '<pre>['.$page['count_queries'].'] ';
|
||||
$output.= "\n".$query;
|
||||
$output.= "\n".'(this query time : ';
|
||||
$output.= '<b>'.number_format($time, 3, '.', ' ').' s)</b>';
|
||||
$output.= "\n".'(total SQL time : ';
|
||||
$output.= number_format($page['queries_time'], 3, '.', ' ').' s)';
|
||||
$output.= "\n".'(total time : ';
|
||||
$output.= number_format( ($time+$start-$t2), 3, '.', ' ').' s)';
|
||||
if ( $result!=null and preg_match('/\s*SELECT\s+/i',$query) )
|
||||
{
|
||||
$output.= "\n".'(num rows : ';
|
||||
$output.= pwg_db_num_rows($result).' )';
|
||||
}
|
||||
elseif ( $result!=null
|
||||
and preg_match('/\s*INSERT|UPDATE|REPLACE|DELETE\s+/i',$query) )
|
||||
{
|
||||
$output.= "\n".'(affected rows : ';
|
||||
$output.= pwg_db_changes().' )';
|
||||
}
|
||||
$output.= "</pre>\n";
|
||||
|
||||
$debug .= $output;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get max value plus one of a particular column.
|
||||
*
|
||||
* @param string $column
|
||||
* @param string $table
|
||||
* @param int
|
||||
*/
|
||||
function pwg_db_nextval($column, $table)
|
||||
{
|
||||
$query = '
|
||||
SELECT IF(MAX('.$column.')+1 IS NULL, 1, MAX('.$column.')+1)
|
||||
FROM '.$table;
|
||||
list($next) = pwg_db_fetch_row(pwg_query($query));
|
||||
|
||||
return $next;
|
||||
}
|
||||
|
||||
function pwg_db_changes()
|
||||
{
|
||||
global $mysqli;
|
||||
|
||||
return $mysqli->affected_rows;
|
||||
}
|
||||
|
||||
function pwg_db_num_rows($result)
|
||||
{
|
||||
return $result->num_rows;
|
||||
}
|
||||
|
||||
function pwg_db_fetch_array($result)
|
||||
{
|
||||
return $result->fetch_array();
|
||||
}
|
||||
|
||||
function pwg_db_fetch_assoc($result)
|
||||
{
|
||||
return $result->fetch_assoc();
|
||||
}
|
||||
|
||||
function pwg_db_fetch_row($result)
|
||||
{
|
||||
return $result->fetch_row();
|
||||
}
|
||||
|
||||
function pwg_db_fetch_object($result)
|
||||
{
|
||||
return $result->fetch_object();
|
||||
}
|
||||
|
||||
function pwg_db_free_result($result)
|
||||
{
|
||||
return $result->free_result();
|
||||
}
|
||||
|
||||
function pwg_db_real_escape_string($s)
|
||||
{
|
||||
global $mysqli;
|
||||
|
||||
return $mysqli->real_escape_string($s);
|
||||
}
|
||||
|
||||
function pwg_db_insert_id()
|
||||
{
|
||||
global $mysqli;
|
||||
|
||||
return $mysqli->insert_id;
|
||||
}
|
||||
|
||||
function pwg_db_errno()
|
||||
{
|
||||
global $mysqli;
|
||||
|
||||
return $mysqli->errno;
|
||||
}
|
||||
|
||||
function pwg_db_error()
|
||||
{
|
||||
global $mysqli;
|
||||
|
||||
return $mysqli->error;
|
||||
}
|
||||
|
||||
function pwg_db_close()
|
||||
{
|
||||
global $mysqli;
|
||||
|
||||
return $mysqli->close();
|
||||
}
|
||||
|
||||
|
||||
define('MASS_UPDATES_SKIP_EMPTY', 1);
|
||||
|
||||
/**
|
||||
* Updates multiple lines in a table.
|
||||
*
|
||||
* @param string $tablename
|
||||
* @param array $dbfields - contains 'primary' and 'update' arrays
|
||||
* @param array $datas - indexed by column names
|
||||
* @param int $flags - if MASS_UPDATES_SKIP_EMPTY, empty values do not overwrite existing ones
|
||||
*/
|
||||
function mass_updates($tablename, $dbfields, $datas, $flags=0)
|
||||
{
|
||||
if (count($datas) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// we use the multi table update or N update queries
|
||||
if (count($datas) < 10)
|
||||
{
|
||||
foreach ($datas as $data)
|
||||
{
|
||||
$is_first = true;
|
||||
|
||||
$query = '
|
||||
UPDATE '.$tablename.'
|
||||
SET ';
|
||||
|
||||
foreach ($dbfields['update'] as $key)
|
||||
{
|
||||
$separator = $is_first ? '' : ",\n ";
|
||||
|
||||
if (isset($data[$key]) and $data[$key] != '')
|
||||
{
|
||||
$query.= $separator.$key.' = \''.$data[$key].'\'';
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($flags & MASS_UPDATES_SKIP_EMPTY)
|
||||
{
|
||||
continue; // next field
|
||||
}
|
||||
$query.= "$separator$key = NULL";
|
||||
}
|
||||
$is_first = false;
|
||||
}
|
||||
|
||||
if (!$is_first)
|
||||
{// only if one field at least updated
|
||||
$is_first = true;
|
||||
|
||||
$query.= '
|
||||
WHERE ';
|
||||
foreach ($dbfields['primary'] as $key)
|
||||
{
|
||||
if (!$is_first)
|
||||
{
|
||||
$query.= ' AND ';
|
||||
}
|
||||
if (isset($data[$key]))
|
||||
{
|
||||
$query.= $key.' = \''.$data[$key].'\'';
|
||||
}
|
||||
else
|
||||
{
|
||||
$query.= $key.' IS NULL';
|
||||
}
|
||||
$is_first = false;
|
||||
}
|
||||
|
||||
pwg_query($query);
|
||||
}
|
||||
} // foreach update
|
||||
} // if count<X
|
||||
else
|
||||
{
|
||||
// creation of the temporary table
|
||||
$result = pwg_query('SHOW FULL COLUMNS FROM '.$tablename);
|
||||
$columns = array();
|
||||
$all_fields = array_merge($dbfields['primary'], $dbfields['update']);
|
||||
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
if (in_array($row['Field'], $all_fields))
|
||||
{
|
||||
$column = $row['Field'];
|
||||
$column.= ' '.$row['Type'];
|
||||
|
||||
$nullable = true;
|
||||
if (!isset($row['Null']) or $row['Null'] == '' or $row['Null']=='NO')
|
||||
{
|
||||
$column.= ' NOT NULL';
|
||||
$nullable = false;
|
||||
}
|
||||
if (isset($row['Default']))
|
||||
{
|
||||
$column.= " default '".$row['Default']."'";
|
||||
}
|
||||
elseif ($nullable)
|
||||
{
|
||||
$column.= " default NULL";
|
||||
}
|
||||
if (isset($row['Collation']) and $row['Collation'] != 'NULL')
|
||||
{
|
||||
$column.= " collate '".$row['Collation']."'";
|
||||
}
|
||||
$columns[] = $column;
|
||||
}
|
||||
}
|
||||
|
||||
$temporary_tablename = $tablename.'_'.micro_seconds();
|
||||
|
||||
$query = '
|
||||
CREATE TABLE '.$temporary_tablename.'
|
||||
(
|
||||
'.implode(",\n ", $columns).',
|
||||
UNIQUE KEY the_key ('.implode(',', $dbfields['primary']).')
|
||||
)';
|
||||
|
||||
pwg_query($query);
|
||||
mass_inserts($temporary_tablename, $all_fields, $datas);
|
||||
|
||||
if ($flags & MASS_UPDATES_SKIP_EMPTY)
|
||||
$func_set = create_function('$s', 'return "t1.$s = IFNULL(t2.$s, t1.$s)";');
|
||||
else
|
||||
$func_set = create_function('$s', 'return "t1.$s = t2.$s";');
|
||||
|
||||
// update of table by joining with temporary table
|
||||
$query = '
|
||||
UPDATE '.$tablename.' AS t1, '.$temporary_tablename.' AS t2
|
||||
SET '.
|
||||
implode(
|
||||
"\n , ",
|
||||
array_map($func_set,$dbfields['update'])
|
||||
).'
|
||||
WHERE '.
|
||||
implode(
|
||||
"\n AND ",
|
||||
array_map(
|
||||
create_function('$s', 'return "t1.$s = t2.$s";'),
|
||||
$dbfields['primary']
|
||||
)
|
||||
);
|
||||
pwg_query($query);
|
||||
|
||||
pwg_query('DROP TABLE '.$temporary_tablename);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates one line in a table.
|
||||
*
|
||||
* @param string $tablename
|
||||
* @param array $datas
|
||||
* @param array $where
|
||||
* @param int $flags - if MASS_UPDATES_SKIP_EMPTY, empty values do not overwrite existing ones
|
||||
*/
|
||||
function single_update($tablename, $datas, $where, $flags=0)
|
||||
{
|
||||
if (count($datas) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$is_first = true;
|
||||
|
||||
$query = '
|
||||
UPDATE '.$tablename.'
|
||||
SET ';
|
||||
|
||||
foreach ($datas as $key => $value)
|
||||
{
|
||||
$separator = $is_first ? '' : ",\n ";
|
||||
|
||||
if (isset($value) and $value !== '')
|
||||
{
|
||||
$query.= $separator.$key.' = \''.$value.'\'';
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($flags & MASS_UPDATES_SKIP_EMPTY)
|
||||
{
|
||||
continue; // next field
|
||||
}
|
||||
$query.= "$separator$key = NULL";
|
||||
}
|
||||
$is_first = false;
|
||||
}
|
||||
|
||||
if (!$is_first)
|
||||
{// only if one field at least updated
|
||||
$is_first = true;
|
||||
|
||||
$query.= '
|
||||
WHERE ';
|
||||
|
||||
foreach ($where as $key => $value)
|
||||
{
|
||||
if (!$is_first)
|
||||
{
|
||||
$query.= ' AND ';
|
||||
}
|
||||
if (isset($value))
|
||||
{
|
||||
$query.= $key.' = \''.$value.'\'';
|
||||
}
|
||||
else
|
||||
{
|
||||
$query.= $key.' IS NULL';
|
||||
}
|
||||
$is_first = false;
|
||||
}
|
||||
|
||||
pwg_query($query);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts multiple lines in a table.
|
||||
*
|
||||
* @param string $table_name
|
||||
* @param array $dbfields - fields from $datas which will be used
|
||||
* @param array $datas
|
||||
* @param array $options
|
||||
* - boolean ignore - use "INSERT IGNORE"
|
||||
*/
|
||||
function mass_inserts($table_name, $dbfields, $datas, $options=array())
|
||||
{
|
||||
$ignore = '';
|
||||
if (isset($options['ignore']) and $options['ignore'])
|
||||
{
|
||||
$ignore = 'IGNORE';
|
||||
}
|
||||
|
||||
if (count($datas) != 0)
|
||||
{
|
||||
$first = true;
|
||||
|
||||
$query = 'SHOW VARIABLES LIKE \'max_allowed_packet\'';
|
||||
list(, $packet_size) = pwg_db_fetch_row(pwg_query($query));
|
||||
$packet_size = $packet_size - 2000; // The last list of values MUST not exceed 2000 character*/
|
||||
$query = '';
|
||||
|
||||
foreach ($datas as $insert)
|
||||
{
|
||||
if (strlen($query) >= $packet_size)
|
||||
{
|
||||
pwg_query($query);
|
||||
$first = true;
|
||||
}
|
||||
|
||||
if ($first)
|
||||
{
|
||||
$query = '
|
||||
INSERT '.$ignore.' INTO '.$table_name.'
|
||||
('.implode(',', $dbfields).')
|
||||
VALUES';
|
||||
$first = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$query .= '
|
||||
, ';
|
||||
}
|
||||
|
||||
$query .= '(';
|
||||
foreach ($dbfields as $field_id => $dbfield)
|
||||
{
|
||||
if ($field_id > 0)
|
||||
{
|
||||
$query .= ',';
|
||||
}
|
||||
|
||||
if (!isset($insert[$dbfield]) or $insert[$dbfield] === '')
|
||||
{
|
||||
$query .= 'NULL';
|
||||
}
|
||||
else
|
||||
{
|
||||
$query .= "'".$insert[$dbfield]."'";
|
||||
}
|
||||
}
|
||||
$query .= ')';
|
||||
}
|
||||
|
||||
pwg_query($query);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts one line in a table.
|
||||
*
|
||||
* @param string $table_name
|
||||
* @param array $data
|
||||
*/
|
||||
function single_insert($table_name, $data)
|
||||
{
|
||||
if (count($data) != 0)
|
||||
{
|
||||
$query = '
|
||||
INSERT INTO '.$table_name.'
|
||||
('.implode(',', array_keys($data)).')
|
||||
VALUES';
|
||||
|
||||
$query .= '(';
|
||||
$is_first = true;
|
||||
foreach ($data as $key => $value)
|
||||
{
|
||||
if (!$is_first)
|
||||
{
|
||||
$query .= ',';
|
||||
}
|
||||
else
|
||||
{
|
||||
$is_first = false;
|
||||
}
|
||||
|
||||
if ($value === '' || is_null($value))
|
||||
{
|
||||
$query .= 'NULL';
|
||||
}
|
||||
else
|
||||
{
|
||||
$query .= "'".$value."'";
|
||||
}
|
||||
}
|
||||
$query .= ')';
|
||||
|
||||
pwg_query($query);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Do maintenance on all Piwigo tables
|
||||
*/
|
||||
function do_maintenance_all_tables()
|
||||
{
|
||||
global $prefixeTable, $page;
|
||||
|
||||
$all_tables = array();
|
||||
|
||||
// List all tables
|
||||
$query = 'SHOW TABLES LIKE \''.$prefixeTable.'%\'';
|
||||
$result = pwg_query($query);
|
||||
while ($row = pwg_db_fetch_row($result))
|
||||
{
|
||||
$all_tables[] = $row[0];
|
||||
}
|
||||
|
||||
// Repair all tables
|
||||
$query = 'REPAIR TABLE '.implode(', ', $all_tables);
|
||||
$mysqli_rc = pwg_query($query);
|
||||
|
||||
// Re-Order all tables
|
||||
foreach ($all_tables as $table_name)
|
||||
{
|
||||
$all_primary_key = array();
|
||||
|
||||
$query = 'DESC '.$table_name.';';
|
||||
$result = pwg_query($query);
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
if ($row['Key'] == 'PRI')
|
||||
{
|
||||
$all_primary_key[] = $row['Field'];
|
||||
}
|
||||
}
|
||||
|
||||
if (count($all_primary_key) != 0)
|
||||
{
|
||||
$query = 'ALTER TABLE '.$table_name.' ORDER BY '.implode(', ', $all_primary_key).';';
|
||||
$mysqli_rc = $mysqli_rc && pwg_query($query);
|
||||
}
|
||||
}
|
||||
|
||||
// Optimize all tables
|
||||
$query = 'OPTIMIZE TABLE '.implode(', ', $all_tables);
|
||||
$mysqli_rc = $mysqli_rc && pwg_query($query);
|
||||
if ($mysqli_rc)
|
||||
{
|
||||
$page['infos'][] = l10n('All optimizations have been successfully completed.');
|
||||
}
|
||||
else
|
||||
{
|
||||
$page['errors'][] = l10n('Optimizations have been completed with some errors.');
|
||||
}
|
||||
}
|
||||
|
||||
function pwg_db_concat($array)
|
||||
{
|
||||
$string = implode($array, ',');
|
||||
return 'CONCAT('. $string.')';
|
||||
}
|
||||
|
||||
function pwg_db_concat_ws($array, $separator)
|
||||
{
|
||||
$string = implode($array, ',');
|
||||
return 'CONCAT_WS(\''.$separator.'\','. $string.')';
|
||||
}
|
||||
|
||||
function pwg_db_cast_to_text($string)
|
||||
{
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array containing the possible values of an enum field.
|
||||
*
|
||||
* @param string $table
|
||||
* @param string $field
|
||||
* @return string[]
|
||||
*/
|
||||
function get_enums($table, $field)
|
||||
{
|
||||
$result = pwg_query('DESC '.$table);
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
if ($row['Field'] == $field)
|
||||
{
|
||||
// parse enum('blue','green','black')
|
||||
$options = explode(',', substr($row['Type'], 5, -1));
|
||||
foreach ($options as $i => $option)
|
||||
{
|
||||
$options[$i] = str_replace("'", '',$option);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pwg_db_free_result($result);
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a variable is equivalent to true or false.
|
||||
*
|
||||
* @param mixed $input
|
||||
* @return bool
|
||||
*/
|
||||
function get_boolean($input)
|
||||
{
|
||||
if ('false' === strtolower($input))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return (bool)$input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns string 'true' or 'false' if the given var is boolean.
|
||||
* If the input is another type, it is not changed.
|
||||
*
|
||||
* @param mixed $var
|
||||
* @return mixed
|
||||
*/
|
||||
function boolean_to_string($var)
|
||||
{
|
||||
if (is_bool($var))
|
||||
{
|
||||
return $var ? 'true' : 'false';
|
||||
}
|
||||
else
|
||||
{
|
||||
return $var;
|
||||
}
|
||||
}
|
||||
|
||||
function pwg_db_get_recent_period_expression($period, $date='CURRENT_DATE')
|
||||
{
|
||||
if ($date!='CURRENT_DATE')
|
||||
{
|
||||
$date = '\''.$date.'\'';
|
||||
}
|
||||
|
||||
return 'SUBDATE('.$date.',INTERVAL '.$period.' DAY)';
|
||||
}
|
||||
|
||||
function pwg_db_get_recent_period($period, $date='CURRENT_DATE')
|
||||
{
|
||||
$query = '
|
||||
SELECT '.pwg_db_get_recent_period_expression($period);
|
||||
list($d) = pwg_db_fetch_row(pwg_query($query));
|
||||
|
||||
return $d;
|
||||
}
|
||||
|
||||
function pwg_db_get_flood_period_expression($seconds)
|
||||
{
|
||||
return 'SUBDATE(NOW(), INTERVAL '.$seconds.' SECOND)';
|
||||
}
|
||||
|
||||
function pwg_db_get_hour($date)
|
||||
{
|
||||
return 'HOUR('.$date.')';
|
||||
}
|
||||
|
||||
function pwg_db_get_date_YYYYMM($date)
|
||||
{
|
||||
return 'DATE_FORMAT('.$date.', \'%Y%m\')';
|
||||
}
|
||||
|
||||
function pwg_db_get_date_MMDD($date)
|
||||
{
|
||||
return 'DATE_FORMAT('.$date.', \'%m%d\')';
|
||||
}
|
||||
|
||||
function pwg_db_get_year($date)
|
||||
{
|
||||
return 'YEAR('.$date.')';
|
||||
}
|
||||
|
||||
function pwg_db_get_month($date)
|
||||
{
|
||||
return 'MONTH('.$date.')';
|
||||
}
|
||||
|
||||
function pwg_db_get_week($date, $mode=null)
|
||||
{
|
||||
if ($mode)
|
||||
{
|
||||
return 'WEEK('.$date.', '.$mode.')';
|
||||
}
|
||||
else
|
||||
{
|
||||
return 'WEEK('.$date.')';
|
||||
}
|
||||
}
|
||||
|
||||
function pwg_db_get_dayofmonth($date)
|
||||
{
|
||||
return 'DAYOFMONTH('.$date.')';
|
||||
}
|
||||
|
||||
function pwg_db_get_dayofweek($date)
|
||||
{
|
||||
return 'DAYOFWEEK('.$date.')';
|
||||
}
|
||||
|
||||
function pwg_db_get_weekday($date)
|
||||
{
|
||||
return 'WEEKDAY('.$date.')';
|
||||
}
|
||||
|
||||
function pwg_db_date_to_ts($date)
|
||||
{
|
||||
return 'UNIX_TIMESTAMP('.$date.')';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns (or send to standard output) the message concerning the
|
||||
* error occured for the last mysql query.
|
||||
*/
|
||||
function my_error($header, $die)
|
||||
{
|
||||
global $mysqli;
|
||||
|
||||
$error = "[mysql error ".$mysqli->errno.'] '.$mysqli->error."\n";
|
||||
$error .= $header;
|
||||
|
||||
if ($die)
|
||||
{
|
||||
fatal_error($error);
|
||||
}
|
||||
echo("<pre>");
|
||||
trigger_error($error, E_USER_WARNING);
|
||||
echo("</pre>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds an data array from a SQL query.
|
||||
* Depending on $key_name and $value_name it can return :
|
||||
*
|
||||
* - an array of arrays of all fields (key=null, value=null)
|
||||
* array(
|
||||
* array('id'=>1, 'name'=>'DSC8956', ...),
|
||||
* array('id'=>2, 'name'=>'DSC8957', ...),
|
||||
* ...
|
||||
* )
|
||||
*
|
||||
* - an array of a single field (key=null, value='...')
|
||||
* array('DSC8956', 'DSC8957', ...)
|
||||
*
|
||||
* - an associative array of array of all fields (key='...', value=null)
|
||||
* array(
|
||||
* 'DSC8956' => array('id'=>1, 'name'=>'DSC8956', ...),
|
||||
* 'DSC8957' => array('id'=>2, 'name'=>'DSC8957', ...),
|
||||
* ...
|
||||
* )
|
||||
*
|
||||
* - an associative array of a single field (key='...', value='...')
|
||||
* array(
|
||||
* 'DSC8956' => 1,
|
||||
* 'DSC8957' => 2,
|
||||
* ...
|
||||
* )
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param string $query
|
||||
* @param string $key_name
|
||||
* @param string $value_name
|
||||
* @return array
|
||||
*/
|
||||
function query2array($query, $key_name=null, $value_name=null)
|
||||
{
|
||||
$result = pwg_query($query);
|
||||
$data = array();
|
||||
|
||||
if (isset($key_name))
|
||||
{
|
||||
if (isset($value_name))
|
||||
{
|
||||
while ($row = $result->fetch_assoc())
|
||||
$data[ $row[$key_name] ] = $row[$value_name];
|
||||
}
|
||||
else
|
||||
{
|
||||
while ($row = $result->fetch_assoc())
|
||||
$data[ $row[$key_name] ] = $row;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isset($value_name))
|
||||
{
|
||||
while ($row = $result->fetch_assoc())
|
||||
$data[] = $row[$value_name];
|
||||
}
|
||||
else
|
||||
{
|
||||
while ($row = $result->fetch_assoc())
|
||||
$data[] = $row;
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
?>
|
||||
539
zoesch.de/galerie/include/derivative.inc.php
Normal file
539
zoesch.de/galerie/include/derivative.inc.php
Normal file
@@ -0,0 +1,539 @@
|
||||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Piwigo - a PHP based photo gallery |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright(C) 2008-2016 Piwigo Team http://piwigo.org |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
* @package Derivatives
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* A source image is used to get a derivative image. It is either
|
||||
* the original file for a jpg/png/... or a 'representative' image
|
||||
* of a non image file or a standard icon for the non-image file.
|
||||
*/
|
||||
final class SrcImage
|
||||
{
|
||||
const IS_ORIGINAL = 0x01;
|
||||
const IS_MIMETYPE = 0x02;
|
||||
const DIM_NOT_GIVEN = 0x04;
|
||||
|
||||
/** @var int */
|
||||
public $id;
|
||||
/** @var string */
|
||||
public $rel_path;
|
||||
/** @var int */
|
||||
public $rotation = 0;
|
||||
/** @var int[] */
|
||||
private $size=null;
|
||||
/** @var int */
|
||||
private $flags=0;
|
||||
|
||||
/**
|
||||
* @param array $infos assoc array of data from images table
|
||||
*/
|
||||
function __construct($infos)
|
||||
{
|
||||
global $conf;
|
||||
|
||||
$this->id = $infos['id'];
|
||||
$ext = strtolower(get_extension($infos['path']));
|
||||
if (in_array($ext, $conf['picture_ext']))
|
||||
{
|
||||
$this->rel_path = $infos['path'];
|
||||
$this->flags |= self::IS_ORIGINAL;
|
||||
}
|
||||
elseif (!empty($infos['representative_ext']))
|
||||
{
|
||||
$this->rel_path = original_to_representative($infos['path'], $infos['representative_ext']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->rel_path = trigger_change('get_mimetype_location', get_themeconf('mime_icon_dir').$ext.'.png', $ext );
|
||||
$this->flags |= self::IS_MIMETYPE;
|
||||
if ( ($size=@getimagesize(PHPWG_ROOT_PATH.$this->rel_path)) === false)
|
||||
{
|
||||
$this->rel_path = 'themes/default/icon/mimetypes/unknown.png';
|
||||
$size = getimagesize(PHPWG_ROOT_PATH.$this->rel_path);
|
||||
}
|
||||
$this->size = array($size[0],$size[1]);
|
||||
}
|
||||
|
||||
if (!$this->size)
|
||||
{
|
||||
if (isset($infos['width']) && isset($infos['height']))
|
||||
{
|
||||
$width = $infos['width'];
|
||||
$height = $infos['height'];
|
||||
|
||||
$this->rotation = intval($infos['rotation']) % 4;
|
||||
// 1 or 5 => 90 clockwise
|
||||
// 3 or 7 => 270 clockwise
|
||||
if ($this->rotation % 2)
|
||||
{
|
||||
$width = $infos['height'];
|
||||
$height = $infos['width'];
|
||||
}
|
||||
|
||||
$this->size = array($width, $height);
|
||||
}
|
||||
elseif (!array_key_exists('width', $infos))
|
||||
{
|
||||
$this->flags |= self::DIM_NOT_GIVEN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
function is_original()
|
||||
{
|
||||
return $this->flags & self::IS_ORIGINAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
function is_mimetype()
|
||||
{
|
||||
return $this->flags & self::IS_MIMETYPE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
function get_path()
|
||||
{
|
||||
return PHPWG_ROOT_PATH.$this->rel_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
function get_url()
|
||||
{
|
||||
$url = get_root_url().$this->rel_path;
|
||||
if ( !($this->flags & self::IS_MIMETYPE) )
|
||||
{
|
||||
$url = trigger_change('get_src_image_url', $url, $this);
|
||||
}
|
||||
return embellish_url($url);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
function has_size()
|
||||
{
|
||||
return $this->size != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int[]|null 0=width, 1=height or null if fail to compute size
|
||||
*/
|
||||
function get_size()
|
||||
{
|
||||
if ($this->size == null)
|
||||
{
|
||||
if ($this->flags & self::DIM_NOT_GIVEN)
|
||||
fatal_error('SrcImage dimensions required but not provided');
|
||||
// probably not metadata synced
|
||||
if ( ($size = getimagesize( $this->get_path() )) !== false)
|
||||
{
|
||||
$this->size = array($size[0],$size[1]);
|
||||
pwg_query('UPDATE '.IMAGES_TABLE.' SET width='.$size[0].', height='.$size[1].' WHERE id='.$this->id);
|
||||
}
|
||||
}
|
||||
return $this->size;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Holds information (path, url, dimensions) about a derivative image.
|
||||
* A derivative image is constructed from a source image (SrcImage class)
|
||||
* and derivative parameters (DerivativeParams class).
|
||||
*/
|
||||
final class DerivativeImage
|
||||
{
|
||||
/** @var SrcImage */
|
||||
public $src_image;
|
||||
/** @var array */
|
||||
private $params;
|
||||
/** @var string */
|
||||
private $rel_path;
|
||||
/** @var string */
|
||||
private $rel_url;
|
||||
/** @var bool */
|
||||
private $is_cached=true;
|
||||
|
||||
/**
|
||||
* @param string|DerivativeParams $type standard derivative param type (e.g. IMG_*)
|
||||
* or a DerivativeParams object
|
||||
* @param SrcImage $src_image the source image of this derivative
|
||||
*/
|
||||
function __construct($type, SrcImage $src_image)
|
||||
{
|
||||
$this->src_image = $src_image;
|
||||
if (is_string($type))
|
||||
{
|
||||
$this->params = ImageStdParams::get_by_type($type);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->params = $type;
|
||||
}
|
||||
|
||||
self::build($src_image, $this->params, $this->rel_path, $this->rel_url, $this->is_cached);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the url of a thumbnail.
|
||||
*
|
||||
* @param array|SrcImage $infos array of info from db or SrcImage
|
||||
* @return string
|
||||
*/
|
||||
static function thumb_url($infos)
|
||||
{
|
||||
return self::url(IMG_THUMB, $infos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the url for a particular photo size.
|
||||
*
|
||||
* @param string|DerivativeParams $type standard derivative param type (e.g. IMG_*)
|
||||
* or a DerivativeParams object
|
||||
* @param array|SrcImage $infos array of info from db or SrcImage
|
||||
* @return string
|
||||
*/
|
||||
static function url($type, $infos)
|
||||
{
|
||||
$src_image = is_object($infos) ? $infos : new SrcImage($infos);
|
||||
$params = is_string($type) ? ImageStdParams::get_by_type($type) : $type;
|
||||
self::build($src_image, $params, $rel_path, $rel_url);
|
||||
if ($params == null)
|
||||
{
|
||||
return $src_image->get_url();
|
||||
}
|
||||
return embellish_url(
|
||||
trigger_change('get_derivative_url',
|
||||
get_root_url().$rel_url,
|
||||
$params, $src_image, $rel_url
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return associative an array of all DerivativeImage for a specific image.
|
||||
* Disabled derivative types can be still found in the return, mapped to an
|
||||
* enabled derivative (e.g. the values are not unique in the return array).
|
||||
* This is useful for any plugin/theme to just use $deriv[IMG_XLARGE] even if
|
||||
* the XLARGE is disabled.
|
||||
*
|
||||
* @param array|SrcImage $src_image array of info from db or SrcImage
|
||||
* @return DerivativeImage[]
|
||||
*/
|
||||
static function get_all($src_image)
|
||||
{
|
||||
if (!is_object($src_image))
|
||||
{
|
||||
$src_image = new SrcImage($src_image);
|
||||
}
|
||||
|
||||
$ret = array();
|
||||
// build enabled types
|
||||
foreach (ImageStdParams::get_defined_type_map() as $type => $params)
|
||||
{
|
||||
$derivative = new DerivativeImage($params, $src_image);
|
||||
$ret[$type] = $derivative;
|
||||
}
|
||||
// disabled types, fallback to enabled types
|
||||
foreach (ImageStdParams::get_undefined_type_map() as $type => $type2)
|
||||
{
|
||||
$ret[$type] = $ret[$type2];
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an instance of DerivativeImage for a specific image and size.
|
||||
* Disabled derivatives fallback to an enabled derivative.
|
||||
*
|
||||
* @param string $type standard derivative param type (e.g. IMG_*)
|
||||
* @param array|SrcImage $src_image array of info from db or SrcImage
|
||||
* @return DerivativeImage|null null if $type not found
|
||||
*/
|
||||
static function get_one($type, $src_image)
|
||||
{
|
||||
if (!is_object($src_image))
|
||||
{
|
||||
$src_image = new SrcImage($src_image);
|
||||
}
|
||||
|
||||
$defined = ImageStdParams::get_defined_type_map();
|
||||
if (isset($defined[$type]))
|
||||
{
|
||||
return new DerivativeImage($defined[$type], $src_image);
|
||||
}
|
||||
|
||||
$undefined = ImageStdParams::get_undefined_type_map();
|
||||
if (isset($undefined[$type]))
|
||||
{
|
||||
return new DerivativeImage($defined[ $undefined[$type] ], $src_image);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo : documentation of DerivativeImage::build
|
||||
*/
|
||||
private static function build($src, &$params, &$rel_path, &$rel_url, &$is_cached=null)
|
||||
{
|
||||
if ( $src->has_size() && $params->is_identity( $src->get_size() ) )
|
||||
{// the source image is smaller than what we should do - we do not upsample
|
||||
if (!$params->will_watermark($src->get_size()) && !$src->rotation)
|
||||
{// no watermark, no rotation required -> we will use the source image
|
||||
$params = null;
|
||||
$rel_path = $rel_url = $src->rel_path;
|
||||
return;
|
||||
}
|
||||
$defined_types = array_keys(ImageStdParams::get_defined_type_map());
|
||||
for ($i=0; $i<count($defined_types); $i++)
|
||||
{
|
||||
if ($defined_types[$i] == $params->type)
|
||||
{
|
||||
for ($i--; $i>=0; $i--)
|
||||
{
|
||||
$smaller = ImageStdParams::get_by_type($defined_types[$i]);
|
||||
if ($smaller->sizing->max_crop==$params->sizing->max_crop && $smaller->is_identity( $src->get_size() ))
|
||||
{
|
||||
$params = $smaller;
|
||||
self::build($src, $params, $rel_path, $rel_url, $is_cached);
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$tokens=array();
|
||||
$tokens[] = substr($params->type,0,2);
|
||||
|
||||
if ($params->type==IMG_CUSTOM)
|
||||
{
|
||||
$params->add_url_tokens($tokens);
|
||||
}
|
||||
|
||||
$loc = $src->rel_path;
|
||||
if (substr_compare($loc, './', 0, 2)==0)
|
||||
{
|
||||
$loc = substr($loc, 2);
|
||||
}
|
||||
elseif (substr_compare($loc, '../', 0, 3)==0)
|
||||
{
|
||||
$loc = substr($loc, 3);
|
||||
}
|
||||
$loc = substr_replace($loc, '-'.implode('_', $tokens), strrpos($loc, '.'), 0 );
|
||||
|
||||
$rel_path = PWG_DERIVATIVE_DIR.$loc;
|
||||
|
||||
global $conf;
|
||||
$url_style=$conf['derivative_url_style'];
|
||||
if (!$url_style)
|
||||
{
|
||||
$mtime = @filemtime(PHPWG_ROOT_PATH.$rel_path);
|
||||
if ($mtime===false or $mtime < $params->last_mod_time)
|
||||
{
|
||||
$is_cached = false;
|
||||
$url_style = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
$url_style = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ($url_style == 2)
|
||||
{
|
||||
$rel_url = 'i';
|
||||
if ($conf['php_extension_in_urls']) $rel_url .= '.php';
|
||||
if ($conf['question_mark_in_urls']) $rel_url .= '?';
|
||||
$rel_url .= '/'.$loc;
|
||||
}
|
||||
else
|
||||
{
|
||||
$rel_url = $rel_path;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
function get_path()
|
||||
{
|
||||
return PHPWG_ROOT_PATH.$this->rel_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
function get_url()
|
||||
{
|
||||
if ($this->params == null)
|
||||
{
|
||||
return $this->src_image->get_url();
|
||||
}
|
||||
return embellish_url(
|
||||
trigger_change('get_derivative_url',
|
||||
get_root_url().$this->rel_url,
|
||||
$this->params, $this->src_image, $this->rel_url
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
function same_as_source()
|
||||
{
|
||||
return $this->params == null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string one if IMG_* or 'Original'
|
||||
*/
|
||||
function get_type()
|
||||
{
|
||||
if ($this->params == null)
|
||||
return 'Original';
|
||||
return $this->params->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int[]
|
||||
*/
|
||||
function get_size()
|
||||
{
|
||||
if ($this->params == null)
|
||||
{
|
||||
return $this->src_image->get_size();
|
||||
}
|
||||
return $this->params->compute_final_size($this->src_image->get_size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size as CSS rule.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function get_size_css()
|
||||
{
|
||||
$size = $this->get_size();
|
||||
if ($size)
|
||||
{
|
||||
return 'width:'.$size[0].'px; height:'.$size[1].'px';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size as HTML attributes.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function get_size_htm()
|
||||
{
|
||||
$size = $this->get_size();
|
||||
if ($size)
|
||||
{
|
||||
return 'width="'.$size[0].'" height="'.$size[1].'"';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns literal size: $widthx$height.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function get_size_hr()
|
||||
{
|
||||
$size = $this->get_size();
|
||||
if ($size)
|
||||
{
|
||||
return $size[0].' x '.$size[1];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $maxw
|
||||
* @param int $mawh
|
||||
* @return int[]
|
||||
*/
|
||||
function get_scaled_size($maxw, $maxh)
|
||||
{
|
||||
$size = $this->get_size();
|
||||
if ($size)
|
||||
{
|
||||
$ratio_w = $size[0] / $maxw;
|
||||
$ratio_h = $size[1] / $maxh;
|
||||
if ($ratio_w>1 || $ratio_h>1)
|
||||
{
|
||||
if ($ratio_w > $ratio_h)
|
||||
{
|
||||
$size[0] = $maxw;
|
||||
$size[1] = floor($size[1] / $ratio_w);
|
||||
}
|
||||
else
|
||||
{
|
||||
$size[0] = floor($size[0] / $ratio_h);
|
||||
$size[1] = $maxh;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the scaled size as HTML attributes.
|
||||
*
|
||||
* @param int $maxw
|
||||
* @param int $mawh
|
||||
* @return string
|
||||
*/
|
||||
function get_scaled_size_htm($maxw=9999, $maxh=9999)
|
||||
{
|
||||
$size = $this->get_scaled_size($maxw, $maxh);
|
||||
if ($size)
|
||||
{
|
||||
return 'width="'.$size[0].'" height="'.$size[1].'"';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
function is_cached()
|
||||
{
|
||||
return $this->is_cached;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
436
zoesch.de/galerie/include/derivative_params.inc.php
Normal file
436
zoesch.de/galerie/include/derivative_params.inc.php
Normal file
@@ -0,0 +1,436 @@
|
||||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Piwigo - a PHP based photo gallery |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright(C) 2008-2016 Piwigo Team http://piwigo.org |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
* @package Derivatives
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Formats a size name into a 2 chars identifier usable in filename.
|
||||
*
|
||||
* @param string $t one of IMG_*
|
||||
* @return string
|
||||
*/
|
||||
function derivative_to_url($t)
|
||||
{
|
||||
return substr($t, 0, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a size array into a identifier usable in filename.
|
||||
*
|
||||
* @param int[] $s
|
||||
* @return string
|
||||
*/
|
||||
function size_to_url($s)
|
||||
{
|
||||
if ($s[0]==$s[1])
|
||||
{
|
||||
return $s[0];
|
||||
}
|
||||
return $s[0].'x'.$s[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int[] $s1
|
||||
* @param int[] $s2
|
||||
* @return bool
|
||||
*/
|
||||
function size_equals($s1, $s2)
|
||||
{
|
||||
return ($s1[0]==$s2[0] && $s1[1]==$s2[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a char a-z into a float.
|
||||
*
|
||||
* @param string
|
||||
* @return float
|
||||
*/
|
||||
function char_to_fraction($c)
|
||||
{
|
||||
return (ord($c) - ord('a'))/25;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a float into a char a-z.
|
||||
*
|
||||
* @param float
|
||||
* @return string
|
||||
*/
|
||||
function fraction_to_char($f)
|
||||
{
|
||||
return chr(ord('a') + round($f*25));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Small utility to manipulate a 'rectangle'.
|
||||
*/
|
||||
final class ImageRect
|
||||
{
|
||||
/**
|
||||
* @var int $l
|
||||
* @var int $t
|
||||
* @var int $r
|
||||
* @var int $b
|
||||
*/
|
||||
public $l,$t,$r,$b;
|
||||
|
||||
/**
|
||||
* @param int[] $l width and height
|
||||
*/
|
||||
function __construct($l)
|
||||
{
|
||||
$this->l = $this->t = 0;
|
||||
$this->r = $l[0];
|
||||
$this->b = $l[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
function width()
|
||||
{
|
||||
return $this->r - $this->l;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
function height()
|
||||
{
|
||||
return $this->b - $this->t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Crops horizontally this rectangle by increasing left side and/or reducing the right side.
|
||||
*
|
||||
* @param int $pixels - the amount to substract from the width
|
||||
* @param stirng $coi - a 4 character string (or null) containing the center of interest
|
||||
*/
|
||||
function crop_h($pixels, $coi)
|
||||
{
|
||||
if ($this->width() <= $pixels)
|
||||
return;
|
||||
$tlcrop = floor($pixels/2);
|
||||
|
||||
if (!empty($coi))
|
||||
{
|
||||
$coil = floor($this->r * char_to_fraction($coi[0]));
|
||||
$coir = ceil($this->r * char_to_fraction($coi[2]));
|
||||
$availableL = $coil > $this->l ? $coil - $this->l : 0;
|
||||
$availableR = $coir < $this->r ? $this->r - $coir : 0;
|
||||
if ($availableL + $availableR >= $pixels)
|
||||
{
|
||||
if ($availableL < $tlcrop)
|
||||
{
|
||||
$tlcrop = $availableL;
|
||||
}
|
||||
elseif ($availableR < $tlcrop)
|
||||
{
|
||||
$tlcrop = $pixels - $availableR;
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->l += $tlcrop;
|
||||
$this->r -= $pixels - $tlcrop;
|
||||
}
|
||||
|
||||
/**
|
||||
* Crops vertically this rectangle by increasing top side and/or reducing the bottom side.
|
||||
*
|
||||
* @param int $pixels - the amount to substract from the height
|
||||
* @param string $coi - a 4 character string (or null) containing the center of interest
|
||||
*/
|
||||
function crop_v($pixels, $coi)
|
||||
{
|
||||
if ($this->height() <= $pixels)
|
||||
return;
|
||||
$tlcrop = floor($pixels/2);
|
||||
|
||||
if (!empty($coi))
|
||||
{
|
||||
$coit = floor($this->b * char_to_fraction($coi[1]));
|
||||
$coib = ceil($this->b * char_to_fraction($coi[3]));
|
||||
$availableT = $coit > $this->t ? $coit - $this->t : 0;
|
||||
$availableB = $coib < $this->b ? $this->b - $coib : 0;
|
||||
if ($availableT + $availableB >= $pixels)
|
||||
{
|
||||
if ($availableT < $tlcrop)
|
||||
{
|
||||
$tlcrop = $availableT;
|
||||
}
|
||||
elseif ($availableB < $tlcrop)
|
||||
{
|
||||
$tlcrop = $pixels - $availableB;
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->t += $tlcrop;
|
||||
$this->b -= $pixels - $tlcrop;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Paramaters for derivative scaling and cropping.
|
||||
* Instance of this class contained by DerivativeParams class.
|
||||
*/
|
||||
final class SizingParams
|
||||
{
|
||||
/** @var int[] */
|
||||
var $ideal_size;
|
||||
/** @var float */
|
||||
var $max_crop;
|
||||
/** @var int[] */
|
||||
var $min_size;
|
||||
|
||||
/**
|
||||
* @param int[] $ideal_size - two element array of maximum output dimensions (width, height)
|
||||
* @param float $max_crop - from 0=no cropping to 1= max cropping (100% of width/height);
|
||||
* expressed as a factor of the input width/height
|
||||
* @param int[] $min_size - (used only if _$max_crop_ !=0) two element array of output dimensions (width, height)
|
||||
*/
|
||||
function __construct($ideal_size, $max_crop=0, $min_size=null)
|
||||
{
|
||||
$this->ideal_size = $ideal_size;
|
||||
$this->max_crop = $max_crop;
|
||||
$this->min_size = $min_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a simple SizingParams object.
|
||||
*
|
||||
* @param int $w
|
||||
* @param int $h
|
||||
* @return SizingParams
|
||||
*/
|
||||
static function classic($w, $h)
|
||||
{
|
||||
return new SizingParams( array($w,$h) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a square SizingParams object.
|
||||
*
|
||||
* @param int $x
|
||||
* @return SizingParams
|
||||
*/
|
||||
static function square($w)
|
||||
{
|
||||
return new SizingParams( array($w,$w), 1, array($w,$w) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds tokens depending on sizing configuration.
|
||||
*
|
||||
* @param array &$tokens
|
||||
*/
|
||||
function add_url_tokens(&$tokens)
|
||||
{
|
||||
if ($this->max_crop == 0)
|
||||
{
|
||||
$tokens[] = 's'.size_to_url($this->ideal_size);
|
||||
}
|
||||
elseif ($this->max_crop == 1 && size_equals($this->ideal_size, $this->min_size) )
|
||||
{
|
||||
$tokens[] = 'e'.size_to_url($this->ideal_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
$tokens[] = size_to_url($this->ideal_size);
|
||||
$tokens[] = fraction_to_char($this->max_crop);
|
||||
$tokens[] = size_to_url($this->min_size);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the cropping rectangle and the scaled size for an input image size.
|
||||
*
|
||||
* @param int[] $in_size - two element array of input dimensions (width, height)
|
||||
* @param string $coi - four character encoded string containing the center of interest (unused if max_crop=0)
|
||||
* @param ImageRect &$crop_rect - ImageRect containing the cropping rectangle or null if cropping is not required
|
||||
* @param int[] &$scale_size - two element array containing width and height of the scaled image
|
||||
*/
|
||||
function compute($in_size, $coi, &$crop_rect, &$scale_size)
|
||||
{
|
||||
$destCrop = new ImageRect($in_size);
|
||||
|
||||
if ($this->max_crop > 0)
|
||||
{
|
||||
$ratio_w = $destCrop->width() / $this->ideal_size[0];
|
||||
$ratio_h = $destCrop->height() / $this->ideal_size[1];
|
||||
if ($ratio_w>1 || $ratio_h>1)
|
||||
{
|
||||
if ($ratio_w > $ratio_h)
|
||||
{
|
||||
$h = $destCrop->height() / $ratio_w;
|
||||
if ($h < $this->min_size[1])
|
||||
{
|
||||
$idealCropPx = $destCrop->width() - floor($destCrop->height() * $this->ideal_size[0] / $this->min_size[1]);
|
||||
$maxCropPx = round($this->max_crop * $destCrop->width());
|
||||
$destCrop->crop_h( min($idealCropPx, $maxCropPx), $coi);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$w = $destCrop->width() / $ratio_h;
|
||||
if ($w < $this->min_size[0])
|
||||
{
|
||||
$idealCropPx = $destCrop->height() - floor($destCrop->width() * $this->ideal_size[1] / $this->min_size[0]);
|
||||
$maxCropPx = round($this->max_crop * $destCrop->height());
|
||||
$destCrop->crop_v( min($idealCropPx, $maxCropPx), $coi);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$scale_size = array($destCrop->width(), $destCrop->height());
|
||||
|
||||
$ratio_w = $destCrop->width() / $this->ideal_size[0];
|
||||
$ratio_h = $destCrop->height() / $this->ideal_size[1];
|
||||
if ($ratio_w>1 || $ratio_h>1)
|
||||
{
|
||||
if ($ratio_w > $ratio_h)
|
||||
{
|
||||
$scale_size[0] = $this->ideal_size[0];
|
||||
$scale_size[1] = floor(1e-6 + $scale_size[1] / $ratio_w);
|
||||
}
|
||||
else
|
||||
{
|
||||
$scale_size[0] = floor(1e-6 + $scale_size[0] / $ratio_h);
|
||||
$scale_size[1] = $this->ideal_size[1];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$scale_size = null;
|
||||
}
|
||||
|
||||
$crop_rect = null;
|
||||
if ($destCrop->width()!=$in_size[0] || $destCrop->height()!=$in_size[1] )
|
||||
{
|
||||
$crop_rect = $destCrop;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* All needed parameters to generate a derivative image.
|
||||
*/
|
||||
final class DerivativeParams
|
||||
{
|
||||
/** @var SizingParams */
|
||||
public $sizing;
|
||||
/** @var string among IMG_* */
|
||||
public $type = IMG_CUSTOM;
|
||||
/** @var int used for non-custom images to regenerate the cached files */
|
||||
public $last_mod_time = 0;
|
||||
/** @var bool */
|
||||
public $use_watermark = false;
|
||||
/** @var float from 0=no sharpening to 1=max sharpening */
|
||||
public $sharpen = 0;
|
||||
|
||||
/**
|
||||
* @param SizingParams $sizing
|
||||
*/
|
||||
function __construct($sizing)
|
||||
{
|
||||
$this->sizing = $sizing;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function __sleep()
|
||||
{
|
||||
return array('last_mod_time', 'sizing', 'sharpen');
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds tokens depending on sizing configuration.
|
||||
*
|
||||
* @param array &$tokens
|
||||
*/
|
||||
function add_url_tokens(&$tokens)
|
||||
{
|
||||
$this->sizing->add_url_tokens($tokens);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int[]
|
||||
*/
|
||||
function compute_final_size($in_size)
|
||||
{
|
||||
$this->sizing->compute( $in_size, null, $crop_rect, $scale_size );
|
||||
return $scale_size != null ? $scale_size : $in_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
function max_width()
|
||||
{
|
||||
return $this->sizing->ideal_size[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
function max_height()
|
||||
{
|
||||
return $this->sizing->ideal_size[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo : description of DerivativeParams::is_identity
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function is_identity($in_size)
|
||||
{
|
||||
if ($in_size[0] > $this->sizing->ideal_size[0] or
|
||||
$in_size[1] > $this->sizing->ideal_size[1] )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
function will_watermark($out_size)
|
||||
{
|
||||
if ($this->use_watermark)
|
||||
{
|
||||
$min_size = ImageStdParams::get_watermark()->min_size;
|
||||
return $min_size[0]<=$out_size[0]
|
||||
|| $min_size[1]<=$out_size[1];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
283
zoesch.de/galerie/include/derivative_std_params.inc.php
Normal file
283
zoesch.de/galerie/include/derivative_std_params.inc.php
Normal file
@@ -0,0 +1,283 @@
|
||||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Piwigo - a PHP based photo gallery |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright(C) 2008-2016 Piwigo Team http://piwigo.org |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
* @package Derivatives
|
||||
*/
|
||||
|
||||
|
||||
define('IMG_SQUARE', 'square');
|
||||
define('IMG_THUMB', 'thumb');
|
||||
define('IMG_XXSMALL', '2small');
|
||||
define('IMG_XSMALL', 'xsmall');
|
||||
define('IMG_SMALL', 'small');
|
||||
define('IMG_MEDIUM', 'medium');
|
||||
define('IMG_LARGE', 'large');
|
||||
define('IMG_XLARGE', 'xlarge');
|
||||
define('IMG_XXLARGE', 'xxlarge');
|
||||
define('IMG_CUSTOM', 'custom');
|
||||
|
||||
|
||||
/**
|
||||
* Container for watermark configuration.
|
||||
*/
|
||||
final class WatermarkParams
|
||||
{
|
||||
/** @var string */
|
||||
public $file = '';
|
||||
/** @var int[] */
|
||||
public $min_size = array(500,500);
|
||||
/** @var int */
|
||||
public $xpos = 50;
|
||||
/** @var int */
|
||||
public $ypos = 50;
|
||||
/** @var int */
|
||||
public $xrepeat = 0;
|
||||
/** @var int */
|
||||
public $yrepeat = 0;
|
||||
/** @var int */
|
||||
public $opacity = 100;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Container for standard derivatives parameters.
|
||||
*/
|
||||
final class ImageStdParams
|
||||
{
|
||||
/** @var string[] */
|
||||
private static $all_types = array(
|
||||
IMG_SQUARE, IMG_THUMB, IMG_XXSMALL, IMG_XSMALL, IMG_SMALL,
|
||||
IMG_MEDIUM, IMG_LARGE, IMG_XLARGE, IMG_XXLARGE
|
||||
);
|
||||
/** @var DerivativeParams[] */
|
||||
private static $all_type_map = array();
|
||||
/** @var DerivativeParams[] */
|
||||
private static $type_map = array();
|
||||
/** @var DerivativeParams[] */
|
||||
private static $undefined_type_map = array();
|
||||
/** @var WatermarkParams */
|
||||
private static $watermark;
|
||||
/** @var array */
|
||||
public static $custom = array();
|
||||
/** @var int */
|
||||
public static $quality=95;
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
static function get_all_types()
|
||||
{
|
||||
return self::$all_types;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return DerivativeParams[]
|
||||
*/
|
||||
static function get_all_type_map()
|
||||
{
|
||||
return self::$all_type_map;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return DerivativeParams[]
|
||||
*/
|
||||
static function get_defined_type_map()
|
||||
{
|
||||
return self::$type_map;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return DerivativeParams[]
|
||||
*/
|
||||
static function get_undefined_type_map()
|
||||
{
|
||||
return self::$undefined_type_map;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return DerivativeParams
|
||||
*/
|
||||
static function get_by_type($type)
|
||||
{
|
||||
return self::$all_type_map[$type];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $w
|
||||
* @param int $h
|
||||
* @param float $crop
|
||||
* @param int $minw
|
||||
* @param int $minh
|
||||
* @return DerivativeParams
|
||||
*/
|
||||
static function get_custom($w, $h, $crop=0, $minw=null, $minh=null)
|
||||
{
|
||||
$params = new DerivativeParams( new SizingParams( array($w,$h), $crop, array($minw,$minh)) );
|
||||
self::apply_global($params);
|
||||
|
||||
$key = array();
|
||||
$params->add_url_tokens($key);
|
||||
$key = implode('_',$key);
|
||||
if ( @self::$custom[$key] < time() - 24*3600)
|
||||
{
|
||||
self::$custom[$key] = time();
|
||||
self::save();
|
||||
}
|
||||
return $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WatermarkParams
|
||||
*/
|
||||
static function get_watermark()
|
||||
{
|
||||
return self::$watermark;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads derivative configuration from database or initializes it.
|
||||
*/
|
||||
static function load_from_db()
|
||||
{
|
||||
global $conf;
|
||||
$arr = @unserialize($conf['derivatives']);
|
||||
if (false!==$arr)
|
||||
{
|
||||
self::$type_map = $arr['d'];
|
||||
self::$watermark = @$arr['w'];
|
||||
if (!self::$watermark) self::$watermark = new WatermarkParams();
|
||||
self::$custom = @$arr['c'];
|
||||
if (!self::$custom) self::$custom = array();
|
||||
if (isset($arr['q'])) self::$quality = $arr['q'];
|
||||
}
|
||||
else
|
||||
{
|
||||
self::$watermark = new WatermarkParams();
|
||||
self::$type_map = self::get_default_sizes();
|
||||
self::save();
|
||||
}
|
||||
self::build_maps();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WatermarkParams $watermark
|
||||
*/
|
||||
static function set_watermark($watermark)
|
||||
{
|
||||
self::$watermark = $watermark;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ImageStdParams::save()
|
||||
*
|
||||
* @param DerivativeParams[] $map
|
||||
*/
|
||||
static function set_and_save($map)
|
||||
{
|
||||
self::$type_map = $map;
|
||||
self::save();
|
||||
self::build_maps();
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the configuration in database.
|
||||
*/
|
||||
static function save()
|
||||
{
|
||||
$ser = serialize( array(
|
||||
'd' => self::$type_map,
|
||||
'q' => self::$quality,
|
||||
'w' => self::$watermark,
|
||||
'c' => self::$custom,
|
||||
) );
|
||||
conf_update_param('derivatives', addslashes($ser) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return DerivativeParams[]
|
||||
*/
|
||||
static function get_default_sizes()
|
||||
{
|
||||
$arr = array(
|
||||
IMG_SQUARE => new DerivativeParams( SizingParams::square(120,120) ),
|
||||
IMG_THUMB => new DerivativeParams( SizingParams::classic(144,144) ),
|
||||
IMG_XXSMALL => new DerivativeParams( SizingParams::classic(240,240) ),
|
||||
IMG_XSMALL => new DerivativeParams( SizingParams::classic(432,324) ),
|
||||
IMG_SMALL => new DerivativeParams( SizingParams::classic(576,432) ),
|
||||
IMG_MEDIUM => new DerivativeParams( SizingParams::classic(792,594) ),
|
||||
IMG_LARGE => new DerivativeParams( SizingParams::classic(1008,756) ),
|
||||
IMG_XLARGE => new DerivativeParams( SizingParams::classic(1224,918) ),
|
||||
IMG_XXLARGE => new DerivativeParams( SizingParams::classic(1656,1242) ),
|
||||
);
|
||||
$now = time();
|
||||
foreach($arr as $params)
|
||||
{
|
||||
$params->last_mod_time = $now;
|
||||
}
|
||||
return $arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute 'apply_watermark'
|
||||
*
|
||||
* @param DerivativeParams $params
|
||||
*/
|
||||
static function apply_global($params)
|
||||
{
|
||||
$params->use_watermark = !empty(self::$watermark->file) &&
|
||||
(self::$watermark->min_size[0]<=$params->sizing->ideal_size[0]
|
||||
or self::$watermark->min_size[1]<=$params->sizing->ideal_size[1] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Build 'type_map', 'all_type_map' and 'undefined_type_map'.
|
||||
*/
|
||||
private static function build_maps()
|
||||
{
|
||||
foreach (self::$type_map as $type=>$params)
|
||||
{
|
||||
$params->type = $type;
|
||||
self::apply_global($params);
|
||||
}
|
||||
self::$all_type_map = self::$type_map;
|
||||
|
||||
for ($i=0; $i<count(self::$all_types); $i++)
|
||||
{
|
||||
$tocheck = self::$all_types[$i];
|
||||
if (!isset(self::$type_map[$tocheck]))
|
||||
{
|
||||
for ($j=$i-1; $j>=0; $j--)
|
||||
{
|
||||
$target = self::$all_types[$j];
|
||||
if (isset(self::$type_map[$target]))
|
||||
{
|
||||
self::$all_type_map[$tocheck] = self::$type_map[$target];
|
||||
self::$undefined_type_map[$tocheck] = $target;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
682
zoesch.de/galerie/include/emogrifier.class.php
Normal file
682
zoesch.de/galerie/include/emogrifier.class.php
Normal file
@@ -0,0 +1,682 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This class provides functions for converting CSS styles into inline style attributes in your HTML code.
|
||||
*
|
||||
* For more information, please see the README.md file.
|
||||
*
|
||||
* @author Cameron Brooks
|
||||
* @author Jaime Prado
|
||||
*/
|
||||
class Emogrifier {
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
const ENCODING = 'UTF-8';
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*/
|
||||
const CACHE_KEY_CSS = 0;
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*/
|
||||
const CACHE_KEY_SELECTOR = 1;
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*/
|
||||
const CACHE_KEY_XPATH = 2;
|
||||
|
||||
/**
|
||||
* for calculating nth-of-type and nth-child selectors
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
const INDEX = 0;
|
||||
|
||||
/**
|
||||
* for calculating nth-of-type and nth-child selectors
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
const MULTIPLIER = 1;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
const ID_ATTRIBUTE_MATCHER = '/(\\w+)?\\#([\\w\\-]+)/';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
const CLASS_ATTRIBUTE_MATCHER = '/(\\w+|[\\*\\]])?((\\.[\\w\\-]+)+)/';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $html = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $css = '';
|
||||
|
||||
/**
|
||||
* @var array<string>
|
||||
*/
|
||||
private $unprocessableHtmlTags = array('wbr');
|
||||
|
||||
/**
|
||||
* @var array<array>
|
||||
*/
|
||||
private $caches = array(
|
||||
self::CACHE_KEY_CSS => array(),
|
||||
self::CACHE_KEY_SELECTOR => array(),
|
||||
self::CACHE_KEY_XPATH => array(),
|
||||
);
|
||||
|
||||
/**
|
||||
* the visited nodes with the XPath paths as array keys
|
||||
*
|
||||
* @var array<\DOMNode>
|
||||
*/
|
||||
private $visitedNodes = array();
|
||||
|
||||
/**
|
||||
* the styles to apply to the nodes with the XPath paths as array keys for the outer array and the attribute names/values
|
||||
* as key/value pairs for the inner array
|
||||
*
|
||||
* @var array<array><string>
|
||||
*/
|
||||
private $styleAttributesForNodes = array();
|
||||
|
||||
/**
|
||||
* This attribute applies to the case where you want to preserve your original text encoding.
|
||||
*
|
||||
* By default, emogrifier translates your text into HTML entities for two reasons:
|
||||
*
|
||||
* 1. Because of client incompatibilities, it is better practice to send out HTML entities rather than unicode over email.
|
||||
*
|
||||
* 2. It translates any illegal XML characters that DOMDocument cannot work with.
|
||||
*
|
||||
* If you would like to preserve your original encoding, set this attribute to TRUE.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
public $preserveEncoding = FALSE;
|
||||
|
||||
/**
|
||||
* The constructor.
|
||||
*
|
||||
* @param string $html the HTML to emogrify, must be UTF-8-encoded
|
||||
* @param string $css the CSS to merge, must be UTF-8-encoded
|
||||
*/
|
||||
public function __construct($html = '', $css = '') {
|
||||
$this->setHtml($html);
|
||||
$this->setCss($css);
|
||||
}
|
||||
|
||||
/**
|
||||
* The destructor.
|
||||
*/
|
||||
public function __destruct() {
|
||||
$this->purgeVisitedNodes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the HTML to emogrify.
|
||||
*
|
||||
* @param string $html the HTML to emogrify, must be UTF-8-encoded
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setHtml($html = '') {
|
||||
$this->html = $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the CSS to merge with the HTML.
|
||||
*
|
||||
* @param string $css the CSS to merge, must be UTF-8-encoded
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setCss($css = '') {
|
||||
$this->css = $css;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all caches.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function clearAllCaches() {
|
||||
$this->clearCache(self::CACHE_KEY_CSS);
|
||||
$this->clearCache(self::CACHE_KEY_SELECTOR);
|
||||
$this->clearCache(self::CACHE_KEY_XPATH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears a single cache by key.
|
||||
*
|
||||
* @param integer $key the cache key, must be CACHE_KEY_CSS, CACHE_KEY_SELECTOR or CACHE_KEY_XPATH
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
private function clearCache($key) {
|
||||
$allowedCacheKeys = array(self::CACHE_KEY_CSS, self::CACHE_KEY_SELECTOR, self::CACHE_KEY_XPATH);
|
||||
if (!in_array($key, $allowedCacheKeys, TRUE)) {
|
||||
throw new InvalidArgumentException('Invalid cache key: ' . $key, 1391822035);
|
||||
}
|
||||
|
||||
$this->caches[$key] = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Purges the visited nodes.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function purgeVisitedNodes() {
|
||||
$this->visitedNodes = array();
|
||||
$this->styleAttributesForNodes = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks a tag for removal.
|
||||
*
|
||||
* There are some HTML tags that DOMDocument cannot process, and it will throw an error if it encounters them.
|
||||
* In particular, DOMDocument will complain if you try to use HTML5 tags in an XHTML document.
|
||||
*
|
||||
* Note: The tags will not be removed if they have any content.
|
||||
*
|
||||
* @param string $tagName the tag name, e.g., "p"
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addUnprocessableHtmlTag($tagName) {
|
||||
$this->unprocessableHtmlTags[] = $tagName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Drops a tag from the removal list.
|
||||
*
|
||||
* @param string $tagName the tag name, e.g., "p"
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function removeUnprocessableHtmlTag($tagName) {
|
||||
$key = array_search($tagName, $this->unprocessableHtmlTags, TRUE);
|
||||
if ($key !== FALSE) {
|
||||
unset($this->unprocessableHtmlTags[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the CSS you submit to the HTML you submit.
|
||||
*
|
||||
* This method places the CSS inline.
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws \BadMethodCallException
|
||||
*/
|
||||
public function emogrify() {
|
||||
if ($this->html === '') {
|
||||
throw new BadMethodCallException('Please set some HTML first before calling emogrify.', 1390393096);
|
||||
}
|
||||
|
||||
$xmlDocument = $this->createXmlDocument();
|
||||
$xpath = new DOMXPath($xmlDocument);
|
||||
$this->clearAllCaches();
|
||||
|
||||
// before be begin processing the CSS file, parse the document and normalize all existing CSS attributes (changes 'DISPLAY: none' to 'display: none');
|
||||
// we wouldn't have to do this if DOMXPath supported XPath 2.0.
|
||||
// also store a reference of nodes with existing inline styles so we don't overwrite them
|
||||
$this->purgeVisitedNodes();
|
||||
|
||||
$nodesWithStyleAttributes = $xpath->query('//*[@style]');
|
||||
if ($nodesWithStyleAttributes !== FALSE) {
|
||||
$callback = create_function('$m', 'return strtolower($m[0]);');
|
||||
|
||||
/** @var $nodeWithStyleAttribute \DOMNode */
|
||||
foreach ($nodesWithStyleAttributes as $node) {
|
||||
$normalizedOriginalStyle = preg_replace_callback(
|
||||
'/[A-z\\-]+(?=\\:)/S',
|
||||
$callback,
|
||||
$node->getAttribute('style')
|
||||
);
|
||||
|
||||
// in order to not overwrite existing style attributes in the HTML, we have to save the original HTML styles
|
||||
$nodePath = $node->getNodePath();
|
||||
if (!isset($this->styleAttributesForNodes[$nodePath])) {
|
||||
$this->styleAttributesForNodes[$nodePath] = $this->parseCssDeclarationBlock($normalizedOriginalStyle);
|
||||
$this->visitedNodes[$nodePath] = $node;
|
||||
}
|
||||
|
||||
$node->setAttribute('style', $normalizedOriginalStyle);
|
||||
}
|
||||
}
|
||||
|
||||
// grab any existing style blocks from the html and append them to the existing CSS
|
||||
// (these blocks should be appended so as to have precedence over conflicting styles in the existing CSS)
|
||||
$css = $this->css;
|
||||
$styleNodes = $xpath->query('//style');
|
||||
if ($styleNodes !== FALSE) {
|
||||
/** @var $styleNode \DOMNode */
|
||||
foreach ($styleNodes as $styleNode) {
|
||||
// append the css
|
||||
$css .= "\n\n" . $styleNode->nodeValue;
|
||||
// remove the <style> node
|
||||
$styleNode->parentNode->removeChild($styleNode);
|
||||
}
|
||||
}
|
||||
|
||||
// filter the CSS
|
||||
$search = array(
|
||||
// get rid of css comment code
|
||||
'/\\/\\*.*\\*\\//sU',
|
||||
// strip out any import directives
|
||||
'/^\\s*@import\\s[^;]+;/misU',
|
||||
// strip any empty media enclosures
|
||||
'/^\\s*@media\\s[^{]+{\\s*}/misU',
|
||||
// strip out all media rules that are not 'screen' or 'all' (these don't apply to email)
|
||||
'/^\\s*@media\\s+((aural|braille|embossed|handheld|print|projection|speech|tty|tv)\\s*,*\\s*)+{.*}\\s*}/misU',
|
||||
// get rid of remaining media type rules
|
||||
'/^\\s*@media\\s[^{]+{(.*})\\s*}/misU',
|
||||
);
|
||||
|
||||
$replace = array(
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'\\1',
|
||||
);
|
||||
|
||||
$css = preg_replace($search, $replace, $css);
|
||||
|
||||
$cssKey = md5($css);
|
||||
if (!isset($this->caches[self::CACHE_KEY_CSS][$cssKey])) {
|
||||
// process the CSS file for selectors and definitions
|
||||
preg_match_all('/(?:^|[^{}])\\s*([^{]+){([^}]*)}/mis', $css, $matches, PREG_SET_ORDER);
|
||||
|
||||
$allSelectors = array();
|
||||
foreach ($matches as $key => $selectorString) {
|
||||
// if there is a blank definition, skip
|
||||
if (!strlen(trim($selectorString[2]))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// else split by commas and duplicate attributes so we can sort by selector precedence
|
||||
$selectors = explode(',', $selectorString[1]);
|
||||
foreach ($selectors as $selector) {
|
||||
// don't process pseudo-elements and behavioral (dynamic) pseudo-classes; ONLY allow structural pseudo-classes
|
||||
if (strpos($selector, ':') !== FALSE && !preg_match('/:\\S+\\-(child|type)\\(/i', $selector)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$allSelectors[] = array('selector' => trim($selector),
|
||||
'attributes' => trim($selectorString[2]),
|
||||
// keep track of where it appears in the file, since order is important
|
||||
'line' => $key,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// now sort the selectors by precedence
|
||||
usort($allSelectors, array($this,'sortBySelectorPrecedence'));
|
||||
|
||||
$this->caches[self::CACHE_KEY_CSS][$cssKey] = $allSelectors;
|
||||
}
|
||||
|
||||
foreach ($this->caches[self::CACHE_KEY_CSS][$cssKey] as $value) {
|
||||
// query the body for the xpath selector
|
||||
$nodesMatchingCssSelectors = $xpath->query($this->translateCssToXpath(trim($value['selector'])));
|
||||
|
||||
/** @var $node \DOMNode */
|
||||
foreach ($nodesMatchingCssSelectors as $node) {
|
||||
// if it has a style attribute, get it, process it, and append (overwrite) new stuff
|
||||
if ($node->hasAttribute('style')) {
|
||||
// break it up into an associative array
|
||||
$oldStyleDeclarations = $this->parseCssDeclarationBlock($node->getAttribute('style'));
|
||||
$newStyleDeclarations = $this->parseCssDeclarationBlock($value['attributes']);
|
||||
|
||||
// new styles overwrite the old styles (not technically accurate, but close enough)
|
||||
$combinedArray = array_merge($oldStyleDeclarations, $newStyleDeclarations);
|
||||
$style = '';
|
||||
foreach ($combinedArray as $attributeName => $attributeValue) {
|
||||
$style .= (strtolower($attributeName) . ':' . $attributeValue . ';');
|
||||
}
|
||||
} else {
|
||||
// otherwise create a new style
|
||||
$style = trim($value['attributes']);
|
||||
}
|
||||
$node->setAttribute('style', $style);
|
||||
}
|
||||
}
|
||||
|
||||
// now iterate through the nodes that contained inline styles in the original HTML
|
||||
foreach ($this->styleAttributesForNodes as $nodePath => $styleAttributesForNode) {
|
||||
$node = $this->visitedNodes[$nodePath];
|
||||
$currentStyleAttributes = $this->parseCssDeclarationBlock($node->getAttribute('style'));
|
||||
|
||||
$combinedArray = array_merge($currentStyleAttributes, $styleAttributesForNode);
|
||||
$style = '';
|
||||
foreach ($combinedArray as $attributeName => $attributeValue) {
|
||||
$style .= (strtolower($attributeName) . ':' . $attributeValue . ';');
|
||||
}
|
||||
|
||||
$node->setAttribute('style', $style);
|
||||
}
|
||||
|
||||
// This removes styles from your email that contain display:none.
|
||||
// We need to look for display:none, but we need to do a case-insensitive search. Since DOMDocument only supports XPath 1.0,
|
||||
// lower-case() isn't available to us. We've thus far only set attributes to lowercase, not attribute values. Consequently, we need
|
||||
// to translate() the letters that would be in 'NONE' ("NOE") to lowercase.
|
||||
$nodesWithStyleDisplayNone = $xpath->query('//*[contains(translate(translate(@style," ",""),"NOE","noe"),"display:none")]');
|
||||
// The checks on parentNode and is_callable below ensure that if we've deleted the parent node,
|
||||
// we don't try to call removeChild on a nonexistent child node
|
||||
if ($nodesWithStyleDisplayNone->length > 0) {
|
||||
/** @var $node \DOMNode */
|
||||
foreach ($nodesWithStyleDisplayNone as $node) {
|
||||
if ($node->parentNode && is_callable(array($node->parentNode,'removeChild'))) {
|
||||
$node->parentNode->removeChild($node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->preserveEncoding) {
|
||||
return mb_convert_encoding($xmlDocument->saveHTML(), self::ENCODING, 'HTML-ENTITIES');
|
||||
} else {
|
||||
return $xmlDocument->saveHTML();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a DOMDocument instance with the current HTML.
|
||||
*
|
||||
* @return \DOMDocument
|
||||
*/
|
||||
private function createXmlDocument() {
|
||||
$xmlDocument = new DOMDocument;
|
||||
$xmlDocument->encoding = self::ENCODING;
|
||||
$xmlDocument->strictErrorChecking = FALSE;
|
||||
$xmlDocument->formatOutput = TRUE;
|
||||
$libxmlState = libxml_use_internal_errors(TRUE);
|
||||
$xmlDocument->loadHTML($this->getUnifiedHtml());
|
||||
libxml_clear_errors();
|
||||
libxml_use_internal_errors($libxmlState);
|
||||
$xmlDocument->normalizeDocument();
|
||||
|
||||
return $xmlDocument;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the HTML with the non-ASCII characters converts into HTML entities and the unprocessable HTML tags removed.
|
||||
*
|
||||
* @return string the unified HTML
|
||||
*
|
||||
* @throws \BadMethodCallException
|
||||
*/
|
||||
private function getUnifiedHtml() {
|
||||
if (!empty($this->unprocessableHtmlTags)) {
|
||||
$unprocessableHtmlTags = implode('|', $this->unprocessableHtmlTags);
|
||||
$bodyWithoutUnprocessableTags = preg_replace('/<\\/?(' . $unprocessableHtmlTags . ')[^>]*>/i', '', $this->html);
|
||||
} else {
|
||||
$bodyWithoutUnprocessableTags = $this->html;
|
||||
}
|
||||
|
||||
return mb_convert_encoding($bodyWithoutUnprocessableTags, 'HTML-ENTITIES', self::ENCODING);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $a
|
||||
* @param array $b
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
private function sortBySelectorPrecedence(array $a, array $b) {
|
||||
$precedenceA = $this->getCssSelectorPrecedence($a['selector']);
|
||||
$precedenceB = $this->getCssSelectorPrecedence($b['selector']);
|
||||
|
||||
// We want these sorted in ascending order so selectors with lesser precedence get processed first and
|
||||
// selectors with greater precedence get sorted last.
|
||||
// The parenthesis around the -1 are necessary to avoid a PHP_CodeSniffer warning about missing spaces around
|
||||
// arithmetic operators.
|
||||
// @see http://forge.typo3.org/issues/55605
|
||||
$precedenceForEquals = ($a['line'] < $b['line'] ? (-1) : 1);
|
||||
$precedenceForNotEquals = ($precedenceA < $precedenceB ? (-1) : 1);
|
||||
return ($precedenceA === $precedenceB) ? $precedenceForEquals : $precedenceForNotEquals;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $selector
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
private function getCssSelectorPrecedence($selector) {
|
||||
$selectorKey = md5($selector);
|
||||
if (!isset($this->caches[self::CACHE_KEY_SELECTOR][$selectorKey])) {
|
||||
$precedence = 0;
|
||||
$value = 100;
|
||||
// ids: worth 100, classes: worth 10, elements: worth 1
|
||||
$search = array('\\#','\\.','');
|
||||
|
||||
foreach ($search as $s) {
|
||||
if (trim($selector == '')) {
|
||||
break;
|
||||
}
|
||||
$number = 0;
|
||||
$selector = preg_replace('/' . $s . '\\w+/', '', $selector, -1, $number);
|
||||
$precedence += ($value * $number);
|
||||
$value /= 10;
|
||||
}
|
||||
$this->caches[self::CACHE_KEY_SELECTOR][$selectorKey] = $precedence;
|
||||
}
|
||||
|
||||
return $this->caches[self::CACHE_KEY_SELECTOR][$selectorKey];
|
||||
}
|
||||
|
||||
/**
|
||||
* Right now, we support all CSS 1 selectors and most CSS2/3 selectors.
|
||||
*
|
||||
* @see http://plasmasturm.org/log/444/
|
||||
*
|
||||
* @param string $cssSelector
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function translateCssToXpath($cssSelector) {
|
||||
$cssSelector = trim($cssSelector);
|
||||
$xpathKey = md5($cssSelector);
|
||||
if (!isset($this->caches[self::CACHE_KEY_XPATH][$xpathKey])) {
|
||||
// returns an Xpath selector
|
||||
$search = array(
|
||||
// Matches any element that is a child of parent.
|
||||
'/\\s+>\\s+/',
|
||||
// Matches any element that is an adjacent sibling.
|
||||
'/\\s+\\+\\s+/',
|
||||
// Matches any element that is a descendant of an parent element element.
|
||||
'/\\s+/',
|
||||
// first-child pseudo-selector
|
||||
'/([^\\/]+):first-child/i',
|
||||
// last-child pseudo-selector
|
||||
'/([^\\/]+):last-child/i',
|
||||
// Matches element with attribute
|
||||
'/(\\w)\\[(\\w+)\\]/',
|
||||
// Matches element with EXACT attribute
|
||||
'/(\\w)\\[(\\w+)\\=[\'"]?(\\w+)[\'"]?\\]/',
|
||||
);
|
||||
$replace = array(
|
||||
'/',
|
||||
'/following-sibling::*[1]/self::',
|
||||
'//',
|
||||
'*[1]/self::\\1',
|
||||
'*[last()]/self::\\1',
|
||||
'\\1[@\\2]',
|
||||
'\\1[@\\2="\\3"]',
|
||||
);
|
||||
|
||||
$cssSelector = '//' . preg_replace($search, $replace, $cssSelector);
|
||||
|
||||
$cssSelector = preg_replace_callback(self::ID_ATTRIBUTE_MATCHER, array($this, 'matchIdAttributes'), $cssSelector);
|
||||
$cssSelector = preg_replace_callback(self::CLASS_ATTRIBUTE_MATCHER, array($this, 'matchClassAttributes'), $cssSelector);
|
||||
|
||||
// Advanced selectors are going to require a bit more advanced emogrification.
|
||||
// When we required PHP 5.3, we could do this with closures.
|
||||
$cssSelector = preg_replace_callback(
|
||||
'/([^\\/]+):nth-child\\(\s*(odd|even|[+\-]?\\d|[+\\-]?\\d?n(\\s*[+\\-]\\s*\\d)?)\\s*\\)/i',
|
||||
array($this, 'translateNthChild'), $cssSelector
|
||||
);
|
||||
$cssSelector = preg_replace_callback(
|
||||
'/([^\\/]+):nth-of-type\\(\s*(odd|even|[+\-]?\\d|[+\\-]?\\d?n(\\s*[+\\-]\\s*\\d)?)\\s*\\)/i',
|
||||
array($this, 'translateNthOfType'), $cssSelector
|
||||
);
|
||||
|
||||
$this->caches[self::CACHE_KEY_SELECTOR][$xpathKey] = $cssSelector;
|
||||
}
|
||||
return $this->caches[self::CACHE_KEY_SELECTOR][$xpathKey];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $match
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function matchIdAttributes(array $match) {
|
||||
return (strlen($match[1]) ? $match[1] : '*') . '[@id="' . $match[2] . '"]';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $match
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function matchClassAttributes(array $match) {
|
||||
return (strlen($match[1]) ? $match[1] : '*') . '[contains(concat(" ",@class," "),concat(" ","' .
|
||||
implode(
|
||||
'"," "))][contains(concat(" ",@class," "),concat(" ","',
|
||||
explode('.', substr($match[2], 1))
|
||||
) . '"," "))]';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $match
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function translateNthChild(array $match) {
|
||||
$result = $this->parseNth($match);
|
||||
|
||||
if (isset($result[self::MULTIPLIER])) {
|
||||
if ($result[self::MULTIPLIER] < 0) {
|
||||
$result[self::MULTIPLIER] = abs($result[self::MULTIPLIER]);
|
||||
return sprintf('*[(last() - position()) mod %u = %u]/self::%s', $result[self::MULTIPLIER], $result[self::INDEX], $match[1]);
|
||||
} else {
|
||||
return sprintf('*[position() mod %u = %u]/self::%s', $result[self::MULTIPLIER], $result[self::INDEX], $match[1]);
|
||||
}
|
||||
} else {
|
||||
return sprintf('*[%u]/self::%s', $result[self::INDEX], $match[1]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $match
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function translateNthOfType(array $match) {
|
||||
$result = $this->parseNth($match);
|
||||
|
||||
if (isset($result[self::MULTIPLIER])) {
|
||||
if ($result[self::MULTIPLIER] < 0) {
|
||||
$result[self::MULTIPLIER] = abs($result[self::MULTIPLIER]);
|
||||
return sprintf('%s[(last() - position()) mod %u = %u]', $match[1], $result[self::MULTIPLIER], $result[self::INDEX]);
|
||||
} else {
|
||||
return sprintf('%s[position() mod %u = %u]', $match[1], $result[self::MULTIPLIER], $result[self::INDEX]);
|
||||
}
|
||||
} else {
|
||||
return sprintf('%s[%u]', $match[1], $result[self::INDEX]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $match
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function parseNth(array $match) {
|
||||
if (in_array(strtolower($match[2]), array('even','odd'))) {
|
||||
$index = strtolower($match[2]) == 'even' ? 0 : 1;
|
||||
return array(self::MULTIPLIER => 2, self::INDEX => $index);
|
||||
} elseif (stripos($match[2], 'n') === FALSE) {
|
||||
// if there is a multiplier
|
||||
$index = intval(str_replace(' ', '', $match[2]));
|
||||
return array(self::INDEX => $index);
|
||||
} else {
|
||||
if (isset($match[3])) {
|
||||
$multipleTerm = str_replace($match[3], '', $match[2]);
|
||||
$index = intval(str_replace(' ', '', $match[3]));
|
||||
} else {
|
||||
$multipleTerm = $match[2];
|
||||
$index = 0;
|
||||
}
|
||||
|
||||
$multiplier = str_ireplace('n', '', $multipleTerm);
|
||||
|
||||
if (!strlen($multiplier)) {
|
||||
$multiplier = 1;
|
||||
} elseif ($multiplier == 0) {
|
||||
return array(self::INDEX => $index);
|
||||
} else {
|
||||
$multiplier = intval($multiplier);
|
||||
}
|
||||
|
||||
while ($index < 0) {
|
||||
$index += abs($multiplier);
|
||||
}
|
||||
|
||||
return array(self::MULTIPLIER => $multiplier, self::INDEX => $index);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a CSS declaration block into property name/value pairs.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* The declaration block
|
||||
*
|
||||
* "color: #000; font-weight: bold;"
|
||||
*
|
||||
* will be parsed into the following array:
|
||||
*
|
||||
* "color" => "#000"
|
||||
* "font-weight" => "bold"
|
||||
*
|
||||
* @param string $cssDeclarationBlock the CSS declaration block without the curly braces, may be empty
|
||||
*
|
||||
* @return array the CSS declarations with the property names as array keys and the property values as array values
|
||||
*/
|
||||
private function parseCssDeclarationBlock($cssDeclarationBlock) {
|
||||
$properties = array();
|
||||
|
||||
$declarations = explode(';', $cssDeclarationBlock);
|
||||
foreach ($declarations as $declaration) {
|
||||
$matches = array();
|
||||
if (!preg_match('/ *([a-z\-]+) *: *([^;]+) */', $declaration, $matches)) {
|
||||
continue;
|
||||
}
|
||||
$propertyName = $matches[1];
|
||||
$propertyValue = $matches[2];
|
||||
$properties[$propertyName] = $propertyValue;
|
||||
}
|
||||
|
||||
return $properties;
|
||||
}
|
||||
}
|
||||
1541
zoesch.de/galerie/include/feedcreator.class.php
Normal file
1541
zoesch.de/galerie/include/feedcreator.class.php
Normal file
File diff suppressed because it is too large
Load Diff
146
zoesch.de/galerie/include/filter.inc.php
Normal file
146
zoesch.de/galerie/include/filter.inc.php
Normal file
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Piwigo - a PHP based photo gallery |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright(C) 2008-2016 Piwigo Team http://piwigo.org |
|
||||
// | Copyright(C) 2003-2008 PhpWebGallery Team http://phpwebgallery.net |
|
||||
// | Copyright(C) 2002-2003 Pierrick LE GALL http://le-gall.net/pierrick |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
// $filter['enabled']: Filter is enabled
|
||||
// $filter['recent_period']: Recent period used to computed filter data
|
||||
// $filter['categories']: Computed data of filtered categories
|
||||
// $filter['visible_categories']:
|
||||
// List of visible categories (count(visible) < count(forbidden) more often)
|
||||
// $filter['visible_images']: List of visible images
|
||||
|
||||
if (!get_filter_page_value('cancel'))
|
||||
{
|
||||
if (isset($_GET['filter']))
|
||||
{
|
||||
$filter['matches'] = array();
|
||||
$filter['enabled'] =
|
||||
preg_match('/^start-recent-(\d+)$/', $_GET['filter'], $filter['matches']) === 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
$filter['enabled'] = pwg_get_session_var('filter_enabled', false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$filter['enabled'] = false;
|
||||
}
|
||||
|
||||
if ($filter['enabled'])
|
||||
{
|
||||
$filter_key = pwg_get_session_var('filter_check_key', array('user'=>0,'recent_period'=>-1, 'time'=>0, 'date'=> '') );
|
||||
|
||||
if (isset($filter['matches']))
|
||||
{
|
||||
$filter['recent_period'] = $filter['matches'][1];
|
||||
}
|
||||
else
|
||||
{
|
||||
$filter['recent_period'] = $filter_key['recent_period']>0 ? $filter_key['recent_period'] : $user['recent_period'];
|
||||
}
|
||||
|
||||
if (
|
||||
// New filter
|
||||
!pwg_get_session_var('filter_enabled', false) or
|
||||
// Cache data updated
|
||||
$filter_key['time'] <= $user['cache_update_time'] or
|
||||
// Date, period, user are changed
|
||||
$filter_key['user'] != $user['id'] or
|
||||
$filter_key['recent_period'] != $filter['recent_period'] or
|
||||
$filter_key['date'] != date('Ymd')
|
||||
)
|
||||
{
|
||||
// Need to compute dats
|
||||
$filter_key = array(
|
||||
'user'=>(int)$user['id'],'recent_period'=>(int)$filter['recent_period'], 'time'=>time(), 'date'=> date('Ymd')
|
||||
);
|
||||
|
||||
$filter['categories'] = get_computed_categories($user, (int)$filter['recent_period']);
|
||||
|
||||
$filter['visible_categories'] = implode(',', array_keys($filter['categories']));
|
||||
if (empty($filter['visible_categories']))
|
||||
{
|
||||
// Must be not empty
|
||||
$filter['visible_categories'] = -1;
|
||||
}
|
||||
|
||||
$query ='
|
||||
SELECT
|
||||
distinct image_id
|
||||
FROM '.
|
||||
IMAGE_CATEGORY_TABLE.' INNER JOIN '.IMAGES_TABLE.' ON image_id = id
|
||||
WHERE ';
|
||||
if (!empty($filter['visible_categories']))
|
||||
{
|
||||
$query.= '
|
||||
category_id IN ('.$filter['visible_categories'].') and';
|
||||
}
|
||||
$query.= '
|
||||
date_available >= '.pwg_db_get_recent_period_expression($filter['recent_period']);
|
||||
|
||||
$filter['visible_images'] = implode(',', array_from_query($query, 'image_id'));
|
||||
|
||||
if (empty($filter['visible_images']))
|
||||
{
|
||||
// Must be not empty
|
||||
$filter['visible_images'] = -1;
|
||||
}
|
||||
|
||||
// Save filter data on session
|
||||
pwg_set_session_var('filter_enabled', $filter['enabled']);
|
||||
pwg_set_session_var('filter_check_key', $filter_key);
|
||||
pwg_set_session_var('filter_categories', serialize($filter['categories']));
|
||||
pwg_set_session_var('filter_visible_categories', $filter['visible_categories']);
|
||||
pwg_set_session_var('filter_visible_images', $filter['visible_images']);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Read only data
|
||||
$filter['categories'] = unserialize(pwg_get_session_var('filter_categories', serialize(array())));
|
||||
$filter['visible_categories'] = pwg_get_session_var('filter_visible_categories', '');
|
||||
$filter['visible_images'] = pwg_get_session_var('filter_visible_images', '');
|
||||
}
|
||||
unset($filter_key);
|
||||
if (get_filter_page_value('add_notes'))
|
||||
{
|
||||
$header_notes[] = l10n_dec(
|
||||
'Photos posted within the last %d day.', 'Photos posted within the last %d days.',
|
||||
$filter['recent_period']
|
||||
);
|
||||
}
|
||||
include_once(PHPWG_ROOT_PATH.'include/functions_filter.inc.php');
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pwg_get_session_var('filter_enabled', false))
|
||||
{
|
||||
pwg_unset_session_var('filter_enabled');
|
||||
pwg_unset_session_var('filter_check_key');
|
||||
pwg_unset_session_var('filter_categories');
|
||||
pwg_unset_session_var('filter_visible_categories');
|
||||
pwg_unset_session_var('filter_visible_images');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
2185
zoesch.de/galerie/include/functions.inc.php
Normal file
2185
zoesch.de/galerie/include/functions.inc.php
Normal file
File diff suppressed because it is too large
Load Diff
319
zoesch.de/galerie/include/functions_calendar.inc.php
Normal file
319
zoesch.de/galerie/include/functions_calendar.inc.php
Normal file
@@ -0,0 +1,319 @@
|
||||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Piwigo - a PHP based photo gallery |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright(C) 2008-2016 Piwigo Team http://piwigo.org |
|
||||
// | Copyright(C) 2003-2008 PhpWebGallery Team http://phpwebgallery.net |
|
||||
// | Copyright(C) 2002-2003 Pierrick LE GALL http://le-gall.net/pierrick |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
* @package functions\calendar
|
||||
*/
|
||||
|
||||
/** URL keyword for list view */
|
||||
define('CAL_VIEW_LIST', 'list');
|
||||
/** URL keyword for calendar view */
|
||||
define('CAL_VIEW_CALENDAR', 'calendar');
|
||||
|
||||
|
||||
/**
|
||||
* Initialize _$page_ and _$template_ vars for calendar view.
|
||||
*/
|
||||
function initialize_calendar()
|
||||
{
|
||||
global $page, $conf, $user, $template, $persistent_cache, $filter;
|
||||
|
||||
//------------------ initialize the condition on items to take into account ---
|
||||
$inner_sql = ' FROM ' . IMAGES_TABLE;
|
||||
|
||||
if ($page['section']=='categories')
|
||||
{ // we will regenerate the items by including subcats elements
|
||||
$page['items'] = array();
|
||||
$inner_sql .= '
|
||||
INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON id = image_id';
|
||||
|
||||
if ( isset($page['category']) )
|
||||
{
|
||||
$sub_ids = array_diff(
|
||||
get_subcat_ids(array($page['category']['id'])),
|
||||
explode(',', $user['forbidden_categories'])
|
||||
);
|
||||
|
||||
if (empty($sub_ids))
|
||||
{
|
||||
return; // nothing to do
|
||||
}
|
||||
$inner_sql .= '
|
||||
WHERE category_id IN ('.implode(',',$sub_ids).')';
|
||||
$inner_sql .= '
|
||||
'.get_sql_condition_FandF
|
||||
(
|
||||
array
|
||||
(
|
||||
'visible_images' => 'id'
|
||||
),
|
||||
'AND', false
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$inner_sql .= '
|
||||
'.get_sql_condition_FandF
|
||||
(
|
||||
array
|
||||
(
|
||||
'forbidden_categories' => 'category_id',
|
||||
'visible_categories' => 'category_id',
|
||||
'visible_images' => 'id'
|
||||
),
|
||||
'WHERE', true
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( empty($page['items']) )
|
||||
{
|
||||
return; // nothing to do
|
||||
}
|
||||
$inner_sql .= '
|
||||
WHERE id IN (' . implode(',',$page['items']) .')';
|
||||
}
|
||||
|
||||
//-------------------------------------- initialize the calendar parameters ---
|
||||
pwg_debug('start initialize_calendar');
|
||||
|
||||
$fields = array(
|
||||
// Created
|
||||
'created' => array(
|
||||
'label' => l10n('Creation date'),
|
||||
),
|
||||
// Posted
|
||||
'posted' => array(
|
||||
'label' => l10n('Post date'),
|
||||
),
|
||||
);
|
||||
|
||||
$styles = array(
|
||||
// Monthly style
|
||||
'monthly' => array(
|
||||
'include' => 'calendar_monthly.class.php',
|
||||
'view_calendar' => true,
|
||||
'classname' => 'CalendarMonthly',
|
||||
),
|
||||
// Weekly style
|
||||
'weekly' => array(
|
||||
'include' => 'calendar_weekly.class.php',
|
||||
'view_calendar' => false,
|
||||
'classname' => 'CalendarWeekly',
|
||||
),
|
||||
);
|
||||
|
||||
$views = array(CAL_VIEW_LIST,CAL_VIEW_CALENDAR);
|
||||
|
||||
// Retrieve calendar field
|
||||
isset( $fields[ $page['chronology_field'] ] ) or fatal_error('bad chronology field');
|
||||
|
||||
// Retrieve style
|
||||
if ( !isset( $styles[ $page['chronology_style'] ] ) )
|
||||
{
|
||||
$page['chronology_style'] = 'monthly';
|
||||
}
|
||||
$cal_style = $page['chronology_style'];
|
||||
$classname = $styles[$cal_style]['classname'];
|
||||
|
||||
include(PHPWG_ROOT_PATH.'include/'. $styles[$cal_style]['include']);
|
||||
$calendar = new $classname();
|
||||
|
||||
// Retrieve view
|
||||
|
||||
if ( !isset($page['chronology_view']) or
|
||||
!in_array( $page['chronology_view'], $views ) )
|
||||
{
|
||||
$page['chronology_view'] = CAL_VIEW_LIST;
|
||||
}
|
||||
|
||||
if ( CAL_VIEW_CALENDAR==$page['chronology_view'] and
|
||||
!$styles[$cal_style]['view_calendar'] )
|
||||
{
|
||||
|
||||
$page['chronology_view'] = CAL_VIEW_LIST;
|
||||
}
|
||||
|
||||
// perform a sanity check on $requested
|
||||
if (!isset($page['chronology_date']))
|
||||
{
|
||||
$page['chronology_date'] = array();
|
||||
}
|
||||
while ( count($page['chronology_date']) > 3)
|
||||
{
|
||||
array_pop($page['chronology_date']);
|
||||
}
|
||||
|
||||
$any_count = 0;
|
||||
for ($i = 0; $i < count($page['chronology_date']); $i++)
|
||||
{
|
||||
if ($page['chronology_date'][$i] == 'any')
|
||||
{
|
||||
if ($page['chronology_view'] == CAL_VIEW_CALENDAR)
|
||||
{// we dont allow any in calendar view
|
||||
while ($i < count($page['chronology_date']))
|
||||
{
|
||||
array_pop($page['chronology_date']);
|
||||
}
|
||||
break;
|
||||
}
|
||||
$any_count++;
|
||||
}
|
||||
elseif ($page['chronology_date'][$i] == '')
|
||||
{
|
||||
while ($i < count($page['chronology_date']))
|
||||
{
|
||||
array_pop($page['chronology_date']);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$page['chronology_date'][$i] = (int)$page['chronology_date'][$i];
|
||||
}
|
||||
}
|
||||
if ($any_count == 3)
|
||||
{
|
||||
array_pop($page['chronology_date']);
|
||||
}
|
||||
|
||||
$calendar->initialize($inner_sql);
|
||||
|
||||
//echo ('<pre>'. var_export($calendar, true) . '</pre>');
|
||||
|
||||
$must_show_list = true; // true until calendar generates its own display
|
||||
if (script_basename() != 'picture') // basename without file extention
|
||||
{
|
||||
if ($calendar->generate_category_content())
|
||||
{
|
||||
$page['items'] = array();
|
||||
$must_show_list = false;
|
||||
}
|
||||
|
||||
$page['comment'] = '';
|
||||
$template->assign('FILE_CHRONOLOGY_VIEW', 'month_calendar.tpl');
|
||||
|
||||
foreach ($styles as $style => $style_data)
|
||||
{
|
||||
foreach ($views as $view)
|
||||
{
|
||||
if ( $style_data['view_calendar'] or $view != CAL_VIEW_CALENDAR)
|
||||
{
|
||||
$selected = false;
|
||||
|
||||
if ($style!=$cal_style)
|
||||
{
|
||||
$chronology_date = array();
|
||||
if ( isset($page['chronology_date'][0]) )
|
||||
{
|
||||
$chronology_date[] = $page['chronology_date'][0];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$chronology_date = $page['chronology_date'];
|
||||
}
|
||||
$url = duplicate_index_url(
|
||||
array(
|
||||
'chronology_style' => $style,
|
||||
'chronology_view' => $view,
|
||||
'chronology_date' => $chronology_date,
|
||||
)
|
||||
);
|
||||
|
||||
if ($style==$cal_style and $view==$page['chronology_view'] )
|
||||
{
|
||||
$selected = true;
|
||||
}
|
||||
|
||||
$template->append(
|
||||
'chronology_views',
|
||||
array(
|
||||
'VALUE' => $url,
|
||||
'CONTENT' => l10n('chronology_'.$style.'_'.$view),
|
||||
'SELECTED' => $selected,
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
$url = duplicate_index_url(
|
||||
array(), array('start', 'chronology_date')
|
||||
);
|
||||
$calendar_title = '<a href="'.$url.'">'
|
||||
.$fields[$page['chronology_field']]['label'].'</a>';
|
||||
$calendar_title.= $calendar->get_display_name();
|
||||
$template->assign('chronology',
|
||||
array(
|
||||
'TITLE' => $calendar_title
|
||||
)
|
||||
);
|
||||
} // end category calling
|
||||
|
||||
if ($must_show_list)
|
||||
{
|
||||
if ( isset($page['super_order_by']) )
|
||||
{
|
||||
$order_by = $conf['order_by'];
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( count($page['chronology_date'])==0
|
||||
or in_array('any', $page['chronology_date']) )
|
||||
{// selected period is very big so we show newest first
|
||||
$order = ' DESC, ';
|
||||
}
|
||||
else
|
||||
{// selected period is small (month,week) so we show oldest first
|
||||
$order = ' ASC, ';
|
||||
}
|
||||
$order_by = str_replace(
|
||||
'ORDER BY ',
|
||||
'ORDER BY '.$calendar->date_field.$order, $conf['order_by']
|
||||
);
|
||||
}
|
||||
|
||||
if ('categories'==$page['section'] && !isset($page['category'])
|
||||
&& ( count($page['chronology_date'])==0
|
||||
OR ($page['chronology_date'][0]=='any' && count($page['chronology_date'])==1) )
|
||||
)
|
||||
{
|
||||
$cache_key = $persistent_cache->make_key($user['id'].$user['cache_update_time']
|
||||
.$calendar->date_field.$order_by);
|
||||
}
|
||||
|
||||
if ( !isset($cache_key) || !$persistent_cache->get($cache_key, $page['items']))
|
||||
{
|
||||
$query = 'SELECT DISTINCT id '
|
||||
.$calendar->inner_sql.'
|
||||
'.$calendar->get_date_where().'
|
||||
'.$order_by;
|
||||
$page['items'] = array_from_query($query, 'id');
|
||||
if ( isset($cache_key) )
|
||||
$persistent_cache->set($cache_key, $page['items']);
|
||||
}
|
||||
}
|
||||
pwg_debug('end initialize_calendar');
|
||||
}
|
||||
|
||||
?>
|
||||
620
zoesch.de/galerie/include/functions_category.inc.php
Normal file
620
zoesch.de/galerie/include/functions_category.inc.php
Normal file
@@ -0,0 +1,620 @@
|
||||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Piwigo - a PHP based photo gallery |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright(C) 2008-2016 Piwigo Team http://piwigo.org |
|
||||
// | Copyright(C) 2003-2008 PhpWebGallery Team http://phpwebgallery.net |
|
||||
// | Copyright(C) 2002-2003 Pierrick LE GALL http://le-gall.net/pierrick |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
* @package functions\category
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Callback used for sorting by global_rank
|
||||
*/
|
||||
function global_rank_compare($a, $b)
|
||||
{
|
||||
return strnatcasecmp($a['global_rank'], $b['global_rank']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback used for sorting by rank
|
||||
*/
|
||||
function rank_compare($a, $b)
|
||||
{
|
||||
return $a['rank'] - $b['rank'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the category accessible to the connected user ?
|
||||
* If the user is not authorized to see this category, script exits
|
||||
*
|
||||
* @param int $category_id
|
||||
*/
|
||||
function check_restrictions($category_id)
|
||||
{
|
||||
global $user;
|
||||
|
||||
// $filter['visible_categories'] and $filter['visible_images']
|
||||
// are not used because it's not necessary (filter <> restriction)
|
||||
if (in_array($category_id, explode(',', $user['forbidden_categories'])))
|
||||
{
|
||||
access_denied();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns template vars for main categories menu.
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
function get_categories_menu()
|
||||
{
|
||||
global $page, $user, $filter, $conf;
|
||||
|
||||
$query = '
|
||||
SELECT ';
|
||||
// From CATEGORIES_TABLE
|
||||
$query.= '
|
||||
id, name, permalink, nb_images, global_rank,';
|
||||
// From USER_CACHE_CATEGORIES_TABLE
|
||||
$query.= '
|
||||
date_last, max_date_last, count_images, count_categories';
|
||||
|
||||
// $user['forbidden_categories'] including with USER_CACHE_CATEGORIES_TABLE
|
||||
$query.= '
|
||||
FROM '.CATEGORIES_TABLE.' INNER JOIN '.USER_CACHE_CATEGORIES_TABLE.'
|
||||
ON id = cat_id and user_id = '.$user['id'];
|
||||
|
||||
// Always expand when filter is activated
|
||||
if (!$user['expand'] and !$filter['enabled'])
|
||||
{
|
||||
$where = '
|
||||
(id_uppercat is NULL';
|
||||
if (isset($page['category']))
|
||||
{
|
||||
$where .= ' OR id_uppercat IN ('.$page['category']['uppercats'].')';
|
||||
}
|
||||
$where .= ')';
|
||||
}
|
||||
else
|
||||
{
|
||||
$where = '
|
||||
'.get_sql_condition_FandF
|
||||
(
|
||||
array
|
||||
(
|
||||
'visible_categories' => 'id',
|
||||
),
|
||||
null,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
$where = trigger_change('get_categories_menu_sql_where',
|
||||
$where, $user['expand'], $filter['enabled'] );
|
||||
|
||||
$query.= '
|
||||
WHERE '.$where.'
|
||||
;';
|
||||
|
||||
$result = pwg_query($query);
|
||||
$cats = array();
|
||||
$selected_category = isset($page['category']) ? $page['category'] : null;
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
$child_date_last = @$row['max_date_last']> @$row['date_last'];
|
||||
$row = array_merge($row,
|
||||
array(
|
||||
'NAME' => trigger_change(
|
||||
'render_category_name',
|
||||
$row['name'],
|
||||
'get_categories_menu'
|
||||
),
|
||||
'TITLE' => get_display_images_count(
|
||||
$row['nb_images'],
|
||||
$row['count_images'],
|
||||
$row['count_categories'],
|
||||
false,
|
||||
' / '
|
||||
),
|
||||
'URL' => make_index_url(array('category' => $row)),
|
||||
'LEVEL' => substr_count($row['global_rank'], '.') + 1,
|
||||
'SELECTED' => $selected_category['id'] == $row['id'] ? true : false,
|
||||
'IS_UPPERCAT' => $selected_category['id_uppercat'] == $row['id'] ? true : false,
|
||||
)
|
||||
);
|
||||
if ($conf['index_new_icon'])
|
||||
{
|
||||
$row['icon_ts'] = get_icon($row['max_date_last'], $child_date_last);
|
||||
}
|
||||
$cats[] = $row;
|
||||
if ($row['id']==@$page['category']['id']) //save the number of subcats for later optim
|
||||
$page['category']['count_categories'] = $row['count_categories'];
|
||||
}
|
||||
usort($cats, 'global_rank_compare');
|
||||
|
||||
// Update filtered data
|
||||
if (function_exists('update_cats_with_filtered_data'))
|
||||
{
|
||||
update_cats_with_filtered_data($cats);
|
||||
}
|
||||
|
||||
return $cats;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves informations about a category.
|
||||
*
|
||||
* @param int $id
|
||||
* @return array
|
||||
*/
|
||||
function get_cat_info($id)
|
||||
{
|
||||
$query = '
|
||||
SELECT *
|
||||
FROM '.CATEGORIES_TABLE.'
|
||||
WHERE id = '.$id.'
|
||||
;';
|
||||
$cat = pwg_db_fetch_assoc(pwg_query($query));
|
||||
if (empty($cat))
|
||||
return null;
|
||||
|
||||
foreach ($cat as $k => $v)
|
||||
{
|
||||
// If the field is true or false, the variable is transformed into a
|
||||
// boolean value.
|
||||
if ($cat[$k] == 'true' or $cat[$k] == 'false')
|
||||
{
|
||||
$cat[$k] = get_boolean( $cat[$k] );
|
||||
}
|
||||
}
|
||||
|
||||
$upper_ids = explode(',', $cat['uppercats']);
|
||||
if ( count($upper_ids)==1 )
|
||||
{// no need to make a query for level 1
|
||||
$cat['upper_names'] = array(
|
||||
array(
|
||||
'id' => $cat['id'],
|
||||
'name' => $cat['name'],
|
||||
'permalink' => $cat['permalink'],
|
||||
)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$query = '
|
||||
SELECT id, name, permalink
|
||||
FROM '.CATEGORIES_TABLE.'
|
||||
WHERE id IN ('.$cat['uppercats'].')
|
||||
;';
|
||||
$names = query2array($query, 'id');
|
||||
|
||||
// category names must be in the same order than uppercats list
|
||||
$cat['upper_names'] = array();
|
||||
foreach ($upper_ids as $cat_id)
|
||||
{
|
||||
$cat['upper_names'][] = $names[$cat_id];
|
||||
}
|
||||
}
|
||||
return $cat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of image orders available for users/visitors.
|
||||
* Each entry is an array containing
|
||||
* 0: name
|
||||
* 1: SQL ORDER command
|
||||
* 2: visiblity (true or false)
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
function get_category_preferred_image_orders()
|
||||
{
|
||||
global $conf, $page;
|
||||
|
||||
return trigger_change('get_category_preferred_image_orders', array(
|
||||
array(l10n('Default'), '', true),
|
||||
array(l10n('Photo title, A → Z'), 'name ASC', true),
|
||||
array(l10n('Photo title, Z → A'), 'name DESC', true),
|
||||
array(l10n('Date created, new → old'), 'date_creation DESC', true),
|
||||
array(l10n('Date created, old → new'), 'date_creation ASC', true),
|
||||
array(l10n('Date posted, new → old'), 'date_available DESC', true),
|
||||
array(l10n('Date posted, old → new'), 'date_available ASC', true),
|
||||
array(l10n('Rating score, high → low'), 'rating_score DESC', $conf['rate']),
|
||||
array(l10n('Rating score, low → high'), 'rating_score ASC', $conf['rate']),
|
||||
array(l10n('Visits, high → low'), 'hit DESC', true),
|
||||
array(l10n('Visits, low → high'), 'hit ASC', true),
|
||||
array(l10n('Permissions'), 'level DESC', is_admin()),
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign a template var useable with {html_options} from a list of categories
|
||||
*
|
||||
* @param array[] $categories (at least id,name,global_rank,uppercats for each)
|
||||
* @param int[] $selected ids of selected items
|
||||
* @param string $blockname variable name in template
|
||||
* @param bool $fullname full breadcrumb or not
|
||||
*/
|
||||
function display_select_categories($categories,
|
||||
$selecteds,
|
||||
$blockname,
|
||||
$fullname = true)
|
||||
{
|
||||
global $template;
|
||||
|
||||
$tpl_cats = array();
|
||||
foreach ($categories as $category)
|
||||
{
|
||||
if ($fullname)
|
||||
{
|
||||
$option = strip_tags(
|
||||
get_cat_display_name_cache(
|
||||
$category['uppercats'],
|
||||
null
|
||||
)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$option = str_repeat(' ',
|
||||
(3 * substr_count($category['global_rank'], '.')));
|
||||
$option.= '- ';
|
||||
$option.= strip_tags(
|
||||
trigger_change(
|
||||
'render_category_name',
|
||||
$category['name'],
|
||||
'display_select_categories'
|
||||
)
|
||||
);
|
||||
}
|
||||
$tpl_cats[ $category['id'] ] = $option;
|
||||
}
|
||||
|
||||
$template->assign( $blockname, $tpl_cats);
|
||||
$template->assign( $blockname.'_selected', $selecteds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as display_select_categories but categories are ordered by rank
|
||||
* @see display_select_categories()
|
||||
*/
|
||||
function display_select_cat_wrapper($query,
|
||||
$selecteds,
|
||||
$blockname,
|
||||
$fullname = true)
|
||||
{
|
||||
$categories = query2array($query);
|
||||
usort($categories, 'global_rank_compare');
|
||||
display_select_categories($categories, $selecteds, $blockname, $fullname);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all subcategory identifiers of given category ids
|
||||
*
|
||||
* @param int[] $ids
|
||||
* @return int[]
|
||||
*/
|
||||
function get_subcat_ids($ids)
|
||||
{
|
||||
$query = '
|
||||
SELECT DISTINCT(id)
|
||||
FROM '.CATEGORIES_TABLE.'
|
||||
WHERE ';
|
||||
foreach ($ids as $num => $category_id)
|
||||
{
|
||||
is_numeric($category_id)
|
||||
or trigger_error(
|
||||
'get_subcat_ids expecting numeric, not '.gettype($category_id),
|
||||
E_USER_WARNING
|
||||
);
|
||||
if ($num > 0)
|
||||
{
|
||||
$query.= '
|
||||
OR ';
|
||||
}
|
||||
$query.= 'uppercats '.DB_REGEX_OPERATOR.' \'(^|,)'.$category_id.'(,|$)\'';
|
||||
}
|
||||
$query.= '
|
||||
;';
|
||||
return query2array($query, null, 'id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a matching category id from a potential list of permalinks
|
||||
*
|
||||
* @param string[] $permalinks
|
||||
* @param int &$idx filled with the index in $permalinks that matches
|
||||
* @return int|null
|
||||
*/
|
||||
function get_cat_id_from_permalinks($permalinks, &$idx)
|
||||
{
|
||||
$in = '';
|
||||
foreach($permalinks as $permalink)
|
||||
{
|
||||
if ( !empty($in) ) $in.=', ';
|
||||
$in .= '\''.$permalink.'\'';
|
||||
}
|
||||
$query ='
|
||||
SELECT cat_id AS id, permalink, 1 AS is_old
|
||||
FROM '.OLD_PERMALINKS_TABLE.'
|
||||
WHERE permalink IN ('.$in.')
|
||||
UNION
|
||||
SELECT id, permalink, 0 AS is_old
|
||||
FROM '.CATEGORIES_TABLE.'
|
||||
WHERE permalink IN ('.$in.')
|
||||
;';
|
||||
$perma_hash = query2array($query, 'permalink');
|
||||
|
||||
if ( empty($perma_hash) )
|
||||
return null;
|
||||
for ($i=count($permalinks)-1; $i>=0; $i--)
|
||||
{
|
||||
if ( isset( $perma_hash[ $permalinks[$i] ] ) )
|
||||
{
|
||||
$idx = $i;
|
||||
$cat_id = $perma_hash[ $permalinks[$i] ]['id'];
|
||||
if ($perma_hash[ $permalinks[$i] ]['is_old'])
|
||||
{
|
||||
$query='
|
||||
UPDATE '.OLD_PERMALINKS_TABLE.' SET last_hit=NOW(), hit=hit+1
|
||||
WHERE permalink=\''.$permalinks[$i].'\' AND cat_id='.$cat_id.'
|
||||
LIMIT 1';
|
||||
pwg_query($query);
|
||||
}
|
||||
return $cat_id;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns display text for images counter of category
|
||||
*
|
||||
* @param int $cat_nb_images nb images directly in category
|
||||
* @param int $cat_count_images nb images in category (including subcats)
|
||||
* @param int $cat_count_categories nb subcats
|
||||
* @param bool $short_message if true append " in this album"
|
||||
* @param string $separator
|
||||
* @return string
|
||||
*/
|
||||
function get_display_images_count($cat_nb_images, $cat_count_images, $cat_count_categories, $short_message = true, $separator = '\n')
|
||||
{
|
||||
$display_text = '';
|
||||
|
||||
if ($cat_count_images > 0)
|
||||
{
|
||||
if ($cat_nb_images > 0 and $cat_nb_images < $cat_count_images)
|
||||
{
|
||||
$display_text.= get_display_images_count($cat_nb_images, $cat_nb_images, 0, $short_message, $separator).$separator;
|
||||
$cat_count_images-= $cat_nb_images;
|
||||
$cat_nb_images = 0;
|
||||
}
|
||||
|
||||
//at least one image direct or indirect
|
||||
$display_text.= l10n_dec('%d photo', '%d photos', $cat_count_images);
|
||||
|
||||
if ($cat_count_categories == 0 or $cat_nb_images == $cat_count_images)
|
||||
{
|
||||
//no descendant categories or descendants do not contain images
|
||||
if (!$short_message)
|
||||
{
|
||||
$display_text.= ' '.l10n('in this album');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$display_text.= ' '.l10n_dec('in %d sub-album', 'in %d sub-albums', $cat_count_categories);
|
||||
}
|
||||
}
|
||||
|
||||
return $display_text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a random photo among all photos inside an album (including sub-albums)
|
||||
*
|
||||
* @param array $category (at least id,uppercats,count_images)
|
||||
* @param bool $recursive
|
||||
* @return int|null
|
||||
*/
|
||||
function get_random_image_in_category($category, $recursive=true)
|
||||
{
|
||||
$image_id = null;
|
||||
if ($category['count_images']>0)
|
||||
{
|
||||
$query = '
|
||||
SELECT image_id
|
||||
FROM '.CATEGORIES_TABLE.' AS c
|
||||
INNER JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON ic.category_id = c.id
|
||||
WHERE ';
|
||||
if ($recursive)
|
||||
{
|
||||
$query.= '
|
||||
(c.id='.$category['id'].' OR uppercats LIKE \''.$category['uppercats'].',%\')';
|
||||
}
|
||||
else
|
||||
{
|
||||
$query.= '
|
||||
c.id='.$category['id'];
|
||||
}
|
||||
$query.= '
|
||||
'.get_sql_condition_FandF
|
||||
(
|
||||
array
|
||||
(
|
||||
'forbidden_categories' => 'c.id',
|
||||
'visible_categories' => 'c.id',
|
||||
'visible_images' => 'image_id',
|
||||
),
|
||||
"\n AND"
|
||||
).'
|
||||
ORDER BY '.DB_RANDOM_FUNCTION.'()
|
||||
LIMIT 1
|
||||
;';
|
||||
$result = pwg_query($query);
|
||||
if (pwg_db_num_rows($result) > 0)
|
||||
{
|
||||
list($image_id) = pwg_db_fetch_row($result);
|
||||
}
|
||||
}
|
||||
|
||||
return $image_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get computed array of categories, that means cache data of all categories
|
||||
* available for the current user (count_categories, count_images, etc.).
|
||||
*
|
||||
* @param array &$userdata
|
||||
* @param int $filter_days number of recent days to filter on or null
|
||||
* @return array
|
||||
*/
|
||||
function get_computed_categories(&$userdata, $filter_days=null)
|
||||
{
|
||||
$query = 'SELECT c.id AS cat_id, id_uppercat';
|
||||
$query.= ', global_rank';
|
||||
// Count by date_available to avoid count null
|
||||
$query .= ',
|
||||
MAX(date_available) AS date_last, COUNT(date_available) AS nb_images
|
||||
FROM '.CATEGORIES_TABLE.' as c
|
||||
LEFT JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON ic.category_id = c.id
|
||||
LEFT JOIN '.IMAGES_TABLE.' AS i
|
||||
ON ic.image_id = i.id
|
||||
AND i.level<='.$userdata['level'];
|
||||
|
||||
if ( isset($filter_days) )
|
||||
{
|
||||
$query .= ' AND i.date_available > '.pwg_db_get_recent_period_expression($filter_days);
|
||||
}
|
||||
|
||||
if ( !empty($userdata['forbidden_categories']) )
|
||||
{
|
||||
$query.= '
|
||||
WHERE c.id NOT IN ('.$userdata['forbidden_categories'].')';
|
||||
}
|
||||
|
||||
$query.= '
|
||||
GROUP BY c.id';
|
||||
|
||||
$result = pwg_query($query);
|
||||
|
||||
$userdata['last_photo_date'] = null;
|
||||
$cats = array();
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
$row['user_id'] = $userdata['id'];
|
||||
$row['nb_categories'] = 0;
|
||||
$row['count_categories'] = 0;
|
||||
$row['count_images'] = (int)$row['nb_images'];
|
||||
$row['max_date_last'] = $row['date_last'];
|
||||
if ($row['date_last'] > $userdata['last_photo_date'])
|
||||
{
|
||||
$userdata['last_photo_date'] = $row['date_last'];
|
||||
}
|
||||
|
||||
$cats[$row['cat_id']] = $row;
|
||||
}
|
||||
|
||||
// it is important to logically sort the albums because some operations
|
||||
// (like removal) rely on this logical order. Child album doesn't always
|
||||
// have a bigger id than its parent (if it was moved afterwards).
|
||||
uasort($cats, 'global_rank_compare');
|
||||
|
||||
foreach ($cats as $cat)
|
||||
{
|
||||
if ( !isset( $cat['id_uppercat'] ) )
|
||||
continue;
|
||||
|
||||
// Piwigo before 2.5.3 may have generated inconsistent permissions, ie
|
||||
// private album A1/A2 permitted to user U1 but private album A1 not
|
||||
// permitted to U1.
|
||||
//
|
||||
// TODO 2.7: add an upgrade script to repair permissions and remove this
|
||||
// test
|
||||
if ( !isset($cats[ $cat['id_uppercat'] ]))
|
||||
continue;
|
||||
|
||||
$parent = & $cats[ $cat['id_uppercat'] ];
|
||||
$parent['nb_categories']++;
|
||||
|
||||
do
|
||||
{
|
||||
$parent['count_images'] += $cat['nb_images'];
|
||||
$parent['count_categories']++;
|
||||
|
||||
if ((empty($parent['max_date_last'])) or ($parent['max_date_last'] < $cat['date_last']))
|
||||
{
|
||||
$parent['max_date_last'] = $cat['date_last'];
|
||||
}
|
||||
|
||||
if ( !isset( $parent['id_uppercat'] ) )
|
||||
break;
|
||||
$parent = & $cats[$parent['id_uppercat']];
|
||||
}
|
||||
while (true);
|
||||
unset($parent);
|
||||
}
|
||||
|
||||
if ( isset($filter_days) )
|
||||
{
|
||||
foreach ($cats as $category)
|
||||
{
|
||||
if (empty($category['max_date_last']))
|
||||
{
|
||||
remove_computed_category($cats, $category);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $cats;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a category from computed array of categories and updates counters.
|
||||
*
|
||||
* @param array &$cats
|
||||
* @param array $cat category to remove
|
||||
*/
|
||||
function remove_computed_category(&$cats, $cat)
|
||||
{
|
||||
if ( isset($cats[$cat['id_uppercat']]) )
|
||||
{
|
||||
$parent = &$cats[ $cat['id_uppercat'] ];
|
||||
$parent['nb_categories']--;
|
||||
|
||||
do
|
||||
{
|
||||
$parent['count_images'] -= $cat['nb_images'];
|
||||
$parent['count_categories'] -= 1+$cat['count_categories'];
|
||||
|
||||
if ( !isset($cats[$parent['id_uppercat']]) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
$parent = &$cats[$parent['id_uppercat']];
|
||||
}
|
||||
while (true);
|
||||
}
|
||||
|
||||
unset($cats[$cat['cat_id']]);
|
||||
}
|
||||
|
||||
?>
|
||||
539
zoesch.de/galerie/include/functions_comment.inc.php
Normal file
539
zoesch.de/galerie/include/functions_comment.inc.php
Normal file
@@ -0,0 +1,539 @@
|
||||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Piwigo - a PHP based photo gallery |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright(C) 2008-2016 Piwigo Team http://piwigo.org |
|
||||
// | Copyright(C) 2003-2008 PhpWebGallery Team http://phpwebgallery.net |
|
||||
// | Copyright(C) 2002-2003 Pierrick LE GALL http://le-gall.net/pierrick |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
* @package functions\comment
|
||||
*/
|
||||
|
||||
|
||||
add_event_handler('user_comment_check', 'user_comment_check');
|
||||
|
||||
/**
|
||||
* Does basic check on comment and returns action to perform.
|
||||
* This method is called by a trigger_change()
|
||||
*
|
||||
* @param string $action before check
|
||||
* @param array $comment
|
||||
* @return string validate, moderate, reject
|
||||
*/
|
||||
function user_comment_check($action, $comment)
|
||||
{
|
||||
global $conf,$user;
|
||||
|
||||
if ($action=='reject')
|
||||
return $action;
|
||||
|
||||
$my_action = $conf['comment_spam_reject'] ? 'reject':'moderate';
|
||||
|
||||
if ($action==$my_action)
|
||||
return $action;
|
||||
|
||||
// we do here only BASIC spam check (plugins can do more)
|
||||
if ( !is_a_guest() )
|
||||
return $action;
|
||||
|
||||
$link_count = preg_match_all( '/https?:\/\//',
|
||||
$comment['content'], $matches);
|
||||
|
||||
if ( strpos($comment['author'], 'http://')!==false )
|
||||
{
|
||||
$link_count++;
|
||||
}
|
||||
|
||||
if ( $link_count>$conf['comment_spam_max_links'] )
|
||||
{
|
||||
$_POST['cr'][] = 'links';
|
||||
return $my_action;
|
||||
}
|
||||
return $action;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to insert a user comment and returns action to perform.
|
||||
*
|
||||
* @param array &$comm
|
||||
* @param string $key secret key sent back to the browser
|
||||
* @param array &$infos output array of error messages
|
||||
* @return string validate, moderate, reject
|
||||
*/
|
||||
function insert_user_comment(&$comm, $key, &$infos)
|
||||
{
|
||||
global $conf, $user;
|
||||
|
||||
$comm = array_merge( $comm,
|
||||
array(
|
||||
'ip' => $_SERVER['REMOTE_ADDR'],
|
||||
'agent' => $_SERVER['HTTP_USER_AGENT']
|
||||
)
|
||||
);
|
||||
|
||||
$infos = array();
|
||||
if (!$conf['comments_validation'] or is_admin())
|
||||
{
|
||||
$comment_action='validate'; //one of validate, moderate, reject
|
||||
}
|
||||
else
|
||||
{
|
||||
$comment_action='moderate'; //one of validate, moderate, reject
|
||||
}
|
||||
|
||||
// display author field if the user status is guest or generic
|
||||
if (!is_classic_user())
|
||||
{
|
||||
if ( empty($comm['author']) )
|
||||
{
|
||||
if ($conf['comments_author_mandatory'])
|
||||
{
|
||||
$infos[] = l10n('Username is mandatory');
|
||||
$comment_action='reject';
|
||||
}
|
||||
$comm['author'] = 'guest';
|
||||
}
|
||||
$comm['author_id'] = $conf['guest_id'];
|
||||
// if a guest try to use the name of an already existing user, he must be
|
||||
// rejected
|
||||
if ( $comm['author'] != 'guest' )
|
||||
{
|
||||
$query = '
|
||||
SELECT COUNT(*) AS user_exists
|
||||
FROM '.USERS_TABLE.'
|
||||
WHERE '.$conf['user_fields']['username']." = '".addslashes($comm['author'])."'";
|
||||
$row = pwg_db_fetch_assoc( pwg_query( $query ) );
|
||||
if ( $row['user_exists'] == 1 )
|
||||
{
|
||||
$infos[] = l10n('This login is already used by another user');
|
||||
$comment_action='reject';
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$comm['author'] = addslashes($user['username']);
|
||||
$comm['author_id'] = $user['id'];
|
||||
}
|
||||
|
||||
if ( empty($comm['content']) )
|
||||
{ // empty comment content
|
||||
$comment_action='reject';
|
||||
}
|
||||
|
||||
if ( !verify_ephemeral_key(@$key, $comm['image_id']) )
|
||||
{
|
||||
$comment_action='reject';
|
||||
$_POST['cr'][] = 'key'; // rvelices: I use this outside to see how spam robots work
|
||||
}
|
||||
|
||||
// website
|
||||
if (!empty($comm['website_url']))
|
||||
{
|
||||
if (!$conf['comments_enable_website'])
|
||||
{ // honeypot: if the field is disabled, it should be empty !
|
||||
$comment_action='reject';
|
||||
$_POST['cr'][] = 'website_url';
|
||||
}
|
||||
else
|
||||
{
|
||||
$comm['website_url'] = strip_tags($comm['website_url']);
|
||||
if (!preg_match('/^https?/i', $comm['website_url']))
|
||||
{
|
||||
$comm['website_url'] = 'http://'.$comm['website_url'];
|
||||
}
|
||||
if (!url_check_format($comm['website_url']))
|
||||
{
|
||||
$infos[] = l10n('Your website URL is invalid');
|
||||
$comment_action='reject';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// email
|
||||
if (empty($comm['email']))
|
||||
{
|
||||
if (!empty($user['email']))
|
||||
{
|
||||
$comm['email'] = $user['email'];
|
||||
}
|
||||
elseif ($conf['comments_email_mandatory'])
|
||||
{
|
||||
$infos[] = l10n('Email address is missing. Please specify an email address.');
|
||||
$comment_action='reject';
|
||||
}
|
||||
}
|
||||
elseif (!email_check_format($comm['email']))
|
||||
{
|
||||
$infos[] = l10n('mail address must be like xxx@yyy.eee (example : jack@altern.org)');
|
||||
$comment_action='reject';
|
||||
}
|
||||
|
||||
// anonymous id = ip address
|
||||
$ip_components = explode('.', $comm['ip']);
|
||||
if (count($ip_components) > 3)
|
||||
{
|
||||
array_pop($ip_components);
|
||||
}
|
||||
$anonymous_id = implode('.', $ip_components);
|
||||
|
||||
if ($comment_action!='reject' and $conf['anti-flood_time']>0 and !is_admin())
|
||||
{ // anti-flood system
|
||||
$reference_date = pwg_db_get_flood_period_expression($conf['anti-flood_time']);
|
||||
|
||||
$query = '
|
||||
SELECT count(1) FROM '.COMMENTS_TABLE.'
|
||||
WHERE date > '.$reference_date.'
|
||||
AND author_id = '.$comm['author_id'];
|
||||
if (!is_classic_user())
|
||||
{
|
||||
$query.= '
|
||||
AND anonymous_id LIKE "'.$anonymous_id.'.%"';
|
||||
}
|
||||
$query.= '
|
||||
;';
|
||||
|
||||
list($counter) = pwg_db_fetch_row(pwg_query($query));
|
||||
if ( $counter > 0 )
|
||||
{
|
||||
$infos[] = l10n('Anti-flood system : please wait for a moment before trying to post another comment');
|
||||
$comment_action='reject';
|
||||
$_POST['cr'][] = 'flood_time';
|
||||
}
|
||||
}
|
||||
|
||||
// perform more spam check
|
||||
$comment_action = trigger_change('user_comment_check',
|
||||
$comment_action, $comm
|
||||
);
|
||||
|
||||
if ( $comment_action!='reject' )
|
||||
{
|
||||
$query = '
|
||||
INSERT INTO '.COMMENTS_TABLE.'
|
||||
(author, author_id, anonymous_id, content, date, validated, validation_date, image_id, website_url, email)
|
||||
VALUES (
|
||||
\''.$comm['author'].'\',
|
||||
'.$comm['author_id'].',
|
||||
\''.$comm['ip'].'\',
|
||||
\''.$comm['content'].'\',
|
||||
NOW(),
|
||||
\''.($comment_action=='validate' ? 'true':'false').'\',
|
||||
'.($comment_action=='validate' ? 'NOW()':'NULL').',
|
||||
'.$comm['image_id'].',
|
||||
'.(!empty($comm['website_url']) ? '\''.$comm['website_url'].'\'' : 'NULL').',
|
||||
'.(!empty($comm['email']) ? '\''.$comm['email'].'\'' : 'NULL').'
|
||||
)
|
||||
';
|
||||
pwg_query($query);
|
||||
$comm['id'] = pwg_db_insert_id(COMMENTS_TABLE);
|
||||
|
||||
invalidate_user_cache_nb_comments();
|
||||
|
||||
if ( ($conf['email_admin_on_comment'] && 'validate' == $comment_action)
|
||||
or ($conf['email_admin_on_comment_validation'] and 'moderate' == $comment_action))
|
||||
{
|
||||
include_once(PHPWG_ROOT_PATH.'include/functions_mail.inc.php');
|
||||
|
||||
$comment_url = get_absolute_root_url().'comments.php?comment_id='.$comm['id'];
|
||||
|
||||
$keyargs_content = array(
|
||||
get_l10n_args('Author: %s', stripslashes($comm['author']) ),
|
||||
get_l10n_args('Email: %s', stripslashes($comm['email']) ),
|
||||
get_l10n_args('Comment: %s', stripslashes($comm['content']) ),
|
||||
get_l10n_args(''),
|
||||
get_l10n_args('Manage this user comment: %s', $comment_url),
|
||||
);
|
||||
|
||||
if ('moderate' == $comment_action)
|
||||
{
|
||||
$keyargs_content[] = get_l10n_args('(!) This comment requires validation');
|
||||
}
|
||||
|
||||
pwg_mail_notification_admins(
|
||||
get_l10n_args('Comment by %s', stripslashes($comm['author']) ),
|
||||
$keyargs_content
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $comment_action;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to delete a (or more) user comment.
|
||||
* only admin can delete all comments
|
||||
* other users can delete their own comments
|
||||
*
|
||||
* @param int|int[] $comment_id
|
||||
* @return bool false if nothing deleted
|
||||
*/
|
||||
function delete_user_comment($comment_id)
|
||||
{
|
||||
$user_where_clause = '';
|
||||
if (!is_admin())
|
||||
{
|
||||
$user_where_clause = ' AND author_id = \''.$GLOBALS['user']['id'].'\'';
|
||||
}
|
||||
|
||||
if (is_array($comment_id))
|
||||
$where_clause = 'id IN('.implode(',', $comment_id).')';
|
||||
else
|
||||
$where_clause = 'id = '.$comment_id;
|
||||
|
||||
$query = '
|
||||
DELETE FROM '.COMMENTS_TABLE.'
|
||||
WHERE '.$where_clause.
|
||||
$user_where_clause.'
|
||||
;';
|
||||
|
||||
if ( pwg_db_changes(pwg_query($query)) )
|
||||
{
|
||||
invalidate_user_cache_nb_comments();
|
||||
|
||||
email_admin('delete',
|
||||
array('author' => $GLOBALS['user']['username'],
|
||||
'comment_id' => $comment_id
|
||||
));
|
||||
trigger_notify('user_comment_deletion', $comment_id);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to update a user comment
|
||||
* only admin can update all comments
|
||||
* users can edit their own comments if admin allow them
|
||||
*
|
||||
* @param array $comment
|
||||
* @param string $post_key secret key sent back to the browser
|
||||
* @return string validate, moderate, reject
|
||||
*/
|
||||
|
||||
function update_user_comment($comment, $post_key)
|
||||
{
|
||||
global $conf, $page;
|
||||
|
||||
$comment_action = 'validate';
|
||||
|
||||
if ( !verify_ephemeral_key($post_key, $comment['image_id']) )
|
||||
{
|
||||
$comment_action='reject';
|
||||
}
|
||||
elseif (!$conf['comments_validation'] or is_admin()) // should the updated comment must be validated
|
||||
{
|
||||
$comment_action='validate'; //one of validate, moderate, reject
|
||||
}
|
||||
else
|
||||
{
|
||||
$comment_action='moderate'; //one of validate, moderate, reject
|
||||
}
|
||||
|
||||
// perform more spam check
|
||||
$comment_action =
|
||||
trigger_change('user_comment_check',
|
||||
$comment_action,
|
||||
array_merge($comment,
|
||||
array('author' => $GLOBALS['user']['username'])
|
||||
)
|
||||
);
|
||||
|
||||
// website
|
||||
if (!empty($comment['website_url']))
|
||||
{
|
||||
$comm['website_url'] = strip_tags($comm['website_url']);
|
||||
if (!preg_match('/^https?/i', $comment['website_url']))
|
||||
{
|
||||
$comment['website_url'] = 'http://'.$comment['website_url'];
|
||||
}
|
||||
if (!url_check_format($comment['website_url']))
|
||||
{
|
||||
$page['errors'][] = l10n('Your website URL is invalid');
|
||||
$comment_action='reject';
|
||||
}
|
||||
}
|
||||
|
||||
if ( $comment_action!='reject' )
|
||||
{
|
||||
$user_where_clause = '';
|
||||
if (!is_admin())
|
||||
{
|
||||
$user_where_clause = ' AND author_id = \''.
|
||||
$GLOBALS['user']['id'].'\'';
|
||||
}
|
||||
|
||||
$query = '
|
||||
UPDATE '.COMMENTS_TABLE.'
|
||||
SET content = \''.$comment['content'].'\',
|
||||
website_url = '.(!empty($comment['website_url']) ? '\''.$comment['website_url'].'\'' : 'NULL').',
|
||||
validated = \''.($comment_action=='validate' ? 'true':'false').'\',
|
||||
validation_date = '.($comment_action=='validate' ? 'NOW()':'NULL').'
|
||||
WHERE id = '.$comment['comment_id'].
|
||||
$user_where_clause.'
|
||||
;';
|
||||
$result = pwg_query($query);
|
||||
|
||||
// mail admin and ask to validate the comment
|
||||
if ($result and $conf['email_admin_on_comment_validation'] and 'moderate' == $comment_action)
|
||||
{
|
||||
include_once(PHPWG_ROOT_PATH.'include/functions_mail.inc.php');
|
||||
|
||||
$comment_url = get_absolute_root_url().'comments.php?comment_id='.$comment['comment_id'];
|
||||
|
||||
$keyargs_content = array(
|
||||
get_l10n_args('Author: %s', stripslashes($GLOBALS['user']['username']) ),
|
||||
get_l10n_args('Comment: %s', stripslashes($comment['content']) ),
|
||||
get_l10n_args(''),
|
||||
get_l10n_args('Manage this user comment: %s', $comment_url),
|
||||
get_l10n_args('(!) This comment requires validation'),
|
||||
);
|
||||
|
||||
pwg_mail_notification_admins(
|
||||
get_l10n_args('Comment by %s', stripslashes($GLOBALS['user']['username']) ),
|
||||
$keyargs_content
|
||||
);
|
||||
}
|
||||
// just mail admin
|
||||
elseif ($result)
|
||||
{
|
||||
email_admin('edit', array('author' => $GLOBALS['user']['username'],
|
||||
'content' => stripslashes($comment['content'])) );
|
||||
}
|
||||
}
|
||||
|
||||
return $comment_action;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies admins about updated or deleted comment.
|
||||
* Only used when no validation is needed, otherwise pwg_mail_notification_admins() is used.
|
||||
*
|
||||
* @param string $action edit, delete
|
||||
* @param array $comment
|
||||
*/
|
||||
function email_admin($action, $comment)
|
||||
{
|
||||
global $conf;
|
||||
|
||||
if (!in_array($action, array('edit', 'delete'))
|
||||
or (($action=='edit') and !$conf['email_admin_on_comment_edition'])
|
||||
or (($action=='delete') and !$conf['email_admin_on_comment_deletion']))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'include/functions_mail.inc.php');
|
||||
|
||||
$keyargs_content = array(
|
||||
get_l10n_args('Author: %s', $comment['author']),
|
||||
);
|
||||
|
||||
if ($action=='delete')
|
||||
{
|
||||
$keyargs_content[] = get_l10n_args('This author removed the comment with id %d', $comment['comment_id']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$keyargs_content[] = get_l10n_args('This author modified following comment:');
|
||||
$keyargs_content[] = get_l10n_args('Comment: %s', $comment['content']);
|
||||
}
|
||||
|
||||
pwg_mail_notification_admins(
|
||||
get_l10n_args('Comment by %s', $comment['author']),
|
||||
$keyargs_content
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the author id of a comment
|
||||
*
|
||||
* @param int $comment_id
|
||||
* @param bool $die_on_error
|
||||
* @return int
|
||||
*/
|
||||
function get_comment_author_id($comment_id, $die_on_error=true)
|
||||
{
|
||||
$query = '
|
||||
SELECT
|
||||
author_id
|
||||
FROM '.COMMENTS_TABLE.'
|
||||
WHERE id = '.$comment_id.'
|
||||
;';
|
||||
$result = pwg_query($query);
|
||||
if (pwg_db_num_rows($result) == 0)
|
||||
{
|
||||
if ($die_on_error)
|
||||
{
|
||||
fatal_error('Unknown comment identifier');
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
list($author_id) = pwg_db_fetch_row($result);
|
||||
|
||||
return $author_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to validate a user comment.
|
||||
*
|
||||
* @param int|int[] $comment_id
|
||||
*/
|
||||
function validate_user_comment($comment_id)
|
||||
{
|
||||
if (is_array($comment_id))
|
||||
$where_clause = 'id IN('.implode(',', $comment_id).')';
|
||||
else
|
||||
$where_clause = 'id = '.$comment_id;
|
||||
|
||||
$query = '
|
||||
UPDATE '.COMMENTS_TABLE.'
|
||||
SET validated = \'true\'
|
||||
, validation_date = NOW()
|
||||
WHERE '.$where_clause.'
|
||||
;';
|
||||
pwg_query($query);
|
||||
|
||||
invalidate_user_cache_nb_comments();
|
||||
trigger_notify('user_comment_validation', $comment_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears cache of nb comments for all users
|
||||
*/
|
||||
function invalidate_user_cache_nb_comments()
|
||||
{
|
||||
global $user;
|
||||
|
||||
unset($user['nb_available_comments']);
|
||||
|
||||
$query = '
|
||||
UPDATE '.USER_CACHE_TABLE.'
|
||||
SET nb_available_comments = NULL
|
||||
;';
|
||||
pwg_query($query);
|
||||
}
|
||||
|
||||
?>
|
||||
139
zoesch.de/galerie/include/functions_cookie.inc.php
Normal file
139
zoesch.de/galerie/include/functions_cookie.inc.php
Normal file
@@ -0,0 +1,139 @@
|
||||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Piwigo - a PHP based photo gallery |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright(C) 2008-2016 Piwigo Team http://piwigo.org |
|
||||
// | Copyright(C) 2003-2008 PhpWebGallery Team http://phpwebgallery.net |
|
||||
// | Copyright(C) 2002-2003 Pierrick LE GALL http://le-gall.net/pierrick |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
* @package functions\cookie
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Returns the path to use for the Piwigo cookie.
|
||||
* If Piwigo is installed on :
|
||||
* http://domain.org/meeting/gallery/
|
||||
* it will return : "/meeting/gallery"
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function cookie_path()
|
||||
{
|
||||
if ( isset($_SERVER['REDIRECT_SCRIPT_NAME']) and
|
||||
!empty($_SERVER['REDIRECT_SCRIPT_NAME']) )
|
||||
{
|
||||
$scr = $_SERVER['REDIRECT_SCRIPT_NAME'];
|
||||
}
|
||||
else if ( isset($_SERVER['REDIRECT_URL']) )
|
||||
{
|
||||
// mod_rewrite is activated for upper level directories. we must set the
|
||||
// cookie to the path shown in the browser otherwise it will be discarded.
|
||||
if
|
||||
(
|
||||
isset($_SERVER['PATH_INFO']) and !empty($_SERVER['PATH_INFO']) and
|
||||
($_SERVER['REDIRECT_URL'] !== $_SERVER['PATH_INFO']) and
|
||||
(substr($_SERVER['REDIRECT_URL'],-strlen($_SERVER['PATH_INFO']))
|
||||
== $_SERVER['PATH_INFO'])
|
||||
)
|
||||
{
|
||||
$scr = substr($_SERVER['REDIRECT_URL'], 0,
|
||||
strlen($_SERVER['REDIRECT_URL'])-strlen($_SERVER['PATH_INFO']));
|
||||
}
|
||||
else
|
||||
{
|
||||
$scr = $_SERVER['REDIRECT_URL'];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$scr = $_SERVER['SCRIPT_NAME'];
|
||||
}
|
||||
|
||||
$scr = substr($scr,0,strrpos( $scr,'/'));
|
||||
|
||||
// add a trailing '/' if needed
|
||||
if ((strlen($scr) == 0) or ($scr{strlen($scr)-1} !== '/'))
|
||||
{
|
||||
$scr .= '/';
|
||||
}
|
||||
|
||||
if ( substr(PHPWG_ROOT_PATH,0,3)=='../')
|
||||
{ // this is maybe a plugin inside pwg directory
|
||||
// TODO - what if it is an external script outside PWG ?
|
||||
$scr = $scr.PHPWG_ROOT_PATH;
|
||||
while (1)
|
||||
{
|
||||
$new = preg_replace('#[^/]+/\.\.(/|$)#', '', $scr);
|
||||
if ($new==$scr)
|
||||
{
|
||||
break;
|
||||
}
|
||||
$scr=$new;
|
||||
}
|
||||
}
|
||||
return $scr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Persistently stores a variable in pwg cookie.
|
||||
* Set $value to null to delete the cookie.
|
||||
*
|
||||
* @param string $car
|
||||
* @param mixed $value
|
||||
* @param int|null $expire
|
||||
* @return bool
|
||||
*/
|
||||
function pwg_set_cookie_var($var, $value, $expire=null)
|
||||
{
|
||||
if ($value==null or $expire===0)
|
||||
{
|
||||
unset($_COOKIE['pwg_'.$var]);
|
||||
return setcookie('pwg_'.$var, false, 0, cookie_path());
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
$_COOKIE['pwg_'.$var] = $value;
|
||||
$expire = is_numeric($expire) ? $expire : strtotime('+10 years');
|
||||
return setcookie('pwg_'.$var, $value, $expire, cookie_path());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the value of a persistent variable in pwg cookie
|
||||
* @see pwg_set_cookie_var
|
||||
*
|
||||
* @param string $var
|
||||
* @param mixed $default
|
||||
* @return mixed
|
||||
*/
|
||||
function pwg_get_cookie_var($var, $default = null)
|
||||
{
|
||||
if (isset($_COOKIE['pwg_'.$var]))
|
||||
{
|
||||
return $_COOKIE['pwg_'.$var];
|
||||
}
|
||||
else
|
||||
{
|
||||
return $default;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
52
zoesch.de/galerie/include/functions_filter.inc.php
Normal file
52
zoesch.de/galerie/include/functions_filter.inc.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Piwigo - a PHP based photo gallery |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright(C) 2008-2016 Piwigo Team http://piwigo.org |
|
||||
// | Copyright(C) 2003-2008 PhpWebGallery Team http://phpwebgallery.net |
|
||||
// | Copyright(C) 2002-2003 Pierrick LE GALL http://le-gall.net/pierrick |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
* @package functions\filter
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Updates data of categories with filtered values
|
||||
*
|
||||
* @param array &$cats
|
||||
*/
|
||||
function update_cats_with_filtered_data(&$cats)
|
||||
{
|
||||
global $filter;
|
||||
|
||||
if ($filter['enabled'])
|
||||
{
|
||||
$upd_fields = array('date_last', 'max_date_last', 'count_images', 'count_categories', 'nb_images');
|
||||
|
||||
foreach ($cats as $cat_id => $category)
|
||||
{
|
||||
foreach ($upd_fields as $upd_field)
|
||||
{
|
||||
$cats[$cat_id][$upd_field] = $filter['categories'][$category['id']][$upd_field];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
662
zoesch.de/galerie/include/functions_html.inc.php
Normal file
662
zoesch.de/galerie/include/functions_html.inc.php
Normal file
@@ -0,0 +1,662 @@
|
||||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Piwigo - a PHP based photo gallery |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright(C) 2008-2016 Piwigo Team http://piwigo.org |
|
||||
// | Copyright(C) 2003-2008 PhpWebGallery Team http://phpwebgallery.net |
|
||||
// | Copyright(C) 2002-2003 Pierrick LE GALL http://le-gall.net/pierrick |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
* @package functions\html
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Generates breadcrumb from categories list.
|
||||
* Categories string returned contains categories as given in the input
|
||||
* array $cat_informations. $cat_informations array must be an array
|
||||
* of array( id=>?, name=>?, permalink=>?). If url input parameter is null,
|
||||
* returns only the categories name without links.
|
||||
*
|
||||
* @param array $cat_informations
|
||||
* @param string|null $url
|
||||
* @return string
|
||||
*/
|
||||
function get_cat_display_name($cat_informations, $url='')
|
||||
{
|
||||
global $conf;
|
||||
|
||||
//$output = '<a href="'.get_absolute_root_url().$conf['home_page'].'">'.l10n('Home').'</a>';
|
||||
$output = '';
|
||||
$is_first=true;
|
||||
|
||||
foreach ($cat_informations as $cat)
|
||||
{
|
||||
is_array($cat) or trigger_error(
|
||||
'get_cat_display_name wrong type for category ', E_USER_WARNING
|
||||
);
|
||||
|
||||
$cat['name'] = trigger_change(
|
||||
'render_category_name',
|
||||
$cat['name'],
|
||||
'get_cat_display_name'
|
||||
);
|
||||
|
||||
if ($is_first)
|
||||
{
|
||||
$is_first=false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$output.= $conf['level_separator'];
|
||||
}
|
||||
|
||||
if ( !isset($url) )
|
||||
{
|
||||
$output.= $cat['name'];
|
||||
}
|
||||
elseif ($url == '')
|
||||
{
|
||||
$output.= '<a href="'
|
||||
.make_index_url(
|
||||
array(
|
||||
'category' => $cat,
|
||||
)
|
||||
)
|
||||
.'">';
|
||||
$output.= $cat['name'].'</a>';
|
||||
}
|
||||
else
|
||||
{
|
||||
$output.= '<a href="'.PHPWG_ROOT_PATH.$url.$cat['id'].'">';
|
||||
$output.= $cat['name'].'</a>';
|
||||
}
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates breadcrumb from categories list using a cache.
|
||||
* @see get_cat_display_name()
|
||||
*
|
||||
* @param string $uppercats
|
||||
* @param string|null $url
|
||||
* @param bool $single_link
|
||||
* @param string|null $link_class
|
||||
* @return string
|
||||
*/
|
||||
function get_cat_display_name_cache($uppercats,
|
||||
$url = '',
|
||||
$single_link = false,
|
||||
$link_class = null,
|
||||
$auth_key=null)
|
||||
{
|
||||
global $cache, $conf;
|
||||
|
||||
$add_url_params = array();
|
||||
if (isset($auth_key))
|
||||
{
|
||||
$add_url_params['auth'] = $auth_key;
|
||||
}
|
||||
|
||||
if (!isset($cache['cat_names']))
|
||||
{
|
||||
$query = '
|
||||
SELECT id, name, permalink
|
||||
FROM '.CATEGORIES_TABLE.'
|
||||
;';
|
||||
$cache['cat_names'] = query2array($query, 'id');
|
||||
}
|
||||
|
||||
$output = '';
|
||||
if ($single_link)
|
||||
{
|
||||
$single_url = add_url_params(get_root_url().$url.array_pop(explode(',', $uppercats)), $add_url_params);
|
||||
$output.= '<a href="'.$single_url.'"';
|
||||
if (isset($link_class))
|
||||
{
|
||||
$output.= ' class="'.$link_class.'"';
|
||||
}
|
||||
$output.= '>';
|
||||
}
|
||||
$is_first = true;
|
||||
foreach (explode(',', $uppercats) as $category_id)
|
||||
{
|
||||
$cat = $cache['cat_names'][$category_id];
|
||||
|
||||
$cat['name'] = trigger_change(
|
||||
'render_category_name',
|
||||
$cat['name'],
|
||||
'get_cat_display_name_cache'
|
||||
);
|
||||
|
||||
if ($is_first)
|
||||
{
|
||||
$is_first = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$output.= $conf['level_separator'];
|
||||
}
|
||||
|
||||
if ( !isset($url) or $single_link )
|
||||
{
|
||||
$output.= $cat['name'];
|
||||
}
|
||||
elseif ($url == '')
|
||||
{
|
||||
$output.= '
|
||||
<a href="'
|
||||
.add_url_params(
|
||||
make_index_url(
|
||||
array(
|
||||
'category' => $cat,
|
||||
)
|
||||
),
|
||||
$add_url_params
|
||||
)
|
||||
.'">'.$cat['name'].'</a>';
|
||||
}
|
||||
else
|
||||
{
|
||||
$output.= '
|
||||
<a href="'.PHPWG_ROOT_PATH.$url.$category_id.'">'.$cat['name'].'</a>';
|
||||
}
|
||||
}
|
||||
|
||||
if ($single_link and isset($single_url))
|
||||
{
|
||||
$output.= '</a>';
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates breadcrumb for a category.
|
||||
* @see get_cat_display_name()
|
||||
*
|
||||
* @param int $cat_id
|
||||
* @param string|null $url
|
||||
* @return string
|
||||
*/
|
||||
function get_cat_display_name_from_id($cat_id, $url = '')
|
||||
{
|
||||
$cat_info = get_cat_info($cat_id);
|
||||
return get_cat_display_name($cat_info['upper_names'], $url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply basic markdown transformations to a text.
|
||||
* newlines becomes br tags
|
||||
* _word_ becomes underline
|
||||
* /word/ becomes italic
|
||||
* *word* becomes bolded
|
||||
* urls becomes a tags
|
||||
*
|
||||
* @param string $content
|
||||
* @return string
|
||||
*/
|
||||
function render_comment_content($content)
|
||||
{
|
||||
$content = htmlspecialchars($content);
|
||||
$pattern = '/(https?:\/\/\S*)/';
|
||||
$replacement = '<a href="$1" rel="nofollow">$1</a>';
|
||||
$content = preg_replace($pattern, $replacement, $content);
|
||||
|
||||
$content = nl2br($content);
|
||||
|
||||
// replace _word_ by an underlined word
|
||||
$pattern = '/\b_(\S*)_\b/';
|
||||
$replacement = '<span style="text-decoration:underline;">$1</span>';
|
||||
$content = preg_replace($pattern, $replacement, $content);
|
||||
|
||||
// replace *word* by a bolded word
|
||||
$pattern = '/\b\*(\S*)\*\b/';
|
||||
$replacement = '<span style="font-weight:bold;">$1</span>';
|
||||
$content = preg_replace($pattern, $replacement, $content);
|
||||
|
||||
// replace /word/ by an italic word
|
||||
$pattern = "/\/(\S*)\/(\s)/";
|
||||
$replacement = '<span style="font-style:italic;">$1$2</span>';
|
||||
$content = preg_replace($pattern, $replacement, $content);
|
||||
|
||||
// TODO : add a trigger
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Callback used for sorting by name.
|
||||
*/
|
||||
function name_compare($a, $b)
|
||||
{
|
||||
return strcmp(strtolower($a['name']), strtolower($b['name']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback used for sorting by name (slug) with cache.
|
||||
*/
|
||||
function tag_alpha_compare($a, $b)
|
||||
{
|
||||
global $cache;
|
||||
|
||||
foreach (array($a, $b) as $tag)
|
||||
{
|
||||
if (!isset($cache[__FUNCTION__][ $tag['name'] ]))
|
||||
{
|
||||
$cache[__FUNCTION__][ $tag['name'] ] = pwg_transliterate($tag['name']);
|
||||
}
|
||||
}
|
||||
|
||||
return strcmp($cache[__FUNCTION__][ $a['name'] ], $cache[__FUNCTION__][ $b['name'] ]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Exits the current script (or redirect to login page if not logged).
|
||||
*/
|
||||
function access_denied()
|
||||
{
|
||||
global $user, $conf;
|
||||
|
||||
$login_url =
|
||||
get_root_url().'identification.php?redirect='
|
||||
.urlencode(urlencode($_SERVER['REQUEST_URI']));
|
||||
|
||||
if ( isset($user) and !is_a_guest() )
|
||||
{
|
||||
set_status_header(401);
|
||||
|
||||
echo '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">';
|
||||
echo '<div style="text-align:center;">'.l10n('You are not authorized to access the requested page').'<br>';
|
||||
echo '<a href="'.get_root_url().'identification.php">'.l10n('Identification').'</a> ';
|
||||
echo '<a href="'.make_index_url().'">'.l10n('Home').'</a></div>';
|
||||
echo str_repeat( ' ', 512); //IE6 doesn't error output if below a size
|
||||
exit();
|
||||
}
|
||||
elseif (!$conf['guest_access'] and is_a_guest())
|
||||
{
|
||||
redirect_http($login_url);
|
||||
}
|
||||
else
|
||||
{
|
||||
redirect_html($login_url);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Exits the current script with 403 code.
|
||||
* @todo nice display if $template loaded
|
||||
*
|
||||
* @param string $msg
|
||||
* @param string|null $alternate_url redirect to this url
|
||||
*/
|
||||
function page_forbidden($msg, $alternate_url=null)
|
||||
{
|
||||
set_status_header(403);
|
||||
if ($alternate_url==null)
|
||||
$alternate_url = make_index_url();
|
||||
redirect_html( $alternate_url,
|
||||
'<div style="text-align:left; margin-left:5em;margin-bottom:5em;">
|
||||
<h1 style="text-align:left; font-size:36px;">'.l10n('Forbidden').'</h1><br>'
|
||||
.$msg.'</div>',
|
||||
5 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Exits the current script with 400 code.
|
||||
* @todo nice display if $template loaded
|
||||
*
|
||||
* @param string $msg
|
||||
* @param string|null $alternate_url redirect to this url
|
||||
*/
|
||||
function bad_request($msg, $alternate_url=null)
|
||||
{
|
||||
set_status_header(400);
|
||||
if ($alternate_url==null)
|
||||
$alternate_url = make_index_url();
|
||||
redirect_html( $alternate_url,
|
||||
'<div style="text-align:left; margin-left:5em;margin-bottom:5em;">
|
||||
<h1 style="text-align:left; font-size:36px;">'.l10n('Bad request').'</h1><br>'
|
||||
.$msg.'</div>',
|
||||
5 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Exits the current script with 404 code.
|
||||
* @todo nice display if $template loaded
|
||||
*
|
||||
* @param string $msg
|
||||
* @param string|null $alternate_url redirect to this url
|
||||
*/
|
||||
function page_not_found($msg, $alternate_url=null)
|
||||
{
|
||||
set_status_header(404);
|
||||
if ($alternate_url==null)
|
||||
$alternate_url = make_index_url();
|
||||
redirect_html( $alternate_url,
|
||||
'<div style="text-align:left; margin-left:5em;margin-bottom:5em;">
|
||||
<h1 style="text-align:left; font-size:36px;">'.l10n('Page not found').'</h1><br>'
|
||||
.$msg.'</div>',
|
||||
5 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Exits the current script with 500 code.
|
||||
* @todo nice display if $template loaded
|
||||
*
|
||||
* @param string $msg
|
||||
* @param string|null $title
|
||||
* @param bool $show_trace
|
||||
*/
|
||||
function fatal_error($msg, $title=null, $show_trace=true)
|
||||
{
|
||||
if (empty($title))
|
||||
{
|
||||
$title = l10n('Piwigo encountered a non recoverable error');
|
||||
}
|
||||
|
||||
$btrace_msg = '';
|
||||
if ($show_trace and function_exists('debug_backtrace'))
|
||||
{
|
||||
$bt = debug_backtrace();
|
||||
for ($i=1; $i<count($bt); $i++)
|
||||
{
|
||||
$class = isset($bt[$i]['class']) ? (@$bt[$i]['class'].'::') : '';
|
||||
$btrace_msg .= "#$i\t".$class.@$bt[$i]['function'].' '.@$bt[$i]['file']."(".@$bt[$i]['line'].")\n";
|
||||
}
|
||||
$btrace_msg = trim($btrace_msg);
|
||||
$msg .= "\n";
|
||||
}
|
||||
|
||||
$display = "<meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
|
||||
<h1>$title</h1>
|
||||
<pre style='font-size:larger;background:white;color:red;padding:1em;margin:0;clear:both;display:block;width:auto;height:auto;overflow:auto'>
|
||||
<b>$msg</b>
|
||||
$btrace_msg
|
||||
</pre>\n";
|
||||
|
||||
@set_status_header(500);
|
||||
echo $display.str_repeat( ' ', 300); //IE6 doesn't error output if below a size
|
||||
|
||||
if ( function_exists('ini_set') )
|
||||
{// if possible turn off error display (we display it)
|
||||
ini_set('display_errors', false);
|
||||
}
|
||||
error_reporting( E_ALL );
|
||||
trigger_error( strip_tags($msg).$btrace_msg, E_USER_ERROR );
|
||||
die(0); // just in case
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the breadcrumb to be displayed above thumbnails on tag page.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function get_tags_content_title()
|
||||
{
|
||||
global $page;
|
||||
$title = '<a href="'.get_root_url().'tags.php" title="'.l10n('display available tags').'">'
|
||||
. l10n( count($page['tags']) > 1 ? 'Tags' : 'Tag' )
|
||||
. '</a> ';
|
||||
|
||||
for ($i=0; $i<count($page['tags']); $i++)
|
||||
{
|
||||
$title.= $i>0 ? ' + ' : '';
|
||||
|
||||
$title.=
|
||||
'<a href="'
|
||||
.make_index_url(
|
||||
array(
|
||||
'tags' => array( $page['tags'][$i] )
|
||||
)
|
||||
)
|
||||
.'" title="'
|
||||
.l10n('display photos linked to this tag')
|
||||
.'">'
|
||||
.trigger_change('render_tag_name', $page['tags'][$i]['name'], $page['tags'][$i])
|
||||
.'</a>';
|
||||
|
||||
if (count($page['tags']) > 2)
|
||||
{
|
||||
$other_tags = $page['tags'];
|
||||
unset($other_tags[$i]);
|
||||
$remove_url = make_index_url(
|
||||
array(
|
||||
'tags' => $other_tags
|
||||
)
|
||||
);
|
||||
|
||||
$title.=
|
||||
'<a href="'.$remove_url.'" style="border:none;" title="'
|
||||
.l10n('remove this tag from the list')
|
||||
.'"><img src="'
|
||||
.get_root_url().get_themeconf('icon_dir').'/remove_s.png'
|
||||
.'" alt="x" style="vertical-align:bottom;">'
|
||||
.'</a>';
|
||||
}
|
||||
}
|
||||
return $title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the http status header (200,401,...)
|
||||
* @param int $code
|
||||
* @param string $text for exotic http codes
|
||||
*/
|
||||
function set_status_header($code, $text='')
|
||||
{
|
||||
if (empty($text))
|
||||
{
|
||||
switch ($code)
|
||||
{
|
||||
case 200: $text='OK';break;
|
||||
case 301: $text='Moved permanently';break;
|
||||
case 302: $text='Moved temporarily';break;
|
||||
case 304: $text='Not modified';break;
|
||||
case 400: $text='Bad request';break;
|
||||
case 401: $text='Authorization required';break;
|
||||
case 403: $text='Forbidden';break;
|
||||
case 404: $text='Not found';break;
|
||||
case 500: $text='Server error';break;
|
||||
case 501: $text='Not implemented';break;
|
||||
case 503: $text='Service unavailable';break;
|
||||
}
|
||||
}
|
||||
$protocol = $_SERVER["SERVER_PROTOCOL"];
|
||||
if ( ('HTTP/1.1' != $protocol) && ('HTTP/1.0' != $protocol) )
|
||||
$protocol = 'HTTP/1.0';
|
||||
|
||||
header( "$protocol $code $text", true, $code );
|
||||
trigger_notify('set_status_header', $code, $text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the category comment for rendering in html textual mode (subcatify)
|
||||
* This method is called by a trigger_notify()
|
||||
*
|
||||
* @param string $desc
|
||||
* @return string
|
||||
*/
|
||||
function render_category_literal_description($desc)
|
||||
{
|
||||
return strip_tags($desc, '<span><p><a><br><b><i><small><big><strong><em>');
|
||||
}
|
||||
|
||||
/**
|
||||
* Add known menubar blocks.
|
||||
* This method is called by a trigger_change()
|
||||
*
|
||||
* @param BlockManager[] $menu_ref_arr
|
||||
*/
|
||||
function register_default_menubar_blocks($menu_ref_arr)
|
||||
{
|
||||
$menu = & $menu_ref_arr[0];
|
||||
if ($menu->get_id() != 'menubar')
|
||||
return;
|
||||
$menu->register_block( new RegisteredBlock( 'mbLinks', 'Links', 'piwigo'));
|
||||
$menu->register_block( new RegisteredBlock( 'mbCategories', 'Albums', 'piwigo'));
|
||||
$menu->register_block( new RegisteredBlock( 'mbTags', 'Related tags', 'piwigo'));
|
||||
$menu->register_block( new RegisteredBlock( 'mbSpecials', 'Specials', 'piwigo'));
|
||||
$menu->register_block( new RegisteredBlock( 'mbMenu', 'Menu', 'piwigo'));
|
||||
|
||||
// We hide the quick identification menu on the identification page. It
|
||||
// would be confusing.
|
||||
if (script_basename() != 'identification')
|
||||
{
|
||||
$menu->register_block( new RegisteredBlock( 'mbIdentification', 'Identification', 'piwigo') );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns display name for an element.
|
||||
* Returns 'name' if exists of name from 'file'.
|
||||
*
|
||||
* @param array $info at least file or name
|
||||
* @return string
|
||||
*/
|
||||
function render_element_name($info)
|
||||
{
|
||||
if (!empty($info['name']))
|
||||
{
|
||||
return trigger_change('render_element_name', $info['name']);
|
||||
}
|
||||
return get_name_from_file($info['file']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns display description for an element.
|
||||
*
|
||||
* @param array $info at least comment
|
||||
* @param string $param used to identify the trigger
|
||||
* @return string
|
||||
*/
|
||||
function render_element_description($info, $param='')
|
||||
{
|
||||
if (!empty($info['comment']))
|
||||
{
|
||||
return trigger_change('render_element_description', $info['comment'], $param);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Add info to the title of the thumbnail based on photo properties.
|
||||
*
|
||||
* @param array $info hit, rating_score, nb_comments
|
||||
* @param string $title
|
||||
* @param string $comment
|
||||
* @return string
|
||||
*/
|
||||
function get_thumbnail_title($info, $title, $comment='')
|
||||
{
|
||||
global $conf, $user;
|
||||
|
||||
$details = array();
|
||||
|
||||
if (!empty($info['hit']))
|
||||
{
|
||||
$details[] = $info['hit'].' '.strtolower(l10n('Visits'));
|
||||
}
|
||||
|
||||
if ($conf['rate'] and !empty($info['rating_score']))
|
||||
{
|
||||
$details[] = strtolower(l10n('Rating score')).' '.$info['rating_score'];
|
||||
}
|
||||
|
||||
if (isset($info['nb_comments']) and $info['nb_comments'] != 0)
|
||||
{
|
||||
$details[] = l10n_dec('%d comment', '%d comments', $info['nb_comments']);
|
||||
}
|
||||
|
||||
if (count($details) > 0)
|
||||
{
|
||||
$title.= ' ('.implode(', ', $details).')';
|
||||
}
|
||||
|
||||
if (!empty($comment))
|
||||
{
|
||||
$comment = strip_tags($comment);
|
||||
$title.= ' '.substr($comment, 0, 100).(strlen($comment) > 100 ? '...' : '');
|
||||
}
|
||||
|
||||
$title = htmlspecialchars(strip_tags($title));
|
||||
$title = trigger_change('get_thumbnail_title', $title, $info);
|
||||
|
||||
return $title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Event handler to protect src image urls.
|
||||
*
|
||||
* @param string $url
|
||||
* @param SrcImage $src_image
|
||||
* @return string
|
||||
*/
|
||||
function get_src_image_url_protection_handler($url, $src_image)
|
||||
{
|
||||
return get_action_url($src_image->id, $src_image->is_original() ? 'e' : 'r', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Event handler to protect element urls.
|
||||
*
|
||||
* @param string $url
|
||||
* @param array $infos id, path
|
||||
* @return string
|
||||
*/
|
||||
function get_element_url_protection_handler($url, $infos)
|
||||
{
|
||||
global $conf;
|
||||
if ('images'==$conf['original_url_protection'])
|
||||
{// protect only images and not other file types (for example large movies that we don't want to send through our file proxy)
|
||||
$ext = get_extension($infos['path']);
|
||||
if (!in_array($ext, $conf['picture_ext']))
|
||||
{
|
||||
return $url;
|
||||
}
|
||||
}
|
||||
return get_action_url($infos['id'], 'e', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends to the template all messages stored in $page and in the session.
|
||||
*/
|
||||
function flush_page_messages()
|
||||
{
|
||||
global $template, $page;
|
||||
if ($template->get_template_vars('page_refresh') === null)
|
||||
{
|
||||
foreach (array('errors','infos','warnings', 'messages') as $mode)
|
||||
{
|
||||
if (isset($_SESSION['page_'.$mode]))
|
||||
{
|
||||
$page[$mode] = array_merge($page[$mode], $_SESSION['page_'.$mode]);
|
||||
unset($_SESSION['page_'.$mode]);
|
||||
}
|
||||
|
||||
if (count($page[$mode]) != 0)
|
||||
{
|
||||
$template->assign($mode, $page[$mode]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
1002
zoesch.de/galerie/include/functions_mail.inc.php
Normal file
1002
zoesch.de/galerie/include/functions_mail.inc.php
Normal file
File diff suppressed because it is too large
Load Diff
241
zoesch.de/galerie/include/functions_metadata.inc.php
Normal file
241
zoesch.de/galerie/include/functions_metadata.inc.php
Normal file
@@ -0,0 +1,241 @@
|
||||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Piwigo - a PHP based photo gallery |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright(C) 2008-2016 Piwigo Team http://piwigo.org |
|
||||
// | Copyright(C) 2003-2008 PhpWebGallery Team http://phpwebgallery.net |
|
||||
// | Copyright(C) 2002-2003 Pierrick LE GALL http://le-gall.net/pierrick |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
* @package functions\metadata
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* returns informations from IPTC metadata, mapping is done in this function.
|
||||
*
|
||||
* @param string $filename
|
||||
* @param array $map
|
||||
* @return array
|
||||
*/
|
||||
function get_iptc_data($filename, $map, $array_sep=',')
|
||||
{
|
||||
global $conf;
|
||||
|
||||
$result = array();
|
||||
|
||||
$imginfo = array();
|
||||
if (false == @getimagesize($filename, $imginfo) )
|
||||
{
|
||||
return $result;
|
||||
}
|
||||
|
||||
if (isset($imginfo['APP13']))
|
||||
{
|
||||
$iptc = iptcparse($imginfo['APP13']);
|
||||
if (is_array($iptc))
|
||||
{
|
||||
$rmap = array_flip($map);
|
||||
foreach (array_keys($rmap) as $iptc_key)
|
||||
{
|
||||
if (isset($iptc[$iptc_key][0]))
|
||||
{
|
||||
if ($iptc_key == '2#025')
|
||||
{
|
||||
$value = implode($array_sep,
|
||||
array_map('clean_iptc_value',$iptc[$iptc_key]));
|
||||
}
|
||||
else
|
||||
{
|
||||
$value = clean_iptc_value($iptc[$iptc_key][0]);
|
||||
}
|
||||
|
||||
foreach (array_keys($map, $iptc_key) as $pwg_key)
|
||||
{
|
||||
$result[$pwg_key] = $value;
|
||||
|
||||
if (!$conf['allow_html_in_metadata'])
|
||||
{
|
||||
// in case the origin of the photo is unsecure (user upload), we
|
||||
// remove HTML tags to avoid XSS (malicious execution of
|
||||
// javascript)
|
||||
$result[$pwg_key] = strip_tags($result[$pwg_key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* return a cleaned IPTC value.
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
function clean_iptc_value($value)
|
||||
{
|
||||
// strip leading zeros (weird Kodak Scanner software)
|
||||
while ( isset($value[0]) and $value[0] == chr(0))
|
||||
{
|
||||
$value = substr($value, 1);
|
||||
}
|
||||
// remove binary nulls
|
||||
$value = str_replace(chr(0x00), ' ', $value);
|
||||
|
||||
if ( preg_match('/[\x80-\xff]/', $value) )
|
||||
{
|
||||
// apparently mac uses some MacRoman crap encoding. I don't know
|
||||
// how to detect it so a plugin should do the trick.
|
||||
$value = trigger_change('clean_iptc_value', $value);
|
||||
if ( ($qual = qualify_utf8($value)) != 0)
|
||||
{// has non ascii chars
|
||||
if ($qual>0)
|
||||
{
|
||||
$input_encoding = 'utf-8';
|
||||
}
|
||||
else
|
||||
{
|
||||
$input_encoding = 'iso-8859-1';
|
||||
if (function_exists('iconv') or function_exists('mb_convert_encoding'))
|
||||
{
|
||||
// using windows-1252 because it supports additional characters
|
||||
// such as "oe" in a single character (ligature). About the
|
||||
// difference between Windows-1252 and ISO-8859-1: the characters
|
||||
// 0x80-0x9F will not convert correctly. But these are control
|
||||
// characters which are almost never used.
|
||||
$input_encoding = 'windows-1252';
|
||||
}
|
||||
}
|
||||
|
||||
$value = convert_charset($value, $input_encoding, get_pwg_charset());
|
||||
}
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns informations from EXIF metadata, mapping is done in this function.
|
||||
*
|
||||
* @param string $filename
|
||||
* @param array $map
|
||||
* @return array
|
||||
*/
|
||||
function get_exif_data($filename, $map)
|
||||
{
|
||||
global $conf;
|
||||
|
||||
$result = array();
|
||||
|
||||
if (!function_exists('read_exif_data'))
|
||||
{
|
||||
die('Exif extension not available, admin should disable exif use');
|
||||
}
|
||||
|
||||
// Read EXIF data
|
||||
if ($exif = @read_exif_data($filename) or $exif2 = trigger_change('format_exif_data', $exif=null, $filename, $map))
|
||||
{
|
||||
if (!empty($exif2))
|
||||
{
|
||||
$exif = $exif2;
|
||||
}
|
||||
else
|
||||
{
|
||||
$exif = trigger_change('format_exif_data', $exif, $filename, $map);
|
||||
}
|
||||
|
||||
// configured fields
|
||||
foreach ($map as $key => $field)
|
||||
{
|
||||
if (strpos($field, ';') === false)
|
||||
{
|
||||
if (isset($exif[$field]))
|
||||
{
|
||||
$result[$key] = $exif[$field];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$tokens = explode(';', $field);
|
||||
if (isset($exif[$tokens[0]][$tokens[1]]))
|
||||
{
|
||||
$result[$key] = $exif[$tokens[0]][$tokens[1]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// GPS data
|
||||
$gps_exif = array_intersect_key($exif, array_flip(array('GPSLatitudeRef', 'GPSLatitude', 'GPSLongitudeRef', 'GPSLongitude')));
|
||||
if (count($gps_exif) == 4)
|
||||
{
|
||||
if (
|
||||
is_array($gps_exif['GPSLatitude']) and in_array($gps_exif['GPSLatitudeRef'], array('S', 'N')) and
|
||||
is_array($gps_exif['GPSLongitude']) and in_array($gps_exif['GPSLongitudeRef'], array('W', 'E'))
|
||||
)
|
||||
{
|
||||
$result['latitude'] = parse_exif_gps_data($gps_exif['GPSLatitude'], $gps_exif['GPSLatitudeRef']);
|
||||
$result['longitude'] = parse_exif_gps_data($gps_exif['GPSLongitude'], $gps_exif['GPSLongitudeRef']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$conf['allow_html_in_metadata'])
|
||||
{
|
||||
foreach ($result as $key => $value)
|
||||
{
|
||||
// in case the origin of the photo is unsecure (user upload), we remove
|
||||
// HTML tags to avoid XSS (malicious execution of javascript)
|
||||
$result[$key] = strip_tags($value);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts EXIF GPS format to a float value.
|
||||
* @since 2.6
|
||||
*
|
||||
* @param string[] $raw eg:
|
||||
* - 41/1
|
||||
* - 54/1
|
||||
* - 9843/500
|
||||
* @param string $ref 'S', 'N', 'E', 'W'. eg: 'N'
|
||||
* @return float eg: 41.905468
|
||||
*/
|
||||
function parse_exif_gps_data($raw, $ref)
|
||||
{
|
||||
foreach ($raw as &$i)
|
||||
{
|
||||
$i = explode('/', $i);
|
||||
$i = $i[1]==0 ? 0 : $i[0]/$i[1];
|
||||
}
|
||||
unset($i);
|
||||
|
||||
$v = $raw[0] + $raw[1]/60 + $raw[2]/3600;
|
||||
|
||||
$ref = strtoupper($ref);
|
||||
if ($ref == 'S' or $ref == 'W') $v= -$v;
|
||||
|
||||
return $v;
|
||||
}
|
||||
|
||||
?>
|
||||
639
zoesch.de/galerie/include/functions_notification.inc.php
Normal file
639
zoesch.de/galerie/include/functions_notification.inc.php
Normal file
@@ -0,0 +1,639 @@
|
||||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Piwigo - a PHP based photo gallery |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright(C) 2008-2016 Piwigo Team http://piwigo.org |
|
||||
// | Copyright(C) 2003-2008 PhpWebGallery Team http://phpwebgallery.net |
|
||||
// | Copyright(C) 2002-2003 Pierrick LE GALL http://le-gall.net/pierrick |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
* @package functions\notification
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Get standard sql where in order to restrict and filter categories and images.
|
||||
* IMAGE_CATEGORY_TABLE must be named "ic" in the query
|
||||
*
|
||||
* @param string $prefix_condition
|
||||
* @param string $img_field
|
||||
* @param bool $force_one_condition
|
||||
* @return string
|
||||
*/
|
||||
function get_std_sql_where_restrict_filter($prefix_condition,
|
||||
$img_field = 'ic.image_id',
|
||||
$force_one_condition = false)
|
||||
{
|
||||
return get_sql_condition_FandF(
|
||||
array(
|
||||
'forbidden_categories' => 'ic.category_id',
|
||||
'visible_categories' => 'ic.category_id',
|
||||
'visible_images' => $img_field
|
||||
),
|
||||
$prefix_condition,
|
||||
$force_one_condition
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute custom notification query.
|
||||
* @todo use a cache for all data returned by custom_notification_query()
|
||||
*
|
||||
* @param string $action 'count', 'info'
|
||||
* @param string $type 'new_comments', 'unvalidated_comments', 'new_elements', 'updated_categories', 'new_users'
|
||||
* @param string $start (mysql datetime format)
|
||||
* @param string $end (mysql datetime format)
|
||||
* @return int|array int for action count array for info
|
||||
*/
|
||||
function custom_notification_query($action, $type, $start=null, $end=null)
|
||||
{
|
||||
global $user;
|
||||
|
||||
switch($type)
|
||||
{
|
||||
case 'new_comments':
|
||||
{
|
||||
$query = '
|
||||
FROM '.COMMENTS_TABLE.' AS c
|
||||
INNER JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON c.image_id = ic.image_id
|
||||
WHERE 1=1';
|
||||
if (!empty($start))
|
||||
{
|
||||
$query.= '
|
||||
AND c.validation_date > \''.$start.'\'';
|
||||
}
|
||||
if (!empty($end))
|
||||
{
|
||||
$query.= '
|
||||
AND c.validation_date <= \''.$end.'\'';
|
||||
}
|
||||
$query.= get_std_sql_where_restrict_filter('AND');
|
||||
break;
|
||||
}
|
||||
|
||||
case 'unvalidated_comments':
|
||||
{
|
||||
$query = '
|
||||
FROM '.COMMENTS_TABLE.'
|
||||
WHERE 1=1';
|
||||
if (!empty($start))
|
||||
{
|
||||
$query.= '
|
||||
AND date > \''.$start.'\'';
|
||||
}
|
||||
if (!empty($end))
|
||||
{
|
||||
$query.= '
|
||||
AND date <= \''.$end.'\'';
|
||||
}
|
||||
$query.= '
|
||||
AND validated = \'false\'';
|
||||
break;
|
||||
}
|
||||
|
||||
case 'new_elements':
|
||||
{
|
||||
$query = '
|
||||
FROM '.IMAGES_TABLE.'
|
||||
INNER JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON image_id = id
|
||||
WHERE 1=1';
|
||||
if (!empty($start))
|
||||
{
|
||||
$query.= '
|
||||
AND date_available > \''.$start.'\'';
|
||||
}
|
||||
if (!empty($end))
|
||||
{
|
||||
$query.= '
|
||||
AND date_available <= \''.$end.'\'';
|
||||
}
|
||||
$query.= get_std_sql_where_restrict_filter('AND', 'id');
|
||||
break;
|
||||
}
|
||||
|
||||
case 'updated_categories':
|
||||
{
|
||||
$query = '
|
||||
FROM '.IMAGES_TABLE.'
|
||||
INNER JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON image_id = id
|
||||
WHERE 1=1';
|
||||
if (!empty($start))
|
||||
{
|
||||
$query.= '
|
||||
AND date_available > \''.$start.'\'';
|
||||
}
|
||||
if (!empty($end))
|
||||
{
|
||||
$query.= '
|
||||
AND date_available <= \''.$end.'\'';
|
||||
}
|
||||
$query.= get_std_sql_where_restrict_filter('AND', 'id');
|
||||
break;
|
||||
}
|
||||
|
||||
case 'new_users':
|
||||
{
|
||||
$query = '
|
||||
FROM '.USER_INFOS_TABLE.'
|
||||
WHERE 1=1';
|
||||
if (!empty($start))
|
||||
{
|
||||
$query.= '
|
||||
AND registration_date > \''.$start.'\'';
|
||||
}
|
||||
if (!empty($end))
|
||||
{
|
||||
$query.= '
|
||||
AND registration_date <= \''.$end.'\'';
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return null; // stop and return nothing
|
||||
}
|
||||
|
||||
switch($action)
|
||||
{
|
||||
case 'count':
|
||||
{
|
||||
switch($type)
|
||||
{
|
||||
case 'new_comments':
|
||||
$field_id = 'c.id';
|
||||
break;
|
||||
case 'unvalidated_comments':
|
||||
$field_id = 'id';
|
||||
break;
|
||||
case 'new_elements':
|
||||
$field_id = 'image_id';
|
||||
break;
|
||||
case 'updated_categories':
|
||||
$field_id = 'category_id';
|
||||
break;
|
||||
case 'new_users':
|
||||
$field_id = 'user_id';
|
||||
break;
|
||||
}
|
||||
$query = 'SELECT COUNT(DISTINCT '.$field_id.') '.$query.';';
|
||||
list($count) = pwg_db_fetch_row(pwg_query($query));
|
||||
return $count;
|
||||
break;
|
||||
}
|
||||
|
||||
case 'info':
|
||||
{
|
||||
switch($type)
|
||||
{
|
||||
case 'new_comments':
|
||||
$field_id = 'c.id';
|
||||
break;
|
||||
case 'unvalidated_comments':
|
||||
$field_id = 'id';
|
||||
break;
|
||||
case 'new_elements':
|
||||
$field_id = 'image_id';
|
||||
break;
|
||||
case 'updated_categories':
|
||||
$field_id = 'category_id';
|
||||
break;
|
||||
case 'new_users':
|
||||
$field_id = 'user_id';
|
||||
break;
|
||||
}
|
||||
$query = 'SELECT DISTINCT '.$field_id.' '.$query.';';
|
||||
$infos = query2array($query);
|
||||
return $infos;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return null; // stop and return nothing
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns number of new comments between two dates.
|
||||
*
|
||||
* @param string $start (mysql datetime format)
|
||||
* @param string $end (mysql datetime format)
|
||||
* @return int
|
||||
*/
|
||||
function nb_new_comments($start=null, $end=null)
|
||||
{
|
||||
return custom_notification_query('count', 'new_comments', $start, $end);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns new comments between two dates.
|
||||
*
|
||||
* @param string $start (mysql datetime format)
|
||||
* @param string $end (mysql datetime format)
|
||||
* @return int[] comment ids
|
||||
*/
|
||||
function new_comments($start=null, $end=null)
|
||||
{
|
||||
return custom_notification_query('info', 'new_comments', $start, $end);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns number of unvalidated comments between two dates.
|
||||
*
|
||||
* @param string $start (mysql datetime format)
|
||||
* @param string $end (mysql datetime format)
|
||||
* @return int
|
||||
*/
|
||||
function nb_unvalidated_comments($start=null, $end=null)
|
||||
{
|
||||
return custom_notification_query('count', 'unvalidated_comments', $start, $end);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns number of new photos between two dates.
|
||||
*
|
||||
* @param string $start (mysql datetime format)
|
||||
* @param string $end (mysql datetime format)
|
||||
* @return int
|
||||
*/
|
||||
function nb_new_elements($start=null, $end=null)
|
||||
{
|
||||
return custom_notification_query('count', 'new_elements', $start, $end);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns new photos between two dates.es
|
||||
*
|
||||
* @param string $start (mysql datetime format)
|
||||
* @param string $end (mysql datetime format)
|
||||
* @return int[] photos ids
|
||||
*/
|
||||
function new_elements($start=null, $end=null)
|
||||
{
|
||||
return custom_notification_query('info', 'new_elements', $start, $end);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns number of updated categories between two dates.
|
||||
*
|
||||
* @param string $start (mysql datetime format)
|
||||
* @param string $end (mysql datetime format)
|
||||
* @return int
|
||||
*/
|
||||
function nb_updated_categories($start=null, $end=null)
|
||||
{
|
||||
return custom_notification_query('count', 'updated_categories', $start, $end);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns updated categories between two dates.
|
||||
*
|
||||
* @param string $start (mysql datetime format)
|
||||
* @param string $end (mysql datetime format)
|
||||
* @return int[] categories ids
|
||||
*/
|
||||
function updated_categories($start=null, $end=null)
|
||||
{
|
||||
return custom_notification_query('info', 'updated_categories', $start, $end);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns number of new users between two dates.
|
||||
*
|
||||
* @param string $start (mysql datetime format)
|
||||
* @param string $end (mysql datetime format)
|
||||
* @return int
|
||||
*/
|
||||
function nb_new_users($start=null, $end=null)
|
||||
{
|
||||
return custom_notification_query('count', 'new_users', $start, $end);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns new users between two dates.
|
||||
*
|
||||
* @param string $start (mysql datetime format)
|
||||
* @param string $end (mysql datetime format)
|
||||
* @return int[] user ids
|
||||
*/
|
||||
function new_users($start=null, $end=null)
|
||||
{
|
||||
return custom_notification_query('info', 'new_users', $start, $end);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if there was new activity between two dates.
|
||||
*
|
||||
* Takes in account: number of new comments, number of new elements, number of
|
||||
* updated categories. Administrators are also informed about: number of
|
||||
* unvalidated comments, number of new users.
|
||||
* @todo number of unvalidated elements
|
||||
*
|
||||
* @param string $start (mysql datetime format)
|
||||
* @param string $end (mysql datetime format)
|
||||
* @return boolean
|
||||
*/
|
||||
function news_exists($start=null, $end=null)
|
||||
{
|
||||
return (
|
||||
(nb_new_comments($start, $end) > 0) or
|
||||
(nb_new_elements($start, $end) > 0) or
|
||||
(nb_updated_categories($start, $end) > 0) or
|
||||
((is_admin()) and (nb_unvalidated_comments($start, $end) > 0)) or
|
||||
((is_admin()) and (nb_new_users($start, $end) > 0)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a news line and adds it to the array (e.g. '5 new elements')
|
||||
*
|
||||
* @param array &$news
|
||||
* @param int $count
|
||||
* @param string $singular_key
|
||||
* @param string $plural_key
|
||||
* @param string $url
|
||||
* @param bool $add_url
|
||||
*/
|
||||
function add_news_line(&$news, $count, $singular_key, $plural_key, $url='', $add_url=false)
|
||||
{
|
||||
if ($count > 0)
|
||||
{
|
||||
$line = l10n_dec($singular_key, $plural_key, $count);
|
||||
if ($add_url and !empty($url) )
|
||||
{
|
||||
$line = '<a href="'.$url.'">'.$line.'</a>';
|
||||
}
|
||||
$news[] = $line;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns new activity between two dates.
|
||||
*
|
||||
* Takes in account: number of new comments, number of new elements, number of
|
||||
* updated categories. Administrators are also informed about: number of
|
||||
* unvalidated comments, number of new users.
|
||||
* @todo number of unvalidated elements
|
||||
*
|
||||
* @param string $start (mysql datetime format)
|
||||
* @param string $end (mysql datetime format)
|
||||
* @param bool $exclude_img_cats if true, no info about new images/categories
|
||||
* @param bool $add_url add html link around news
|
||||
* @return array
|
||||
*/
|
||||
function news($start=null, $end=null, $exclude_img_cats=false, $add_url=false, $auth_key=null)
|
||||
{
|
||||
$news = array();
|
||||
|
||||
$add_url_params = array();
|
||||
if (isset($auth_key))
|
||||
{
|
||||
$add_url_params['auth'] = $auth_key;
|
||||
}
|
||||
|
||||
if (!$exclude_img_cats)
|
||||
{
|
||||
add_news_line(
|
||||
$news,
|
||||
nb_new_elements($start, $end),
|
||||
'%d new photo',
|
||||
'%d new photos',
|
||||
add_url_params(make_index_url(array('section'=>'recent_pics')), $add_url_params),
|
||||
$add_url
|
||||
);
|
||||
|
||||
add_news_line(
|
||||
$news,
|
||||
nb_updated_categories($start, $end),
|
||||
'%d album updated',
|
||||
'%d albums updated',
|
||||
add_url_params(make_index_url(array('section'=>'recent_cats')), $add_url_params),
|
||||
$add_url
|
||||
);
|
||||
}
|
||||
|
||||
add_news_line(
|
||||
$news,
|
||||
nb_new_comments($start, $end),
|
||||
'%d new comment',
|
||||
'%d new comments',
|
||||
add_url_params(get_root_url().'comments.php', $add_url_params),
|
||||
$add_url
|
||||
);
|
||||
|
||||
if (is_admin())
|
||||
{
|
||||
add_news_line( $news,
|
||||
nb_unvalidated_comments($start, $end), '%d comment to validate', '%d comments to validate',
|
||||
get_root_url().'admin.php?page=comments', $add_url );
|
||||
|
||||
add_news_line( $news,
|
||||
nb_new_users($start, $end), '%d new user', '%d new users',
|
||||
get_root_url().'admin.php?page=user_list', $add_url );
|
||||
}
|
||||
|
||||
return $news;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information about recently published elements grouped by post date.
|
||||
*
|
||||
* @param int $max_dates maximum number of recent dates
|
||||
* @param int $max_elements maximum number of elements per date
|
||||
* @param int $max_cats maximum number of categories per date
|
||||
* @return array
|
||||
*/
|
||||
function get_recent_post_dates($max_dates, $max_elements, $max_cats)
|
||||
{
|
||||
global $conf, $user, $persistent_cache;
|
||||
|
||||
$cache_key = $persistent_cache->make_key('recent_posts'.$user['id'].$user['cache_update_time'].$max_dates.$max_elements.$max_cats);
|
||||
if ($persistent_cache->get($cache_key, $cached))
|
||||
{
|
||||
return $cached;
|
||||
}
|
||||
$where_sql = get_std_sql_where_restrict_filter('WHERE', 'i.id', true);
|
||||
|
||||
$query = '
|
||||
SELECT
|
||||
date_available,
|
||||
COUNT(DISTINCT id) AS nb_elements,
|
||||
COUNT(DISTINCT category_id) AS nb_cats
|
||||
FROM '.IMAGES_TABLE.' i INNER JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON id=image_id
|
||||
'.$where_sql.'
|
||||
GROUP BY date_available
|
||||
ORDER BY date_available DESC
|
||||
LIMIT '.$max_dates.'
|
||||
;';
|
||||
$dates = query2array($query);
|
||||
|
||||
for ($i=0; $i<count($dates); $i++)
|
||||
{
|
||||
if ($max_elements>0)
|
||||
{ // get some thumbnails ...
|
||||
$query = '
|
||||
SELECT DISTINCT i.*
|
||||
FROM '.IMAGES_TABLE.' i
|
||||
INNER JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON id=image_id
|
||||
'.$where_sql.'
|
||||
AND date_available=\''.$dates[$i]['date_available'].'\'
|
||||
ORDER BY '.DB_RANDOM_FUNCTION.'()
|
||||
LIMIT '.$max_elements.'
|
||||
;';
|
||||
$dates[$i]['elements'] = query2array($query);
|
||||
}
|
||||
|
||||
if ($max_cats>0)
|
||||
{// get some categories ...
|
||||
$query = '
|
||||
SELECT
|
||||
DISTINCT c.uppercats,
|
||||
COUNT(DISTINCT i.id) AS img_count
|
||||
FROM '.IMAGES_TABLE.' i
|
||||
INNER JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON i.id=image_id
|
||||
INNER JOIN '.CATEGORIES_TABLE.' c ON c.id=category_id
|
||||
'.$where_sql.'
|
||||
AND date_available=\''.$dates[$i]['date_available'].'\'
|
||||
GROUP BY category_id, c.uppercats
|
||||
ORDER BY img_count DESC
|
||||
LIMIT '.$max_cats.'
|
||||
;';
|
||||
$dates[$i]['categories'] = query2array($query);
|
||||
}
|
||||
}
|
||||
|
||||
$persistent_cache->set($cache_key, $dates);
|
||||
return $dates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information about recently published elements grouped by post date.
|
||||
* Same as get_recent_post_dates() but parameters as an indexed array.
|
||||
* @see get_recent_post_dates()
|
||||
*
|
||||
* @param array $args
|
||||
* @return array
|
||||
*/
|
||||
function get_recent_post_dates_array($args)
|
||||
{
|
||||
return get_recent_post_dates(
|
||||
(empty($args['max_dates']) ? 3 : $args['max_dates']),
|
||||
(empty($args['max_elements']) ? 3 : $args['max_elements']),
|
||||
(empty($args['max_cats']) ? 3 : $args['max_cats'])
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns html description about recently published elements grouped by post date.
|
||||
* @todo clean up HTML output, currently messy and invalid !
|
||||
*
|
||||
* @param array $date_detail returned value of get_recent_post_dates()
|
||||
* @return string
|
||||
*/
|
||||
function get_html_description_recent_post_date($date_detail, $auth_key=null)
|
||||
{
|
||||
global $conf;
|
||||
|
||||
$add_url_params = array();
|
||||
if (isset($auth_key))
|
||||
{
|
||||
$add_url_params['auth'] = $auth_key;
|
||||
}
|
||||
|
||||
$description = '<ul>';
|
||||
|
||||
$description .=
|
||||
'<li>'
|
||||
.l10n_dec('%d new photo', '%d new photos', $date_detail['nb_elements'])
|
||||
.' ('
|
||||
.'<a href="'.add_url_params(make_index_url(array('section'=>'recent_pics')), $add_url_params).'">'
|
||||
.l10n('Recent photos').'</a>'
|
||||
.')'
|
||||
.'</li><br>';
|
||||
|
||||
foreach($date_detail['elements'] as $element)
|
||||
{
|
||||
$tn_src = DerivativeImage::thumb_url($element);
|
||||
$description .= '<a href="'.
|
||||
add_url_params(
|
||||
make_picture_url(
|
||||
array(
|
||||
'image_id' => $element['id'],
|
||||
'image_file' => $element['file'],
|
||||
)
|
||||
),
|
||||
$add_url_params
|
||||
)
|
||||
.'"><img src="'.$tn_src.'"></a>';
|
||||
}
|
||||
$description .= '...<br>';
|
||||
|
||||
$description .=
|
||||
'<li>'
|
||||
.l10n_dec('%d album updated', '%d albums updated', $date_detail['nb_cats'])
|
||||
.'</li>';
|
||||
|
||||
$description .= '<ul>';
|
||||
foreach($date_detail['categories'] as $cat)
|
||||
{
|
||||
$description .=
|
||||
'<li>'
|
||||
.get_cat_display_name_cache($cat['uppercats'],'', false, null, $auth_key)
|
||||
.' ('.
|
||||
l10n_dec('%d new photo', '%d new photos', $cat['img_count']).')'
|
||||
.'</li>';
|
||||
}
|
||||
$description .= '</ul>';
|
||||
|
||||
$description .= '</ul>';
|
||||
|
||||
return $description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns title about recently published elements grouped by post date.
|
||||
*
|
||||
* @param array $date_detail returned value of get_recent_post_dates()
|
||||
* @return string
|
||||
*/
|
||||
function get_title_recent_post_date($date_detail)
|
||||
{
|
||||
global $lang;
|
||||
|
||||
$date = $date_detail['date_available'];
|
||||
$exploded_date = strptime($date, '%Y-%m-%d %H:%M:%S');
|
||||
|
||||
$title = l10n_dec('%d new photo', '%d new photos', $date_detail['nb_elements']);
|
||||
$title .= ' ('.$lang['month'][1+$exploded_date['tm_mon']].' '.$exploded_date['tm_mday'].')';
|
||||
|
||||
return $title;
|
||||
}
|
||||
|
||||
if (!function_exists('strptime'))
|
||||
{
|
||||
function strptime($date, $fmt)
|
||||
{
|
||||
if ($fmt != '%Y-%m-%d %H:%M:%S')
|
||||
die('Invalid strptime format '.$fmt);
|
||||
list($y,$m,$d,$H,$M,$S) = preg_split('/[-: ]/', $date);
|
||||
$res = localtime( mktime($H,$M,$S,$m,$d,$y), true );
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
133
zoesch.de/galerie/include/functions_picture.inc.php
Normal file
133
zoesch.de/galerie/include/functions_picture.inc.php
Normal file
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Piwigo - a PHP based photo gallery |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright(C) 2008-2016 Piwigo Team http://piwigo.org |
|
||||
// | Copyright(C) 2003-2008 PhpWebGallery Team http://phpwebgallery.net |
|
||||
// | Copyright(C) 2002-2003 Pierrick LE GALL http://le-gall.net/pierrick |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
* @package functions\picture
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Returns slideshow default params.
|
||||
* - period
|
||||
* - repeat
|
||||
* - play
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function get_default_slideshow_params()
|
||||
{
|
||||
global $conf;
|
||||
|
||||
return array(
|
||||
'period' => $conf['slideshow_period'],
|
||||
'repeat' => $conf['slideshow_repeat'],
|
||||
'play' => true,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks and corrects slideshow params
|
||||
*
|
||||
* @param array $params
|
||||
* @return array
|
||||
*/
|
||||
function correct_slideshow_params($params=array())
|
||||
{
|
||||
global $conf;
|
||||
|
||||
if ($params['period'] < $conf['slideshow_period_min'])
|
||||
{
|
||||
$params['period'] = $conf['slideshow_period_min'];
|
||||
}
|
||||
else if ($params['period'] > $conf['slideshow_period_max'])
|
||||
{
|
||||
$params['period'] = $conf['slideshow_period_max'];
|
||||
}
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes slideshow string params into array
|
||||
*
|
||||
* @param string $encode_params
|
||||
* @return array
|
||||
*/
|
||||
function decode_slideshow_params($encode_params=null)
|
||||
{
|
||||
global $conf;
|
||||
|
||||
$result = get_default_slideshow_params();
|
||||
|
||||
if (is_numeric($encode_params))
|
||||
{
|
||||
$result['period'] = $encode_params;
|
||||
}
|
||||
else
|
||||
{
|
||||
$matches = array();
|
||||
if (preg_match_all('/([a-z]+)-(\d+)/', $encode_params, $matches))
|
||||
{
|
||||
$matchcount = count($matches[1]);
|
||||
for ($i = 0; $i < $matchcount; $i++)
|
||||
{
|
||||
$result[$matches[1][$i]] = $matches[2][$i];
|
||||
}
|
||||
}
|
||||
|
||||
if (preg_match_all('/([a-z]+)-(true|false)/', $encode_params, $matches))
|
||||
{
|
||||
$matchcount = count($matches[1]);
|
||||
for ($i = 0; $i < $matchcount; $i++)
|
||||
{
|
||||
$result[$matches[1][$i]] = get_boolean($matches[2][$i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return correct_slideshow_params($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes slideshow array params into a string
|
||||
*
|
||||
* @param array $decode_params
|
||||
* @return string
|
||||
*/
|
||||
function encode_slideshow_params($decode_params=array())
|
||||
{
|
||||
global $conf;
|
||||
|
||||
$params = array_diff_assoc(correct_slideshow_params($decode_params), get_default_slideshow_params());
|
||||
$result = '';
|
||||
|
||||
foreach ($params as $name => $value)
|
||||
{
|
||||
// boolean_to_string return $value, if it's not a bool
|
||||
$result .= '+'.$name.'-'.boolean_to_string($value);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
?>
|
||||
451
zoesch.de/galerie/include/functions_plugins.inc.php
Normal file
451
zoesch.de/galerie/include/functions_plugins.inc.php
Normal file
@@ -0,0 +1,451 @@
|
||||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Piwigo - a PHP based photo gallery |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright(C) 2008-2016 Piwigo Team http://piwigo.org |
|
||||
// | Copyright(C) 2003-2008 PhpWebGallery Team http://phpwebgallery.net |
|
||||
// | Copyright(C) 2002-2003 Pierrick LE GALL http://le-gall.net/pierrick |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
* @package functions\plugins
|
||||
*/
|
||||
|
||||
|
||||
/** base directory of plugins */
|
||||
define('PHPWG_PLUGINS_PATH', PHPWG_ROOT_PATH.'plugins/');
|
||||
/** default priority for plugins handlers */
|
||||
define('EVENT_HANDLER_PRIORITY_NEUTRAL', 50);
|
||||
|
||||
|
||||
/**
|
||||
* Used to declare maintenance methods of a plugin.
|
||||
*/
|
||||
class PluginMaintain
|
||||
{
|
||||
/** @var string $plugin_id */
|
||||
protected $plugin_id;
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
*/
|
||||
function __construct($id)
|
||||
{
|
||||
$this->plugin_id = $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $plugin_version
|
||||
* @param array &$errors - used to return error messages
|
||||
*/
|
||||
function install($plugin_version, &$errors=array()) {}
|
||||
|
||||
/**
|
||||
* @param string $plugin_version
|
||||
* @param array &$errors - used to return error messages
|
||||
*/
|
||||
function activate($plugin_version, &$errors=array()) {}
|
||||
|
||||
function deactivate() {}
|
||||
|
||||
function uninstall() {}
|
||||
|
||||
/**
|
||||
* @param string $old_version
|
||||
* @param string $new_version
|
||||
* @param array &$errors - used to return error messages
|
||||
*/
|
||||
function update($old_version, $new_version, &$errors=array()) {}
|
||||
|
||||
/**
|
||||
* @removed 2.7
|
||||
*/
|
||||
function autoUpdate()
|
||||
{
|
||||
if (is_admin() && !defined('IN_WS'))
|
||||
{
|
||||
trigger_error('Function PluginMaintain::autoUpdate deprecated', E_USER_WARNING);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to declare maintenance methods of a theme.
|
||||
*/
|
||||
class ThemeMaintain
|
||||
{
|
||||
/** @var string $theme_id */
|
||||
protected $theme_id;
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
*/
|
||||
function __construct($id)
|
||||
{
|
||||
$this->theme_id = $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $theme_version
|
||||
* @param array &$errors - used to return error messages
|
||||
*/
|
||||
function activate($theme_version, &$errors=array()) {}
|
||||
|
||||
function deactivate() {}
|
||||
|
||||
function delete() {}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Register an event handler.
|
||||
*
|
||||
* @param string $event the name of the event to listen to
|
||||
* @param Callable $func the callback function
|
||||
* @param int $priority greater priority will be executed at last
|
||||
* @param string $include_path file to include before executing the callback
|
||||
* @return bool false is handler already exists
|
||||
*/
|
||||
function add_event_handler($event, $func,
|
||||
$priority=EVENT_HANDLER_PRIORITY_NEUTRAL, $include_path=null)
|
||||
{
|
||||
global $pwg_event_handlers;
|
||||
|
||||
if (isset($pwg_event_handlers[$event][$priority]))
|
||||
{
|
||||
foreach ($pwg_event_handlers[$event][$priority] as $handler)
|
||||
{
|
||||
if ($handler['function'] == $func)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$pwg_event_handlers[$event][$priority][] = array(
|
||||
'function' => $func,
|
||||
'include_path' => is_string($include_path) ? $include_path : null,
|
||||
);
|
||||
|
||||
ksort($pwg_event_handlers[$event]);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an event handler.
|
||||
* @see add_event_handler()
|
||||
*
|
||||
* @param string $event
|
||||
* @param Callable $func
|
||||
* @param int $priority
|
||||
*/
|
||||
function remove_event_handler($event, $func,
|
||||
$priority=EVENT_HANDLER_PRIORITY_NEUTRAL)
|
||||
{
|
||||
global $pwg_event_handlers;
|
||||
|
||||
if (!isset($pwg_event_handlers[$event][$priority]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
for ($i=0; $i<count($pwg_event_handlers[$event][$priority]); $i++)
|
||||
{
|
||||
if ($pwg_event_handlers[$event][$priority][$i]['function']==$func)
|
||||
{
|
||||
unset($pwg_event_handlers[$event][$priority][$i]);
|
||||
$pwg_event_handlers[$event][$priority] =
|
||||
array_values($pwg_event_handlers[$event][$priority]);
|
||||
|
||||
if (empty($pwg_event_handlers[$event][$priority]))
|
||||
{
|
||||
unset($pwg_event_handlers[$event][$priority]);
|
||||
if (empty($pwg_event_handlers[$event]))
|
||||
{
|
||||
unset($pwg_event_handlers[$event]);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers a modifier event and calls all registered event handlers.
|
||||
* trigger_change() is used as a modifier: it allows to transmit _$data_
|
||||
* through all handlers, thus each handler MUST return a value,
|
||||
* optional _$args_ are not transmitted.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param string $event
|
||||
* @param mixed $data data to transmit to all handlers
|
||||
* @param mixed $args,... optional arguments
|
||||
* @return mixed $data
|
||||
*/
|
||||
function trigger_change($event, $data=null)
|
||||
{
|
||||
global $pwg_event_handlers;
|
||||
|
||||
if (isset($pwg_event_handlers['trigger']))
|
||||
{// debugging
|
||||
trigger_notify('trigger',
|
||||
array('type'=>'event', 'event'=>$event, 'data'=>$data)
|
||||
);
|
||||
}
|
||||
|
||||
if (!isset($pwg_event_handlers[$event]))
|
||||
{
|
||||
return $data;
|
||||
}
|
||||
$args = func_get_args();
|
||||
array_shift($args);
|
||||
|
||||
foreach ($pwg_event_handlers[$event] as $priority => $handlers)
|
||||
{
|
||||
foreach ($handlers as $handler)
|
||||
{
|
||||
$args[0] = $data;
|
||||
|
||||
if (!empty($handler['include_path']))
|
||||
{
|
||||
include_once($handler['include_path']);
|
||||
}
|
||||
|
||||
$data = call_user_func_array($handler['function'], $args);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($pwg_event_handlers['trigger']))
|
||||
{// debugging
|
||||
trigger_notify('trigger',
|
||||
array('type'=>'post_event', 'event'=>$event, 'data'=>$data)
|
||||
);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers a notifier event and calls all registered event handlers.
|
||||
* trigger_notify() is only used as a notifier, no modification of data is possible
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param string $event
|
||||
* @param mixed $args,... optional arguments
|
||||
*/
|
||||
function trigger_notify($event)
|
||||
{
|
||||
global $pwg_event_handlers;
|
||||
|
||||
if (isset($pwg_event_handlers['trigger']) and $event!='trigger')
|
||||
{// debugging - avoid recursive calls
|
||||
trigger_notify('trigger',
|
||||
array('type'=>'action', 'event'=>$event, 'data'=>null)
|
||||
);
|
||||
}
|
||||
|
||||
if (!isset($pwg_event_handlers[$event]))
|
||||
{
|
||||
return;
|
||||
}
|
||||
$args = func_get_args();
|
||||
array_shift($args);
|
||||
|
||||
foreach ($pwg_event_handlers[$event] as $priority => $handlers)
|
||||
{
|
||||
foreach ($handlers as $handler)
|
||||
{
|
||||
if (!empty($handler['include_path']))
|
||||
{
|
||||
include_once($handler['include_path']);
|
||||
}
|
||||
|
||||
call_user_func_array($handler['function'], $args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves some data with the associated plugin id, data are only available
|
||||
* during script lifetime.
|
||||
* @depracted 2.6
|
||||
*
|
||||
* @param string $plugin_id
|
||||
* @param mixed &$data
|
||||
* @return bool
|
||||
*/
|
||||
function set_plugin_data($plugin_id, &$data)
|
||||
{
|
||||
global $pwg_loaded_plugins;
|
||||
if ( isset($pwg_loaded_plugins[$plugin_id]) )
|
||||
{
|
||||
$pwg_loaded_plugins[$plugin_id]['plugin_data'] = &$data;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves plugin data saved previously with set_plugin_data.
|
||||
* @see set_plugin_data()
|
||||
* @depracted 2.6
|
||||
*
|
||||
* @param string $plugin_id
|
||||
* @return mixed
|
||||
*/
|
||||
function &get_plugin_data($plugin_id)
|
||||
{
|
||||
global $pwg_loaded_plugins;
|
||||
if ( isset($pwg_loaded_plugins[$plugin_id]['plugin_data']) )
|
||||
{
|
||||
return $pwg_loaded_plugins[$plugin_id]['plugin_data'];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of plugins defined in the database.
|
||||
*
|
||||
* @param string $state optional filter
|
||||
* @param string $id returns only data about given plugin
|
||||
* @return array
|
||||
*/
|
||||
function get_db_plugins($state='', $id='')
|
||||
{
|
||||
$query = '
|
||||
SELECT * FROM '.PLUGINS_TABLE;
|
||||
$clauses = array();
|
||||
if (!empty($state))
|
||||
{
|
||||
$clauses[] = 'state=\''.$state.'\'';
|
||||
}
|
||||
if (!empty($id))
|
||||
{
|
||||
$clauses[] = 'id="'.$id.'"';
|
||||
}
|
||||
if (count($clauses))
|
||||
{
|
||||
$query .= '
|
||||
WHERE '. implode(' AND ', $clauses);
|
||||
}
|
||||
|
||||
return query2array($query);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a plugin in memory.
|
||||
* It performs autoupdate, includes the main.inc.php file and updates *$pwg_loaded_plugins*.
|
||||
*
|
||||
* @param string $plugin
|
||||
*/
|
||||
function load_plugin($plugin)
|
||||
{
|
||||
$file_name = PHPWG_PLUGINS_PATH.$plugin['id'].'/main.inc.php';
|
||||
if (file_exists($file_name))
|
||||
{
|
||||
autoupdate_plugin($plugin);
|
||||
global $pwg_loaded_plugins;
|
||||
$pwg_loaded_plugins[ $plugin['id'] ] = $plugin;
|
||||
include_once($file_name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs update task of a plugin.
|
||||
* Autoupdate is only performed if the plugin has a maintain.class.php file.
|
||||
*
|
||||
* @since 2.7
|
||||
*
|
||||
* @param array &$plugin (id, version, state) will be updated if version changes
|
||||
*/
|
||||
function autoupdate_plugin(&$plugin)
|
||||
{
|
||||
// try to find the filesystem version in lines 2 to 10 of main.inc.php
|
||||
$fh = fopen(PHPWG_PLUGINS_PATH.$plugin['id'].'/main.inc.php', 'r');
|
||||
$fs_version = null;
|
||||
$i = -1;
|
||||
|
||||
while (($line = fgets($fh))!==false && $fs_version==null && $i<10)
|
||||
{
|
||||
$i++;
|
||||
if ($i < 2) continue; // first lines are typically "<?php" and "/*"
|
||||
|
||||
if (preg_match('/Version:\\s*([\\w.-]+)/', $line, $matches))
|
||||
{
|
||||
$fs_version = $matches[1];
|
||||
}
|
||||
}
|
||||
|
||||
fclose($fh);
|
||||
|
||||
// if version is auto (dev) or superior
|
||||
if ($fs_version != null && (
|
||||
$fs_version == 'auto' || $plugin['version'] == 'auto' ||
|
||||
safe_version_compare($plugin['version'], $fs_version, '<')
|
||||
)
|
||||
) {
|
||||
$plugin['version'] = $fs_version;
|
||||
|
||||
$maintain_file = PHPWG_PLUGINS_PATH.$plugin['id'].'/maintain.class.php';
|
||||
|
||||
// autoupdate is applicable only to plugins with 2.7 architecture
|
||||
if (file_exists($maintain_file))
|
||||
{
|
||||
global $page;
|
||||
|
||||
// call update method
|
||||
include_once($maintain_file);
|
||||
|
||||
$classname = $plugin['id'].'_maintain';
|
||||
$plugin_maintain = new $classname($plugin['id']);
|
||||
$plugin_maintain->update($plugin['version'], $fs_version, $page['errors']);
|
||||
}
|
||||
|
||||
// update database (only on production)
|
||||
if ($plugin['version'] != 'auto')
|
||||
{
|
||||
$query = '
|
||||
UPDATE '. PLUGINS_TABLE .'
|
||||
SET version = "'. $plugin['version'] .'"
|
||||
WHERE id = "'. $plugin['id'] .'"
|
||||
;';
|
||||
pwg_query($query);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads all the registered plugins.
|
||||
*/
|
||||
function load_plugins()
|
||||
{
|
||||
global $conf, $pwg_loaded_plugins;
|
||||
$pwg_loaded_plugins = array();
|
||||
if ($conf['enable_plugins'])
|
||||
{
|
||||
$plugins = get_db_plugins('active');
|
||||
foreach( $plugins as $plugin)
|
||||
{// include main from a function to avoid using same function context
|
||||
load_plugin($plugin);
|
||||
}
|
||||
trigger_notify('plugins_loaded');
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
218
zoesch.de/galerie/include/functions_rate.inc.php
Normal file
218
zoesch.de/galerie/include/functions_rate.inc.php
Normal file
@@ -0,0 +1,218 @@
|
||||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Piwigo - a PHP based photo gallery |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright(C) 2008-2016 Piwigo Team http://piwigo.org |
|
||||
// | Copyright(C) 2003-2008 PhpWebGallery Team http://phpwebgallery.net |
|
||||
// | Copyright(C) 2002-2003 Pierrick LE GALL http://le-gall.net/pierrick |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
* @package functions\rate
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Rate a picture by the current user.
|
||||
*
|
||||
* @param int $image_id
|
||||
* @param float $rate
|
||||
* @return array as return by update_rating_score()
|
||||
*/
|
||||
function rate_picture($image_id, $rate)
|
||||
{
|
||||
global $conf, $user;
|
||||
|
||||
if (!isset($rate)
|
||||
or !$conf['rate']
|
||||
or !preg_match('/^[0-9]+$/', $rate)
|
||||
or !in_array($rate, $conf['rate_items']))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$user_anonymous = is_autorize_status(ACCESS_CLASSIC) ? false : true;
|
||||
|
||||
if ($user_anonymous and !$conf['rate_anonymous'])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$ip_components = explode('.', $_SERVER["REMOTE_ADDR"]);
|
||||
if (count($ip_components) > 3)
|
||||
{
|
||||
array_pop($ip_components);
|
||||
}
|
||||
$anonymous_id = implode ('.', $ip_components);
|
||||
|
||||
if ($user_anonymous)
|
||||
{
|
||||
$save_anonymous_id = pwg_get_cookie_var('anonymous_rater', $anonymous_id);
|
||||
|
||||
if ($anonymous_id != $save_anonymous_id)
|
||||
{ // client has changed his IP adress or he's trying to fool us
|
||||
$query = '
|
||||
SELECT element_id
|
||||
FROM '.RATE_TABLE.'
|
||||
WHERE user_id = '.$user['id'].'
|
||||
AND anonymous_id = \''.$anonymous_id.'\'
|
||||
;';
|
||||
$already_there = array_from_query($query, 'element_id');
|
||||
|
||||
if (count($already_there) > 0)
|
||||
{
|
||||
$query = '
|
||||
DELETE
|
||||
FROM '.RATE_TABLE.'
|
||||
WHERE user_id = '.$user['id'].'
|
||||
AND anonymous_id = \''.$save_anonymous_id.'\'
|
||||
AND element_id IN ('.implode(',', $already_there).')
|
||||
;';
|
||||
pwg_query($query);
|
||||
}
|
||||
|
||||
$query = '
|
||||
UPDATE '.RATE_TABLE.'
|
||||
SET anonymous_id = \'' .$anonymous_id.'\'
|
||||
WHERE user_id = '.$user['id'].'
|
||||
AND anonymous_id = \'' . $save_anonymous_id.'\'
|
||||
;';
|
||||
pwg_query($query);
|
||||
} // end client changed ip
|
||||
|
||||
pwg_set_cookie_var('anonymous_rater', $anonymous_id);
|
||||
} // end anonymous user
|
||||
|
||||
$query = '
|
||||
DELETE
|
||||
FROM '.RATE_TABLE.'
|
||||
WHERE element_id = '.$image_id.'
|
||||
AND user_id = '.$user['id'].'
|
||||
';
|
||||
if ($user_anonymous)
|
||||
{
|
||||
$query.= ' AND anonymous_id = \''.$anonymous_id.'\'';
|
||||
}
|
||||
pwg_query($query);
|
||||
$query = '
|
||||
INSERT
|
||||
INTO '.RATE_TABLE.'
|
||||
(user_id,anonymous_id,element_id,rate,date)
|
||||
VALUES
|
||||
('
|
||||
.$user['id'].','
|
||||
.'\''.$anonymous_id.'\','
|
||||
.$image_id.','
|
||||
.$rate
|
||||
.',NOW())
|
||||
;';
|
||||
pwg_query($query);
|
||||
|
||||
return update_rating_score($image_id);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update images.rating_score field.
|
||||
* We use a bayesian average (http://en.wikipedia.org/wiki/Bayesian_average) with
|
||||
* C = average number of rates per item
|
||||
* m = global average rate (all rates)
|
||||
*
|
||||
* @param int|false $element_id if false applies to all
|
||||
* @return array (score, average, count) values are null if $element_id is false
|
||||
*/
|
||||
function update_rating_score($element_id = false)
|
||||
{
|
||||
if ( ($alt_result = trigger_change('update_rating_score', false, $element_id)) !== false)
|
||||
{
|
||||
return $alt_result;
|
||||
}
|
||||
|
||||
$query = '
|
||||
SELECT element_id,
|
||||
COUNT(rate) AS rcount,
|
||||
SUM(rate) AS rsum
|
||||
FROM '.RATE_TABLE.'
|
||||
GROUP by element_id';
|
||||
|
||||
$all_rates_count = 0;
|
||||
$all_rates_avg = 0;
|
||||
$item_ratecount_avg = 0;
|
||||
$by_item = array();
|
||||
|
||||
$result = pwg_query($query);
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
$all_rates_count += $row['rcount'];
|
||||
$all_rates_avg += $row['rsum'];
|
||||
$by_item[$row['element_id']] = $row;
|
||||
}
|
||||
|
||||
if ($all_rates_count>0)
|
||||
{
|
||||
$all_rates_avg /= $all_rates_count;
|
||||
$item_ratecount_avg = $all_rates_count / count($by_item);
|
||||
}
|
||||
|
||||
$updates = array();
|
||||
foreach ($by_item as $id => $rate_summary )
|
||||
{
|
||||
$score = ( $item_ratecount_avg * $all_rates_avg + $rate_summary['rsum'] ) / ($item_ratecount_avg + $rate_summary['rcount']);
|
||||
$score = round($score,2);
|
||||
if ($id==$element_id)
|
||||
{
|
||||
$return = array(
|
||||
'score' => $score,
|
||||
'average' => round($rate_summary['rsum'] / $rate_summary['rcount'], 2),
|
||||
'count' => $rate_summary['rcount'],
|
||||
);
|
||||
}
|
||||
$updates[] = array( 'id'=>$id, 'rating_score'=>$score );
|
||||
}
|
||||
mass_updates(
|
||||
IMAGES_TABLE,
|
||||
array(
|
||||
'primary' => array('id'),
|
||||
'update' => array('rating_score')
|
||||
),
|
||||
$updates
|
||||
);
|
||||
|
||||
//set to null all items with no rate
|
||||
if ( !isset($by_item[$element_id]) )
|
||||
{
|
||||
$query='
|
||||
SELECT id FROM '.IMAGES_TABLE .'
|
||||
LEFT JOIN '.RATE_TABLE.' ON id=element_id
|
||||
WHERE element_id IS NULL AND rating_score IS NOT NULL';
|
||||
|
||||
$to_update = array_from_query( $query, 'id');
|
||||
|
||||
if ( !empty($to_update) )
|
||||
{
|
||||
$query='
|
||||
UPDATE '.IMAGES_TABLE .'
|
||||
SET rating_score=NULL
|
||||
WHERE id IN (' . implode(',',$to_update) . ')';
|
||||
pwg_query($query);
|
||||
}
|
||||
}
|
||||
|
||||
return isset($return) ? $return : array('score'=>null, 'average'=>null, 'count'=>0 );
|
||||
}
|
||||
|
||||
?>
|
||||
1493
zoesch.de/galerie/include/functions_search.inc.php
Normal file
1493
zoesch.de/galerie/include/functions_search.inc.php
Normal file
File diff suppressed because it is too large
Load Diff
270
zoesch.de/galerie/include/functions_session.inc.php
Normal file
270
zoesch.de/galerie/include/functions_session.inc.php
Normal file
@@ -0,0 +1,270 @@
|
||||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Piwigo - a PHP based photo gallery |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright(C) 2008-2016 Piwigo Team http://piwigo.org |
|
||||
// | Copyright(C) 2003-2008 PhpWebGallery Team http://phpwebgallery.net |
|
||||
// | Copyright(C) 2002-2003 Pierrick LE GALL http://le-gall.net/pierrick |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
* @package functions\session
|
||||
*/
|
||||
|
||||
|
||||
if (isset($conf['session_save_handler'])
|
||||
and ($conf['session_save_handler'] == 'db')
|
||||
and defined('PHPWG_INSTALLED'))
|
||||
{
|
||||
session_set_save_handler(
|
||||
'pwg_session_open',
|
||||
'pwg_session_close',
|
||||
'pwg_session_read',
|
||||
'pwg_session_write',
|
||||
'pwg_session_destroy',
|
||||
'pwg_session_gc'
|
||||
);
|
||||
|
||||
if (function_exists('ini_set'))
|
||||
{
|
||||
ini_set('session.use_cookies', $conf['session_use_cookies']);
|
||||
ini_set('session.use_only_cookies', $conf['session_use_only_cookies']);
|
||||
ini_set('session.use_trans_sid', intval($conf['session_use_trans_sid']));
|
||||
ini_set('session.cookie_httponly', 1);
|
||||
}
|
||||
|
||||
session_name($conf['session_name']);
|
||||
session_set_cookie_params(0, cookie_path());
|
||||
register_shutdown_function('session_write_close');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generates a pseudo random string.
|
||||
* Characters used are a-z A-Z and numerical values.
|
||||
*
|
||||
* @param int $size
|
||||
* @return string
|
||||
*/
|
||||
function generate_key($size)
|
||||
{
|
||||
include_once(PHPWG_ROOT_PATH.'include/random_compat/random.php');
|
||||
|
||||
try
|
||||
{
|
||||
$bytes = random_bytes($size+10);
|
||||
}
|
||||
catch (Exception $ex)
|
||||
{
|
||||
include_once(PHPWG_ROOT_PATH.'include/srand.php');
|
||||
$bytes = secure_random_bytes($size+10);
|
||||
}
|
||||
|
||||
return substr(
|
||||
str_replace(
|
||||
array('+', '/'),
|
||||
'',
|
||||
base64_encode($bytes)
|
||||
),
|
||||
0,
|
||||
$size
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by PHP session manager, always return true.
|
||||
*
|
||||
* @param string $path
|
||||
* @param sring $name
|
||||
* @return true
|
||||
*/
|
||||
function pwg_session_open($path, $name)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by PHP session manager, always return true.
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
function pwg_session_close()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hash from current user IP
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function get_remote_addr_session_hash()
|
||||
{
|
||||
global $conf;
|
||||
|
||||
if (!$conf['session_use_ip_address'])
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
if (strpos($_SERVER['REMOTE_ADDR'],':')===false)
|
||||
{//ipv4
|
||||
return vsprintf(
|
||||
"%02X%02X",
|
||||
explode('.',$_SERVER['REMOTE_ADDR'])
|
||||
);
|
||||
}
|
||||
return ''; //ipv6 not yet
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by PHP session manager, retrieves data stored in the sessions table.
|
||||
*
|
||||
* @param string $session_id
|
||||
* @return string
|
||||
*/
|
||||
function pwg_session_read($session_id)
|
||||
{
|
||||
$query = '
|
||||
SELECT data
|
||||
FROM '.SESSIONS_TABLE.'
|
||||
WHERE id = \''.get_remote_addr_session_hash().$session_id.'\'
|
||||
;';
|
||||
$result = pwg_query($query);
|
||||
if ( ($row = pwg_db_fetch_assoc($result)) )
|
||||
{
|
||||
return $row['data'];
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by PHP session manager, writes data in the sessions table.
|
||||
*
|
||||
* @param string $session_id
|
||||
* @param sring $data
|
||||
* @return true
|
||||
*/
|
||||
function pwg_session_write($session_id, $data)
|
||||
{
|
||||
$query = '
|
||||
REPLACE INTO '.SESSIONS_TABLE.'
|
||||
(id,data,expiration)
|
||||
VALUES(\''.get_remote_addr_session_hash().$session_id.'\',\''.pwg_db_real_escape_string($data).'\',now())
|
||||
;';
|
||||
pwg_query($query);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by PHP session manager, deletes data in the sessions table.
|
||||
*
|
||||
* @param string $session_id
|
||||
* @return true
|
||||
*/
|
||||
function pwg_session_destroy($session_id)
|
||||
{
|
||||
$query = '
|
||||
DELETE
|
||||
FROM '.SESSIONS_TABLE.'
|
||||
WHERE id = \''.get_remote_addr_session_hash().$session_id.'\'
|
||||
;';
|
||||
pwg_query($query);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by PHP session manager, garbage collector for expired sessions.
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
function pwg_session_gc()
|
||||
{
|
||||
global $conf;
|
||||
|
||||
$query = '
|
||||
DELETE
|
||||
FROM '.SESSIONS_TABLE.'
|
||||
WHERE '.pwg_db_date_to_ts('NOW()').' - '.pwg_db_date_to_ts('expiration').' > '
|
||||
.$conf['session_length'].'
|
||||
;';
|
||||
pwg_query($query);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Persistently stores a variable for the current session.
|
||||
*
|
||||
* @param string $var
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
function pwg_set_session_var($var, $value)
|
||||
{
|
||||
if ( !isset($_SESSION) )
|
||||
return false;
|
||||
$_SESSION['pwg_'.$var] = $value;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the value of a persistent variable for the current session.
|
||||
*
|
||||
* @param string $var
|
||||
* @param mixed $default
|
||||
* @return mixed
|
||||
*/
|
||||
function pwg_get_session_var($var, $default = null)
|
||||
{
|
||||
if (isset( $_SESSION['pwg_'.$var] ) )
|
||||
{
|
||||
return $_SESSION['pwg_'.$var];
|
||||
}
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a persistent variable for the current session.
|
||||
*
|
||||
* @param string $var
|
||||
* @return bool
|
||||
*/
|
||||
function pwg_unset_session_var($var)
|
||||
{
|
||||
if ( !isset($_SESSION) )
|
||||
return false;
|
||||
unset( $_SESSION['pwg_'.$var] );
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* delete all sessions for a given user (certainly deleted)
|
||||
*
|
||||
* @since 2.8
|
||||
* @param int $user_id
|
||||
* @return null
|
||||
*/
|
||||
function delete_user_sessions($user_id)
|
||||
{
|
||||
$query = '
|
||||
DELETE
|
||||
FROM '.SESSIONS_TABLE.'
|
||||
WHERE data LIKE \'%pwg_uid|i:'.(int)$user_id.';%\'
|
||||
;';
|
||||
pwg_query($query);
|
||||
}
|
||||
?>
|
||||
326
zoesch.de/galerie/include/functions_tag.inc.php
Normal file
326
zoesch.de/galerie/include/functions_tag.inc.php
Normal file
@@ -0,0 +1,326 @@
|
||||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Piwigo - a PHP based photo gallery |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright(C) 2008-2016 Piwigo Team http://piwigo.org |
|
||||
// | Copyright(C) 2003-2008 PhpWebGallery Team http://phpwebgallery.net |
|
||||
// | Copyright(C) 2002-2003 Pierrick LE GALL http://le-gall.net/pierrick |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
* @package functions\tag
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Returns the number of available tags for the connected user.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
function get_nb_available_tags()
|
||||
{
|
||||
global $user;
|
||||
if (!isset($user['nb_available_tags']))
|
||||
{
|
||||
$user['nb_available_tags'] = count(get_available_tags());
|
||||
single_update(USER_CACHE_TABLE,
|
||||
array('nb_available_tags'=>$user['nb_available_tags']),
|
||||
array('user_id'=>$user['id'])
|
||||
);
|
||||
}
|
||||
return $user['nb_available_tags'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all available tags for the connected user (not sorted).
|
||||
* The returned list can be a subset of all existing tags due to permissions,
|
||||
* also tags with no images are not returned.
|
||||
*
|
||||
* @return array [id, name, counter, url_name]
|
||||
*/
|
||||
function get_available_tags()
|
||||
{
|
||||
// we can find top fatter tags among reachable images
|
||||
$query = '
|
||||
SELECT tag_id, COUNT(DISTINCT(it.image_id)) AS counter
|
||||
FROM '.IMAGE_CATEGORY_TABLE.' ic
|
||||
INNER JOIN '.IMAGE_TAG_TABLE.' it
|
||||
ON ic.image_id=it.image_id
|
||||
'.get_sql_condition_FandF(
|
||||
array(
|
||||
'forbidden_categories' => 'category_id',
|
||||
'visible_categories' => 'category_id',
|
||||
'visible_images' => 'ic.image_id'
|
||||
),
|
||||
' WHERE '
|
||||
).'
|
||||
GROUP BY tag_id
|
||||
;';
|
||||
$tag_counters = query2array($query, 'tag_id', 'counter');
|
||||
|
||||
if ( empty($tag_counters) )
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
$query = '
|
||||
SELECT *
|
||||
FROM '.TAGS_TABLE;
|
||||
$result = pwg_query($query);
|
||||
|
||||
$tags = array();
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
$counter = intval(@$tag_counters[ $row['id'] ]);
|
||||
if ( $counter )
|
||||
{
|
||||
$row['counter'] = $counter;
|
||||
$row['name'] = trigger_change('render_tag_name', $row['name'], $row);
|
||||
$tags[] = $row;
|
||||
}
|
||||
}
|
||||
return $tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all tags even associated to no image.
|
||||
*
|
||||
* @return array [id, name, url_name]
|
||||
*/
|
||||
function get_all_tags()
|
||||
{
|
||||
$query = '
|
||||
SELECT *
|
||||
FROM '.TAGS_TABLE.'
|
||||
;';
|
||||
$result = pwg_query($query);
|
||||
$tags = array();
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
$row['name'] = trigger_change('render_tag_name', $row['name'], $row);
|
||||
$tags[] = $row;
|
||||
}
|
||||
|
||||
usort($tags, 'tag_alpha_compare');
|
||||
|
||||
return $tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Giving a set of tags with a counter for each one, calculate the display
|
||||
* level of each tag.
|
||||
*
|
||||
* The level of each tag depends on the average count of tags. This
|
||||
* calculation method avoid having very different levels for tags having
|
||||
* nearly the same count when set are small.
|
||||
*
|
||||
* @param array $tags at least [id, counter]
|
||||
* @return array [..., level]
|
||||
*/
|
||||
function add_level_to_tags($tags)
|
||||
{
|
||||
global $conf;
|
||||
|
||||
if (count($tags) == 0)
|
||||
{
|
||||
return $tags;
|
||||
}
|
||||
|
||||
$total_count = 0;
|
||||
|
||||
foreach ($tags as $tag)
|
||||
{
|
||||
$total_count+= $tag['counter'];
|
||||
}
|
||||
|
||||
// average count of available tags will determine the level of each tag
|
||||
$tag_average_count = $total_count / count($tags);
|
||||
|
||||
// tag levels threshold calculation: a tag with an average rate must have
|
||||
// the middle level.
|
||||
for ($i = 1; $i < $conf['tags_levels']; $i++)
|
||||
{
|
||||
$threshold_of_level[$i] =
|
||||
2 * $i * $tag_average_count / $conf['tags_levels'];
|
||||
}
|
||||
|
||||
// display sorted tags
|
||||
foreach ($tags as &$tag)
|
||||
{
|
||||
$tag['level'] = 1;
|
||||
|
||||
// based on threshold, determine current tag level
|
||||
for ($i = $conf['tags_levels'] - 1; $i >= 1; $i--)
|
||||
{
|
||||
if ($tag['counter'] > $threshold_of_level[$i])
|
||||
{
|
||||
$tag['level'] = $i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
unset($tag);
|
||||
|
||||
return $tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of image ids corresponding to given tags.
|
||||
* AND & OR mode supported.
|
||||
*
|
||||
* @param int[] $tag_ids
|
||||
* @param string mode
|
||||
* @param string $extra_images_where_sql - optionally apply a sql where filter to retrieved images
|
||||
* @param string $order_by - optionally overwrite default photo order
|
||||
* @param bool $user_permissions
|
||||
* @return array
|
||||
*/
|
||||
function get_image_ids_for_tags($tag_ids, $mode='AND', $extra_images_where_sql='', $order_by='', $use_permissions=true)
|
||||
{
|
||||
global $conf;
|
||||
if (empty($tag_ids))
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
$query = '
|
||||
SELECT id
|
||||
FROM '.IMAGES_TABLE.' i ';
|
||||
|
||||
if ($use_permissions)
|
||||
{
|
||||
$query.= '
|
||||
INNER JOIN '.IMAGE_CATEGORY_TABLE.' ic ON id=ic.image_id';
|
||||
}
|
||||
|
||||
$query.= '
|
||||
INNER JOIN '.IMAGE_TAG_TABLE.' it ON id=it.image_id
|
||||
WHERE tag_id IN ('.implode(',', $tag_ids).')';
|
||||
|
||||
if ($use_permissions)
|
||||
{
|
||||
$query.= get_sql_condition_FandF(
|
||||
array(
|
||||
'forbidden_categories' => 'category_id',
|
||||
'visible_categories' => 'category_id',
|
||||
'visible_images' => 'id'
|
||||
),
|
||||
"\n AND"
|
||||
);
|
||||
}
|
||||
|
||||
$query.= (empty($extra_images_where_sql) ? '' : " \nAND (".$extra_images_where_sql.')').'
|
||||
GROUP BY id';
|
||||
|
||||
if ($mode=='AND' and count($tag_ids)>1)
|
||||
{
|
||||
$query .= '
|
||||
HAVING COUNT(DISTINCT tag_id)='.count($tag_ids);
|
||||
}
|
||||
$query .= "\n".(empty($order_by) ? $conf['order_by'] : $order_by);
|
||||
|
||||
return query2array($query, null, 'id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of tags corresponding to given items.
|
||||
*
|
||||
* @param int[] $items
|
||||
* @param int $max_tags
|
||||
* @param int[] $excluded_tag_ids
|
||||
* @return array [id, name, counter, url_name]
|
||||
*/
|
||||
function get_common_tags($items, $max_tags, $excluded_tag_ids=array())
|
||||
{
|
||||
if (empty($items))
|
||||
{
|
||||
return array();
|
||||
}
|
||||
$query = '
|
||||
SELECT t.*, count(*) AS counter
|
||||
FROM '.IMAGE_TAG_TABLE.'
|
||||
INNER JOIN '.TAGS_TABLE.' t ON tag_id = id
|
||||
WHERE image_id IN ('.implode(',', $items).')';
|
||||
if (!empty($excluded_tag_ids))
|
||||
{
|
||||
$query.='
|
||||
AND tag_id NOT IN ('.implode(',', $excluded_tag_ids).')';
|
||||
}
|
||||
$query .='
|
||||
GROUP BY t.id
|
||||
ORDER BY ';
|
||||
if ($max_tags>0)
|
||||
{ // TODO : why ORDER field is in the if ?
|
||||
$query .= 'counter DESC
|
||||
LIMIT '.$max_tags;
|
||||
}
|
||||
else
|
||||
{
|
||||
$query .= 'NULL';
|
||||
}
|
||||
|
||||
$result = pwg_query($query);
|
||||
$tags = array();
|
||||
while($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
$row['name'] = trigger_change('render_tag_name', $row['name'], $row);
|
||||
$tags[] = $row;
|
||||
}
|
||||
usort($tags, 'tag_alpha_compare');
|
||||
return $tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of tags corresponding to any of ids, url_names or names.
|
||||
*
|
||||
* @param int[] $ids
|
||||
* @param string[] $url_names
|
||||
* @param string[] $names
|
||||
* @return array [id, name, url_name]
|
||||
*/
|
||||
function find_tags($ids=array(), $url_names=array(), $names=array() )
|
||||
{
|
||||
$where_clauses = array();
|
||||
if (!empty($ids))
|
||||
{
|
||||
$where_clauses[] = 'id IN ('.implode(',', $ids).')';
|
||||
}
|
||||
if (!empty($url_names))
|
||||
{
|
||||
$where_clauses[] =
|
||||
'url_name IN (\''. implode('\', \'', $url_names) .'\')';
|
||||
}
|
||||
if (!empty($names))
|
||||
{
|
||||
$where_clauses[] =
|
||||
'name IN (\''. implode('\', \'', $names) .'\')';
|
||||
}
|
||||
if (empty($where_clauses))
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
$query = '
|
||||
SELECT *
|
||||
FROM '.TAGS_TABLE.'
|
||||
WHERE '. implode( '
|
||||
OR ', $where_clauses);
|
||||
|
||||
return query2array($query);
|
||||
}
|
||||
|
||||
?>
|
||||
827
zoesch.de/galerie/include/functions_url.inc.php
Normal file
827
zoesch.de/galerie/include/functions_url.inc.php
Normal file
@@ -0,0 +1,827 @@
|
||||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Piwigo - a PHP based photo gallery |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright(C) 2008-2016 Piwigo Team http://piwigo.org |
|
||||
// | Copyright(C) 2003-2008 PhpWebGallery Team http://phpwebgallery.net |
|
||||
// | Copyright(C) 2002-2003 Pierrick LE GALL http://le-gall.net/pierrick |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
|
||||
/**
|
||||
* returns a prefix for each url link on displayed page
|
||||
* and return an empty string for current path
|
||||
* @return string
|
||||
*/
|
||||
function get_root_url()
|
||||
{
|
||||
global $page;
|
||||
if ( ($root_url = @$page['root_path']) == null )
|
||||
{// TODO - add HERE the possibility to call PWG functions from external scripts
|
||||
$root_url = PHPWG_ROOT_PATH;
|
||||
if ( strncmp($root_url, './', 2) == 0 )
|
||||
{
|
||||
return substr($root_url, 2);
|
||||
}
|
||||
}
|
||||
return $root_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the absolute url to the root of PWG
|
||||
* @param boolean with_scheme if false - does not add http://toto.com
|
||||
*/
|
||||
function get_absolute_root_url($with_scheme=true)
|
||||
{
|
||||
// TODO - add HERE the possibility to call PWG functions from external scripts
|
||||
$url = '';
|
||||
if ($with_scheme)
|
||||
{
|
||||
$is_https = false;
|
||||
if (isset($_SERVER['HTTPS']) &&
|
||||
((strtolower($_SERVER['HTTPS']) == 'on') or ($_SERVER['HTTPS'] == 1)))
|
||||
{
|
||||
$is_https = true;
|
||||
$url .= 'https://';
|
||||
}
|
||||
else
|
||||
{
|
||||
$url .= 'http://';
|
||||
}
|
||||
if (isset($_SERVER['HTTP_X_FORWARDED_HOST']))
|
||||
{
|
||||
$url .= $_SERVER['HTTP_X_FORWARDED_HOST'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$url .= $_SERVER['HTTP_HOST'];
|
||||
if ( (!$is_https && $_SERVER['SERVER_PORT'] != 80)
|
||||
||($is_https && $_SERVER['SERVER_PORT'] != 443))
|
||||
{
|
||||
$url_port = ':'.$_SERVER['SERVER_PORT'];
|
||||
if (strrchr($url, ':') != $url_port)
|
||||
{
|
||||
$url .= $url_port;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$url .= cookie_path();
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* adds one or more _GET style parameters to an url
|
||||
* example: add_url_params('/x', array('a'=>'b')) returns /x?a=b
|
||||
* add_url_params('/x?cat_id=10', array('a'=>'b')) returns /x?cat_id=10&a=b
|
||||
* @param string url
|
||||
* @param array params
|
||||
* @return string
|
||||
*/
|
||||
function add_url_params($url, $params, $arg_separator='&' )
|
||||
{
|
||||
if ( !empty($params) )
|
||||
{
|
||||
assert( is_array($params) );
|
||||
$is_first = true;
|
||||
foreach($params as $param=>$val)
|
||||
{
|
||||
if ($is_first)
|
||||
{
|
||||
$is_first = false;
|
||||
$url .= ( strpos($url, '?')===false ) ? '?' : $arg_separator;
|
||||
}
|
||||
else
|
||||
{
|
||||
$url .= $arg_separator;
|
||||
}
|
||||
$url .= $param;
|
||||
if (isset($val))
|
||||
{
|
||||
$url .= '='.$val;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* build an index URL for a specific section
|
||||
*
|
||||
* @param array
|
||||
* @return string
|
||||
*/
|
||||
function make_index_url($params = array())
|
||||
{
|
||||
global $conf;
|
||||
$url = get_root_url().'index';
|
||||
if ($conf['php_extension_in_urls'])
|
||||
{
|
||||
$url .= '.php';
|
||||
}
|
||||
if ($conf['question_mark_in_urls'])
|
||||
{
|
||||
$url .= '?';
|
||||
}
|
||||
|
||||
$url_before_params = $url;
|
||||
|
||||
$url.= make_section_in_url($params);
|
||||
$url = add_well_known_params_in_url($url, $params);
|
||||
|
||||
if ($url == $url_before_params)
|
||||
{
|
||||
$url = get_absolute_root_url( url_is_remote($url) );
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* build an index URL with current page parameters, but with redefinitions
|
||||
* and removes.
|
||||
*
|
||||
* duplicate_index_url( array(
|
||||
* 'category' => array('id'=>12, 'name'=>'toto'),
|
||||
* array('start')
|
||||
* ) will create an index URL on the current section (categories), but on
|
||||
* a redefined category and without the start URL parameter.
|
||||
*
|
||||
* @param array redefined keys
|
||||
* @param array removed keys
|
||||
* @return string
|
||||
*/
|
||||
function duplicate_index_url($redefined = array(), $removed = array())
|
||||
{
|
||||
return make_index_url(
|
||||
params_for_duplication($redefined, $removed)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns $page global array with key redefined and key removed
|
||||
*
|
||||
* @param array redefined keys
|
||||
* @param array removed keys
|
||||
* @return array
|
||||
*/
|
||||
function params_for_duplication($redefined, $removed)
|
||||
{
|
||||
global $page;
|
||||
|
||||
$params = $page;
|
||||
|
||||
foreach ($removed as $param_key)
|
||||
{
|
||||
unset($params[$param_key]);
|
||||
}
|
||||
|
||||
foreach ($redefined as $redefined_param => $redefined_value)
|
||||
{
|
||||
$params[$redefined_param] = $redefined_value;
|
||||
}
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* create a picture URL with current page parameters, but with redefinitions
|
||||
* and removes. See duplicate_index_url.
|
||||
*
|
||||
* @param array redefined keys
|
||||
* @param array removed keys
|
||||
* @return string
|
||||
*/
|
||||
function duplicate_picture_url($redefined = array(), $removed = array())
|
||||
{
|
||||
return make_picture_url(
|
||||
params_for_duplication($redefined, $removed)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* create a picture URL on a specific section for a specific picture
|
||||
*
|
||||
* @param array
|
||||
* @return string
|
||||
*/
|
||||
function make_picture_url($params)
|
||||
{
|
||||
global $conf;
|
||||
|
||||
$url = get_root_url().'picture';
|
||||
if ($conf['php_extension_in_urls'])
|
||||
{
|
||||
$url .= '.php';
|
||||
}
|
||||
if ($conf['question_mark_in_urls'])
|
||||
{
|
||||
$url .= '?';
|
||||
}
|
||||
$url.= '/';
|
||||
switch ( $conf['picture_url_style'] )
|
||||
{
|
||||
case 'id-file':
|
||||
$url .= $params['image_id'];
|
||||
if ( isset($params['image_file']) )
|
||||
{
|
||||
$url .= '-'.str2url(get_filename_wo_extension($params['image_file']));
|
||||
}
|
||||
break;
|
||||
case 'file':
|
||||
if ( isset($params['image_file']) )
|
||||
{
|
||||
$fname_wo_ext = get_filename_wo_extension($params['image_file']);
|
||||
if ( ord($fname_wo_ext)>ord('9') or !preg_match('/^\d+(-|$)/', $fname_wo_ext) )
|
||||
{
|
||||
$url .= $fname_wo_ext;
|
||||
break;
|
||||
}
|
||||
}
|
||||
default:
|
||||
$url .= $params['image_id'];
|
||||
}
|
||||
if ( !isset($params['category'] ) )
|
||||
{// make urls shorter ...
|
||||
unset( $params['flat'] );
|
||||
}
|
||||
$url .= make_section_in_url($params);
|
||||
$url = add_well_known_params_in_url($url, $params);
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
*adds to the url the chronology and start parameters
|
||||
*/
|
||||
function add_well_known_params_in_url($url, $params)
|
||||
{
|
||||
if ( isset($params['chronology_field']) )
|
||||
{
|
||||
$url .= '/'. $params['chronology_field'];
|
||||
$url .= '-'. $params['chronology_style'];
|
||||
if ( isset($params['chronology_view']) )
|
||||
{
|
||||
$url .= '-'. $params['chronology_view'];
|
||||
}
|
||||
if ( !empty($params['chronology_date']) )
|
||||
{
|
||||
$url .= '-'. implode('-', $params['chronology_date'] );
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($params['flat']))
|
||||
{
|
||||
$url.= '/flat';
|
||||
}
|
||||
|
||||
if (isset($params['start']) and $params['start'] > 0)
|
||||
{
|
||||
$url.= '/start-'.$params['start'];
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* return the section token of an index or picture URL.
|
||||
*
|
||||
* Depending on section, other parameters are required (see function code
|
||||
* for details)
|
||||
*
|
||||
* @param array
|
||||
* @return string
|
||||
*/
|
||||
function make_section_in_url($params)
|
||||
{
|
||||
global $conf;
|
||||
$section_string = '';
|
||||
$section = @$params['section'];
|
||||
if (!isset($section))
|
||||
{
|
||||
$section_of = array(
|
||||
'category' => 'categories',
|
||||
'tags' => 'tags',
|
||||
'list' => 'list',
|
||||
'search' => 'search',
|
||||
);
|
||||
|
||||
foreach ($section_of as $param => $s)
|
||||
{
|
||||
if (isset($params[$param]))
|
||||
{
|
||||
$section = $s;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($section))
|
||||
{
|
||||
$section = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
switch($section)
|
||||
{
|
||||
case 'categories' :
|
||||
{
|
||||
if (!isset($params['category']))
|
||||
{
|
||||
$section_string.= '/categories';
|
||||
}
|
||||
else
|
||||
{
|
||||
isset($params['category']['name']) or trigger_error(
|
||||
'make_section_in_url category name not set', E_USER_WARNING
|
||||
);
|
||||
|
||||
array_key_exists('permalink', $params['category']) or trigger_error(
|
||||
'make_section_in_url category permalink not set', E_USER_WARNING
|
||||
);
|
||||
|
||||
$section_string.= '/category/';
|
||||
if ( empty($params['category']['permalink']) )
|
||||
{
|
||||
$section_string.= $params['category']['id'];
|
||||
if ( $conf['category_url_style']=='id-name' )
|
||||
{
|
||||
$section_string.= '-'.str2url($params['category']['name']);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$section_string.= $params['category']['permalink'];
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 'tags' :
|
||||
{
|
||||
$section_string.= '/tags';
|
||||
|
||||
foreach ($params['tags'] as $tag)
|
||||
{
|
||||
switch ( $conf['tag_url_style'] )
|
||||
{
|
||||
case 'id':
|
||||
$section_string.= '/'.$tag['id'];
|
||||
break;
|
||||
case 'tag':
|
||||
if (isset($tag['url_name']))
|
||||
{
|
||||
$section_string.= '/'.$tag['url_name'];
|
||||
break;
|
||||
}
|
||||
default:
|
||||
$section_string.= '/'.$tag['id'];
|
||||
if (isset($tag['url_name']))
|
||||
{
|
||||
$section_string.= '-'.$tag['url_name'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 'search' :
|
||||
{
|
||||
$section_string.= '/search/'.$params['search'];
|
||||
break;
|
||||
}
|
||||
case 'list' :
|
||||
{
|
||||
$section_string.= '/list/'.implode(',', $params['list']);
|
||||
break;
|
||||
}
|
||||
case 'none' :
|
||||
{
|
||||
break;
|
||||
}
|
||||
default :
|
||||
{
|
||||
$section_string.= '/'.$section;
|
||||
}
|
||||
}
|
||||
|
||||
return $section_string;
|
||||
}
|
||||
|
||||
/**
|
||||
* the reverse of make_section_in_url
|
||||
* returns the 'section' (categories/tags/...) and the data associated with it
|
||||
*
|
||||
* Depending on section, other parameters are returned (category/tags/list/...)
|
||||
*
|
||||
* @param array of url tokens to parse
|
||||
* @param int the index in the array of url tokens; in/out
|
||||
* @return array
|
||||
*/
|
||||
function parse_section_url( $tokens, &$next_token)
|
||||
{
|
||||
$page=array();
|
||||
if (strncmp(@$tokens[$next_token], 'categor', 7)==0 )
|
||||
{
|
||||
$page['section'] = 'categories';
|
||||
$next_token++;
|
||||
|
||||
if (isset($tokens[$next_token]) )
|
||||
{
|
||||
if (preg_match('/^(\d+)(?:-(.+))?$/', $tokens[$next_token], $matches))
|
||||
{
|
||||
if ( isset($matches[2]) )
|
||||
$page['hit_by']['cat_url_name'] = $matches[2];
|
||||
$page['category'] = $matches[1];
|
||||
$next_token++;
|
||||
}
|
||||
else
|
||||
{// try a permalink
|
||||
$maybe_permalinks = array();
|
||||
$current_token = $next_token;
|
||||
while ( isset($tokens[$current_token])
|
||||
and strpos($tokens[$current_token], 'created-')!==0
|
||||
and strpos($tokens[$current_token], 'posted-')!==0
|
||||
and strpos($tokens[$next_token], 'start-')!==0
|
||||
and strpos($tokens[$next_token], 'startcat-')!==0
|
||||
and $tokens[$current_token] != 'flat')
|
||||
{
|
||||
if (empty($maybe_permalinks))
|
||||
{
|
||||
$maybe_permalinks[] = $tokens[$current_token];
|
||||
}
|
||||
else
|
||||
{
|
||||
$maybe_permalinks[] =
|
||||
$maybe_permalinks[count($maybe_permalinks)-1]
|
||||
. '/' . $tokens[$current_token];
|
||||
}
|
||||
$current_token++;
|
||||
}
|
||||
|
||||
if ( count($maybe_permalinks) )
|
||||
{
|
||||
$cat_id = get_cat_id_from_permalinks($maybe_permalinks, $perma_index);
|
||||
if ( isset($cat_id) )
|
||||
{
|
||||
$next_token += $perma_index+1;
|
||||
$page['category'] = $cat_id;
|
||||
$page['hit_by']['cat_permalink'] = $maybe_permalinks[$perma_index];
|
||||
}
|
||||
else
|
||||
{
|
||||
page_not_found(l10n('Permalink for album not found'));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($page['category']))
|
||||
{
|
||||
$result = get_cat_info($page['category']);
|
||||
if (empty($result))
|
||||
{
|
||||
page_not_found(l10n('Requested album does not exist'));
|
||||
}
|
||||
$page['category']=$result;
|
||||
}
|
||||
}
|
||||
elseif ( 'tags' == @$tokens[$next_token] )
|
||||
{
|
||||
global $conf;
|
||||
|
||||
$page['section'] = 'tags';
|
||||
$page['tags'] = array();
|
||||
|
||||
$next_token++;
|
||||
$i = $next_token;
|
||||
|
||||
$requested_tag_ids = array();
|
||||
$requested_tag_url_names = array();
|
||||
|
||||
while (isset($tokens[$i]))
|
||||
{
|
||||
if (strpos($tokens[$i], 'created-')===0
|
||||
or strpos($tokens[$i], 'posted-')===0
|
||||
or strpos($tokens[$i], 'start-')===0 )
|
||||
break;
|
||||
|
||||
if ( $conf['tag_url_style'] != 'tag' and preg_match('/^(\d+)(?:-(.*)|)$/', $tokens[$i], $matches) )
|
||||
{
|
||||
$requested_tag_ids[] = $matches[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
$requested_tag_url_names[] = $tokens[$i];
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
$next_token = $i;
|
||||
|
||||
if ( empty($requested_tag_ids) && empty($requested_tag_url_names) )
|
||||
{
|
||||
bad_request('at least one tag required');
|
||||
}
|
||||
|
||||
$page['tags'] = find_tags($requested_tag_ids, $requested_tag_url_names);
|
||||
if ( empty($page['tags']) )
|
||||
{
|
||||
page_not_found(l10n('Requested tag does not exist'), get_root_url().'tags.php' );
|
||||
}
|
||||
}
|
||||
elseif ( 'favorites' == @$tokens[$next_token] )
|
||||
{
|
||||
$page['section'] = 'favorites';
|
||||
$next_token++;
|
||||
}
|
||||
elseif ('most_visited' == @$tokens[$next_token])
|
||||
{
|
||||
$page['section'] = 'most_visited';
|
||||
$next_token++;
|
||||
}
|
||||
elseif ('best_rated' == @$tokens[$next_token])
|
||||
{
|
||||
$page['section'] = 'best_rated';
|
||||
$next_token++;
|
||||
}
|
||||
elseif ('recent_pics' == @$tokens[$next_token])
|
||||
{
|
||||
$page['section'] = 'recent_pics';
|
||||
$next_token++;
|
||||
}
|
||||
elseif ('recent_cats' == @$tokens[$next_token])
|
||||
{
|
||||
$page['section'] = 'recent_cats';
|
||||
$next_token++;
|
||||
}
|
||||
elseif ('search' == @$tokens[$next_token])
|
||||
{
|
||||
$page['section'] = 'search';
|
||||
$next_token++;
|
||||
|
||||
preg_match('/(\d+)/', @$tokens[$next_token], $matches);
|
||||
if (!isset($matches[1]))
|
||||
{
|
||||
bad_request('search identifier is missing');
|
||||
}
|
||||
$page['search'] = $matches[1];
|
||||
$next_token++;
|
||||
}
|
||||
elseif ('list' == @$tokens[$next_token])
|
||||
{
|
||||
$page['section'] = 'list';
|
||||
$next_token++;
|
||||
|
||||
$page['list'] = array();
|
||||
|
||||
// No pictures
|
||||
if (empty($tokens[$next_token]))
|
||||
{
|
||||
// Add dummy element list
|
||||
$page['list'][] = -1;
|
||||
}
|
||||
// With pictures list
|
||||
else
|
||||
{
|
||||
if (!preg_match('/^\d+(,\d+)*$/', $tokens[$next_token]))
|
||||
{
|
||||
bad_request('wrong format on list GET parameter');
|
||||
}
|
||||
foreach (explode(',', $tokens[$next_token]) as $image_id)
|
||||
{
|
||||
$page['list'][] = $image_id;
|
||||
}
|
||||
}
|
||||
$next_token++;
|
||||
}
|
||||
return $page;
|
||||
}
|
||||
|
||||
/**
|
||||
* the reverse of add_well_known_params_in_url
|
||||
* parses start, flat and chronology from url tokens
|
||||
*/
|
||||
function parse_well_known_params_url($tokens, &$i)
|
||||
{
|
||||
$page = array();
|
||||
while (isset($tokens[$i]))
|
||||
{
|
||||
if ( 'flat' == $tokens[$i] )
|
||||
{
|
||||
// indicate a special list of images
|
||||
$page['flat'] = true;
|
||||
}
|
||||
elseif (strpos($tokens[$i], 'created-')===0 or strpos($tokens[$i], 'posted-')===0)
|
||||
{
|
||||
$chronology_tokens = explode('-', $tokens[$i] );
|
||||
|
||||
$page['chronology_field'] = $chronology_tokens[0];
|
||||
|
||||
array_shift($chronology_tokens);
|
||||
$page['chronology_style'] = $chronology_tokens[0];
|
||||
|
||||
array_shift($chronology_tokens);
|
||||
if ( count($chronology_tokens)>0 )
|
||||
{
|
||||
if ('list'==$chronology_tokens[0] or
|
||||
'calendar'==$chronology_tokens[0])
|
||||
{
|
||||
$page['chronology_view'] = $chronology_tokens[0];
|
||||
array_shift($chronology_tokens);
|
||||
}
|
||||
$page['chronology_date'] = $chronology_tokens;
|
||||
}
|
||||
}
|
||||
elseif (preg_match('/^start-(\d+)/', $tokens[$i], $matches))
|
||||
{
|
||||
$page['start'] = $matches[1];
|
||||
}
|
||||
elseif (preg_match('/^startcat-(\d+)/', $tokens[$i], $matches))
|
||||
{
|
||||
$page['startcat'] = $matches[1];
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
return $page;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param id image id
|
||||
* @param what_part string one of 'e' (element), 'r' (representative)
|
||||
*/
|
||||
function get_action_url($id, $what_part, $download)
|
||||
{
|
||||
$params = array(
|
||||
'id' => $id,
|
||||
'part' => $what_part,
|
||||
);
|
||||
if ($download)
|
||||
{
|
||||
$params['download'] = null;
|
||||
}
|
||||
|
||||
return add_url_params(get_root_url().'action.php', $params);
|
||||
}
|
||||
|
||||
/*
|
||||
* @param element_info array containing element information from db;
|
||||
* at least 'id', 'path' should be present
|
||||
*/
|
||||
function get_element_url($element_info)
|
||||
{
|
||||
$url = $element_info['path'];
|
||||
if ( !url_is_remote($url) )
|
||||
{
|
||||
$url = embellish_url(get_root_url().$url);
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Indicate to build url with full path
|
||||
*
|
||||
* @param null
|
||||
* @return null
|
||||
*/
|
||||
function set_make_full_url()
|
||||
{
|
||||
global $page;
|
||||
|
||||
if (!isset($page['save_root_path']))
|
||||
{
|
||||
if (isset($page['root_path']))
|
||||
{
|
||||
$page['save_root_path']['path'] = $page['root_path'];
|
||||
}
|
||||
$page['save_root_path']['count'] = 1;
|
||||
$page['root_path'] = get_absolute_root_url();
|
||||
}
|
||||
else
|
||||
{
|
||||
$page['save_root_path']['count'] += 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore old parameter to build url with full path
|
||||
*
|
||||
* @param null
|
||||
* @return null
|
||||
*/
|
||||
function unset_make_full_url()
|
||||
{
|
||||
global $page;
|
||||
|
||||
if (isset($page['save_root_path']))
|
||||
{
|
||||
if ($page['save_root_path']['count'] == 1)
|
||||
{
|
||||
if (isset($page['save_root_path']['path']))
|
||||
{
|
||||
$page['root_path'] = $page['save_root_path']['path'];
|
||||
}
|
||||
else
|
||||
{
|
||||
unset($page['root_path']);
|
||||
}
|
||||
unset($page['save_root_path']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$page['save_root_path']['count'] -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Embellish the url argument
|
||||
*
|
||||
* @param $url
|
||||
* @return $url embellished
|
||||
*/
|
||||
function embellish_url($url)
|
||||
{
|
||||
$url = str_replace('/./', '/', $url);
|
||||
while ( ($dotdot = strpos($url, '/../', 1) ) !== false )
|
||||
{
|
||||
$before = strrpos($url, '/', -(strlen($url)-$dotdot+1) );
|
||||
if ($before !== false)
|
||||
{
|
||||
$url = substr_replace($url, '', $before, $dotdot-$before+3);
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the 'home page' of this gallery
|
||||
*/
|
||||
function get_gallery_home_url()
|
||||
{
|
||||
global $conf;
|
||||
if (!empty($conf['gallery_url']))
|
||||
{
|
||||
if (url_is_remote($conf['gallery_url']) or $conf['gallery_url'][0]=='/' )
|
||||
{
|
||||
return $conf['gallery_url'];
|
||||
}
|
||||
return get_root_url().$conf['gallery_url'];
|
||||
}
|
||||
else
|
||||
{
|
||||
return make_index_url();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* returns $_SERVER['QUERY_STRING'] whithout keys given in parameters
|
||||
*
|
||||
* @param string[] $rejects
|
||||
* @param boolean $escape escape *&* to *&*
|
||||
* @returns string
|
||||
*/
|
||||
function get_query_string_diff($rejects=array(), $escape=true)
|
||||
{
|
||||
if (empty($_SERVER['QUERY_STRING']))
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
parse_str($_SERVER['QUERY_STRING'], $vars);
|
||||
|
||||
$vars = array_diff_key($vars, array_flip($rejects));
|
||||
|
||||
return '?' . http_build_query($vars, '', $escape ? '&' : '&');
|
||||
}
|
||||
|
||||
/**
|
||||
* returns true if the url is absolute (begins with http)
|
||||
*
|
||||
* @param string $url
|
||||
* @returns boolean
|
||||
*/
|
||||
function url_is_remote($url)
|
||||
{
|
||||
if ( strncmp($url, 'http://', 7)==0
|
||||
or strncmp($url, 'https://', 8)==0 )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
?>
|
||||
1659
zoesch.de/galerie/include/functions_user.inc.php
Normal file
1659
zoesch.de/galerie/include/functions_user.inc.php
Normal file
File diff suppressed because it is too large
Load Diff
30
zoesch.de/galerie/include/index.php
Normal file
30
zoesch.de/galerie/include/index.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Piwigo - a PHP based photo gallery |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright(C) 2008-2016 Piwigo Team http://piwigo.org |
|
||||
// | Copyright(C) 2003-2008 PhpWebGallery Team http://phpwebgallery.net |
|
||||
// | Copyright(C) 2002-2003 Pierrick LE GALL http://le-gall.net/pierrick |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
// Recursive call
|
||||
$url = '../';
|
||||
header( 'Request-URI: '.$url );
|
||||
header( 'Content-Location: '.$url );
|
||||
header( 'Location: '.$url );
|
||||
exit();
|
||||
?>
|
||||
160
zoesch.de/galerie/include/inflectors/en.php
Normal file
160
zoesch.de/galerie/include/inflectors/en.php
Normal file
@@ -0,0 +1,160 @@
|
||||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Piwigo - a PHP based photo gallery |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright(C) 2008-2016 Piwigo Team http://piwigo.org |
|
||||
// | Copyright(C) 2003-2008 PhpWebGallery Team http://phpwebgallery.net |
|
||||
// | Copyright(C) 2002-2003 Pierrick LE GALL http://le-gall.net/pierrick |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
class Inflector_en
|
||||
{
|
||||
private $exceptions;
|
||||
private $pluralizers;
|
||||
private $singularizers;
|
||||
|
||||
function __construct()
|
||||
{
|
||||
$tmp = array ('octopus' => 'octopuses',
|
||||
'virus' => 'viruses',
|
||||
'person' => 'people',
|
||||
'man' => 'men',
|
||||
'woman' => 'women',
|
||||
'child' => 'children',
|
||||
'move' => 'moves',
|
||||
'mouse' => 'mice',
|
||||
'ox' => 'oxen',
|
||||
'zombie' => 'zombies', // pl->sg exc.
|
||||
'serie' => 'series', // pl->sg exc.
|
||||
'movie' => 'movies', // pl->sg exc.
|
||||
);
|
||||
|
||||
$this->exceptions = $tmp;
|
||||
foreach ($tmp as $k => $v)
|
||||
$this->exceptions[$v] = $k;
|
||||
|
||||
foreach ( explode(' ', 'new news advice art coal baggage butter clothing cotton currency deer energy equipment experience fish flour food furniture gas homework impatience information jeans knowledge leather love luggage money oil patience police polish progress research rice series sheep silk soap species sugar talent toothpaste travel vinegar weather wood wool work')
|
||||
as $v)
|
||||
{
|
||||
$this->exceptions[$v] = 0;
|
||||
}
|
||||
|
||||
$this->pluralizers = array_reverse(array( '/$/' => 's',
|
||||
'/s$/' => 's',
|
||||
'/^(ax|test)is$/' => '\1es',
|
||||
'/(alias|status)$/' => '\1es',
|
||||
'/(bu)s$/' => '\1ses',
|
||||
'/(buffal|tomat)o$/' => '\1oes',
|
||||
'/([ti])um$/' => '\1a',
|
||||
'/([ti])a$/' => '\1a',
|
||||
'/sis$/' => 'ses',
|
||||
'/(?:([^f])fe|([lr])f)$/' => '\1\2ves',
|
||||
'/(hive)$/' => '\1s',
|
||||
'/([^aeiouy]|qu)y$/' => '\1ies',
|
||||
'/(x|ch|ss|sh)$/' => '\1es',
|
||||
'/(matr|vert|ind)(?:ix|ex)$/' => '\1ices',
|
||||
'/(quiz)$/' => '\1zes',
|
||||
));
|
||||
|
||||
$this->singularizers = array_reverse(array(
|
||||
'/s$/' => '',
|
||||
'/(ss)$/' => '\1',
|
||||
'/([ti])a$/' => '\1um',
|
||||
'/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)(sis|ses)$/' => '\1sis',
|
||||
'/(^analy)(sis|ses)$/' => '\1sis',
|
||||
'/([^f])ves$/' => '\1fe',
|
||||
'/(hive)s$/' => '\1',
|
||||
'/(tive)s$/' => '\1',
|
||||
'/([lr])ves$/' => '\1f',
|
||||
'/([^aeiouy]|qu)ies$/' => '\1y',
|
||||
'/(x|ch|ss|sh)es$/' => '\1',
|
||||
'/(bus)(es)?$/' => '\1',
|
||||
'/(o)es$/' => '\1',
|
||||
'/(shoe)s$/' => '\1',
|
||||
'/(cris|test)(is|es)$/' => '\1is',
|
||||
'/^(a)x[ie]s$/' => '\1xis',
|
||||
'/(alias|status)(es)?$/' => '\1',
|
||||
'/(vert|ind)ices$/' => '\1ex',
|
||||
'/(matr)ices$/' => '\1ix',
|
||||
'/(quiz)zes$/' => '\1',
|
||||
'/(database)s$/' => '\1',
|
||||
));
|
||||
|
||||
$this->er2ing = array_reverse(array(
|
||||
'/ers?$/' => 'ing',
|
||||
'/(be|draw|liv)ers?$/' => '\0'
|
||||
));
|
||||
|
||||
$this->ing2er = array_reverse(array(
|
||||
'/ing$/' => 'er',
|
||||
'/(snow|rain)ing$/' => '\1',
|
||||
'/(th|hous|dur|spr|wedd)ing$/' => '\0',
|
||||
'/(liv|draw)ing$/' => '\0'
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
function get_variants($word)
|
||||
{
|
||||
$res = array();
|
||||
|
||||
$lword = strtolower($word);
|
||||
|
||||
$rc = @$this->exceptions[$lword];
|
||||
if ( isset($rc) )
|
||||
{
|
||||
if (!empty($rc))
|
||||
$res[] = $rc;
|
||||
return $res;
|
||||
}
|
||||
|
||||
self::run($this->pluralizers, $word, $res);
|
||||
self::run($this->singularizers, $word, $res);
|
||||
if (strlen($word)>4)
|
||||
{
|
||||
self::run($this->er2ing, $word, $res);
|
||||
}
|
||||
if (strlen($word)>5)
|
||||
{
|
||||
$rc = self::run($this->ing2er, $word, $res);
|
||||
if ($rc !== false)
|
||||
{
|
||||
self::run($this->pluralizers, $rc, $res);
|
||||
}
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
private static function run($rules, $word, &$res)
|
||||
{
|
||||
foreach ($rules as $rule => $replacement)
|
||||
{
|
||||
$rc = preg_replace($rule.'i', $replacement, $word, -1, $count);
|
||||
if ($count)
|
||||
{
|
||||
if ($rc !== $word)
|
||||
{
|
||||
$res[] = $rc;
|
||||
return $rc;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
?>
|
||||
96
zoesch.de/galerie/include/inflectors/fr.php
Normal file
96
zoesch.de/galerie/include/inflectors/fr.php
Normal file
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Piwigo - a PHP based photo gallery |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright(C) 2008-2016 Piwigo Team http://piwigo.org |
|
||||
// | Copyright(C) 2003-2008 PhpWebGallery Team http://phpwebgallery.net |
|
||||
// | Copyright(C) 2002-2003 Pierrick LE GALL http://le-gall.net/pierrick |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
class Inflector_fr
|
||||
{
|
||||
private $exceptions;
|
||||
private $pluralizers;
|
||||
private $singularizers;
|
||||
|
||||
function __construct()
|
||||
{
|
||||
$tmp = array ('monsieur' => 'messieurs',
|
||||
'madame' => 'mesdames',
|
||||
'mademoiselle' => 'mesdemoiselles',
|
||||
);
|
||||
|
||||
$this->exceptions = $tmp;
|
||||
foreach ($tmp as $k => $v)
|
||||
$this->exceptions[$v] = $k;
|
||||
|
||||
$this->pluralizers = array_reverse(array( '/$/' => 's',
|
||||
'/(bijou|caillou|chou|genou|hibou|joujou|pou|au|eu|eau)$/' => '\1x',
|
||||
'/(bleu|<7C>meu|landau|lieu|pneu|sarrau)$/' => '\1s',
|
||||
'/al$/' => 'aux',
|
||||
'/ail$/' => 'ails',
|
||||
'/(b|cor|<7C>m|gemm|soupir|trav|vant|vitr)ail$/' => '\1aux',
|
||||
'/(s|x|z)$/' => '\1',
|
||||
));
|
||||
|
||||
$this->singularizers = array_reverse(array(
|
||||
'/s$/' => '',
|
||||
'/(bijou|caillou|chou|genou|hibou|joujou|pou|au|eu|eau)x$/' => '\1',
|
||||
'/(journ|chev)aux$/' => '\1al',
|
||||
'/ails$/' => 'ail',
|
||||
'/(b|cor|<7C>m|gemm|soupir|trav|vant|vitr)aux$/' => '\1ail',
|
||||
));
|
||||
}
|
||||
|
||||
function get_variants($word)
|
||||
{
|
||||
$res = array();
|
||||
|
||||
$word = strtolower($word);
|
||||
|
||||
$rc = @$this->exceptions[$word];
|
||||
if ( isset($rc) )
|
||||
{
|
||||
if (!empty($rc))
|
||||
$res[] = $rc;
|
||||
return $res;
|
||||
}
|
||||
|
||||
foreach ($this->pluralizers as $rule => $replacement)
|
||||
{
|
||||
$rc = preg_replace($rule, $replacement, $word, -1, $count);
|
||||
if ($count)
|
||||
{
|
||||
$res[] = $rc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->singularizers as $rule => $replacement)
|
||||
{
|
||||
$rc = preg_replace($rule, $replacement, $word, -1, $count);
|
||||
if ($count)
|
||||
{
|
||||
$res[] = $rc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
?>
|
||||
469
zoesch.de/galerie/include/jshrink.class.php
Normal file
469
zoesch.de/galerie/include/jshrink.class.php
Normal file
@@ -0,0 +1,469 @@
|
||||
<?php
|
||||
/**
|
||||
* JShrink
|
||||
*
|
||||
* Copyright (c) 2009-2012, Robert Hafner <tedivm@tedivm.com>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* * Neither the name of Robert Hafner nor the names of his
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @package JShrink
|
||||
* @author Robert Hafner <tedivm@tedivm.com>
|
||||
* @copyright 2009-2012 Robert Hafner <tedivm@tedivm.com>
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
* @link https://github.com/tedivm/JShrink
|
||||
* @version Release: 0.5.1
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* JShrink_Minifier
|
||||
*
|
||||
* Usage - JShrink_Minifier::minify($js);
|
||||
* Usage - JShrink_Minifier::minify($js, $options);
|
||||
* Usage - JShrink_Minifier::minify($js, array('flaggedComments' => false));
|
||||
*
|
||||
* @package JShrink
|
||||
* @author Robert Hafner <tedivm@tedivm.com>
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
*/
|
||||
class JShrink_Minifier
|
||||
{
|
||||
/**
|
||||
* The input javascript to be minified.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $input;
|
||||
|
||||
/**
|
||||
* The location of the character (in the input string) that is next to be
|
||||
* processed.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $index = 0;
|
||||
|
||||
/**
|
||||
* The first of the characters currently being looked at.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $a = '';
|
||||
|
||||
|
||||
/**
|
||||
* The next character being looked at (after a);
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $b = '';
|
||||
|
||||
/**
|
||||
* This character is only active when certain look ahead actions take place.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $c;
|
||||
|
||||
/**
|
||||
* Contains the options for the current minification process.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $options;
|
||||
|
||||
/**
|
||||
* Contains the default options for minification. This array is merged with
|
||||
* the one passed in by the user to create the request specific set of
|
||||
* options (stored in the $options attribute).
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
static protected $defaultOptions = array('flaggedComments' => true);
|
||||
|
||||
/**
|
||||
* Contains a copy of the JShrink object used to run minification. This is
|
||||
* only used internally, and is only stored for performance reasons. There
|
||||
* is no internal data shared between minification requests.
|
||||
*/
|
||||
static protected $jshrink;
|
||||
|
||||
/**
|
||||
* Minifier::minify takes a string containing javascript and removes
|
||||
* unneeded characters in order to shrink the code without altering it's
|
||||
* functionality.
|
||||
*/
|
||||
static public function minify($js, $options = array())
|
||||
{
|
||||
try{
|
||||
ob_start();
|
||||
$currentOptions = array_merge(self::$defaultOptions, $options);
|
||||
|
||||
if(!isset(self::$jshrink))
|
||||
self::$jshrink = new JShrink_Minifier();
|
||||
|
||||
self::$jshrink->breakdownScript($js, $currentOptions);
|
||||
return ob_get_clean();
|
||||
|
||||
}catch(Exception $e){
|
||||
if(isset(self::$jshrink))
|
||||
self::$jshrink->clean();
|
||||
|
||||
ob_end_clean();
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a javascript string and outputs only the required characters,
|
||||
* stripping out all unneeded characters.
|
||||
*
|
||||
* @param string $js The raw javascript to be minified
|
||||
* @param array $currentOptions Various runtime options in an associative array
|
||||
*/
|
||||
protected function breakdownScript($js, $currentOptions)
|
||||
{
|
||||
// reset work attributes in case this isn't the first run.
|
||||
$this->clean();
|
||||
|
||||
$this->options = $currentOptions;
|
||||
|
||||
$js = str_replace("\r\n", "\n", $js);
|
||||
$this->input = str_replace("\r", "\n", $js);
|
||||
|
||||
|
||||
$this->a = $this->getReal();
|
||||
|
||||
// the only time the length can be higher than 1 is if a conditional
|
||||
// comment needs to be displayed and the only time that can happen for
|
||||
// $a is on the very first run
|
||||
while(strlen($this->a) > 1)
|
||||
{
|
||||
echo $this->a;
|
||||
$this->a = $this->getReal();
|
||||
}
|
||||
|
||||
$this->b = $this->getReal();
|
||||
|
||||
while($this->a !== false && !is_null($this->a) && $this->a !== '')
|
||||
{
|
||||
|
||||
// now we give $b the same check for conditional comments we gave $a
|
||||
// before we began looping
|
||||
if(strlen($this->b) > 1)
|
||||
{
|
||||
echo $this->a . $this->b;
|
||||
$this->a = $this->getReal();
|
||||
$this->b = $this->getReal();
|
||||
continue;
|
||||
}
|
||||
|
||||
switch($this->a)
|
||||
{
|
||||
// new lines
|
||||
case "\n":
|
||||
// if the next line is something that can't stand alone
|
||||
// preserve the newline
|
||||
if(strpos('(-+{[@', $this->b) !== false)
|
||||
{
|
||||
echo $this->a;
|
||||
$this->saveString();
|
||||
break;
|
||||
}
|
||||
|
||||
// if its a space we move down to the string test below
|
||||
if($this->b === ' ')
|
||||
break;
|
||||
|
||||
// otherwise we treat the newline like a space
|
||||
|
||||
case ' ':
|
||||
if(self::isAlphaNumeric($this->b))
|
||||
echo $this->a;
|
||||
|
||||
$this->saveString();
|
||||
break;
|
||||
|
||||
default:
|
||||
switch($this->b)
|
||||
{
|
||||
case "\n":
|
||||
if(strpos('}])+-"\'', $this->a) !== false)
|
||||
{
|
||||
echo $this->a;
|
||||
$this->saveString();
|
||||
break;
|
||||
}else{
|
||||
if(self::isAlphaNumeric($this->a))
|
||||
{
|
||||
echo $this->a;
|
||||
$this->saveString();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ' ':
|
||||
if(!self::isAlphaNumeric($this->a))
|
||||
break;
|
||||
|
||||
default:
|
||||
// check for some regex that breaks stuff
|
||||
if($this->a == '/' && ($this->b == '\'' || $this->b == '"'))
|
||||
{
|
||||
$this->saveRegex();
|
||||
continue;
|
||||
}
|
||||
|
||||
echo $this->a;
|
||||
$this->saveString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// do reg check of doom
|
||||
$this->b = $this->getReal();
|
||||
|
||||
if(($this->b == '/' && strpos('(,=:[!&|?', $this->a) !== false))
|
||||
$this->saveRegex();
|
||||
}
|
||||
$this->clean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next string for processing based off of the current index.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getChar()
|
||||
{
|
||||
if(isset($this->c))
|
||||
{
|
||||
$char = $this->c;
|
||||
unset($this->c);
|
||||
}else{
|
||||
$tchar = substr($this->input, $this->index, 1);
|
||||
if(isset($tchar) && $tchar !== false)
|
||||
{
|
||||
$char = $tchar;
|
||||
$this->index++;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if($char !== "\n" && ord($char) < 32)
|
||||
return ' ';
|
||||
|
||||
return $char;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function gets the next "real" character. It is essentially a wrapper
|
||||
* around the getChar function that skips comments. This has significant
|
||||
* performance benefits as the skipping is done using native functions (ie,
|
||||
* c code) rather than in script php.
|
||||
*
|
||||
* @return string Next 'real' character to be processed.
|
||||
*/
|
||||
protected function getReal()
|
||||
{
|
||||
$startIndex = $this->index;
|
||||
$char = $this->getChar();
|
||||
|
||||
if($char == '/')
|
||||
{
|
||||
$this->c = $this->getChar();
|
||||
|
||||
if($this->c == '/')
|
||||
{
|
||||
$thirdCommentString = substr($this->input, $this->index, 1);
|
||||
|
||||
// kill rest of line
|
||||
$char = $this->getNext("\n");
|
||||
|
||||
if($thirdCommentString == '@')
|
||||
{
|
||||
$endPoint = ($this->index) - $startIndex;
|
||||
unset($this->c);
|
||||
$char = "\n" . substr($this->input, $startIndex, $endPoint);
|
||||
}else{
|
||||
$char = $this->getChar();
|
||||
$char = $this->getChar();
|
||||
}
|
||||
|
||||
}elseif($this->c == '*'){
|
||||
|
||||
$this->getChar(); // current C
|
||||
$thirdCommentString = $this->getChar();
|
||||
|
||||
if($thirdCommentString == '@')
|
||||
{
|
||||
// conditional comment
|
||||
|
||||
// we're gonna back up a bit and and send the comment back,
|
||||
// where the first char will be echoed and the rest will be
|
||||
// treated like a string
|
||||
$this->index = $this->index-2;
|
||||
return '/';
|
||||
|
||||
}elseif($this->getNext('*/')){
|
||||
// kill everything up to the next */
|
||||
|
||||
$this->getChar(); // get *
|
||||
$this->getChar(); // get /
|
||||
|
||||
$char = $this->getChar(); // get next real character
|
||||
|
||||
// if YUI-style comments are enabled we reinsert it into the stream
|
||||
if($this->options['flaggedComments'] && $thirdCommentString == '!')
|
||||
{
|
||||
$endPoint = ($this->index - 1) - $startIndex;
|
||||
echo "\n" . substr($this->input, $startIndex, $endPoint) . "\n";
|
||||
}
|
||||
|
||||
}else{
|
||||
$char = false;
|
||||
}
|
||||
|
||||
if($char === false)
|
||||
throw new RuntimeException('Stray comment. ' . $this->index);
|
||||
|
||||
// if we're here c is part of the comment and therefore tossed
|
||||
if(isset($this->c))
|
||||
unset($this->c);
|
||||
}
|
||||
}
|
||||
return $char;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pushes the index ahead to the next instance of the supplied string. If it
|
||||
* is found the first character of the string is returned.
|
||||
*
|
||||
* @return string|false Returns the first character of the string or false.
|
||||
*/
|
||||
protected function getNext($string)
|
||||
{
|
||||
$pos = strpos($this->input, $string, $this->index);
|
||||
|
||||
if($pos === false)
|
||||
return false;
|
||||
|
||||
$this->index = $pos;
|
||||
return substr($this->input, $this->index, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* When a javascript string is detected this function crawls for the end of
|
||||
* it and saves the whole string.
|
||||
*
|
||||
*/
|
||||
protected function saveString()
|
||||
{
|
||||
$this->a = $this->b;
|
||||
if($this->a == "'" || $this->a == '"') // is the character a quote
|
||||
{
|
||||
// save literal string
|
||||
$stringType = $this->a;
|
||||
|
||||
while(1)
|
||||
{
|
||||
echo $this->a;
|
||||
$this->a = $this->getChar();
|
||||
|
||||
switch($this->a)
|
||||
{
|
||||
case $stringType:
|
||||
break 2;
|
||||
|
||||
case "\n":
|
||||
throw new RuntimeException('Unclosed string. ' . $this->index);
|
||||
break;
|
||||
|
||||
case '\\':
|
||||
echo $this->a;
|
||||
$this->a = $this->getChar();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* When a regular expression is detected this funcion crawls for the end of
|
||||
* it and saves the whole regex.
|
||||
*/
|
||||
protected function saveRegex()
|
||||
{
|
||||
echo $this->a . $this->b;
|
||||
|
||||
while(($this->a = $this->getChar()) !== false)
|
||||
{
|
||||
if($this->a == '/')
|
||||
break;
|
||||
|
||||
if($this->a == '\\')
|
||||
{
|
||||
echo $this->a;
|
||||
$this->a = $this->getChar();
|
||||
}
|
||||
|
||||
if($this->a == "\n")
|
||||
throw new RuntimeException('Stray regex pattern. ' . $this->index);
|
||||
|
||||
echo $this->a;
|
||||
}
|
||||
$this->b = $this->getReal();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets attributes that do not need to be stored between requests so that
|
||||
* the next request is ready to go.
|
||||
*/
|
||||
protected function clean()
|
||||
{
|
||||
unset($this->input);
|
||||
$this->index = 0;
|
||||
$this->a = $this->b = '';
|
||||
unset($this->c);
|
||||
unset($this->options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if a character is alphanumeric.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
static protected function isAlphaNumeric($char)
|
||||
{
|
||||
return preg_match('/^[\w\$]$/', $char) === 1 || $char == '/';
|
||||
}
|
||||
|
||||
}
|
||||
1287
zoesch.de/galerie/include/mdetect.php
Normal file
1287
zoesch.de/galerie/include/mdetect.php
Normal file
File diff suppressed because it is too large
Load Diff
340
zoesch.de/galerie/include/menubar.inc.php
Normal file
340
zoesch.de/galerie/include/menubar.inc.php
Normal file
@@ -0,0 +1,340 @@
|
||||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Piwigo - a PHP based photo gallery |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright(C) 2008-2016 Piwigo Team http://piwigo.org |
|
||||
// | Copyright(C) 2003-2008 PhpWebGallery Team http://phpwebgallery.net |
|
||||
// | Copyright(C) 2002-2003 Pierrick LE GALL http://le-gall.net/pierrick |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
* @package functions\menubar
|
||||
*/
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'include/block.class.php');
|
||||
|
||||
initialize_menu();
|
||||
|
||||
/**
|
||||
* Setups each block the main menubar.
|
||||
*/
|
||||
function initialize_menu()
|
||||
{
|
||||
global $page, $conf, $user, $template, $filter;
|
||||
|
||||
$menu = new BlockManager("menubar");
|
||||
$menu->load_registered_blocks();
|
||||
$menu->prepare_display();
|
||||
|
||||
if ( @$page['section']=='search' and isset($page['qsearch_details']) )
|
||||
{
|
||||
$template->assign('QUERY_SEARCH', htmlspecialchars($page['qsearch_details']['q']) );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------- external links
|
||||
if ( ($block=$menu->get_block('mbLinks')) and !empty($conf['links']) )
|
||||
{
|
||||
$block->data = array();
|
||||
foreach ($conf['links'] as $url => $url_data)
|
||||
{
|
||||
if (!is_array($url_data))
|
||||
{
|
||||
$url_data = array('label' => $url_data);
|
||||
}
|
||||
|
||||
if
|
||||
(
|
||||
(!isset($url_data['eval_visible']))
|
||||
or
|
||||
(eval($url_data['eval_visible']))
|
||||
)
|
||||
{
|
||||
$tpl_var = array(
|
||||
'URL' => $url,
|
||||
'LABEL' => $url_data['label']
|
||||
);
|
||||
|
||||
if (!isset($url_data['new_window']) or $url_data['new_window'])
|
||||
{
|
||||
$tpl_var['new_window'] =
|
||||
array(
|
||||
'NAME' => (isset($url_data['nw_name']) ? $url_data['nw_name'] : ''),
|
||||
'FEATURES' => (isset($url_data['nw_features']) ? $url_data['nw_features'] : '')
|
||||
);
|
||||
}
|
||||
$block->data[] = $tpl_var;
|
||||
}
|
||||
}
|
||||
if ( !empty($block->data) )
|
||||
{
|
||||
$block->template = 'menubar_links.tpl';
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------- categories
|
||||
$block = $menu->get_block('mbCategories');
|
||||
//------------------------------------------------------------------------ filter
|
||||
if ($conf['menubar_filter_icon'] and !empty($conf['filter_pages']) and get_filter_page_value('used'))
|
||||
{
|
||||
if ($filter['enabled'])
|
||||
{
|
||||
$template->assign(
|
||||
'U_STOP_FILTER',
|
||||
add_url_params(make_index_url(array()), array('filter' => 'stop'))
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$template->assign(
|
||||
'U_START_FILTER',
|
||||
add_url_params(make_index_url(array()), array('filter' => 'start-recent-'.$user['recent_period']))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ( $block!=null )
|
||||
{
|
||||
$block->data = array(
|
||||
'NB_PICTURE' => $user['nb_total_images'],
|
||||
'MENU_CATEGORIES' => get_categories_menu(),
|
||||
'U_CATEGORIES' => make_index_url(array('section' => 'categories')),
|
||||
);
|
||||
$block->template = 'menubar_categories.tpl';
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------ tags
|
||||
$block = $menu->get_block('mbTags');
|
||||
if ( $block!=null and !empty($page['items']) and 'picture' != script_basename() )
|
||||
{
|
||||
if ('tags'==@$page['section'])
|
||||
{
|
||||
$tags = get_common_tags(
|
||||
$page['items'],
|
||||
$conf['menubar_tag_cloud_items_number'],
|
||||
$page['tag_ids']
|
||||
);
|
||||
$tags = add_level_to_tags($tags);
|
||||
|
||||
foreach ($tags as $tag)
|
||||
{
|
||||
$block->data[] = array_merge(
|
||||
$tag,
|
||||
array(
|
||||
'U_ADD' => make_index_url(
|
||||
array(
|
||||
'tags' => array_merge(
|
||||
$page['tags'],
|
||||
array($tag)
|
||||
)
|
||||
)
|
||||
),
|
||||
'URL' => make_index_url( array( 'tags' => array($tag) )
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$selection = array_slice( $page['items'], $page['start'], $page['nb_image_page'] );
|
||||
$tags = add_level_to_tags( get_common_tags($selection, $conf['content_tag_cloud_items_number']) );
|
||||
foreach ($tags as $tag)
|
||||
{
|
||||
$block->data[] =
|
||||
array_merge( $tag,
|
||||
array(
|
||||
'URL' => make_index_url( array( 'tags' => array($tag) ) ),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
if ( !empty($block->data) )
|
||||
{
|
||||
$block->template = 'menubar_tags.tpl';
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------- special categories
|
||||
if ( ($block = $menu->get_block('mbSpecials')) != null )
|
||||
{
|
||||
if ( !is_a_guest() )
|
||||
{// favorites
|
||||
$block->data['favorites'] =
|
||||
array(
|
||||
'URL' => make_index_url(array('section' => 'favorites')),
|
||||
'TITLE' => l10n('display your favorites photos'),
|
||||
'NAME' => l10n('Your favorites')
|
||||
);
|
||||
}
|
||||
|
||||
$block->data['most_visited'] =
|
||||
array(
|
||||
'URL' => make_index_url(array('section' => 'most_visited')),
|
||||
'TITLE' => l10n('display most visited photos'),
|
||||
'NAME' => l10n('Most visited')
|
||||
);
|
||||
|
||||
if ($conf['rate'])
|
||||
{
|
||||
$block->data['best_rated'] =
|
||||
array(
|
||||
'URL' => make_index_url(array('section' => 'best_rated')),
|
||||
'TITLE' => l10n('display best rated photos'),
|
||||
'NAME' => l10n('Best rated')
|
||||
);
|
||||
}
|
||||
|
||||
$block->data['recent_pics'] =
|
||||
array(
|
||||
'URL' => make_index_url(array('section' => 'recent_pics')),
|
||||
'TITLE' => l10n('display most recent photos'),
|
||||
'NAME' => l10n('Recent photos'),
|
||||
);
|
||||
|
||||
$block->data['recent_cats'] =
|
||||
array(
|
||||
'URL' => make_index_url(array('section' => 'recent_cats')),
|
||||
'TITLE' => l10n('display recently updated albums'),
|
||||
'NAME' => l10n('Recent albums'),
|
||||
);
|
||||
|
||||
$block->data['random'] =
|
||||
array(
|
||||
'URL' => get_root_url().'random.php',
|
||||
'TITLE' => l10n('display a set of random photos'),
|
||||
'NAME' => l10n('Random photos'),
|
||||
'REL'=> 'rel="nofollow"'
|
||||
);
|
||||
|
||||
$block->data['calendar'] =
|
||||
array(
|
||||
'URL' =>
|
||||
make_index_url(
|
||||
array(
|
||||
'chronology_field' => ($conf['calendar_datefield']=='date_available'
|
||||
? 'posted' : 'created'),
|
||||
'chronology_style'=> 'monthly',
|
||||
'chronology_view' => 'calendar'
|
||||
)
|
||||
),
|
||||
'TITLE' => l10n('display each day with photos, month per month'),
|
||||
'NAME' => l10n('Calendar'),
|
||||
'REL'=> 'rel="nofollow"'
|
||||
);
|
||||
$block->template = 'menubar_specials.tpl';
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------- summary
|
||||
if ( ($block=$menu->get_block('mbMenu')) != null )
|
||||
{
|
||||
// quick search block will be displayed only if data['qsearch'] is set
|
||||
// to "yes"
|
||||
$block->data['qsearch']=true;
|
||||
|
||||
// tags link
|
||||
$block->data['tags'] =
|
||||
array(
|
||||
'TITLE' => l10n('display available tags'),
|
||||
'NAME' => l10n('Tags'),
|
||||
'URL'=> get_root_url().'tags.php',
|
||||
'COUNTER' => get_nb_available_tags(),
|
||||
);
|
||||
|
||||
// search link
|
||||
$block->data['search'] =
|
||||
array(
|
||||
'TITLE'=>l10n('search'),
|
||||
'NAME'=>l10n('Search'),
|
||||
'URL'=> get_root_url().'search.php',
|
||||
'REL'=> 'rel="search"'
|
||||
);
|
||||
|
||||
if ($conf['activate_comments'])
|
||||
{
|
||||
// comments link
|
||||
$block->data['comments'] =
|
||||
array(
|
||||
'TITLE'=>l10n('display last user comments'),
|
||||
'NAME'=>l10n('Comments'),
|
||||
'URL'=> get_root_url().'comments.php',
|
||||
'COUNTER' => get_nb_available_comments(),
|
||||
);
|
||||
}
|
||||
|
||||
// about link
|
||||
$block->data['about'] =
|
||||
array(
|
||||
'TITLE' => l10n('About Piwigo'),
|
||||
'NAME' => l10n('About'),
|
||||
'URL' => get_root_url().'about.php',
|
||||
);
|
||||
|
||||
// notification
|
||||
$block->data['rss'] =
|
||||
array(
|
||||
'TITLE'=>l10n('RSS feed'),
|
||||
'NAME'=>l10n('Notification'),
|
||||
'URL'=> get_root_url().'notification.php',
|
||||
'REL'=> 'rel="nofollow"'
|
||||
);
|
||||
$block->template = 'menubar_menu.tpl';
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------- identification
|
||||
if (is_a_guest())
|
||||
{
|
||||
$template->assign(
|
||||
array(
|
||||
'U_LOGIN' => get_root_url().'identification.php',
|
||||
'U_LOST_PASSWORD' => get_root_url().'password.php',
|
||||
'AUTHORIZE_REMEMBERING' => $conf['authorize_remembering']
|
||||
)
|
||||
);
|
||||
if ($conf['allow_user_registration'])
|
||||
{
|
||||
$template->assign( 'U_REGISTER', get_root_url().'register.php');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$template->assign('USERNAME', stripslashes($user['username']));
|
||||
if (is_autorize_status(ACCESS_CLASSIC))
|
||||
{
|
||||
$template->assign('U_PROFILE', get_root_url().'profile.php');
|
||||
}
|
||||
|
||||
// the logout link has no meaning with Apache authentication : it is not
|
||||
// possible to logout with this kind of authentication.
|
||||
if (!$conf['apache_authentication'])
|
||||
{
|
||||
$template->assign('U_LOGOUT', get_root_url().'?act=logout');
|
||||
}
|
||||
if (is_admin())
|
||||
{
|
||||
$template->assign('U_ADMIN', get_root_url().'admin.php');
|
||||
}
|
||||
}
|
||||
if ( ($block=$menu->get_block('mbIdentification')) != null )
|
||||
{
|
||||
$block->template = 'menubar_identification.tpl';
|
||||
}
|
||||
$menu->apply('MENUBAR', 'menubar.tpl' );
|
||||
}
|
||||
|
||||
?>
|
||||
111
zoesch.de/galerie/include/no_photo_yet.inc.php
Normal file
111
zoesch.de/galerie/include/no_photo_yet.inc.php
Normal file
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Piwigo - a PHP based photo gallery |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright(C) 2008-2016 Piwigo Team http://piwigo.org |
|
||||
// | Copyright(C) 2003-2008 PhpWebGallery Team http://phpwebgallery.net |
|
||||
// | Copyright(C) 2002-2003 Pierrick LE GALL http://le-gall.net/pierrick |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
|
||||
// The "No Photo Yet" feature: if you have no photo yet in your gallery, the
|
||||
// gallery displays only a big box to show you the way for adding your first
|
||||
// photos
|
||||
if (
|
||||
!(defined('IN_ADMIN') and IN_ADMIN) // no message inside administration
|
||||
and script_basename() != 'identification' // keep the ability to login
|
||||
and script_basename() != 'ws' // keep the ability to discuss with web API
|
||||
and script_basename() != 'popuphelp' // keep the ability to display help popups
|
||||
and !isset($_SESSION['no_photo_yet']) // temporary hide
|
||||
)
|
||||
{
|
||||
$query = '
|
||||
SELECT
|
||||
COUNT(*)
|
||||
FROM '.IMAGES_TABLE.'
|
||||
;';
|
||||
list($nb_photos) = pwg_db_fetch_row(pwg_query($query));
|
||||
if (0 == $nb_photos)
|
||||
{
|
||||
// make sure we don't use the mobile theme, which is not compatible with
|
||||
// the "no photo yet" feature
|
||||
$template = new Template(PHPWG_ROOT_PATH.'themes', $user['theme']);
|
||||
|
||||
if (isset($_GET['no_photo_yet']))
|
||||
{
|
||||
if ('browse' == $_GET['no_photo_yet'])
|
||||
{
|
||||
$_SESSION['no_photo_yet'] = 'browse';
|
||||
redirect(make_index_url());
|
||||
exit();
|
||||
}
|
||||
|
||||
if ('deactivate' == $_GET['no_photo_yet'])
|
||||
{
|
||||
conf_update_param('no_photo_yet', 'false');
|
||||
redirect(make_index_url());
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
header('Content-Type: text/html; charset='.get_pwg_charset());
|
||||
$template->set_filenames(array('no_photo_yet'=>'no_photo_yet.tpl'));
|
||||
|
||||
if (is_admin())
|
||||
{
|
||||
$url = $conf['no_photo_yet_url'];
|
||||
if (substr($url, 0, 4) != 'http')
|
||||
{
|
||||
$url = get_root_url().$url;
|
||||
}
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'step' => 2,
|
||||
'intro' => l10n(
|
||||
'Hello %s, your Piwigo photo gallery is empty!',
|
||||
$user['username']
|
||||
),
|
||||
'next_step_url' => $url,
|
||||
'deactivate_url' => get_root_url().'?no_photo_yet=deactivate',
|
||||
)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'step' => 1,
|
||||
'U_LOGIN' => 'identification.php',
|
||||
'deactivate_url' => get_root_url().'?no_photo_yet=browse',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
trigger_notify('loc_end_no_photo_yet');
|
||||
|
||||
$template->pparse('no_photo_yet');
|
||||
exit();
|
||||
}
|
||||
else
|
||||
{
|
||||
conf_update_param('no_photo_yet', 'false');
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
105
zoesch.de/galerie/include/page_header.php
Normal file
105
zoesch.de/galerie/include/page_header.php
Normal file
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Piwigo - a PHP based photo gallery |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright(C) 2008-2016 Piwigo Team http://piwigo.org |
|
||||
// | Copyright(C) 2003-2008 PhpWebGallery Team http://phpwebgallery.net |
|
||||
// | Copyright(C) 2002-2003 Pierrick LE GALL http://le-gall.net/pierrick |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
//
|
||||
// Start output of page
|
||||
//
|
||||
$template->set_filenames(array('header'=>'header.tpl'));
|
||||
|
||||
trigger_notify('loc_begin_page_header');
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'GALLERY_TITLE' =>
|
||||
isset($page['gallery_title']) ?
|
||||
$page['gallery_title'] : $conf['gallery_title'],
|
||||
|
||||
'PAGE_BANNER' =>
|
||||
trigger_change(
|
||||
'render_page_banner',
|
||||
str_replace(
|
||||
'%gallery_title%',
|
||||
$conf['gallery_title'],
|
||||
isset($page['page_banner']) ? $page['page_banner'] : $conf['page_banner']
|
||||
)
|
||||
),
|
||||
|
||||
'BODY_ID' =>
|
||||
isset($page['body_id']) ?
|
||||
$page['body_id'] : '',
|
||||
|
||||
'CONTENT_ENCODING' => get_pwg_charset(),
|
||||
'PAGE_TITLE' => strip_tags($title),
|
||||
|
||||
'U_HOME' => get_gallery_home_url(),
|
||||
|
||||
'LEVEL_SEPARATOR' => $conf['level_separator'],
|
||||
));
|
||||
|
||||
|
||||
// Header notes
|
||||
if ( !empty($header_notes) )
|
||||
{
|
||||
$template->assign('header_notes',$header_notes);
|
||||
}
|
||||
|
||||
// No referencing is required
|
||||
if ( !$conf['meta_ref'] )
|
||||
{
|
||||
$page['meta_robots']['noindex'] = 1;
|
||||
$page['meta_robots']['nofollow'] = 1;
|
||||
}
|
||||
|
||||
if ( !empty($page['meta_robots']) )
|
||||
{
|
||||
$template->append('head_elements',
|
||||
'<meta name="robots" content="'
|
||||
.implode(',', array_keys($page['meta_robots']))
|
||||
.'">'
|
||||
);
|
||||
}
|
||||
if ( !isset($page['meta_robots']['noindex']) )
|
||||
{
|
||||
$template->assign('meta_ref',1);
|
||||
}
|
||||
|
||||
// refresh
|
||||
if ( isset( $refresh ) and intval($refresh) >= 0
|
||||
and isset( $url_link ) )
|
||||
{
|
||||
$template->assign(
|
||||
array(
|
||||
'page_refresh' => array(
|
||||
'TIME' => $refresh,
|
||||
'U_REFRESH' => $url_link
|
||||
)
|
||||
));
|
||||
}
|
||||
|
||||
trigger_notify('loc_end_page_header');
|
||||
|
||||
header('Content-Type: text/html; charset='.get_pwg_charset());
|
||||
$template->parse('header');
|
||||
|
||||
trigger_notify('loc_after_page_header');
|
||||
?>
|
||||
110
zoesch.de/galerie/include/page_tail.php
Normal file
110
zoesch.de/galerie/include/page_tail.php
Normal file
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Piwigo - a PHP based photo gallery |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright(C) 2008-2016 Piwigo Team http://piwigo.org |
|
||||
// | Copyright(C) 2003-2008 PhpWebGallery Team http://phpwebgallery.net |
|
||||
// | Copyright(C) 2002-2003 Pierrick LE GALL http://le-gall.net/pierrick |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
$template->set_filenames(array('tail'=>'footer.tpl'));
|
||||
|
||||
trigger_notify('loc_begin_page_tail');
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'VERSION' => $conf['show_version'] ? PHPWG_VERSION : '',
|
||||
'PHPWG_URL' => defined('PHPWG_URL') ? PHPWG_URL : '',
|
||||
));
|
||||
|
||||
//--------------------------------------------------------------------- contact
|
||||
|
||||
if (!is_a_guest())
|
||||
{
|
||||
$template->assign(
|
||||
'CONTACT_MAIL', get_webmaster_mail_address()
|
||||
);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------- update notification
|
||||
if ($conf['update_notify_check_period'] > 0)
|
||||
{
|
||||
$check_for_updates = false;
|
||||
if (isset($conf['update_notify_last_check']))
|
||||
{
|
||||
if (strtotime($conf['update_notify_last_check']) < strtotime($conf['update_notify_check_period'].' seconds ago'))
|
||||
{
|
||||
$check_for_updates = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$check_for_updates = true;
|
||||
}
|
||||
|
||||
if ($check_for_updates)
|
||||
{
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/updates.class.php');
|
||||
$updates = new updates();
|
||||
$updates->notify_piwigo_new_versions();
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------- generation time
|
||||
$debug_vars = array();
|
||||
|
||||
if ($conf['show_queries'])
|
||||
{
|
||||
$debug_vars = array_merge($debug_vars, array('QUERIES_LIST' => $debug) );
|
||||
}
|
||||
|
||||
if ($conf['show_gt'])
|
||||
{
|
||||
if (!isset($page['count_queries']))
|
||||
{
|
||||
$page['count_queries'] = 0;
|
||||
$page['queries_time'] = 0;
|
||||
}
|
||||
$time = get_elapsed_time($t2, get_moment());
|
||||
|
||||
$debug_vars = array_merge($debug_vars,
|
||||
array('TIME' => $time,
|
||||
'NB_QUERIES' => $page['count_queries'],
|
||||
'SQL_TIME' => number_format($page['queries_time'],3,'.',' ').' s')
|
||||
);
|
||||
}
|
||||
|
||||
$template->assign('debug', $debug_vars );
|
||||
|
||||
//------------------------------------------------------------- mobile version
|
||||
if ( !empty($conf['mobile_theme']) && (get_device() != 'desktop' || mobile_theme()))
|
||||
{
|
||||
$template->assign('TOGGLE_MOBILE_THEME_URL',
|
||||
add_url_params(
|
||||
htmlspecialchars($_SERVER['REQUEST_URI']),
|
||||
array('mobile' => mobile_theme() ? 'false' : 'true')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
trigger_notify('loc_end_page_tail');
|
||||
//
|
||||
// Generate the page
|
||||
//
|
||||
$template->parse('tail');
|
||||
$template->p();
|
||||
?>
|
||||
276
zoesch.de/galerie/include/passwordhash.class.php
Normal file
276
zoesch.de/galerie/include/passwordhash.class.php
Normal file
@@ -0,0 +1,276 @@
|
||||
<?php
|
||||
/**
|
||||
* Portable PHP password hashing framework.
|
||||
* @package phpass
|
||||
* @since 2.5.0
|
||||
* @version 0.3 / WordPress
|
||||
* @link http://www.openwall.com/phpass/
|
||||
*/
|
||||
|
||||
#
|
||||
# Written by Solar Designer <solar at openwall.com> in 2004-2006 and placed in
|
||||
# the public domain. Revised in subsequent years, still public domain.
|
||||
#
|
||||
# There's absolutely no warranty.
|
||||
#
|
||||
# Please be sure to update the Version line if you edit this file in any way.
|
||||
# It is suggested that you leave the main version number intact, but indicate
|
||||
# your project name (after the slash) and add your own revision information.
|
||||
#
|
||||
# Please do not change the "private" password hashing method implemented in
|
||||
# here, thereby making your hashes incompatible. However, if you must, please
|
||||
# change the hash type identifier (the "$P$") to something different.
|
||||
#
|
||||
# Obviously, since this code is in the public domain, the above are not
|
||||
# requirements (there can be none), but merely suggestions.
|
||||
#
|
||||
|
||||
/**
|
||||
* Portable PHP password hashing framework.
|
||||
*
|
||||
* @package phpass
|
||||
* @version 0.3 / WordPress
|
||||
* @link http://www.openwall.com/phpass/
|
||||
* @since 2.5.0
|
||||
*/
|
||||
class PasswordHash {
|
||||
var $itoa64;
|
||||
var $iteration_count_log2;
|
||||
var $portable_hashes;
|
||||
var $random_state;
|
||||
|
||||
/**
|
||||
* PHP5 constructor.
|
||||
*/
|
||||
function __construct( $iteration_count_log2, $portable_hashes )
|
||||
{
|
||||
$this->itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
|
||||
|
||||
if ($iteration_count_log2 < 4 || $iteration_count_log2 > 31)
|
||||
$iteration_count_log2 = 8;
|
||||
$this->iteration_count_log2 = $iteration_count_log2;
|
||||
|
||||
$this->portable_hashes = $portable_hashes;
|
||||
|
||||
$this->random_state = microtime() . uniqid(rand(), TRUE); // removed getmypid() for compatibility reasons
|
||||
}
|
||||
|
||||
/**
|
||||
* PHP4 constructor.
|
||||
*/
|
||||
public function PasswordHash( $iteration_count_log2, $portable_hashes ) {
|
||||
self::__construct( $iteration_count_log2, $portable_hashes );
|
||||
}
|
||||
|
||||
function get_random_bytes($count)
|
||||
{
|
||||
$output = '';
|
||||
if ( @is_readable('/dev/urandom') &&
|
||||
($fh = @fopen('/dev/urandom', 'rb'))) {
|
||||
$output = fread($fh, $count);
|
||||
fclose($fh);
|
||||
}
|
||||
|
||||
if (strlen($output) < $count) {
|
||||
$output = '';
|
||||
for ($i = 0; $i < $count; $i += 16) {
|
||||
$this->random_state =
|
||||
md5(microtime() . $this->random_state);
|
||||
$output .=
|
||||
pack('H*', md5($this->random_state));
|
||||
}
|
||||
$output = substr($output, 0, $count);
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
function encode64($input, $count)
|
||||
{
|
||||
$output = '';
|
||||
$i = 0;
|
||||
do {
|
||||
$value = ord($input[$i++]);
|
||||
$output .= $this->itoa64[$value & 0x3f];
|
||||
if ($i < $count)
|
||||
$value |= ord($input[$i]) << 8;
|
||||
$output .= $this->itoa64[($value >> 6) & 0x3f];
|
||||
if ($i++ >= $count)
|
||||
break;
|
||||
if ($i < $count)
|
||||
$value |= ord($input[$i]) << 16;
|
||||
$output .= $this->itoa64[($value >> 12) & 0x3f];
|
||||
if ($i++ >= $count)
|
||||
break;
|
||||
$output .= $this->itoa64[($value >> 18) & 0x3f];
|
||||
} while ($i < $count);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
function gensalt_private($input)
|
||||
{
|
||||
$output = '$P$';
|
||||
$output .= $this->itoa64[min($this->iteration_count_log2 +
|
||||
((PHP_VERSION >= '5') ? 5 : 3), 30)];
|
||||
$output .= $this->encode64($input, 6);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
function crypt_private($password, $setting)
|
||||
{
|
||||
$output = '*0';
|
||||
if (substr($setting, 0, 2) == $output)
|
||||
$output = '*1';
|
||||
|
||||
$id = substr($setting, 0, 3);
|
||||
# We use "$P$", phpBB3 uses "$H$" for the same thing
|
||||
if ($id != '$P$' && $id != '$H$')
|
||||
return $output;
|
||||
|
||||
$count_log2 = strpos($this->itoa64, $setting[3]);
|
||||
if ($count_log2 < 7 || $count_log2 > 30)
|
||||
return $output;
|
||||
|
||||
$count = 1 << $count_log2;
|
||||
|
||||
$salt = substr($setting, 4, 8);
|
||||
if (strlen($salt) != 8)
|
||||
return $output;
|
||||
|
||||
# We're kind of forced to use MD5 here since it's the only
|
||||
# cryptographic primitive available in all versions of PHP
|
||||
# currently in use. To implement our own low-level crypto
|
||||
# in PHP would result in much worse performance and
|
||||
# consequently in lower iteration counts and hashes that are
|
||||
# quicker to crack (by non-PHP code).
|
||||
if (PHP_VERSION >= '5') {
|
||||
$hash = md5($salt . $password, TRUE);
|
||||
do {
|
||||
$hash = md5($hash . $password, TRUE);
|
||||
} while (--$count);
|
||||
} else {
|
||||
$hash = pack('H*', md5($salt . $password));
|
||||
do {
|
||||
$hash = pack('H*', md5($hash . $password));
|
||||
} while (--$count);
|
||||
}
|
||||
|
||||
$output = substr($setting, 0, 12);
|
||||
$output .= $this->encode64($hash, 16);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
function gensalt_extended($input)
|
||||
{
|
||||
$count_log2 = min($this->iteration_count_log2 + 8, 24);
|
||||
# This should be odd to not reveal weak DES keys, and the
|
||||
# maximum valid value is (2**24 - 1) which is odd anyway.
|
||||
$count = (1 << $count_log2) - 1;
|
||||
|
||||
$output = '_';
|
||||
$output .= $this->itoa64[$count & 0x3f];
|
||||
$output .= $this->itoa64[($count >> 6) & 0x3f];
|
||||
$output .= $this->itoa64[($count >> 12) & 0x3f];
|
||||
$output .= $this->itoa64[($count >> 18) & 0x3f];
|
||||
|
||||
$output .= $this->encode64($input, 3);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
function gensalt_blowfish($input)
|
||||
{
|
||||
# This one needs to use a different order of characters and a
|
||||
# different encoding scheme from the one in encode64() above.
|
||||
# We care because the last character in our encoded string will
|
||||
# only represent 2 bits. While two known implementations of
|
||||
# bcrypt will happily accept and correct a salt string which
|
||||
# has the 4 unused bits set to non-zero, we do not want to take
|
||||
# chances and we also do not want to waste an additional byte
|
||||
# of entropy.
|
||||
$itoa64 = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
|
||||
$output = '$2a$';
|
||||
$output .= chr(ord('0') + $this->iteration_count_log2 / 10);
|
||||
$output .= chr(ord('0') + $this->iteration_count_log2 % 10);
|
||||
$output .= '$';
|
||||
|
||||
$i = 0;
|
||||
do {
|
||||
$c1 = ord($input[$i++]);
|
||||
$output .= $itoa64[$c1 >> 2];
|
||||
$c1 = ($c1 & 0x03) << 4;
|
||||
if ($i >= 16) {
|
||||
$output .= $itoa64[$c1];
|
||||
break;
|
||||
}
|
||||
|
||||
$c2 = ord($input[$i++]);
|
||||
$c1 |= $c2 >> 4;
|
||||
$output .= $itoa64[$c1];
|
||||
$c1 = ($c2 & 0x0f) << 2;
|
||||
|
||||
$c2 = ord($input[$i++]);
|
||||
$c1 |= $c2 >> 6;
|
||||
$output .= $itoa64[$c1];
|
||||
$output .= $itoa64[$c2 & 0x3f];
|
||||
} while (1);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
function HashPassword($password)
|
||||
{
|
||||
if ( strlen( $password ) > 4096 ) {
|
||||
return '*';
|
||||
}
|
||||
|
||||
$random = '';
|
||||
|
||||
if (CRYPT_BLOWFISH == 1 && !$this->portable_hashes) {
|
||||
$random = $this->get_random_bytes(16);
|
||||
$hash =
|
||||
crypt($password, $this->gensalt_blowfish($random));
|
||||
if (strlen($hash) == 60)
|
||||
return $hash;
|
||||
}
|
||||
|
||||
if (CRYPT_EXT_DES == 1 && !$this->portable_hashes) {
|
||||
if (strlen($random) < 3)
|
||||
$random = $this->get_random_bytes(3);
|
||||
$hash =
|
||||
crypt($password, $this->gensalt_extended($random));
|
||||
if (strlen($hash) == 20)
|
||||
return $hash;
|
||||
}
|
||||
|
||||
if (strlen($random) < 6)
|
||||
$random = $this->get_random_bytes(6);
|
||||
$hash =
|
||||
$this->crypt_private($password,
|
||||
$this->gensalt_private($random));
|
||||
if (strlen($hash) == 34)
|
||||
return $hash;
|
||||
|
||||
# Returning '*' on error is safe here, but would _not_ be safe
|
||||
# in a crypt(3)-like function used _both_ for generating new
|
||||
# hashes and for validating passwords against existing hashes.
|
||||
return '*';
|
||||
}
|
||||
|
||||
function CheckPassword($password, $stored_hash)
|
||||
{
|
||||
if ( strlen( $password ) > 4096 ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$hash = $this->crypt_private($password, $stored_hash);
|
||||
if ($hash[0] == '*')
|
||||
$hash = crypt($password, $stored_hash);
|
||||
|
||||
return $hash === $stored_hash;
|
||||
}
|
||||
}
|
||||
9
zoesch.de/galerie/include/php_compat/gzopen.php
Normal file
9
zoesch.de/galerie/include/php_compat/gzopen.php
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
if (!function_exists('gzopen') && function_exists('gzopen64'))
|
||||
{
|
||||
function gzopen(string $filename , string $mode, int $use_include_path = null)
|
||||
{
|
||||
return gzopen64($filename, $mode, $use_include_path);
|
||||
}
|
||||
}
|
||||
?>
|
||||
30
zoesch.de/galerie/include/php_compat/index.php
Normal file
30
zoesch.de/galerie/include/php_compat/index.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Piwigo - a PHP based photo gallery |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright(C) 2008-2016 Piwigo Team http://piwigo.org |
|
||||
// | Copyright(C) 2003-2008 PhpWebGallery Team http://phpwebgallery.net |
|
||||
// | Copyright(C) 2002-2003 Pierrick LE GALL http://le-gall.net/pierrick |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
// Recursive call
|
||||
$url = '../';
|
||||
header( 'Request-URI: '.$url );
|
||||
header( 'Content-Location: '.$url );
|
||||
header( 'Location: '.$url );
|
||||
exit();
|
||||
?>
|
||||
49
zoesch.de/galerie/include/phpmailer/PHPMailerAutoload.php
Normal file
49
zoesch.de/galerie/include/phpmailer/PHPMailerAutoload.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
/**
|
||||
* PHPMailer SPL autoloader.
|
||||
* PHP Version 5
|
||||
* @package PHPMailer
|
||||
* @link https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
|
||||
* @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
|
||||
* @author Jim Jagielski (jimjag) <jimjag@gmail.com>
|
||||
* @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
|
||||
* @author Brent R. Matzelle (original founder)
|
||||
* @copyright 2012 - 2014 Marcus Bointon
|
||||
* @copyright 2010 - 2012 Jim Jagielski
|
||||
* @copyright 2004 - 2009 Andy Prevost
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
* @note This program is distributed in the hope that it will be useful - WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* PHPMailer SPL autoloader.
|
||||
* @param string $classname The name of the class to load
|
||||
*/
|
||||
function PHPMailerAutoload($classname)
|
||||
{
|
||||
//Can't use __DIR__ as it's only in PHP 5.3+
|
||||
$filename = dirname(__FILE__).DIRECTORY_SEPARATOR.'class.'.strtolower($classname).'.php';
|
||||
if (is_readable($filename)) {
|
||||
require $filename;
|
||||
}
|
||||
}
|
||||
|
||||
if (version_compare(PHP_VERSION, '5.1.2', '>=')) {
|
||||
//SPL autoloading was introduced in PHP 5.1.2
|
||||
if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
|
||||
spl_autoload_register('PHPMailerAutoload', true, true);
|
||||
} else {
|
||||
spl_autoload_register('PHPMailerAutoload');
|
||||
}
|
||||
} else {
|
||||
/**
|
||||
* Fall back to traditional autoload for old PHP versions
|
||||
* @param string $classname The name of the class to load
|
||||
*/
|
||||
function __autoload($classname)
|
||||
{
|
||||
PHPMailerAutoload($classname);
|
||||
}
|
||||
}
|
||||
4025
zoesch.de/galerie/include/phpmailer/class.phpmailer.php
Normal file
4025
zoesch.de/galerie/include/phpmailer/class.phpmailer.php
Normal file
File diff suppressed because it is too large
Load Diff
1249
zoesch.de/galerie/include/phpmailer/class.smtp.php
Normal file
1249
zoesch.de/galerie/include/phpmailer/class.smtp.php
Normal file
File diff suppressed because it is too large
Load Diff
279
zoesch.de/galerie/include/picture_comment.inc.php
Normal file
279
zoesch.de/galerie/include/picture_comment.inc.php
Normal file
@@ -0,0 +1,279 @@
|
||||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Piwigo - a PHP based photo gallery |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright(C) 2008-2016 Piwigo Team http://piwigo.org |
|
||||
// | Copyright(C) 2003-2008 PhpWebGallery Team http://phpwebgallery.net |
|
||||
// | Copyright(C) 2002-2003 Pierrick LE GALL http://le-gall.net/pierrick |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
* This file is included by the picture page to manage user comments
|
||||
*
|
||||
*/
|
||||
|
||||
// the picture is commentable if it belongs at least to one category which
|
||||
// is commentable
|
||||
$page['show_comments'] = false;
|
||||
foreach ($related_categories as $category)
|
||||
{
|
||||
if ($category['commentable']=='true')
|
||||
{
|
||||
$page['show_comments'] = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $page['show_comments'] and isset( $_POST['content'] ) )
|
||||
{
|
||||
if ( is_a_guest() and !$conf['comments_forall'] )
|
||||
{
|
||||
die ('Session expired');
|
||||
}
|
||||
|
||||
$comm = array(
|
||||
'author' => trim( @$_POST['author'] ),
|
||||
'content' => trim( $_POST['content'] ),
|
||||
'website_url' => trim( @$_POST['website_url'] ),
|
||||
'email' => trim( @$_POST['email'] ),
|
||||
'image_id' => $page['image_id'],
|
||||
);
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'include/functions_comment.inc.php');
|
||||
|
||||
$comment_action = insert_user_comment($comm, @$_POST['key'], $page['errors']);
|
||||
|
||||
switch ($comment_action)
|
||||
{
|
||||
case 'moderate':
|
||||
$page['infos'][] = l10n('An administrator must authorize your comment before it is visible.');
|
||||
case 'validate':
|
||||
$page['infos'][] = l10n('Your comment has been registered');
|
||||
break;
|
||||
case 'reject':
|
||||
set_status_header(403);
|
||||
$page['errors'][] = l10n('Your comment has NOT been registered because it did not pass the validation rules');
|
||||
break;
|
||||
default:
|
||||
trigger_error('Invalid comment action '.$comment_action, E_USER_WARNING);
|
||||
}
|
||||
|
||||
// allow plugins to notify what's going on
|
||||
trigger_notify( 'user_comment_insertion',
|
||||
array_merge($comm, array('action'=>$comment_action) )
|
||||
);
|
||||
}
|
||||
elseif ( isset($_POST['content']) )
|
||||
{
|
||||
set_status_header(403);
|
||||
die('ugly spammer');
|
||||
}
|
||||
|
||||
if ($page['show_comments'])
|
||||
{
|
||||
if ( !is_admin() )
|
||||
{
|
||||
$validated_clause = ' AND validated = \'true\'';
|
||||
}
|
||||
else
|
||||
{
|
||||
$validated_clause = '';
|
||||
}
|
||||
|
||||
// number of comments for this picture
|
||||
$query = '
|
||||
SELECT
|
||||
COUNT(*) AS nb_comments
|
||||
FROM '.COMMENTS_TABLE.'
|
||||
WHERE image_id = '.$page['image_id']
|
||||
.$validated_clause.'
|
||||
;';
|
||||
$row = pwg_db_fetch_assoc( pwg_query( $query ) );
|
||||
|
||||
// navigation bar creation
|
||||
if (!isset($page['start']))
|
||||
{
|
||||
$page['start'] = 0;
|
||||
}
|
||||
|
||||
$navigation_bar = create_navigation_bar(
|
||||
duplicate_picture_url(array(), array('start')),
|
||||
$row['nb_comments'],
|
||||
$page['start'],
|
||||
$conf['nb_comment_page'],
|
||||
true // We want a clean URL
|
||||
);
|
||||
|
||||
$template->assign(
|
||||
array(
|
||||
'COMMENT_COUNT' => $row['nb_comments'],
|
||||
'navbar' => $navigation_bar,
|
||||
)
|
||||
);
|
||||
|
||||
if ($row['nb_comments'] > 0)
|
||||
{
|
||||
// comments order (get, session, conf)
|
||||
if (!empty($_GET['comments_order']) && in_array(strtoupper($_GET['comments_order']), array('ASC', 'DESC')))
|
||||
{
|
||||
pwg_set_session_var('comments_order', $_GET['comments_order']);
|
||||
}
|
||||
$comments_order = pwg_get_session_var('comments_order', $conf['comments_order']);
|
||||
|
||||
$template->assign(array(
|
||||
'COMMENTS_ORDER_URL' => add_url_params( duplicate_picture_url(), array('comments_order'=> ($comments_order == 'ASC' ? 'DESC' : 'ASC') ) ),
|
||||
'COMMENTS_ORDER_TITLE' => $comments_order == 'ASC' ? l10n('Show latest comments first') : l10n('Show oldest comments first'),
|
||||
));
|
||||
|
||||
$query = '
|
||||
SELECT
|
||||
com.id,
|
||||
author,
|
||||
author_id,
|
||||
u.'.$conf['user_fields']['email'].' AS user_email,
|
||||
date,
|
||||
image_id,
|
||||
website_url,
|
||||
com.email,
|
||||
content,
|
||||
validated
|
||||
FROM '.COMMENTS_TABLE.' AS com
|
||||
LEFT JOIN '.USERS_TABLE.' AS u
|
||||
ON u.'.$conf['user_fields']['id'].' = author_id
|
||||
WHERE image_id = '.$page['image_id'].'
|
||||
'.$validated_clause.'
|
||||
ORDER BY date '.$comments_order.'
|
||||
LIMIT '.$conf['nb_comment_page'].' OFFSET '.$page['start'].'
|
||||
;';
|
||||
$result = pwg_query( $query );
|
||||
|
||||
while ($row = pwg_db_fetch_assoc($result))
|
||||
{
|
||||
if ($row['author'] == 'guest')
|
||||
{
|
||||
$row['author'] = l10n('guest');
|
||||
}
|
||||
|
||||
$email = null;
|
||||
if (!empty($row['user_email']))
|
||||
{
|
||||
$email = $row['user_email'];
|
||||
}
|
||||
elseif (!empty($row['email']))
|
||||
{
|
||||
$email = $row['email'];
|
||||
}
|
||||
|
||||
$tpl_comment =
|
||||
array(
|
||||
'ID' => $row['id'],
|
||||
'AUTHOR' => trigger_change('render_comment_author', $row['author']),
|
||||
'DATE' => format_date($row['date'], array('day_name','day','month','year','time')),
|
||||
'CONTENT' => trigger_change('render_comment_content',$row['content']),
|
||||
'WEBSITE_URL' => $row['website_url'],
|
||||
);
|
||||
|
||||
if (can_manage_comment('delete', $row['author_id']))
|
||||
{
|
||||
$tpl_comment['U_DELETE'] = add_url_params(
|
||||
$url_self,
|
||||
array(
|
||||
'action'=>'delete_comment',
|
||||
'comment_to_delete'=>$row['id'],
|
||||
'pwg_token' => get_pwg_token(),
|
||||
)
|
||||
);
|
||||
}
|
||||
if (can_manage_comment('edit', $row['author_id']))
|
||||
{
|
||||
$tpl_comment['U_EDIT'] = add_url_params(
|
||||
$url_self,
|
||||
array(
|
||||
'action'=>'edit_comment',
|
||||
'comment_to_edit'=>$row['id'],
|
||||
)
|
||||
);
|
||||
if (isset($edit_comment) and ($row['id'] == $edit_comment))
|
||||
{
|
||||
$tpl_comment['IN_EDIT'] = true;
|
||||
$key = get_ephemeral_key(2, $page['image_id']);
|
||||
$tpl_comment['KEY'] = $key;
|
||||
$tpl_comment['CONTENT'] = $row['content'];
|
||||
$tpl_comment['PWG_TOKEN'] = get_pwg_token();
|
||||
$tpl_comment['U_CANCEL'] = $url_self;
|
||||
}
|
||||
}
|
||||
if (is_admin())
|
||||
{
|
||||
$tpl_comment['EMAIL'] = $email;
|
||||
|
||||
if ($row['validated'] != 'true')
|
||||
{
|
||||
$tpl_comment['U_VALIDATE'] = add_url_params(
|
||||
$url_self,
|
||||
array(
|
||||
'action' => 'validate_comment',
|
||||
'comment_to_validate' => $row['id'],
|
||||
'pwg_token' => get_pwg_token(),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
$template->append('comments', $tpl_comment);
|
||||
}
|
||||
}
|
||||
|
||||
$show_add_comment_form = true;
|
||||
if (isset($edit_comment))
|
||||
{
|
||||
$show_add_comment_form = false;
|
||||
}
|
||||
if (is_a_guest() and !$conf['comments_forall'])
|
||||
{
|
||||
$show_add_comment_form = false;
|
||||
}
|
||||
|
||||
if ($show_add_comment_form)
|
||||
{
|
||||
$key = get_ephemeral_key(3, $page['image_id']);
|
||||
|
||||
$tpl_var = array(
|
||||
'F_ACTION' => $url_self,
|
||||
'KEY' => $key,
|
||||
'CONTENT' => '',
|
||||
'SHOW_AUTHOR' => !is_classic_user(),
|
||||
'AUTHOR_MANDATORY' => $conf['comments_author_mandatory'],
|
||||
'AUTHOR' => '',
|
||||
'WEBSITE_URL' => '',
|
||||
'SHOW_EMAIL' => !is_classic_user() or empty($user['email']),
|
||||
'EMAIL_MANDATORY' => $conf['comments_email_mandatory'],
|
||||
'EMAIL' => '',
|
||||
'SHOW_WEBSITE' => $conf['comments_enable_website'],
|
||||
);
|
||||
|
||||
if ('reject'==@$comment_action)
|
||||
{
|
||||
foreach( array('content', 'author', 'website_url', 'email') as $k)
|
||||
{
|
||||
$tpl_var[strtoupper($k)] = htmlspecialchars( stripslashes(@$_POST[$k]) );
|
||||
}
|
||||
}
|
||||
$template->assign('comment_add', $tpl_var);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
105
zoesch.de/galerie/include/picture_metadata.inc.php
Normal file
105
zoesch.de/galerie/include/picture_metadata.inc.php
Normal file
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Piwigo - a PHP based photo gallery |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright(C) 2008-2016 Piwigo Team http://piwigo.org |
|
||||
// | Copyright(C) 2003-2008 PhpWebGallery Team http://phpwebgallery.net |
|
||||
// | Copyright(C) 2002-2003 Pierrick LE GALL http://le-gall.net/pierrick |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
* This file is included by the picture page to manage picture metadata
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'/include/functions_metadata.inc.php');
|
||||
if (($conf['show_exif']) and (function_exists('read_exif_data')))
|
||||
{
|
||||
$exif_mapping = array();
|
||||
foreach ($conf['show_exif_fields'] as $field)
|
||||
{
|
||||
$exif_mapping[$field] = $field;
|
||||
}
|
||||
|
||||
$exif = get_exif_data($picture['current']['src_image']->get_path(), $exif_mapping);
|
||||
|
||||
if (count($exif) > 0)
|
||||
{
|
||||
$tpl_meta = array(
|
||||
'TITLE' => l10n('EXIF Metadata'),
|
||||
'lines' => array(),
|
||||
);
|
||||
|
||||
foreach ($conf['show_exif_fields'] as $field)
|
||||
{
|
||||
if (strpos($field, ';') === false)
|
||||
{
|
||||
if (isset($exif[$field]))
|
||||
{
|
||||
$key = $field;
|
||||
if (isset($lang['exif_field_'.$field]))
|
||||
{
|
||||
$key = $lang['exif_field_'.$field];
|
||||
}
|
||||
$tpl_meta['lines'][$key] = $exif[$field];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$tokens = explode(';', $field);
|
||||
if (isset($exif[$field]))
|
||||
{
|
||||
$key = $tokens[1];
|
||||
if (isset($lang['exif_field_'.$key]))
|
||||
{
|
||||
$key = $lang['exif_field_'.$key];
|
||||
}
|
||||
$tpl_meta['lines'][$key] = $exif[$field];
|
||||
}
|
||||
}
|
||||
}
|
||||
$template->append('metadata', $tpl_meta);
|
||||
}
|
||||
}
|
||||
|
||||
if ($conf['show_iptc'])
|
||||
{
|
||||
$iptc = get_iptc_data($picture['current']['src_image']->get_path(), $conf['show_iptc_mapping'], ', ');
|
||||
|
||||
if (count($iptc) > 0)
|
||||
{
|
||||
$tpl_meta = array(
|
||||
'TITLE' => l10n('IPTC Metadata'),
|
||||
'lines' => array(),
|
||||
);
|
||||
|
||||
foreach ($iptc as $field => $value)
|
||||
{
|
||||
$key = $field;
|
||||
if (isset($lang[$field]))
|
||||
{
|
||||
$key = $lang[$field];
|
||||
}
|
||||
$tpl_meta['lines'][$key] = $value;
|
||||
}
|
||||
$template->append('metadata', $tpl_meta);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
87
zoesch.de/galerie/include/picture_rate.inc.php
Normal file
87
zoesch.de/galerie/include/picture_rate.inc.php
Normal file
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Piwigo - a PHP based photo gallery |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright(C) 2008-2016 Piwigo Team http://piwigo.org |
|
||||
// | Copyright(C) 2003-2008 PhpWebGallery Team http://phpwebgallery.net |
|
||||
// | Copyright(C) 2002-2003 Pierrick LE GALL http://le-gall.net/pierrick |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
* This file is included by the picture page to manage rates
|
||||
*
|
||||
*/
|
||||
|
||||
if ($conf['rate'])
|
||||
{
|
||||
$rate_summary = array( 'count'=>0, 'score'=>$picture['current']['rating_score'], 'average'=>null );
|
||||
if ( NULL != $rate_summary['score'] )
|
||||
{
|
||||
$query = '
|
||||
SELECT COUNT(rate) AS count
|
||||
, ROUND(AVG(rate),2) AS average
|
||||
FROM '.RATE_TABLE.'
|
||||
WHERE element_id = '.$picture['current']['id'].'
|
||||
;';
|
||||
list($rate_summary['count'], $rate_summary['average']) = pwg_db_fetch_row(pwg_query($query));
|
||||
}
|
||||
$template->assign('rate_summary', $rate_summary);
|
||||
|
||||
$user_rate = null;
|
||||
if ($conf['rate_anonymous'] or is_autorize_status(ACCESS_CLASSIC) )
|
||||
{
|
||||
if ($rate_summary['count']>0)
|
||||
{
|
||||
$query = 'SELECT rate
|
||||
FROM '.RATE_TABLE.'
|
||||
WHERE element_id = '.$page['image_id'] . '
|
||||
AND user_id = '.$user['id'] ;
|
||||
|
||||
if ( !is_autorize_status(ACCESS_CLASSIC) )
|
||||
{
|
||||
$ip_components = explode('.', $_SERVER['REMOTE_ADDR']);
|
||||
if ( count($ip_components)>3 )
|
||||
{
|
||||
array_pop($ip_components);
|
||||
}
|
||||
$anonymous_id = implode ('.', $ip_components);
|
||||
$query .= ' AND anonymous_id = \''.$anonymous_id . '\'';
|
||||
}
|
||||
|
||||
$result = pwg_query($query);
|
||||
if (pwg_db_num_rows($result) > 0)
|
||||
{
|
||||
$row = pwg_db_fetch_assoc($result);
|
||||
$user_rate = $row['rate'];
|
||||
}
|
||||
}
|
||||
|
||||
$template->assign(
|
||||
'rating',
|
||||
array(
|
||||
'F_ACTION' => add_url_params(
|
||||
$url_self,
|
||||
array('action'=>'rate')
|
||||
),
|
||||
'USER_RATE'=> $user_rate,
|
||||
'marks' => $conf['rate_items']
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
181
zoesch.de/galerie/include/random_compat/byte_safe_strings.php
Normal file
181
zoesch.de/galerie/include/random_compat/byte_safe_strings.php
Normal file
@@ -0,0 +1,181 @@
|
||||
<?php
|
||||
/**
|
||||
* Random_* Compatibility Library
|
||||
* for using the new PHP 7 random_* API in PHP 5 projects
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Paragon Initiative Enterprises
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
if (!function_exists('RandomCompat_strlen')) {
|
||||
if (
|
||||
defined('MB_OVERLOAD_STRING') &&
|
||||
ini_get('mbstring.func_overload') & MB_OVERLOAD_STRING
|
||||
) {
|
||||
/**
|
||||
* strlen() implementation that isn't brittle to mbstring.func_overload
|
||||
*
|
||||
* This version uses mb_strlen() in '8bit' mode to treat strings as raw
|
||||
* binary rather than UTF-8, ISO-8859-1, etc
|
||||
*
|
||||
* @param string $binary_string
|
||||
*
|
||||
* @throws TypeError
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
function RandomCompat_strlen($binary_string)
|
||||
{
|
||||
if (!is_string($binary_string)) {
|
||||
throw new TypeError(
|
||||
'RandomCompat_strlen() expects a string'
|
||||
);
|
||||
}
|
||||
|
||||
return mb_strlen($binary_string, '8bit');
|
||||
}
|
||||
|
||||
} else {
|
||||
/**
|
||||
* strlen() implementation that isn't brittle to mbstring.func_overload
|
||||
*
|
||||
* This version just used the default strlen()
|
||||
*
|
||||
* @param string $binary_string
|
||||
*
|
||||
* @throws TypeError
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
function RandomCompat_strlen($binary_string)
|
||||
{
|
||||
if (!is_string($binary_string)) {
|
||||
throw new TypeError(
|
||||
'RandomCompat_strlen() expects a string'
|
||||
);
|
||||
}
|
||||
return strlen($binary_string);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('RandomCompat_substr')) {
|
||||
|
||||
if (
|
||||
defined('MB_OVERLOAD_STRING')
|
||||
&&
|
||||
ini_get('mbstring.func_overload') & MB_OVERLOAD_STRING
|
||||
) {
|
||||
/**
|
||||
* substr() implementation that isn't brittle to mbstring.func_overload
|
||||
*
|
||||
* This version uses mb_substr() in '8bit' mode to treat strings as raw
|
||||
* binary rather than UTF-8, ISO-8859-1, etc
|
||||
*
|
||||
* @param string $binary_string
|
||||
* @param int $start
|
||||
* @param int $length (optional)
|
||||
*
|
||||
* @throws TypeError
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function RandomCompat_substr($binary_string, $start, $length = null)
|
||||
{
|
||||
if (!is_string($binary_string)) {
|
||||
throw new TypeError(
|
||||
'RandomCompat_substr(): First argument should be a string'
|
||||
);
|
||||
}
|
||||
|
||||
if (!is_int($start)) {
|
||||
throw new TypeError(
|
||||
'RandomCompat_substr(): Second argument should be an integer'
|
||||
);
|
||||
}
|
||||
|
||||
if ($length === null) {
|
||||
/**
|
||||
* mb_substr($str, 0, NULL, '8bit') returns an empty string on
|
||||
* PHP 5.3, so we have to find the length ourselves.
|
||||
*/
|
||||
$length = RandomCompat_strlen($length) - $start;
|
||||
} elseif (!is_int($length)) {
|
||||
throw new TypeError(
|
||||
'RandomCompat_substr(): Third argument should be an integer, or omitted'
|
||||
);
|
||||
}
|
||||
|
||||
// Consistency with PHP's behavior
|
||||
if ($start === RandomCompat_strlen($binary_string) && $length === 0) {
|
||||
return '';
|
||||
}
|
||||
if ($start > RandomCompat_strlen($binary_string)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return mb_substr($binary_string, $start, $length, '8bit');
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/**
|
||||
* substr() implementation that isn't brittle to mbstring.func_overload
|
||||
*
|
||||
* This version just uses the default substr()
|
||||
*
|
||||
* @param string $binary_string
|
||||
* @param int $start
|
||||
* @param int $length (optional)
|
||||
*
|
||||
* @throws TypeError
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function RandomCompat_substr($binary_string, $start, $length = null)
|
||||
{
|
||||
if (!is_string($binary_string)) {
|
||||
throw new TypeError(
|
||||
'RandomCompat_substr(): First argument should be a string'
|
||||
);
|
||||
}
|
||||
|
||||
if (!is_int($start)) {
|
||||
throw new TypeError(
|
||||
'RandomCompat_substr(): Second argument should be an integer'
|
||||
);
|
||||
}
|
||||
|
||||
if ($length !== null) {
|
||||
if (!is_int($length)) {
|
||||
throw new TypeError(
|
||||
'RandomCompat_substr(): Third argument should be an integer, or omitted'
|
||||
);
|
||||
}
|
||||
|
||||
return substr($binary_string, $start, $length);
|
||||
}
|
||||
|
||||
return substr($binary_string, $start);
|
||||
}
|
||||
}
|
||||
}
|
||||
71
zoesch.de/galerie/include/random_compat/cast_to_int.php
Normal file
71
zoesch.de/galerie/include/random_compat/cast_to_int.php
Normal file
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
/**
|
||||
* Random_* Compatibility Library
|
||||
* for using the new PHP 7 random_* API in PHP 5 projects
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Paragon Initiative Enterprises
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
if (!function_exists('RandomCompat_intval')) {
|
||||
|
||||
/**
|
||||
* Cast to an integer if we can, safely.
|
||||
*
|
||||
* If you pass it a float in the range (~PHP_INT_MAX, PHP_INT_MAX)
|
||||
* (non-inclusive), it will sanely cast it to an int. If you it's equal to
|
||||
* ~PHP_INT_MAX or PHP_INT_MAX, we let it fail as not an integer. Floats
|
||||
* lose precision, so the <= and => operators might accidentally let a float
|
||||
* through.
|
||||
*
|
||||
* @param int|float $number The number we want to convert to an int
|
||||
* @param boolean $fail_open Set to true to not throw an exception
|
||||
*
|
||||
* @return int (or float if $fail_open)
|
||||
*
|
||||
* @throws TypeError
|
||||
*/
|
||||
function RandomCompat_intval($number, $fail_open = false)
|
||||
{
|
||||
if (is_numeric($number)) {
|
||||
$number += 0;
|
||||
}
|
||||
|
||||
if (
|
||||
is_float($number)
|
||||
&&
|
||||
$number > ~PHP_INT_MAX
|
||||
&&
|
||||
$number < PHP_INT_MAX
|
||||
) {
|
||||
$number = (int) $number;
|
||||
}
|
||||
|
||||
if (is_int($number) || $fail_open) {
|
||||
return $number;
|
||||
}
|
||||
|
||||
throw new TypeError(
|
||||
'Expected an integer.'
|
||||
);
|
||||
}
|
||||
}
|
||||
42
zoesch.de/galerie/include/random_compat/error_polyfill.php
Normal file
42
zoesch.de/galerie/include/random_compat/error_polyfill.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
/**
|
||||
* Random_* Compatibility Library
|
||||
* for using the new PHP 7 random_* API in PHP 5 projects
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Paragon Initiative Enterprises
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
if (!class_exists('Error', false)) {
|
||||
// We can't really avoid making this extend Exception in PHP 5.
|
||||
class Error extends Exception
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (!class_exists('TypeError', false)) {
|
||||
class TypeError extends Error
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
197
zoesch.de/galerie/include/random_compat/random.php
Normal file
197
zoesch.de/galerie/include/random_compat/random.php
Normal file
@@ -0,0 +1,197 @@
|
||||
<?php
|
||||
/**
|
||||
* Random_* Compatibility Library
|
||||
* for using the new PHP 7 random_* API in PHP 5 projects
|
||||
*
|
||||
* @version 2.0.2
|
||||
* @released 2016-04-03
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Paragon Initiative Enterprises
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
if (!defined('PHP_VERSION_ID')) {
|
||||
// This constant was introduced in PHP 5.2.7
|
||||
$RandomCompatversion = explode('.', PHP_VERSION);
|
||||
define(
|
||||
'PHP_VERSION_ID',
|
||||
$RandomCompatversion[0] * 10000
|
||||
+ $RandomCompatversion[1] * 100
|
||||
+ $RandomCompatversion[2]
|
||||
);
|
||||
$RandomCompatversion = null;
|
||||
}
|
||||
|
||||
if (PHP_VERSION_ID < 70000) {
|
||||
|
||||
if (!defined('RANDOM_COMPAT_READ_BUFFER')) {
|
||||
define('RANDOM_COMPAT_READ_BUFFER', 8);
|
||||
}
|
||||
|
||||
$RandomCompatDIR = dirname(__FILE__);
|
||||
|
||||
require_once $RandomCompatDIR.'/byte_safe_strings.php';
|
||||
require_once $RandomCompatDIR.'/cast_to_int.php';
|
||||
require_once $RandomCompatDIR.'/error_polyfill.php';
|
||||
|
||||
if (!function_exists('random_bytes')) {
|
||||
/**
|
||||
* PHP 5.2.0 - 5.6.x way to implement random_bytes()
|
||||
*
|
||||
* We use conditional statements here to define the function in accordance
|
||||
* to the operating environment. It's a micro-optimization.
|
||||
*
|
||||
* In order of preference:
|
||||
* 1. Use libsodium if available.
|
||||
* 2. fread() /dev/urandom if available (never on Windows)
|
||||
* 3. mcrypt_create_iv($bytes, MCRYPT_DEV_URANDOM)
|
||||
* 4. COM('CAPICOM.Utilities.1')->GetRandom()
|
||||
* 5. openssl_random_pseudo_bytes() (absolute last resort)
|
||||
*
|
||||
* See ERRATA.md for our reasoning behind this particular order
|
||||
*/
|
||||
if (extension_loaded('libsodium')) {
|
||||
// See random_bytes_libsodium.php
|
||||
if (PHP_VERSION_ID >= 50300 && function_exists('\\Sodium\\randombytes_buf')) {
|
||||
require_once $RandomCompatDIR.'/random_bytes_libsodium.php';
|
||||
} elseif (method_exists('Sodium', 'randombytes_buf')) {
|
||||
require_once $RandomCompatDIR.'/random_bytes_libsodium_legacy.php';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reading directly from /dev/urandom:
|
||||
*/
|
||||
if (DIRECTORY_SEPARATOR === '/') {
|
||||
// DIRECTORY_SEPARATOR === '/' on Unix-like OSes -- this is a fast
|
||||
// way to exclude Windows.
|
||||
$RandomCompatUrandom = true;
|
||||
$RandomCompat_basedir = ini_get('open_basedir');
|
||||
|
||||
if (!empty($RandomCompat_basedir)) {
|
||||
$RandomCompat_open_basedir = explode(
|
||||
PATH_SEPARATOR,
|
||||
strtolower($RandomCompat_basedir)
|
||||
);
|
||||
$RandomCompatUrandom = (array() !== array_intersect(
|
||||
array('/dev', '/dev/', '/dev/urandom'),
|
||||
$RandomCompat_open_basedir
|
||||
));
|
||||
$RandomCompat_open_basedir = null;
|
||||
}
|
||||
|
||||
if (
|
||||
!function_exists('random_bytes')
|
||||
&&
|
||||
$RandomCompatUrandom
|
||||
&&
|
||||
@is_readable('/dev/urandom')
|
||||
) {
|
||||
// Error suppression on is_readable() in case of an open_basedir
|
||||
// or safe_mode failure. All we care about is whether or not we
|
||||
// can read it at this point. If the PHP environment is going to
|
||||
// panic over trying to see if the file can be read in the first
|
||||
// place, that is not helpful to us here.
|
||||
|
||||
// See random_bytes_dev_urandom.php
|
||||
require_once $RandomCompatDIR.'/random_bytes_dev_urandom.php';
|
||||
}
|
||||
// Unset variables after use
|
||||
$RandomCompat_basedir = null;
|
||||
} else {
|
||||
$RandomCompatUrandom = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* mcrypt_create_iv()
|
||||
*/
|
||||
if (
|
||||
!function_exists('random_bytes')
|
||||
&&
|
||||
PHP_VERSION_ID >= 50307
|
||||
&&
|
||||
extension_loaded('mcrypt')
|
||||
&&
|
||||
(DIRECTORY_SEPARATOR !== '/' || $RandomCompatUrandom)
|
||||
) {
|
||||
// Prevent this code from hanging indefinitely on non-Windows;
|
||||
// see https://bugs.php.net/bug.php?id=69833
|
||||
if (
|
||||
DIRECTORY_SEPARATOR !== '/' ||
|
||||
(PHP_VERSION_ID <= 50609 || PHP_VERSION_ID >= 50613)
|
||||
) {
|
||||
// See random_bytes_mcrypt.php
|
||||
require_once $RandomCompatDIR.'/random_bytes_mcrypt.php';
|
||||
}
|
||||
}
|
||||
$RandomCompatUrandom = null;
|
||||
|
||||
if (
|
||||
!function_exists('random_bytes')
|
||||
&&
|
||||
extension_loaded('com_dotnet')
|
||||
&&
|
||||
class_exists('COM')
|
||||
) {
|
||||
$RandomCompat_disabled_classes = preg_split(
|
||||
'#\s*,\s*#',
|
||||
strtolower(ini_get('disable_classes'))
|
||||
);
|
||||
|
||||
if (!in_array('com', $RandomCompat_disabled_classes)) {
|
||||
try {
|
||||
$RandomCompatCOMtest = new COM('CAPICOM.Utilities.1');
|
||||
if (method_exists($RandomCompatCOMtest, 'GetRandom')) {
|
||||
// See random_bytes_com_dotnet.php
|
||||
require_once $RandomCompatDIR.'/random_bytes_com_dotnet.php';
|
||||
}
|
||||
} catch (com_exception $e) {
|
||||
// Don't try to use it.
|
||||
}
|
||||
}
|
||||
$RandomCompat_disabled_classes = null;
|
||||
$RandomCompatCOMtest = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* throw new Exception
|
||||
*/
|
||||
if (!function_exists('random_bytes')) {
|
||||
/**
|
||||
* We don't have any more options, so let's throw an exception right now
|
||||
* and hope the developer won't let it fail silently.
|
||||
*/
|
||||
function random_bytes($length)
|
||||
{
|
||||
throw new Exception(
|
||||
'There is no suitable CSPRNG installed on your system'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('random_int')) {
|
||||
require_once $RandomCompatDIR.'/random_int.php';
|
||||
}
|
||||
|
||||
$RandomCompatDIR = null;
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
/**
|
||||
* Random_* Compatibility Library
|
||||
* for using the new PHP 7 random_* API in PHP 5 projects
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Paragon Initiative Enterprises
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Windows with PHP < 5.3.0 will not have the function
|
||||
* openssl_random_pseudo_bytes() available, so let's use
|
||||
* CAPICOM to work around this deficiency.
|
||||
*
|
||||
* @param int $bytes
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function random_bytes($bytes)
|
||||
{
|
||||
try {
|
||||
$bytes = RandomCompat_intval($bytes);
|
||||
} catch (TypeError $ex) {
|
||||
throw new TypeError(
|
||||
'random_bytes(): $bytes must be an integer'
|
||||
);
|
||||
}
|
||||
|
||||
if ($bytes < 1) {
|
||||
throw new Error(
|
||||
'Length must be greater than 0'
|
||||
);
|
||||
}
|
||||
|
||||
$buf = '';
|
||||
$util = new COM('CAPICOM.Utilities.1');
|
||||
$execCount = 0;
|
||||
|
||||
/**
|
||||
* Let's not let it loop forever. If we run N times and fail to
|
||||
* get N bytes of random data, then CAPICOM has failed us.
|
||||
*/
|
||||
do {
|
||||
$buf .= base64_decode($util->GetRandom($bytes, 0));
|
||||
if (RandomCompat_strlen($buf) >= $bytes) {
|
||||
/**
|
||||
* Return our random entropy buffer here:
|
||||
*/
|
||||
return RandomCompat_substr($buf, 0, $bytes);
|
||||
}
|
||||
++$execCount;
|
||||
} while ($execCount < $bytes);
|
||||
|
||||
/**
|
||||
* If we reach here, PHP has failed us.
|
||||
*/
|
||||
throw new Exception(
|
||||
'Could not gather sufficient random data'
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
<?php
|
||||
/**
|
||||
* Random_* Compatibility Library
|
||||
* for using the new PHP 7 random_* API in PHP 5 projects
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Paragon Initiative Enterprises
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
if (!defined('RANDOM_COMPAT_READ_BUFFER')) {
|
||||
define('RANDOM_COMPAT_READ_BUFFER', 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unless open_basedir is enabled, use /dev/urandom for
|
||||
* random numbers in accordance with best practices
|
||||
*
|
||||
* Why we use /dev/urandom and not /dev/random
|
||||
* @ref http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers
|
||||
*
|
||||
* @param int $bytes
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function random_bytes($bytes)
|
||||
{
|
||||
static $fp = null;
|
||||
/**
|
||||
* This block should only be run once
|
||||
*/
|
||||
if (empty($fp)) {
|
||||
/**
|
||||
* We use /dev/urandom if it is a char device.
|
||||
* We never fall back to /dev/random
|
||||
*/
|
||||
$fp = fopen('/dev/urandom', 'rb');
|
||||
if (!empty($fp)) {
|
||||
$st = fstat($fp);
|
||||
if (($st['mode'] & 0170000) !== 020000) {
|
||||
fclose($fp);
|
||||
$fp = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($fp)) {
|
||||
/**
|
||||
* stream_set_read_buffer() does not exist in HHVM
|
||||
*
|
||||
* If we don't set the stream's read buffer to 0, PHP will
|
||||
* internally buffer 8192 bytes, which can waste entropy
|
||||
*
|
||||
* stream_set_read_buffer returns 0 on success
|
||||
*/
|
||||
if (function_exists('stream_set_read_buffer')) {
|
||||
stream_set_read_buffer($fp, RANDOM_COMPAT_READ_BUFFER);
|
||||
}
|
||||
if (function_exists('stream_set_chunk_size')) {
|
||||
stream_set_chunk_size($fp, RANDOM_COMPAT_READ_BUFFER);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$bytes = RandomCompat_intval($bytes);
|
||||
} catch (TypeError $ex) {
|
||||
throw new TypeError(
|
||||
'random_bytes(): $bytes must be an integer'
|
||||
);
|
||||
}
|
||||
|
||||
if ($bytes < 1) {
|
||||
throw new Error(
|
||||
'Length must be greater than 0'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* This if() block only runs if we managed to open a file handle
|
||||
*
|
||||
* It does not belong in an else {} block, because the above
|
||||
* if (empty($fp)) line is logic that should only be run once per
|
||||
* page load.
|
||||
*/
|
||||
if (!empty($fp)) {
|
||||
$remaining = $bytes;
|
||||
$buf = '';
|
||||
|
||||
/**
|
||||
* We use fread() in a loop to protect against partial reads
|
||||
*/
|
||||
do {
|
||||
$read = fread($fp, $remaining);
|
||||
if ($read === false) {
|
||||
/**
|
||||
* We cannot safely read from the file. Exit the
|
||||
* do-while loop and trigger the exception condition
|
||||
*/
|
||||
$buf = false;
|
||||
break;
|
||||
}
|
||||
/**
|
||||
* Decrease the number of bytes returned from remaining
|
||||
*/
|
||||
$remaining -= RandomCompat_strlen($read);
|
||||
$buf .= $read;
|
||||
} while ($remaining > 0);
|
||||
|
||||
/**
|
||||
* Is our result valid?
|
||||
*/
|
||||
if ($buf !== false) {
|
||||
if (RandomCompat_strlen($buf) === $bytes) {
|
||||
/**
|
||||
* Return our random entropy buffer here:
|
||||
*/
|
||||
return $buf;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If we reach here, PHP has failed us.
|
||||
*/
|
||||
throw new Exception(
|
||||
'Error reading from source device'
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
/**
|
||||
* Random_* Compatibility Library
|
||||
* for using the new PHP 7 random_* API in PHP 5 projects
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Paragon Initiative Enterprises
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* If the libsodium PHP extension is loaded, we'll use it above any other
|
||||
* solution.
|
||||
*
|
||||
* libsodium-php project:
|
||||
* @ref https://github.com/jedisct1/libsodium-php
|
||||
*
|
||||
* @param int $bytes
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function random_bytes($bytes)
|
||||
{
|
||||
try {
|
||||
$bytes = RandomCompat_intval($bytes);
|
||||
} catch (TypeError $ex) {
|
||||
throw new TypeError(
|
||||
'random_bytes(): $bytes must be an integer'
|
||||
);
|
||||
}
|
||||
|
||||
if ($bytes < 1) {
|
||||
throw new Error(
|
||||
'Length must be greater than 0'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* \Sodium\randombytes_buf() doesn't allow more than 2147483647 bytes to be
|
||||
* generated in one invocation.
|
||||
*/
|
||||
if ($bytes > 2147483647) {
|
||||
$buf = '';
|
||||
for ($i = 0; $i < $bytes; $i += 1073741824) {
|
||||
$n = ($bytes - $i) > 1073741824
|
||||
? 1073741824
|
||||
: $bytes - $i;
|
||||
$buf .= \Sodium\randombytes_buf($n);
|
||||
}
|
||||
} else {
|
||||
$buf = \Sodium\randombytes_buf($bytes);
|
||||
}
|
||||
|
||||
if ($buf !== false) {
|
||||
if (RandomCompat_strlen($buf) === $bytes) {
|
||||
return $buf;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If we reach here, PHP has failed us.
|
||||
*/
|
||||
throw new Exception(
|
||||
'Could not gather sufficient random data'
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
/**
|
||||
* Random_* Compatibility Library
|
||||
* for using the new PHP 7 random_* API in PHP 5 projects
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Paragon Initiative Enterprises
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* If the libsodium PHP extension is loaded, we'll use it above any other
|
||||
* solution.
|
||||
*
|
||||
* libsodium-php project:
|
||||
* @ref https://github.com/jedisct1/libsodium-php
|
||||
*
|
||||
* @param int $bytes
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function random_bytes($bytes)
|
||||
{
|
||||
try {
|
||||
$bytes = RandomCompat_intval($bytes);
|
||||
} catch (TypeError $ex) {
|
||||
throw new TypeError(
|
||||
'random_bytes(): $bytes must be an integer'
|
||||
);
|
||||
}
|
||||
|
||||
if ($bytes < 1) {
|
||||
throw new Error(
|
||||
'Length must be greater than 0'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* \Sodium\randombytes_buf() doesn't allow more than 2147483647 bytes to be
|
||||
* generated in one invocation.
|
||||
*/
|
||||
if ($bytes > 2147483647) {
|
||||
$buf = '';
|
||||
for ($i = 0; $i < $bytes; $i += 1073741824) {
|
||||
$n = ($bytes - $i) > 1073741824
|
||||
? 1073741824
|
||||
: $bytes - $i;
|
||||
$buf .= Sodium::randombytes_buf($n);
|
||||
}
|
||||
} else {
|
||||
$buf = Sodium::randombytes_buf($bytes);
|
||||
}
|
||||
|
||||
if ($buf !== false) {
|
||||
if (RandomCompat_strlen($buf) === $bytes) {
|
||||
return $buf;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If we reach here, PHP has failed us.
|
||||
*/
|
||||
throw new Exception(
|
||||
'Could not gather sufficient random data'
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
/**
|
||||
* Random_* Compatibility Library
|
||||
* for using the new PHP 7 random_* API in PHP 5 projects
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Paragon Initiative Enterprises
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Powered by ext/mcrypt (and thankfully NOT libmcrypt)
|
||||
*
|
||||
* @ref https://bugs.php.net/bug.php?id=55169
|
||||
* @ref https://github.com/php/php-src/blob/c568ffe5171d942161fc8dda066bce844bdef676/ext/mcrypt/mcrypt.c#L1321-L1386
|
||||
*
|
||||
* @param int $bytes
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function random_bytes($bytes)
|
||||
{
|
||||
try {
|
||||
$bytes = RandomCompat_intval($bytes);
|
||||
} catch (TypeError $ex) {
|
||||
throw new TypeError(
|
||||
'random_bytes(): $bytes must be an integer'
|
||||
);
|
||||
}
|
||||
|
||||
if ($bytes < 1) {
|
||||
throw new Error(
|
||||
'Length must be greater than 0'
|
||||
);
|
||||
}
|
||||
|
||||
$buf = @mcrypt_create_iv($bytes, MCRYPT_DEV_URANDOM);
|
||||
if (
|
||||
$buf !== false
|
||||
&&
|
||||
RandomCompat_strlen($buf) === $bytes
|
||||
) {
|
||||
/**
|
||||
* Return our random entropy buffer here:
|
||||
*/
|
||||
return $buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* If we reach here, PHP has failed us.
|
||||
*/
|
||||
throw new Exception(
|
||||
'Could not gather sufficient random data'
|
||||
);
|
||||
}
|
||||
191
zoesch.de/galerie/include/random_compat/random_int.php
Normal file
191
zoesch.de/galerie/include/random_compat/random_int.php
Normal file
@@ -0,0 +1,191 @@
|
||||
<?php
|
||||
/**
|
||||
* Random_* Compatibility Library
|
||||
* for using the new PHP 7 random_* API in PHP 5 projects
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Paragon Initiative Enterprises
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fetch a random integer between $min and $max inclusive
|
||||
*
|
||||
* @param int $min
|
||||
* @param int $max
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
function random_int($min, $max)
|
||||
{
|
||||
/**
|
||||
* Type and input logic checks
|
||||
*
|
||||
* If you pass it a float in the range (~PHP_INT_MAX, PHP_INT_MAX)
|
||||
* (non-inclusive), it will sanely cast it to an int. If you it's equal to
|
||||
* ~PHP_INT_MAX or PHP_INT_MAX, we let it fail as not an integer. Floats
|
||||
* lose precision, so the <= and => operators might accidentally let a float
|
||||
* through.
|
||||
*/
|
||||
|
||||
try {
|
||||
$min = RandomCompat_intval($min);
|
||||
} catch (TypeError $ex) {
|
||||
throw new TypeError(
|
||||
'random_int(): $min must be an integer'
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
$max = RandomCompat_intval($max);
|
||||
} catch (TypeError $ex) {
|
||||
throw new TypeError(
|
||||
'random_int(): $max must be an integer'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Now that we've verified our weak typing system has given us an integer,
|
||||
* let's validate the logic then we can move forward with generating random
|
||||
* integers along a given range.
|
||||
*/
|
||||
if ($min > $max) {
|
||||
throw new Error(
|
||||
'Minimum value must be less than or equal to the maximum value'
|
||||
);
|
||||
}
|
||||
|
||||
if ($max === $min) {
|
||||
return $min;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize variables to 0
|
||||
*
|
||||
* We want to store:
|
||||
* $bytes => the number of random bytes we need
|
||||
* $mask => an integer bitmask (for use with the &) operator
|
||||
* so we can minimize the number of discards
|
||||
*/
|
||||
$attempts = $bits = $bytes = $mask = $valueShift = 0;
|
||||
|
||||
/**
|
||||
* At this point, $range is a positive number greater than 0. It might
|
||||
* overflow, however, if $max - $min > PHP_INT_MAX. PHP will cast it to
|
||||
* a float and we will lose some precision.
|
||||
*/
|
||||
$range = $max - $min;
|
||||
|
||||
/**
|
||||
* Test for integer overflow:
|
||||
*/
|
||||
if (!is_int($range)) {
|
||||
|
||||
/**
|
||||
* Still safely calculate wider ranges.
|
||||
* Provided by @CodesInChaos, @oittaa
|
||||
*
|
||||
* @ref https://gist.github.com/CodesInChaos/03f9ea0b58e8b2b8d435
|
||||
*
|
||||
* We use ~0 as a mask in this case because it generates all 1s
|
||||
*
|
||||
* @ref https://eval.in/400356 (32-bit)
|
||||
* @ref http://3v4l.org/XX9r5 (64-bit)
|
||||
*/
|
||||
$bytes = PHP_INT_SIZE;
|
||||
$mask = ~0;
|
||||
|
||||
} else {
|
||||
|
||||
/**
|
||||
* $bits is effectively ceil(log($range, 2)) without dealing with
|
||||
* type juggling
|
||||
*/
|
||||
while ($range > 0) {
|
||||
if ($bits % 8 === 0) {
|
||||
++$bytes;
|
||||
}
|
||||
++$bits;
|
||||
$range >>= 1;
|
||||
$mask = $mask << 1 | 1;
|
||||
}
|
||||
$valueShift = $min;
|
||||
}
|
||||
|
||||
/**
|
||||
* Now that we have our parameters set up, let's begin generating
|
||||
* random integers until one falls between $min and $max
|
||||
*/
|
||||
do {
|
||||
/**
|
||||
* The rejection probability is at most 0.5, so this corresponds
|
||||
* to a failure probability of 2^-128 for a working RNG
|
||||
*/
|
||||
if ($attempts > 128) {
|
||||
throw new Exception(
|
||||
'random_int: RNG is broken - too many rejections'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Let's grab the necessary number of random bytes
|
||||
*/
|
||||
$randomByteString = random_bytes($bytes);
|
||||
if ($randomByteString === false) {
|
||||
throw new Exception(
|
||||
'Random number generator failure'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Let's turn $randomByteString into an integer
|
||||
*
|
||||
* This uses bitwise operators (<< and |) to build an integer
|
||||
* out of the values extracted from ord()
|
||||
*
|
||||
* Example: [9F] | [6D] | [32] | [0C] =>
|
||||
* 159 + 27904 + 3276800 + 201326592 =>
|
||||
* 204631455
|
||||
*/
|
||||
$val = 0;
|
||||
for ($i = 0; $i < $bytes; ++$i) {
|
||||
$val |= ord($randomByteString[$i]) << ($i * 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply mask
|
||||
*/
|
||||
$val &= $mask;
|
||||
$val += $valueShift;
|
||||
|
||||
++$attempts;
|
||||
/**
|
||||
* If $val overflows to a floating point number,
|
||||
* ... or is larger than $max,
|
||||
* ... or smaller than $min,
|
||||
* then try again.
|
||||
*/
|
||||
} while (!is_int($val) || $val > $max || $val < $min);
|
||||
|
||||
return (int) $val;
|
||||
}
|
||||
641
zoesch.de/galerie/include/section_init.inc.php
Normal file
641
zoesch.de/galerie/include/section_init.inc.php
Normal file
@@ -0,0 +1,641 @@
|
||||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Piwigo - a PHP based photo gallery |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright(C) 2008-2016 Piwigo Team http://piwigo.org |
|
||||
// | Copyright(C) 2003-2008 PhpWebGallery Team http://phpwebgallery.net |
|
||||
// | Copyright(C) 2002-2003 Pierrick LE GALL http://le-gall.net/pierrick |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | This program is distributed in the hope that it will be useful, but |
|
||||
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
* This included page checks section related parameter and provides
|
||||
* following informations:
|
||||
*
|
||||
* - $page['title']
|
||||
*
|
||||
* - $page['items']: ordered list of items to display
|
||||
*
|
||||
*/
|
||||
|
||||
// "index.php?/category/12-foo/start-24" or
|
||||
// "index.php/category/12-foo/start-24"
|
||||
// must return :
|
||||
//
|
||||
// array(
|
||||
// 'section' => 'categories',
|
||||
// 'category' => array('id'=>12, ...),
|
||||
// 'start' => 24
|
||||
// );
|
||||
|
||||
|
||||
$page['items'] = array();
|
||||
$page['start'] = $page['startcat'] = 0;
|
||||
|
||||
// some ISPs set PATH_INFO to empty string or to SCRIPT_FILENAME while in the
|
||||
// default apache implementation it is not set
|
||||
if ( $conf['question_mark_in_urls']==false and
|
||||
isset($_SERVER["PATH_INFO"]) and !empty($_SERVER["PATH_INFO"]) )
|
||||
{
|
||||
$rewritten = $_SERVER["PATH_INFO"];
|
||||
$rewritten = str_replace('//', '/', $rewritten);
|
||||
$path_count = count( explode('/', $rewritten) );
|
||||
$page['root_path'] = PHPWG_ROOT_PATH.str_repeat('../', $path_count-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
$rewritten = '';
|
||||
foreach (array_keys($_GET) as $keynum => $key)
|
||||
{
|
||||
$rewritten = $key;
|
||||
break;
|
||||
}
|
||||
|
||||
// the $_GET keys are not protected in include/common.inc.php, only the values
|
||||
$rewritten = pwg_db_real_escape_string($rewritten);
|
||||
$page['root_path'] = PHPWG_ROOT_PATH;
|
||||
}
|
||||
|
||||
if ( strncmp($page['root_path'], './', 2) == 0 )
|
||||
{
|
||||
$page['root_path'] = substr($page['root_path'], 2);
|
||||
}
|
||||
|
||||
// deleting first "/" if displayed
|
||||
$tokens = explode('/', ltrim($rewritten, '/') );
|
||||
// $tokens = array(
|
||||
// 0 => category,
|
||||
// 1 => 12-foo,
|
||||
// 2 => start-24
|
||||
// );
|
||||
|
||||
$next_token = 0;
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | picture page |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// the first token must be the identifier for the picture
|
||||
if (script_basename() == 'picture')
|
||||
{
|
||||
$token = $tokens[$next_token];
|
||||
$next_token++;
|
||||
if ( is_numeric($token) )
|
||||
{
|
||||
$page['image_id'] = $token;
|
||||
if ($page['image_id']==0)
|
||||
{
|
||||
bad_request('invalid picture identifier');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
preg_match('/^(\d+-)?(.*)?$/', $token, $matches);
|
||||
if (isset($matches[1]) and is_numeric($matches[1]=rtrim($matches[1],'-')) )
|
||||
{
|
||||
$page['image_id'] = $matches[1];
|
||||
if ( !empty($matches[2]) )
|
||||
{
|
||||
$page['image_file'] = $matches[2];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$page['image_id'] = 0; // more work in picture.php
|
||||
if ( !empty($matches[2]) )
|
||||
{
|
||||
$page['image_file'] = $matches[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
bad_request('picture identifier is missing');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$page = array_merge( $page, parse_section_url( $tokens, $next_token) );
|
||||
|
||||
if ( !isset($page['section']) )
|
||||
{
|
||||
$page['section'] = 'categories';
|
||||
|
||||
switch (script_basename())
|
||||
{
|
||||
case 'picture':
|
||||
break;
|
||||
case 'index':
|
||||
{
|
||||
// No section defined, go to random url
|
||||
if ( !empty($conf['random_index_redirect']) and empty($tokens[$next_token]) )
|
||||
{
|
||||
$random_index_redirect = array();
|
||||
foreach ($conf['random_index_redirect'] as $random_url => $random_url_condition)
|
||||
{
|
||||
if (empty($random_url_condition) or eval($random_url_condition))
|
||||
{
|
||||
$random_index_redirect[] = $random_url;
|
||||
}
|
||||
}
|
||||
if (!empty($random_index_redirect))
|
||||
{
|
||||
redirect($random_index_redirect[mt_rand(0, count($random_index_redirect)-1)]);
|
||||
}
|
||||
}
|
||||
$page['is_homepage'] = true;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
trigger_error('script_basename "'.script_basename().'" unknown',
|
||||
E_USER_WARNING);
|
||||
}
|
||||
}
|
||||
|
||||
$page = array_merge( $page, parse_well_known_params_url( $tokens, $next_token) );
|
||||
|
||||
//access a picture only by id, file or id-file without given section
|
||||
if ( script_basename()=='picture' and 'categories'==$page['section'] and
|
||||
!isset($page['category']) and !isset($page['chronology_field']) )
|
||||
{
|
||||
$page['flat'] = true;
|
||||
}
|
||||
|
||||
// $page['nb_image_page'] is the number of picture to display on this page
|
||||
// By default, it is the same as the $user['nb_image_page']
|
||||
$page['nb_image_page'] = $user['nb_image_page'];
|
||||
|
||||
// if flat mode is active, we must consider the image set as a standard set
|
||||
// and not as a category set because we can't use the #image_category.rank :
|
||||
// displayed images are not directly linked to the displayed category
|
||||
if ('categories' == $page['section'] and !isset($page['flat']))
|
||||
{
|
||||
$conf['order_by'] = $conf['order_by_inside_category'];
|
||||
}
|
||||
|
||||
if (pwg_get_session_var('image_order',0) > 0)
|
||||
{
|
||||
$image_order_id = pwg_get_session_var('image_order');
|
||||
|
||||
$orders = get_category_preferred_image_orders();
|
||||
|
||||
// the current session stored image_order might be not compatible with
|
||||
// current image set, for example if the current image_order is the rank
|
||||
// and that we are displaying images related to a tag.
|
||||
//
|
||||
// In case of incompatibility, the session stored image_order is removed.
|
||||
if ($orders[$image_order_id][2])
|
||||
{
|
||||
$conf['order_by'] = str_replace(
|
||||
'ORDER BY ',
|
||||
'ORDER BY '.$orders[$image_order_id][1].',',
|
||||
$conf['order_by']
|
||||
);
|
||||
$page['super_order_by'] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
pwg_unset_session_var('image_order');
|
||||
$page['super_order_by'] = false;
|
||||
}
|
||||
}
|
||||
|
||||
$forbidden = get_sql_condition_FandF(
|
||||
array(
|
||||
'forbidden_categories' => 'category_id',
|
||||
'visible_categories' => 'category_id',
|
||||
'visible_images' => 'id'
|
||||
),
|
||||
'AND'
|
||||
);
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | category |
|
||||
// +-----------------------------------------------------------------------+
|
||||
if ('categories' == $page['section'])
|
||||
{
|
||||
if (isset($page['category']))
|
||||
{
|
||||
$page = array_merge(
|
||||
$page,
|
||||
array(
|
||||
'comment' => trigger_change(
|
||||
'render_category_description',
|
||||
$page['category']['comment'],
|
||||
'main_page_category_description'
|
||||
),
|
||||
'title' => get_cat_display_name($page['category']['upper_names'], '', false),
|
||||
)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$page['title'] = ''; // will be set later
|
||||
}
|
||||
|
||||
// GET IMAGES LIST
|
||||
if
|
||||
(
|
||||
$page['startcat'] == 0 and
|
||||
(!isset($page['chronology_field'])) and // otherwise the calendar will requery all subitems
|
||||
(
|
||||
(isset($page['category'])) or
|
||||
(isset($page['flat']))
|
||||
)
|
||||
)
|
||||
{
|
||||
if ( !empty($page['category']['image_order']) and !isset($page['super_order_by']) )
|
||||
{
|
||||
$conf[ 'order_by' ] = ' ORDER BY '.$page['category']['image_order'];
|
||||
}
|
||||
|
||||
// flat categories mode
|
||||
if (isset($page['flat']))
|
||||
{
|
||||
// get all allowed sub-categories
|
||||
if ( isset($page['category']) )
|
||||
{
|
||||
$query = '
|
||||
SELECT id
|
||||
FROM '.CATEGORIES_TABLE.'
|
||||
WHERE
|
||||
uppercats LIKE \''.$page['category']['uppercats'].',%\' '
|
||||
.get_sql_condition_FandF(
|
||||
array(
|
||||
'forbidden_categories' => 'id',
|
||||
'visible_categories' => 'id',
|
||||
),
|
||||
"\n AND"
|
||||
);
|
||||
|
||||
$subcat_ids = query2array($query,null, 'id');
|
||||
$subcat_ids[] = $page['category']['id'];
|
||||
$where_sql = 'category_id IN ('.implode(',',$subcat_ids).')';
|
||||
// remove categories from forbidden because just checked above
|
||||
$forbidden = get_sql_condition_FandF(
|
||||
array( 'visible_images' => 'id' ),
|
||||
'AND'
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$cache_key = $persistent_cache->make_key('all_iids'.$user['id'].$user['cache_update_time'].$conf['order_by']);
|
||||
unset($page['is_homepage']);
|
||||
$where_sql = '1=1';
|
||||
}
|
||||
}
|
||||
// normal mode
|
||||
else
|
||||
{
|
||||
$where_sql = 'category_id = '.$page['category']['id'];
|
||||
}
|
||||
|
||||
if ( !isset($cache_key) || !$persistent_cache->get($cache_key, $page['items']))
|
||||
{
|
||||
// main query
|
||||
$query = '
|
||||
SELECT DISTINCT(image_id)
|
||||
FROM '.IMAGE_CATEGORY_TABLE.'
|
||||
INNER JOIN '.IMAGES_TABLE.' ON id = image_id
|
||||
WHERE
|
||||
'.$where_sql.'
|
||||
'.$forbidden.'
|
||||
'.$conf['order_by'].'
|
||||
;';
|
||||
|
||||
$page['items'] = query2array($query,null, 'image_id');
|
||||
|
||||
if ( isset($cache_key) )
|
||||
$persistent_cache->set($cache_key, $page['items']);
|
||||
}
|
||||
}
|
||||
}
|
||||
// special sections
|
||||
else
|
||||
{
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | tags section |
|
||||
// +-----------------------------------------------------------------------+
|
||||
if ($page['section'] == 'tags')
|
||||
{
|
||||
$page['tag_ids'] = array();
|
||||
foreach ($page['tags'] as $tag)
|
||||
{
|
||||
$page['tag_ids'][] = $tag['id'];
|
||||
}
|
||||
|
||||
$items = get_image_ids_for_tags($page['tag_ids']);
|
||||
|
||||
$page = array_merge(
|
||||
$page,
|
||||
array(
|
||||
'title' => get_tags_content_title(),
|
||||
'items' => $items,
|
||||
)
|
||||
);
|
||||
}
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | search section |
|
||||
// +-----------------------------------------------------------------------+
|
||||
else if ($page['section'] == 'search')
|
||||
{
|
||||
include_once( PHPWG_ROOT_PATH .'include/functions_search.inc.php' );
|
||||
|
||||
$search_result = get_search_results($page['search'], @$page['super_order_by'] );
|
||||
//save the details of the query search
|
||||
if ( isset($search_result['qs']) )
|
||||
{
|
||||
$page['qsearch_details'] = $search_result['qs'];
|
||||
}
|
||||
|
||||
$page = array_merge(
|
||||
$page,
|
||||
array(
|
||||
'items' => $search_result['items'],
|
||||
'title' => '<a href="'.duplicate_index_url(array('start'=>0)).'">'
|
||||
.l10n('Search results').'</a>',
|
||||
)
|
||||
);
|
||||
}
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | favorite section |
|
||||
// +-----------------------------------------------------------------------+
|
||||
else if ($page['section'] == 'favorites')
|
||||
{
|
||||
check_user_favorites();
|
||||
|
||||
$page = array_merge(
|
||||
$page,
|
||||
array(
|
||||
'title' => l10n('Favorites')
|
||||
)
|
||||
);
|
||||
|
||||
if (!empty($_GET['action']) && ($_GET['action'] == 'remove_all_from_favorites'))
|
||||
{
|
||||
$query = '
|
||||
DELETE FROM '.FAVORITES_TABLE.'
|
||||
WHERE user_id = '.$user['id'].'
|
||||
;';
|
||||
pwg_query($query);
|
||||
redirect(make_index_url( array('section'=>'favorites') ));
|
||||
}
|
||||
else
|
||||
{
|
||||
$query = '
|
||||
SELECT image_id
|
||||
FROM '.FAVORITES_TABLE.'
|
||||
INNER JOIN '.IMAGES_TABLE.' ON image_id = id
|
||||
WHERE user_id = '.$user['id'].'
|
||||
'.get_sql_condition_FandF(
|
||||
array(
|
||||
'visible_images' => 'id'
|
||||
),
|
||||
'AND'
|
||||
).'
|
||||
'.$conf['order_by'].'
|
||||
;';
|
||||
$page = array_merge(
|
||||
$page,
|
||||
array(
|
||||
'items' => query2array($query,null, 'image_id'),
|
||||
)
|
||||
);
|
||||
|
||||
if (count($page['items'])>0)
|
||||
{
|
||||
$template->assign(
|
||||
'favorite',
|
||||
array(
|
||||
'U_FAVORITE' => add_url_params(
|
||||
make_index_url( array('section'=>'favorites') ),
|
||||
array('action'=>'remove_all_from_favorites')
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | recent pictures section |
|
||||
// +-----------------------------------------------------------------------+
|
||||
else if ($page['section'] == 'recent_pics')
|
||||
{
|
||||
if ( !isset($page['super_order_by']) )
|
||||
{
|
||||
$conf['order_by'] = str_replace(
|
||||
'ORDER BY ',
|
||||
'ORDER BY date_available DESC,',
|
||||
$conf['order_by']
|
||||
);
|
||||
}
|
||||
|
||||
$query = '
|
||||
SELECT DISTINCT(id)
|
||||
FROM '.IMAGES_TABLE.'
|
||||
INNER JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON id = ic.image_id
|
||||
WHERE '
|
||||
.get_recent_photos_sql('date_available').'
|
||||
'.$forbidden
|
||||
.$conf['order_by'].'
|
||||
;';
|
||||
|
||||
$page = array_merge(
|
||||
$page,
|
||||
array(
|
||||
'title' => '<a href="'.duplicate_index_url(array('start'=>0)).'">'
|
||||
.l10n('Recent photos').'</a>',
|
||||
'items' => query2array($query,null, 'id'),
|
||||
)
|
||||
);
|
||||
}
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | recently updated categories section |
|
||||
// +-----------------------------------------------------------------------+
|
||||
else if ($page['section'] == 'recent_cats')
|
||||
{
|
||||
$page = array_merge(
|
||||
$page,
|
||||
array(
|
||||
'title' => l10n('Recent albums'),
|
||||
)
|
||||
);
|
||||
}
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | most visited section |
|
||||
// +-----------------------------------------------------------------------+
|
||||
else if ($page['section'] == 'most_visited')
|
||||
{
|
||||
$page['super_order_by'] = true;
|
||||
$conf['order_by'] = ' ORDER BY hit DESC, id DESC';
|
||||
|
||||
$query = '
|
||||
SELECT DISTINCT(id)
|
||||
FROM '.IMAGES_TABLE.'
|
||||
INNER JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON id = ic.image_id
|
||||
WHERE hit > 0
|
||||
'.$forbidden.'
|
||||
'.$conf['order_by'].'
|
||||
LIMIT '.$conf['top_number'].'
|
||||
;';
|
||||
|
||||
$page = array_merge(
|
||||
$page,
|
||||
array(
|
||||
'title' => '<a href="'.duplicate_index_url(array('start'=>0)).'">'
|
||||
.$conf['top_number'].' '.l10n('Most visited').'</a>',
|
||||
'items' => query2array($query,null, 'id'),
|
||||
)
|
||||
);
|
||||
}
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | best rated section |
|
||||
// +-----------------------------------------------------------------------+
|
||||
else if ($page['section'] == 'best_rated')
|
||||
{
|
||||
$page['super_order_by'] = true;
|
||||
$conf['order_by'] = ' ORDER BY rating_score DESC, id DESC';
|
||||
|
||||
$query ='
|
||||
SELECT DISTINCT(id)
|
||||
FROM '.IMAGES_TABLE.'
|
||||
INNER JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON id = ic.image_id
|
||||
WHERE rating_score IS NOT NULL
|
||||
'.$forbidden.'
|
||||
'.$conf['order_by'].'
|
||||
LIMIT '.$conf['top_number'].'
|
||||
;';
|
||||
$page = array_merge(
|
||||
$page,
|
||||
array(
|
||||
'title' => '<a href="'.duplicate_index_url(array('start'=>0)).'">'
|
||||
.$conf['top_number'].' '.l10n('Best rated').'</a>',
|
||||
'items' => query2array($query,null, 'id'),
|
||||
)
|
||||
);
|
||||
}
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | list section |
|
||||
// +-----------------------------------------------------------------------+
|
||||
else if ($page['section'] == 'list')
|
||||
{
|
||||
$query ='
|
||||
SELECT DISTINCT(id)
|
||||
FROM '.IMAGES_TABLE.'
|
||||
INNER JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON id = ic.image_id
|
||||
WHERE image_id IN ('.implode(',', $page['list']).')
|
||||
'.$forbidden.'
|
||||
'.$conf['order_by'].'
|
||||
;';
|
||||
|
||||
$page = array_merge(
|
||||
$page,
|
||||
array(
|
||||
'title' => '<a href="'.duplicate_index_url(array('start'=>0)).'">'
|
||||
.l10n('Random photos').'</a>',
|
||||
'items' => query2array($query,null, 'id'),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | chronology |
|
||||
// +-----------------------------------------------------------------------+
|
||||
if (isset($page['chronology_field']))
|
||||
{
|
||||
unset($page['is_homepage']);
|
||||
include_once( PHPWG_ROOT_PATH.'include/functions_calendar.inc.php' );
|
||||
initialize_calendar();
|
||||
}
|
||||
|
||||
// title update
|
||||
if (isset($page['title']))
|
||||
{
|
||||
$page['section_title'] = '<a href="'.get_gallery_home_url().'">'.l10n('Home').'</a>';
|
||||
if (!empty($page['title']))
|
||||
{
|
||||
$page['section_title'] .= $conf['level_separator'].$page['title'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$page['title'] = $page['section_title'];
|
||||
}
|
||||
}
|
||||
|
||||
// add meta robots noindex, nofollow to avoid unnecesary robot crawls
|
||||
$page['meta_robots']=array();
|
||||
if ( isset($page['chronology_field'])
|
||||
or ( isset($page['flat']) and isset($page['category']) )
|
||||
or 'list'==$page['section'] or 'recent_pics'==$page['section'] )
|
||||
{
|
||||
$page['meta_robots']=array('noindex'=>1, 'nofollow'=>1);
|
||||
}
|
||||
elseif ('tags'==$page['section'])
|
||||
{
|
||||
if ( count($page['tag_ids'])>1 )
|
||||
{
|
||||
$page['meta_robots']=array('noindex'=>1, 'nofollow'=>1);
|
||||
}
|
||||
}
|
||||
elseif ('recent_cats'==$page['section'])
|
||||
{
|
||||
$page['meta_robots']['noindex']=1;
|
||||
}
|
||||
elseif ('search'==$page['section'])
|
||||
{
|
||||
$page['meta_robots']['nofollow']=1;
|
||||
}
|
||||
if ( $filter['enabled'] )
|
||||
{
|
||||
$page['meta_robots']['noindex']=1;
|
||||
}
|
||||
|
||||
// see if we need a redirect because of a permalink
|
||||
if ( 'categories'==$page['section'] and isset($page['category']) )
|
||||
{
|
||||
$need_redirect=false;
|
||||
if ( empty($page['category']['permalink']) )
|
||||
{
|
||||
if ( $conf['category_url_style'] == 'id-name' and
|
||||
@$page['hit_by']['cat_url_name'] !== str2url($page['category']['name']) )
|
||||
{
|
||||
$need_redirect=true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( $page['category']['permalink'] !== @$page['hit_by']['cat_permalink'] )
|
||||
{
|
||||
$need_redirect=true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($need_redirect)
|
||||
{
|
||||
$redirect_url = script_basename()=='picture' ? duplicate_picture_url() : duplicate_index_url();
|
||||
|
||||
if (!headers_sent())
|
||||
{ // this is a permanent redirection
|
||||
set_status_header(301);
|
||||
redirect_http( $redirect_url );
|
||||
}
|
||||
redirect( $redirect_url );
|
||||
}
|
||||
unset( $need_redirect, $page['hit_by'] );
|
||||
}
|
||||
|
||||
trigger_notify('loc_end_section_init');
|
||||
?>
|
||||
22
zoesch.de/galerie/include/smarty/.gitattributes
vendored
Normal file
22
zoesch.de/galerie/include/smarty/.gitattributes
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
||||
|
||||
# Custom for Visual Studio
|
||||
*.cs diff=csharp
|
||||
*.sln merge=union
|
||||
*.csproj merge=union
|
||||
*.vbproj merge=union
|
||||
*.fsproj merge=union
|
||||
*.dbproj merge=union
|
||||
|
||||
# Standard to msysgit
|
||||
*.doc diff=astextplain
|
||||
*.DOC diff=astextplain
|
||||
*.docx diff=astextplain
|
||||
*.DOCX diff=astextplain
|
||||
*.dot diff=astextplain
|
||||
*.DOT diff=astextplain
|
||||
*.pdf diff=astextplain
|
||||
*.PDF diff=astextplain
|
||||
*.rtf diff=astextplain
|
||||
*.RTF diff=astextplain
|
||||
221
zoesch.de/galerie/include/smarty/.gitignore
vendored
Normal file
221
zoesch.de/galerie/include/smarty/.gitignore
vendored
Normal file
@@ -0,0 +1,221 @@
|
||||
#################
|
||||
## Eclipse
|
||||
#################
|
||||
|
||||
*.pydevproject
|
||||
.project
|
||||
.metadata
|
||||
bin/
|
||||
tmp/
|
||||
*.tmp
|
||||
*.bak
|
||||
*.swp
|
||||
*~.nib
|
||||
local.properties
|
||||
.classpath
|
||||
.settings/
|
||||
.loadpath
|
||||
|
||||
# External tool builders
|
||||
.externalToolBuilders/
|
||||
|
||||
# Locally stored "Eclipse launch configurations"
|
||||
*.launch
|
||||
|
||||
# CDT-specific
|
||||
.cproject
|
||||
|
||||
# PDT-specific
|
||||
.buildpath
|
||||
|
||||
|
||||
#################
|
||||
## Visual Studio
|
||||
#################
|
||||
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.sln.docstates
|
||||
|
||||
# Build results
|
||||
|
||||
[Dd]ebug/
|
||||
[Rr]elease/
|
||||
x64/
|
||||
build/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
*_i.c
|
||||
*_p.c
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.log
|
||||
*.scc
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# NCrunch
|
||||
*.ncrunch*
|
||||
.*crunch*.local.xml
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.Publish.xml
|
||||
*.pubxml
|
||||
|
||||
# NuGet Packages Directory
|
||||
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
|
||||
#packages/
|
||||
|
||||
# Windows Azure Build Output
|
||||
csx
|
||||
*.build.csdef
|
||||
|
||||
# Windows Store app package directory
|
||||
AppPackages/
|
||||
|
||||
# Others
|
||||
sql/
|
||||
*.Cache
|
||||
ClientBin/
|
||||
[Ss]tyle[Cc]op.*
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.[Pp]ublish.xml
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file to a newer
|
||||
# Visual Studio version. Backup files are not needed, because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
|
||||
# SQL Server files
|
||||
App_Data/*.mdf
|
||||
App_Data/*.ldf
|
||||
|
||||
#############
|
||||
## Windows detritus
|
||||
#############
|
||||
|
||||
# Windows image file caches
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
|
||||
# Folder config file
|
||||
Desktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Mac crap
|
||||
.DS_Store
|
||||
|
||||
|
||||
#############
|
||||
## Python
|
||||
#############
|
||||
|
||||
*.py[co]
|
||||
|
||||
# Packages
|
||||
*.egg
|
||||
*.egg-info
|
||||
dist/
|
||||
build/
|
||||
eggs/
|
||||
parts/
|
||||
var/
|
||||
sdist/
|
||||
develop-eggs/
|
||||
.installed.cfg
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
.coverage
|
||||
.tox
|
||||
|
||||
#Translations
|
||||
*.mo
|
||||
|
||||
#Mr Developer
|
||||
.mr.developer.cfg
|
||||
|
||||
.idea/
|
||||
|
||||
# Smarty
|
||||
lexer/*.php
|
||||
lexer/*.out
|
||||
25
zoesch.de/galerie/include/smarty/.travis.yml
Normal file
25
zoesch.de/galerie/include/smarty/.travis.yml
Normal file
@@ -0,0 +1,25 @@
|
||||
language: php
|
||||
|
||||
php:
|
||||
- 5.3
|
||||
- 5.4
|
||||
- 5.5
|
||||
- 5.6
|
||||
- 7.0
|
||||
- hhvm
|
||||
|
||||
matrix:
|
||||
allow_failures:
|
||||
- php: hhvm
|
||||
|
||||
before_script:
|
||||
- travis_retry composer self-update
|
||||
- travis_retry composer --prefer-source --dev install
|
||||
|
||||
install:
|
||||
- git clone --depth=50 --branch=master git://github.com/smarty-php/smarty-phpunit.git
|
||||
|
||||
script:
|
||||
- cd smarty-phpunit
|
||||
- phpunit ./
|
||||
|
||||
29
zoesch.de/galerie/include/smarty/COMPOSER_RELEASE_NOTES.txt
Normal file
29
zoesch.de/galerie/include/smarty/COMPOSER_RELEASE_NOTES.txt
Normal file
@@ -0,0 +1,29 @@
|
||||
|
||||
|
||||
Starting with Smarty 3.1.21 Composer has been configured to load the packages from github.
|
||||
|
||||
*******************************************************************************
|
||||
* *
|
||||
* NOTE: Because of this change you must clear your local composer cache with *
|
||||
* the "composer clearcache" command *
|
||||
* *
|
||||
*******************************************************************************
|
||||
|
||||
To get the latest stable version use
|
||||
"require": {
|
||||
"smarty/smarty": "~3.1"
|
||||
}
|
||||
in your composer.json file.
|
||||
|
||||
To get the trunk version use
|
||||
"require": {
|
||||
"smarty/smarty": "~3.1@dev"
|
||||
}
|
||||
|
||||
The "smarty/smarty" package will start at libs/.... subfolder.
|
||||
|
||||
To retrieve the development and documentation folders add
|
||||
"require-dev": {
|
||||
"smarty/smarty-dev": "~3.1@dev"
|
||||
}
|
||||
|
||||
165
zoesch.de/galerie/include/smarty/COPYING.lib
Normal file
165
zoesch.de/galerie/include/smarty/COPYING.lib
Normal file
@@ -0,0 +1,165 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
||||
@@ -0,0 +1,67 @@
|
||||
Starting with version 3.1.28 template inheritance is no longer a compile time process.
|
||||
All {block} tag parent/child relations are resolved at run time.
|
||||
This does resolve all known existing restrictions (see below).
|
||||
|
||||
The $smarty::$inheritance_merge_compiled_includes property has been removed.
|
||||
Any access to it is ignored.
|
||||
|
||||
This does enable some new features:
|
||||
|
||||
Any code outside root {block} tags in child templates is now executed but any output will be ignored.
|
||||
|
||||
{extends 'foo.tpl'}
|
||||
{$bar = 'on'} // assigns variable $bar seen in parent templates
|
||||
{block 'buh'}{/block}
|
||||
|
||||
{extends 'foo.tpl'}
|
||||
{$bar} // the output of variable bar is ignored
|
||||
{block 'buh'}{/block}
|
||||
|
||||
{block} tags can be dynamically en/disabled by conditions.
|
||||
|
||||
{block 'root'}
|
||||
{if $foo}
|
||||
{block 'v1'}
|
||||
....
|
||||
{/block}
|
||||
{else}
|
||||
{block 'v1'}
|
||||
....
|
||||
{/block}
|
||||
{/if}
|
||||
{/block}
|
||||
|
||||
|
||||
|
||||
THE FOLLOWING RESTRICTIONS ARE NO LONGER EXISTING:
|
||||
In Smarty 3.1 template inheritance is a compile time process. All the extending of {block} tags
|
||||
is done at compile time and the parent and child templates are compiled in a single compiled template.
|
||||
{include} subtemplate could also {block} tags. Such subtemplate could not compiled by it's own because
|
||||
it could be used in other context where the {block} extended with a different result. For that reasion
|
||||
the compiled code of {include} subtemplates gets also merged in compiled inheritance template.
|
||||
|
||||
Merging the code into a single compile template has some drawbacks.
|
||||
1. You could not use variable file names in {include} Smarty would use the {include} of compilation time.
|
||||
2. You could not use individual compile_id in {include}
|
||||
3. Seperate caching of subtemplate was not possible
|
||||
4. Any change of the template directory structure between calls was not necessarily seen.
|
||||
|
||||
Starting with 3.1.15 some of the above conditions got checked and resulted in an exception. It turned out
|
||||
that a couple of users did use some of above and now got exceptions.
|
||||
|
||||
To resolve this starting with 3.1.16 there is a new configuration parameter $inheritance_merge_compiled_includes.
|
||||
For most backward compatibility its default setting is true.
|
||||
With this setting all {include} subtemplate will be merge into the compiled inheritance template, but the above cases
|
||||
could be rejected by exception.
|
||||
|
||||
|
||||
If $smarty->inheritance_merge_compiled_includes = false; {include} subtemplate will not be merged.
|
||||
You must now manually merge all {include} subtemplate which do contain {block} tags. This is done by setting the "inline" option.
|
||||
{include file='foo.bar' inline}
|
||||
|
||||
1. In case of a variable file name like {include file=$foo inline} you must use the variable in a compile_id $smarty->compile_id = $foo;
|
||||
2. If you use individual compile_id in {include file='foo.tpl' compile_id=$bar inline} it must be used in the
|
||||
global compile_id as well $smarty->compile_id = $bar;
|
||||
3. If call templates with different template_dir configurations and a parent could same named child template from different folders
|
||||
you must make the folder name part of the compile_id.
|
||||
|
||||
133
zoesch.de/galerie/include/smarty/NEW_FEATURES.txt
Normal file
133
zoesch.de/galerie/include/smarty/NEW_FEATURES.txt
Normal file
@@ -0,0 +1,133 @@
|
||||
|
||||
|
||||
This file contains a brief description of new features which have been added to Smarty 3.1
|
||||
|
||||
Smarty 3.1.28
|
||||
|
||||
OPCACHE
|
||||
=======
|
||||
Smarty does now invalidate automatically updated and cleared compiled or cached template files in OPCACHE.
|
||||
Correct operation is no longer dependent on OPCACHE configuration settings.
|
||||
|
||||
Template inheritance
|
||||
====================
|
||||
Template inheritance is now processed in run time.
|
||||
See the INHERITANCE_RELEASE_NOTES
|
||||
|
||||
Modifier regex_replace
|
||||
======================
|
||||
An optional limit parameter was added
|
||||
|
||||
fetch() and display()
|
||||
=====================
|
||||
The fetch() and display() methods of the template object accept now optionally the same parameter
|
||||
as the corresponding Smarty methods to get the content of another template.
|
||||
Example:
|
||||
$template->display(); Does display template of template object
|
||||
$template->display('foo.tpl'); Does display template 'foo.bar'
|
||||
|
||||
File: resource
|
||||
==============
|
||||
Multiple template_dir entries can now be selected by a comma separated list of indices.
|
||||
The template_dir array is searched in the order of the indices. (Could be used to change the default search order)
|
||||
Example:
|
||||
$smarty->display('[1],[0]foo.bar');
|
||||
|
||||
Filter support
|
||||
==============
|
||||
Optional filter names
|
||||
An optional filter name was added to $smarty->registerFilter(). It can be used to unregister a filter by name.
|
||||
- $smarty->registerFilter('output', $callback, 'name');
|
||||
$smarty->unregister('output', 'name');
|
||||
|
||||
Closures
|
||||
$smarty->registerFilter() does now accept closures.
|
||||
- $smarty->registerFilter('pre', function($source) {return $source;});
|
||||
If no optional filter name was specified it gets the default name 'closure'.
|
||||
If you register multiple closures register each with a unique filter name.
|
||||
- $smarty->registerFilter('pre', function($source) {return $source;}, 'closure_1');
|
||||
- $smarty->registerFilter('pre', function($source) {return $source;}, 'closure_2');
|
||||
|
||||
|
||||
Smarty 3.1.22
|
||||
|
||||
Namespace support within templates
|
||||
==================================
|
||||
Within templates you can now use namespace specifications on:
|
||||
- Constants like foo\bar\FOO
|
||||
- Class names like foo\bar\Baz::FOO, foo\bar\Baz::$foo, foo\bar\Baz::foo()
|
||||
- PHP function names like foo\bar\baz()
|
||||
|
||||
Security
|
||||
========
|
||||
- disable special $smarty variable -
|
||||
The Smarty_Security class has the new property $disabled_special_smarty_vars.
|
||||
It's an array which can be loaded with the $smarty special variable names like
|
||||
'template_object', 'template', 'current_dir' and others which will be disabled.
|
||||
Note: That this security check is performed at compile time.
|
||||
|
||||
- limit template nesting -
|
||||
Property $max_template_nesting of Smarty_Security does set the maximum template nesting level.
|
||||
The main template is level 1. The nesting level is checked at run time. When the maximum will be exceeded
|
||||
an Exception will be thrown. The default setting is 0 which does disable this check.
|
||||
|
||||
- trusted static methods -
|
||||
The Smarty_Security class has the new property $trusted_static_methods to restrict access to static methods.
|
||||
It's an nested array of trusted class and method names.
|
||||
Format:
|
||||
array (
|
||||
'class_1' => array('method_1', 'method_2'), // allowed methods
|
||||
'class_2' => array(), // all methods of class allowed
|
||||
)
|
||||
To disable access for all methods of all classes set $trusted_static_methods = null;
|
||||
The default value is an empty array() which does enables all methods of all classes, but for backward compatibility
|
||||
the setting of $static_classes will be checked.
|
||||
Note: That this security check is performed at compile time.
|
||||
|
||||
- trusted static properties -
|
||||
The Smarty_Security class has the new property $trusted_static_properties to restrict access to static properties.
|
||||
It's an nested array of trusted class and property names.
|
||||
Format:
|
||||
array (
|
||||
'class_1' => array('prop_1', 'prop_2'), // allowed properties listed
|
||||
'class_2' => array(), // all properties of class allowed
|
||||
}
|
||||
To disable access for all properties of all classes set $trusted_static_properties = null;
|
||||
The default value is an empty array() which does enables all properties of all classes, but for backward compatibility
|
||||
the setting of $static_classes will be checked.
|
||||
Note: That this security check is performed at compile time.
|
||||
|
||||
- trusted constants .
|
||||
The Smarty_Security class has the new property $trusted_constants to restrict access to constants.
|
||||
It's an array of trusted constant names.
|
||||
Format:
|
||||
array (
|
||||
'SMARTY_DIR' , // allowed constant
|
||||
}
|
||||
If the array is empty (default) the usage of constants can be controlled with the
|
||||
Smarty_Security::$allow_constants property (default true)
|
||||
|
||||
|
||||
|
||||
Compiled Templates
|
||||
==================
|
||||
Smarty does now automatically detects a change of the $merge_compiled_includes and $escape_html
|
||||
property and creates different compiled templates files depending on the setting.
|
||||
|
||||
Same applies to config files and the $config_overwrite, $config_booleanize and
|
||||
$config_read_hidden properties.
|
||||
|
||||
Debugging
|
||||
=========
|
||||
The layout of the debug window has been changed for better readability
|
||||
|
||||
New class constants
|
||||
Smarty::DEBUG_OFF
|
||||
Smarty::DEBUG_ON
|
||||
Smarty::DEBUG_INDIVIDUAL
|
||||
have been introduced for setting the $debugging property.
|
||||
|
||||
Smarty::DEBUG_INDIVIDUAL will create for each display() and fetch() call an individual debug window.
|
||||
|
||||
.
|
||||
|
||||
575
zoesch.de/galerie/include/smarty/README
Normal file
575
zoesch.de/galerie/include/smarty/README
Normal file
@@ -0,0 +1,575 @@
|
||||
Smarty 3.x
|
||||
|
||||
Author: Monte Ohrt <monte at ohrt dot com >
|
||||
Author: Uwe Tews
|
||||
|
||||
AN INTRODUCTION TO SMARTY 3
|
||||
|
||||
NOTICE FOR 3.1 release:
|
||||
|
||||
Please see the SMARTY_3.1_NOTES.txt file that comes with the distribution.
|
||||
|
||||
NOTICE for 3.0.5 release:
|
||||
|
||||
Smarty now follows the PHP error_reporting level by default. If PHP does not mask E_NOTICE and you try to access an unset template variable, you will now get an E_NOTICE warning. To revert to the old behavior:
|
||||
|
||||
$smarty->error_reporting = E_ALL & ~E_NOTICE;
|
||||
|
||||
NOTICE for 3.0 release:
|
||||
|
||||
IMPORTANT: Some API adjustments have been made between the RC4 and 3.0 release.
|
||||
We felt it is better to make these now instead of after a 3.0 release, then have to
|
||||
immediately deprecate APIs in 3.1. Online documentation has been updated
|
||||
to reflect these changes. Specifically:
|
||||
|
||||
---- API CHANGES RC4 -> 3.0 ----
|
||||
|
||||
$smarty->register->*
|
||||
$smarty->unregister->*
|
||||
$smarty->utility->*
|
||||
$samrty->cache->*
|
||||
|
||||
Have all been changed to local method calls such as:
|
||||
|
||||
$smarty->clearAllCache()
|
||||
$smarty->registerFoo()
|
||||
$smarty->unregisterFoo()
|
||||
$smarty->testInstall()
|
||||
etc.
|
||||
|
||||
Registration of function, block, compiler, and modifier plugins have been
|
||||
consolidated under two API calls:
|
||||
|
||||
$smarty->registerPlugin(...)
|
||||
$smarty->unregisterPlugin(...)
|
||||
|
||||
Registration of pre, post, output and variable filters have been
|
||||
consolidated under two API calls:
|
||||
|
||||
$smarty->registerFilter(...)
|
||||
$smarty->unregisterFilter(...)
|
||||
|
||||
Please refer to the online documentation for all specific changes:
|
||||
|
||||
http://www.smarty.net/documentation
|
||||
|
||||
----
|
||||
|
||||
The Smarty 3 API has been refactored to a syntax geared
|
||||
for consistency and modularity. The Smarty 2 API syntax is still supported, but
|
||||
will throw a deprecation notice. You can disable the notices, but it is highly
|
||||
recommended to adjust your syntax to Smarty 3, as the Smarty 2 syntax must run
|
||||
through an extra rerouting wrapper.
|
||||
|
||||
Basically, all Smarty methods now follow the "fooBarBaz" camel case syntax. Also,
|
||||
all Smarty properties now have getters and setters. So for example, the property
|
||||
$smarty->cache_dir can be set with $smarty->setCacheDir('foo/') and can be
|
||||
retrieved with $smarty->getCacheDir().
|
||||
|
||||
Some of the Smarty 3 APIs have been revoked such as the "is*" methods that were
|
||||
just duplicate functions of the now available "get*" methods.
|
||||
|
||||
Here is a rundown of the Smarty 3 API:
|
||||
|
||||
$smarty->fetch($template, $cache_id = null, $compile_id = null, $parent = null)
|
||||
$smarty->display($template, $cache_id = null, $compile_id = null, $parent = null)
|
||||
$smarty->isCached($template, $cache_id = null, $compile_id = null)
|
||||
$smarty->createData($parent = null)
|
||||
$smarty->createTemplate($template, $cache_id = null, $compile_id = null, $parent = null)
|
||||
$smarty->enableSecurity()
|
||||
$smarty->disableSecurity()
|
||||
$smarty->setTemplateDir($template_dir)
|
||||
$smarty->addTemplateDir($template_dir)
|
||||
$smarty->templateExists($resource_name)
|
||||
$smarty->loadPlugin($plugin_name, $check = true)
|
||||
$smarty->loadFilter($type, $name)
|
||||
$smarty->setExceptionHandler($handler)
|
||||
$smarty->addPluginsDir($plugins_dir)
|
||||
$smarty->getGlobal($varname = null)
|
||||
$smarty->getRegisteredObject($name)
|
||||
$smarty->getDebugTemplate()
|
||||
$smarty->setDebugTemplate($tpl_name)
|
||||
$smarty->assign($tpl_var, $value = null, $nocache = false)
|
||||
$smarty->assignGlobal($varname, $value = null, $nocache = false)
|
||||
$smarty->assignByRef($tpl_var, &$value, $nocache = false)
|
||||
$smarty->append($tpl_var, $value = null, $merge = false, $nocache = false)
|
||||
$smarty->appendByRef($tpl_var, &$value, $merge = false)
|
||||
$smarty->clearAssign($tpl_var)
|
||||
$smarty->clearAllAssign()
|
||||
$smarty->configLoad($config_file, $sections = null)
|
||||
$smarty->getVariable($variable, $_ptr = null, $search_parents = true, $error_enable = true)
|
||||
$smarty->getConfigVariable($variable)
|
||||
$smarty->getStreamVariable($variable)
|
||||
$smarty->getConfigVars($varname = null)
|
||||
$smarty->clearConfig($varname = null)
|
||||
$smarty->getTemplateVars($varname = null, $_ptr = null, $search_parents = true)
|
||||
$smarty->clearAllCache($exp_time = null, $type = null)
|
||||
$smarty->clearCache($template_name, $cache_id = null, $compile_id = null, $exp_time = null, $type = null)
|
||||
|
||||
$smarty->registerPlugin($type, $tag, $callback, $cacheable = true, $cache_attr = array())
|
||||
|
||||
$smarty->registerObject($object_name, $object_impl, $allowed = array(), $smarty_args = true, $block_methods = array())
|
||||
|
||||
$smarty->registerFilter($type, $function_name)
|
||||
$smarty->registerResource($resource_type, $function_names)
|
||||
$smarty->registerDefaultPluginHandler($function_name)
|
||||
$smarty->registerDefaultTemplateHandler($function_name)
|
||||
|
||||
$smarty->unregisterPlugin($type, $tag)
|
||||
$smarty->unregisterObject($object_name)
|
||||
$smarty->unregisterFilter($type, $function_name)
|
||||
$smarty->unregisterResource($resource_type)
|
||||
|
||||
$smarty->compileAllTemplates($extension = '.tpl', $force_compile = false, $time_limit = 0, $max_errors = null)
|
||||
$smarty->clearCompiledTemplate($resource_name = null, $compile_id = null, $exp_time = null)
|
||||
$smarty->testInstall()
|
||||
|
||||
// then all the getters/setters, available for all properties. Here are a few:
|
||||
|
||||
$caching = $smarty->getCaching(); // get $smarty->caching
|
||||
$smarty->setCaching(true); // set $smarty->caching
|
||||
$smarty->setDeprecationNotices(false); // set $smarty->deprecation_notices
|
||||
$smarty->setCacheId($id); // set $smarty->cache_id
|
||||
$debugging = $smarty->getDebugging(); // get $smarty->debugging
|
||||
|
||||
|
||||
FILE STRUCTURE
|
||||
|
||||
The Smarty 3 file structure is similar to Smarty 2:
|
||||
|
||||
/libs/
|
||||
Smarty.class.php
|
||||
/libs/sysplugins/
|
||||
internal.*
|
||||
/libs/plugins/
|
||||
function.mailto.php
|
||||
modifier.escape.php
|
||||
...
|
||||
|
||||
A lot of Smarty 3 core functionality lies in the sysplugins directory; you do
|
||||
not need to change any files here. The /libs/plugins/ folder is where Smarty
|
||||
plugins are located. You can add your own here, or create a separate plugin
|
||||
directory, just the same as Smarty 2. You will still need to create your own
|
||||
/cache/, /templates/, /templates_c/, /configs/ folders. Be sure /cache/ and
|
||||
/templates_c/ are writable.
|
||||
|
||||
The typical way to use Smarty 3 should also look familiar:
|
||||
|
||||
require('Smarty.class.php');
|
||||
$smarty = new Smarty;
|
||||
$smarty->assign('foo','bar');
|
||||
$smarty->display('index.tpl');
|
||||
|
||||
|
||||
However, Smarty 3 works completely different on the inside. Smarty 3 is mostly
|
||||
backward compatible with Smarty 2, except for the following items:
|
||||
|
||||
*) Smarty 3 is PHP 5 only. It will not work with PHP 4.
|
||||
*) The {php} tag is disabled by default. Enable with $smarty->allow_php_tag=true.
|
||||
*) Delimiters surrounded by whitespace are no longer treated as Smarty tags.
|
||||
Therefore, { foo } will not compile as a tag, you must use {foo}. This change
|
||||
Makes Javascript/CSS easier to work with, eliminating the need for {literal}.
|
||||
This can be disabled by setting $smarty->auto_literal = false;
|
||||
*) The Smarty 3 API is a bit different. Many Smarty 2 API calls are deprecated
|
||||
but still work. You will want to update your calls to Smarty 3 for maximum
|
||||
efficiency.
|
||||
|
||||
|
||||
There are many things that are new to Smarty 3. Here are the notable items:
|
||||
|
||||
LEXER/PARSER
|
||||
============
|
||||
|
||||
Smarty 3 now uses a lexing tokenizer for its parser/compiler. Basically, this
|
||||
means Smarty has some syntax additions that make life easier such as in-template
|
||||
math, shorter/intuitive function parameter options, infinite function recursion,
|
||||
more accurate error handling, etc.
|
||||
|
||||
|
||||
WHAT IS NEW IN SMARTY TEMPLATE SYNTAX
|
||||
=====================================
|
||||
|
||||
Smarty 3 allows expressions almost anywhere. Expressions can include PHP
|
||||
functions as long as they are not disabled by the security policy, object
|
||||
methods and properties, etc. The {math} plugin is no longer necessary but
|
||||
is still supported for BC.
|
||||
|
||||
Examples:
|
||||
{$x+$y} will output the sum of x and y.
|
||||
{$foo = strlen($bar)} function in assignment
|
||||
{assign var=foo value= $x+$y} in attributes
|
||||
{$foo = myfunct( ($x+$y)*3 )} as function parameter
|
||||
{$foo[$x+3]} as array index
|
||||
|
||||
Smarty tags can be used as values within other tags.
|
||||
Example: {$foo={counter}+3}
|
||||
|
||||
Smarty tags can also be used inside double quoted strings.
|
||||
Example: {$foo="this is message {counter}"}
|
||||
|
||||
You can define arrays within templates.
|
||||
Examples:
|
||||
{assign var=foo value=[1,2,3]}
|
||||
{assign var=foo value=['y'=>'yellow','b'=>'blue']}
|
||||
Arrays can be nested.
|
||||
{assign var=foo value=[1,[9,8],3]}
|
||||
|
||||
There is a new short syntax supported for assigning variables.
|
||||
Example: {$foo=$bar+2}
|
||||
|
||||
You can assign a value to a specific array element. If the variable exists but
|
||||
is not an array, it is converted to an array before the new values are assigned.
|
||||
Examples:
|
||||
{$foo['bar']=1}
|
||||
{$foo['bar']['blar']=1}
|
||||
|
||||
You can append values to an array. If the variable exists but is not an array,
|
||||
it is converted to an array before the new values are assigned.
|
||||
Example: {$foo[]=1}
|
||||
|
||||
You can use a PHP-like syntax for accessing array elements, as well as the
|
||||
original "dot" notation.
|
||||
Examples:
|
||||
{$foo[1]} normal access
|
||||
{$foo['bar']}
|
||||
{$foo['bar'][1]}
|
||||
{$foo[$x+$x]} index may contain any expression
|
||||
{$foo[$bar[1]]} nested index
|
||||
{$foo[section_name]} smarty section access, not array access!
|
||||
|
||||
The original "dot" notation stays, and with improvements.
|
||||
Examples:
|
||||
{$foo.a.b.c} => $foo['a']['b']['c']
|
||||
{$foo.a.$b.c} => $foo['a'][$b]['c'] with variable index
|
||||
{$foo.a.{$b+4}.c} => $foo['a'][$b+4]['c'] with expression as index
|
||||
{$foo.a.{$b.c}} => $foo['a'][$b['c']] with nested index
|
||||
|
||||
note that { and } are used to address ambiguties when nesting the dot syntax.
|
||||
|
||||
Variable names themselves can be variable and contain expressions.
|
||||
Examples:
|
||||
$foo normal variable
|
||||
$foo_{$bar} variable name containing other variable
|
||||
$foo_{$x+$y} variable name containing expressions
|
||||
$foo_{$bar}_buh_{$blar} variable name with multiple segments
|
||||
{$foo_{$x}} will output the variable $foo_1 if $x has a value of 1.
|
||||
|
||||
Object method chaining is implemented.
|
||||
Example: {$object->method1($x)->method2($y)}
|
||||
|
||||
{for} tag added for looping (replacement for {section} tag):
|
||||
{for $x=0, $y=count($foo); $x<$y; $x++} .... {/for}
|
||||
Any number of statements can be used separated by comma as the first
|
||||
inital expression at {for}.
|
||||
|
||||
{for $x = $start to $end step $step} ... {/for}is in the SVN now .
|
||||
You can use also
|
||||
{for $x = $start to $end} ... {/for}
|
||||
In this case the step value will be automaticall 1 or -1 depending on the start and end values.
|
||||
Instead of $start and $end you can use any valid expression.
|
||||
Inside the loop the following special vars can be accessed:
|
||||
$x@iteration = number of iteration
|
||||
$x@total = total number of iterations
|
||||
$x@first = true on first iteration
|
||||
$x@last = true on last iteration
|
||||
|
||||
|
||||
The Smarty 2 {section} syntax is still supported.
|
||||
|
||||
New shorter {foreach} syntax to loop over an array.
|
||||
Example: {foreach $myarray as $var}...{/foreach}
|
||||
|
||||
Within the foreach loop, properties are access via:
|
||||
|
||||
$var@key foreach $var array key
|
||||
$var@iteration foreach current iteration count (1,2,3...)
|
||||
$var@index foreach current index count (0,1,2...)
|
||||
$var@total foreach $var array total
|
||||
$var@first true on first iteration
|
||||
$var@last true on last iteration
|
||||
|
||||
The Smarty 2 {foreach} tag syntax is still supported.
|
||||
|
||||
NOTE: {$bar[foo]} still indicates a variable inside of a {section} named foo.
|
||||
If you want to access an array element with index foo, you must use quotes
|
||||
such as {$bar['foo']}, or use the dot syntax {$bar.foo}.
|
||||
|
||||
while block tag is now implemented:
|
||||
{while $foo}...{/while}
|
||||
{while $x lt 10}...{/while}
|
||||
|
||||
Direct access to PHP functions:
|
||||
Just as you can use PHP functions as modifiers directly, you can now access
|
||||
PHP functions directly, provided they are permitted by security settings:
|
||||
{time()}
|
||||
|
||||
There is a new {function}...{/function} block tag to implement a template function.
|
||||
This enables reuse of code sequences like a plugin function. It can call itself recursively.
|
||||
Template function must be called with the new {call name=foo...} tag.
|
||||
|
||||
Example:
|
||||
|
||||
Template file:
|
||||
{function name=menu level=0}
|
||||
<ul class="level{$level}">
|
||||
{foreach $data as $entry}
|
||||
{if is_array($entry)}
|
||||
<li>{$entry@key}</li>
|
||||
{call name=menu data=$entry level=$level+1}
|
||||
{else}
|
||||
<li>{$entry}</li>
|
||||
{/if}
|
||||
{/foreach}
|
||||
</ul>
|
||||
{/function}
|
||||
|
||||
{$menu = ['item1','item2','item3' => ['item3-1','item3-2','item3-3' =>
|
||||
['item3-3-1','item3-3-2']],'item4']}
|
||||
|
||||
{call name=menu data=$menu}
|
||||
|
||||
|
||||
Generated output:
|
||||
* item1
|
||||
* item2
|
||||
* item3
|
||||
o item3-1
|
||||
o item3-2
|
||||
o item3-3
|
||||
+ item3-3-1
|
||||
+ item3-3-2
|
||||
* item4
|
||||
|
||||
The function tag itself must have the "name" attribute. This name is the tag
|
||||
name when calling the function. The function tag may have any number of
|
||||
additional attributes. These will be default settings for local variables.
|
||||
|
||||
New {nocache} block function:
|
||||
{nocache}...{/nocache} will declare a section of the template to be non-cached
|
||||
when template caching is enabled.
|
||||
|
||||
New nocache attribute:
|
||||
You can declare variable/function output as non-cached with the nocache attribute.
|
||||
Examples:
|
||||
|
||||
{$foo nocache=true}
|
||||
{$foo nocache} /* same */
|
||||
|
||||
{foo bar="baz" nocache=true}
|
||||
{foo bar="baz" nocache} /* same */
|
||||
|
||||
{time() nocache=true}
|
||||
{time() nocache} /* same */
|
||||
|
||||
Or you can also assign the variable in your script as nocache:
|
||||
$smarty->assign('foo',$something,true); // third param is nocache setting
|
||||
{$foo} /* non-cached */
|
||||
|
||||
$smarty.current_dir returns the directory name of the current template.
|
||||
|
||||
You can use strings directly as templates with the "string" resource type.
|
||||
Examples:
|
||||
$smarty->display('string:This is my template, {$foo}!'); // php
|
||||
{include file="string:This is my template, {$foo}!"} // template
|
||||
|
||||
|
||||
|
||||
VARIABLE SCOPE / VARIABLE STORAGE
|
||||
=================================
|
||||
|
||||
In Smarty 2, all assigned variables were stored within the Smarty object.
|
||||
Therefore, all variables assigned in PHP were accessible by all subsequent
|
||||
fetch and display template calls.
|
||||
|
||||
In Smarty 3, we have the choice to assign variables to the main Smarty object,
|
||||
to user-created data objects, and to user-created template objects.
|
||||
These objects can be chained. The object at the end of a chain can access all
|
||||
variables belonging to that template and all variables within the parent objects.
|
||||
The Smarty object can only be the root of a chain, but a chain can be isolated
|
||||
from the Smarty object.
|
||||
|
||||
All known Smarty assignment interfaces will work on the data and template objects.
|
||||
|
||||
Besides the above mentioned objects, there is also a special storage area for
|
||||
global variables.
|
||||
|
||||
A Smarty data object can be created as follows:
|
||||
$data = $smarty->createData(); // create root data object
|
||||
$data->assign('foo','bar'); // assign variables as usual
|
||||
$data->config_load('my.conf'); // load config file
|
||||
|
||||
$data= $smarty->createData($smarty); // create data object having a parent link to
|
||||
the Smarty object
|
||||
|
||||
$data2= $smarty->createData($data); // create data object having a parent link to
|
||||
the $data data object
|
||||
|
||||
A template object can be created by using the createTemplate method. It has the
|
||||
same parameter assignments as the fetch() or display() method.
|
||||
Function definition:
|
||||
function createTemplate($template, $cache_id = null, $compile_id = null, $parent = null)
|
||||
|
||||
The first parameter can be a template name, a smarty object or a data object.
|
||||
|
||||
Examples:
|
||||
$tpl = $smarty->createTemplate('mytpl.tpl'); // create template object not linked to any parent
|
||||
$tpl->assign('foo','bar'); // directly assign variables
|
||||
$tpl->config_load('my.conf'); // load config file
|
||||
|
||||
$tpl = $smarty->createTemplate('mytpl.tpl',$smarty); // create template having a parent link to the Smarty object
|
||||
$tpl = $smarty->createTemplate('mytpl.tpl',$data); // create template having a parent link to the $data object
|
||||
|
||||
The standard fetch() and display() methods will implicitly create a template object.
|
||||
If the $parent parameter is not specified in these method calls, the template object
|
||||
is will link back to the Smarty object as it's parent.
|
||||
|
||||
If a template is called by an {include...} tag from another template, the
|
||||
subtemplate links back to the calling template as it's parent.
|
||||
|
||||
All variables assigned locally or from a parent template are accessible. If the
|
||||
template creates or modifies a variable by using the {assign var=foo...} or
|
||||
{$foo=...} tags, these new values are only known locally (local scope). When the
|
||||
template exits, none of the new variables or modifications can be seen in the
|
||||
parent template(s). This is same behavior as in Smarty 2.
|
||||
|
||||
With Smarty 3, we can assign variables with a scope attribute which allows the
|
||||
availablility of these new variables or modifications globally (ie in the parent
|
||||
templates.)
|
||||
|
||||
Possible scopes are local, parent, root and global.
|
||||
Examples:
|
||||
{assign var=foo value='bar'} // no scope is specified, the default 'local'
|
||||
{$foo='bar'} // same, local scope
|
||||
{assign var=foo value='bar' scope='local'} // same, local scope
|
||||
|
||||
{assign var=foo value='bar' scope='parent'} // Values will be available to the parent object
|
||||
{$foo='bar' scope='parent'} // (normally the calling template)
|
||||
|
||||
{assign var=foo value='bar' scope='root'} // Values will be exported up to the root object, so they can
|
||||
{$foo='bar' scope='root'} // be seen from all templates using the same root.
|
||||
|
||||
{assign var=foo value='bar' scope='global'} // Values will be exported to global variable storage,
|
||||
{$foo='bar' scope='global'} // they are available to any and all templates.
|
||||
|
||||
|
||||
The scope attribute can also be attached to the {include...} tag. In this case,
|
||||
the specified scope will be the default scope for all assignments within the
|
||||
included template.
|
||||
|
||||
|
||||
PLUGINS
|
||||
=======
|
||||
|
||||
Smarty 3 plugins follow the same coding rules as in Smarty 2.
|
||||
The main difference is that the template object is now passed in place of the smarty object.
|
||||
The smarty object can be still be accessed through $template->smarty.
|
||||
|
||||
smarty_plugintype_name (array $params, Smarty_Internal_Template $template)
|
||||
|
||||
The Smarty 2 plugins are still compatible as long as they do not make use of specific Smarty 2 internals.
|
||||
|
||||
|
||||
TEMPLATE INHERITANCE:
|
||||
=====================
|
||||
|
||||
With template inheritance you can define blocks, which are areas that can be
|
||||
overriden by child templates, so your templates could look like this:
|
||||
|
||||
parent.tpl:
|
||||
<html>
|
||||
<head>
|
||||
<title>{block name='title'}My site name{/block}</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>{block name='page-title'}Default page title{/block}</h1>
|
||||
<div id="content">
|
||||
{block name='content'}
|
||||
Default content
|
||||
{/block}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
child.tpl:
|
||||
{extends file='parent.tpl'}
|
||||
{block name='title'}
|
||||
Child title
|
||||
{/block}
|
||||
|
||||
grandchild.tpl:
|
||||
{extends file='child.tpl'}
|
||||
{block name='title'}Home - {$smarty.block.parent}{/block}
|
||||
{block name='page-title'}My home{/block}
|
||||
{block name='content'}
|
||||
{foreach $images as $img}
|
||||
<img src="{$img.url}" alt="{$img.description}" />
|
||||
{/foreach}
|
||||
{/block}
|
||||
|
||||
We redefined all the blocks here, however in the title block we used {$smarty.block.parent},
|
||||
which tells Smarty to insert the default content from the parent template in its place.
|
||||
The content block was overriden to display the image files, and page-title has also be
|
||||
overriden to display a completely different title.
|
||||
|
||||
If we render grandchild.tpl we will get this:
|
||||
<html>
|
||||
<head>
|
||||
<title>Home - Child title</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>My home</h1>
|
||||
<div id="content">
|
||||
<img src="/example.jpg" alt="image" />
|
||||
<img src="/example2.jpg" alt="image" />
|
||||
<img src="/example3.jpg" alt="image" />
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
NOTE: In the child templates everything outside the {extends} or {block} tag sections
|
||||
is ignored.
|
||||
|
||||
The inheritance tree can be as big as you want (meaning you can extend a file that
|
||||
extends another one that extends another one and so on..), but be aware that all files
|
||||
have to be checked for modifications at runtime so the more inheritance the more overhead you add.
|
||||
|
||||
Instead of defining the parent/child relationships with the {extends} tag in the child template you
|
||||
can use the resource as follow:
|
||||
|
||||
$smarty->display('extends:parent.tpl|child.tpl|grandchild.tpl');
|
||||
|
||||
Child {block} tags may optionally have a append or prepend attribute. In this case the parent block content
|
||||
is appended or prepended to the child block content.
|
||||
|
||||
{block name='title' append} My title {/block}
|
||||
|
||||
|
||||
PHP STREAMS:
|
||||
============
|
||||
|
||||
(see online documentation)
|
||||
|
||||
VARIBLE FILTERS:
|
||||
================
|
||||
|
||||
(see online documentation)
|
||||
|
||||
|
||||
STATIC CLASS ACCESS AND NAMESPACE SUPPORT
|
||||
=========================================
|
||||
|
||||
You can register a class with optional namespace for the use in the template like:
|
||||
|
||||
$smarty->register->templateClass('foo','name\name2\myclass');
|
||||
|
||||
In the template you can use it like this:
|
||||
{foo::method()} etc.
|
||||
|
||||
|
||||
=======================
|
||||
|
||||
Please look through it and send any questions/suggestions/etc to the forums.
|
||||
|
||||
http://www.phpinsider.com/smarty-forum/viewtopic.php?t=14168
|
||||
|
||||
Monte and Uwe
|
||||
65
zoesch.de/galerie/include/smarty/README.md
Normal file
65
zoesch.de/galerie/include/smarty/README.md
Normal file
@@ -0,0 +1,65 @@
|
||||
#Smarty 3 template engine
|
||||
##Distribution repository
|
||||
|
||||
> Smarty 3.1.28 introduces run time template inheritance
|
||||
|
||||
> Read the NEW_FEATURES and INHERITANCE_RELEASE_NOTES file for recent extensions to Smarty 3.1 functionality
|
||||
|
||||
Smarty versions 3.1.11 or later are now on github and can be installed with Composer.
|
||||
|
||||
|
||||
The "smarty/smarty" package will start at libs/.... subfolder.
|
||||
|
||||
To get the latest stable version of Smarty 3.1 use
|
||||
|
||||
```json
|
||||
"require": {
|
||||
"smarty/smarty": "~3.1"
|
||||
}
|
||||
```
|
||||
|
||||
in your composer.json file.
|
||||
|
||||
To get the trunk version use
|
||||
|
||||
```json
|
||||
"require": {
|
||||
"smarty/smarty": "~3.1@dev"
|
||||
}
|
||||
```
|
||||
|
||||
For a specific version use something like
|
||||
|
||||
```json
|
||||
"require": {
|
||||
"smarty/smarty": "3.1.19"
|
||||
}
|
||||
```
|
||||
|
||||
PHPUnit test can be installed by corresponding composer entries like
|
||||
|
||||
```json
|
||||
"require": {
|
||||
"smarty/smarty-phpunit": "3.1.19"
|
||||
}
|
||||
```
|
||||
|
||||
Similar applies for the lexer/parser generator
|
||||
|
||||
```json
|
||||
"require": {
|
||||
"smarty/smarty-lexer": "3.1.19"
|
||||
}
|
||||
```
|
||||
|
||||
Or you could use
|
||||
|
||||
```json
|
||||
"require": {
|
||||
"smarty/smarty-dev": "3.1.19"
|
||||
}
|
||||
```
|
||||
|
||||
Which is a wrapper to install all 3 packages
|
||||
|
||||
Composer can also be used for Smarty2 versions 2.6.24 to 2.6.28
|
||||
109
zoesch.de/galerie/include/smarty/SMARTY_2_BC_NOTES.txt
Normal file
109
zoesch.de/galerie/include/smarty/SMARTY_2_BC_NOTES.txt
Normal file
@@ -0,0 +1,109 @@
|
||||
= Known incompatibilities with Smarty 2 =
|
||||
|
||||
== Syntax ==
|
||||
|
||||
Smarty 3 API has a new syntax. Much of the Smarty 2 syntax is supported
|
||||
by a wrapper but deprecated. See the README that comes with Smarty 3 for more
|
||||
information.
|
||||
|
||||
The {$array|@mod} syntax has always been a bit confusing, where an "@" is required
|
||||
to apply a modifier to an array instead of the individual elements. Normally you
|
||||
always want the modifier to apply to the variable regardless of its type. In Smarty 3,
|
||||
{$array|mod} and {$array|@mod} behave identical. It is safe to drop the "@" and the
|
||||
modifier will still apply to the array. If you really want the modifier to apply to
|
||||
each array element, you must loop the array in-template, or use a custom modifier that
|
||||
supports array iteration. Most smarty functions already escape values where necessary
|
||||
such as {html_options}
|
||||
|
||||
== PHP Version ==
|
||||
Smarty 3 is PHP 5 only. It will not work with PHP 4.
|
||||
|
||||
== {php} Tag ==
|
||||
The {php} tag is disabled by default. The use of {php} tags is
|
||||
deprecated. It can be enabled with $smarty->allow_php_tag=true.
|
||||
|
||||
But if you scatter PHP code which belongs together into several
|
||||
{php} tags it may not work any longer.
|
||||
|
||||
== Delimiters and whitespace ==
|
||||
Delimiters surrounded by whitespace are no longer treated as Smarty tags.
|
||||
Therefore, { foo } will not compile as a tag, you must use {foo}. This change
|
||||
Makes Javascript/CSS easier to work with, eliminating the need for {literal}.
|
||||
This can be disabled by setting $smarty->auto_literal = false;
|
||||
|
||||
== Unquoted Strings ==
|
||||
Smarty 2 was a bit more forgiving (and ambiguous) when it comes to unquoted strings
|
||||
in parameters. Smarty3 is more restrictive. You can still pass strings without quotes
|
||||
so long as they contain no special characters. (anything outside of A-Za-z0-9_)
|
||||
|
||||
For example filename strings must be quoted
|
||||
<source lang="smarty">
|
||||
{include file='path/foo.tpl'}
|
||||
</source>
|
||||
|
||||
== Extending the Smarty class ==
|
||||
Smarty 3 makes use of the __construct method for initialization. If you are extending
|
||||
the Smarty class, its constructor is not called implicitly if the your child class defines
|
||||
its own constructor. In order to run Smarty's constructor, a call to parent::__construct()
|
||||
within your child constructor is required.
|
||||
|
||||
<source lang="php">
|
||||
class MySmarty extends Smarty {
|
||||
function __construct() {
|
||||
parent::__construct();
|
||||
|
||||
// your initialization code goes here
|
||||
|
||||
}
|
||||
}
|
||||
</source>
|
||||
|
||||
== Autoloader ==
|
||||
Smarty 3 does register its own autoloader with spl_autoload_register. If your code has
|
||||
an existing __autoload function then this function must be explicitly registered on
|
||||
the __autoload stack. See http://us3.php.net/manual/en/function.spl-autoload-register.php
|
||||
for further details.
|
||||
|
||||
== Plugin Filenames ==
|
||||
Smarty 3 optionally supports the PHP spl_autoloader. The autoloader requires filenames
|
||||
to be lower case. Because of this, Smarty plugin file names must also be lowercase.
|
||||
In Smarty 2, mixed case file names did work.
|
||||
|
||||
== Scope of Special Smarty Variables ==
|
||||
In Smarty 2 the special Smarty variables $smarty.section... and $smarty.foreach...
|
||||
had global scope. If you had loops with the same name in subtemplates you could accidentally
|
||||
overwrite values of parent template.
|
||||
|
||||
In Smarty 3 these special Smarty variable have only local scope in the template which
|
||||
is defining the loop. If you need their value in a subtemplate you have to pass them
|
||||
as parameter.
|
||||
<source lang="smarty">
|
||||
{include file='path/foo.tpl' index=$smarty.section.foo.index}
|
||||
</source>
|
||||
|
||||
== SMARTY_RESOURCE_CHAR_SET ==
|
||||
Smarty 3 sets the constant SMARTY_RESOURCE_CHAR_SET to utf-8 as default template charset.
|
||||
This is now used also on modifiers like escape as default charset. If your templates use
|
||||
other charsets make sure that you define the constant accordingly. Otherwise you may not
|
||||
get any output.
|
||||
|
||||
== newline at {if} tags ==
|
||||
A \n was added to the compiled code of the {if},{else},{elseif},{/if} tags to get output of newlines as expected by the template source.
|
||||
If one of the {if} tags is at the line end you will now get a newline in the HTML output.
|
||||
|
||||
== trigger_error() ==
|
||||
The API function trigger_error() has been removed because it did just map to PHP trigger_error.
|
||||
However it's still included in the Smarty2 API wrapper.
|
||||
|
||||
== Smarty constants ==
|
||||
The constants
|
||||
SMARTY_PHP_PASSTHRU
|
||||
SMARTY_PHP_QUOTE
|
||||
SMARTY_PHP_REMOVE
|
||||
SMARTY_PHP_ALLOW
|
||||
have been replaced with class constants
|
||||
Smarty::PHP_PASSTHRU
|
||||
Smarty::PHP_QUOTE
|
||||
Smarty::PHP_REMOVE
|
||||
Smarty::PHP_ALLOW
|
||||
|
||||
24
zoesch.de/galerie/include/smarty/SMARTY_3.0_BC_NOTES.txt
Normal file
24
zoesch.de/galerie/include/smarty/SMARTY_3.0_BC_NOTES.txt
Normal file
@@ -0,0 +1,24 @@
|
||||
== Smarty2 backward compatibility ==
|
||||
All Smarty2 specific API functions and deprecated functionallity has been moved
|
||||
to the SmartyBC class.
|
||||
|
||||
== {php} Tag ==
|
||||
The {php} tag is no longer available in the standard Smarty calls.
|
||||
The use of {php} tags is deprecated and only available in the SmartyBC class.
|
||||
|
||||
== {include_php} Tag ==
|
||||
The {include_php} tag is no longer available in the standard Smarty calls.
|
||||
The use of {include_php} tags is deprecated and only available in the SmartyBC class.
|
||||
|
||||
== php template resource ==
|
||||
The support of the php template resource is removed.
|
||||
|
||||
== $cache_dir, $compile_dir, $config_dir, $template_dir access ==
|
||||
The mentioned properties can't be accessed directly any longer. You must use
|
||||
corresponding getter/setters like addConfigDir(), setConfigDir(), getConfigDir()
|
||||
|
||||
== obsolete Smarty class properties ==
|
||||
The following no longer used properties are removed:
|
||||
$allow_php_tag
|
||||
$allow_php_template
|
||||
$deprecation_notices
|
||||
306
zoesch.de/galerie/include/smarty/SMARTY_3.1_NOTES.txt
Normal file
306
zoesch.de/galerie/include/smarty/SMARTY_3.1_NOTES.txt
Normal file
@@ -0,0 +1,306 @@
|
||||
Smarty 3.1 Notes
|
||||
================
|
||||
|
||||
Smarty 3.1 is a departure from 2.0 compatibility. Most notably, all
|
||||
backward compatibility has been moved to a separate class file named
|
||||
SmartyBC.class.php. If you require compatibility with 2.0, you will
|
||||
need to use this class.
|
||||
|
||||
Some differences from 3.0 are also present. 3.1 begins the journey of
|
||||
requiring setters/getters for property access. So far this is only
|
||||
implemented on the five directory properties: template_dir,
|
||||
plugins_dir, configs_dir, compile_dir and cache_dir. These properties
|
||||
are now protected, it is required to use the setters/getters instead.
|
||||
That said, direct property access will still work, however slightly
|
||||
slower since they will now fall through __set() and __get() and in
|
||||
turn passed through the setter/getter methods. 3.2 will exhibit a full
|
||||
list of setter/getter methods for all (currently) public properties,
|
||||
so code-completion in your IDE will work as expected.
|
||||
|
||||
There is absolutely no PHP allowed in templates any more. All
|
||||
deprecated features of Smarty 2.0 are gone. Again, use the SmartyBC
|
||||
class if you need any backward compatibility.
|
||||
|
||||
Internal Changes
|
||||
|
||||
Full UTF-8 Compatibility
|
||||
|
||||
The plugins shipped with Smarty 3.1 have been rewritten to fully
|
||||
support UTF-8 strings if Multibyte String is available. Without
|
||||
MBString UTF-8 cannot be handled properly. For those rare cases where
|
||||
templates themselves have to juggle encodings, the new modifiers
|
||||
to_charset and from_charset may come in handy.
|
||||
|
||||
Plugin API and Performance
|
||||
|
||||
All Plugins (modifiers, functions, blocks, resources,
|
||||
default_template_handlers, etc) are now receiving the
|
||||
Smarty_Internal_Template instance, where they were supplied with the
|
||||
Smarty instance in Smarty 3.0. *. As The Smarty_Internal_Template
|
||||
mimics the behavior of Smarty, this API simplification should not
|
||||
require any changes to custom plugins.
|
||||
|
||||
The plugins shipped with Smarty 3.1 have been rewritten for better
|
||||
performance. Most notably {html_select_date} and {html_select_time}
|
||||
have been improved vastly. Performance aside, plugins have also been
|
||||
reviewed and generalized in their API. {html_select_date} and
|
||||
{html_select_time} now share almost all available options.
|
||||
|
||||
The escape modifier now knows the $double_encode option, which will
|
||||
prevent entities from being encoded again.
|
||||
|
||||
The capitalize modifier now know the $lc_rest option, which makes sure
|
||||
all letters following a captial letter are lower-cased.
|
||||
|
||||
The count_sentences modifier now accepts (.?!) as
|
||||
legitimate endings of a sentence - previously only (.) was
|
||||
accepted
|
||||
|
||||
The new unescape modifier is there to reverse the effects of the
|
||||
escape modifier. This applies to the escape formats html, htmlall and
|
||||
entity.
|
||||
|
||||
default_template_handler_func
|
||||
|
||||
The invocation of $smarty->$default_template_handler_func had to be
|
||||
altered. Instead of a Smarty_Internal_Template, the fifth argument is
|
||||
now provided with the Smarty instance. New footprint:
|
||||
|
||||
|
||||
/**
|
||||
* Default Template Handler
|
||||
*
|
||||
* called when Smarty's file: resource is unable to load a requested file
|
||||
*
|
||||
* @param string $type resource type (e.g. "file", "string", "eval", "resource")
|
||||
* @param string $name resource name (e.g. "foo/bar.tpl")
|
||||
* @param string &$content template's content
|
||||
* @param integer &$modified template's modification time
|
||||
* @param Smarty $smarty Smarty instance
|
||||
* @return string|boolean path to file or boolean true if $content and $modified
|
||||
* have been filled, boolean false if no default template
|
||||
* could be loaded
|
||||
*/
|
||||
function default_template_handler_func($type, $name, &$content, &$modified, Smarty $smarty) {
|
||||
if (false) {
|
||||
// return corrected filepath
|
||||
return "/tmp/some/foobar.tpl";
|
||||
} elseif (false) {
|
||||
// return a template directly
|
||||
$content = "the template source";
|
||||
$modified = time();
|
||||
return true;
|
||||
} else {
|
||||
// tell smarty that we failed
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Stuff done to the compiler
|
||||
|
||||
Many performance improvements have happened internally. One notable
|
||||
improvement is that all compiled templates are now handled as PHP
|
||||
functions. This speeds up repeated templates tremendously, as each one
|
||||
calls an (in-memory) PHP function instead of performing another file
|
||||
include/scan.
|
||||
|
||||
New Features
|
||||
|
||||
Template syntax
|
||||
|
||||
{block}..{/block}
|
||||
|
||||
The {block} tag has a new hide option flag. It does suppress the block
|
||||
content if no corresponding child block exists.
|
||||
EXAMPLE:
|
||||
parent.tpl
|
||||
{block name=body hide} child content "{$smarty.block.child}" was
|
||||
inserted {block}
|
||||
In the above example the whole block will be suppressed if no child
|
||||
block "body" is existing.
|
||||
|
||||
{setfilter}..{/setfilter}
|
||||
|
||||
The new {setfilter} block tag allows the definition of filters which
|
||||
run on variable output.
|
||||
SYNTAX:
|
||||
{setfilter filter1|filter2|filter3....}
|
||||
Smarty3 will lookup up matching filters in the following search order:
|
||||
1. varibale filter plugin in plugins_dir.
|
||||
2. a valid modifier. A modifier specification will also accept
|
||||
additional parameter like filter2:'foo'
|
||||
3. a PHP function
|
||||
{/setfilter} will turn previous filter setting off again.
|
||||
{setfilter} tags can be nested.
|
||||
EXAMPLE:
|
||||
{setfilter filter1}
|
||||
{$foo}
|
||||
{setfilter filter2}
|
||||
{$bar}
|
||||
{/setfilter}
|
||||
{$buh}
|
||||
{/setfilter}
|
||||
{$blar}
|
||||
In the above example filter1 will run on the output of $foo, filter2
|
||||
on $bar, filter1 again on $buh and no filter on $blar.
|
||||
NOTES:
|
||||
- {$foo nofilter} will suppress the filters
|
||||
- These filters will run in addition to filters defined by
|
||||
registerFilter('variable',...), autoLoadFilter('variable',...) and
|
||||
defined default modifier.
|
||||
- {setfilter} will effect only the current template, not included
|
||||
subtemplates.
|
||||
|
||||
Resource API
|
||||
|
||||
Smarty 3.1 features a new approach to resource management. The
|
||||
Smarty_Resource API allows simple, yet powerful integration of custom
|
||||
resources for templates and configuration files. It offers simple
|
||||
functions for loading data from a custom resource (e.g. database) as
|
||||
well as define new template types adhering to the special
|
||||
non-compiling (e,g, plain php) and non-compile-caching (e.g. eval:
|
||||
resource type) resources.
|
||||
|
||||
See demo/plugins/resource.mysql.php for an example custom database
|
||||
resource.
|
||||
|
||||
Note that old-fashioned registration of callbacks for resource
|
||||
management has been deprecated but is still possible with SmartyBC.
|
||||
|
||||
CacheResource API
|
||||
|
||||
In line with the Resource API, the CacheResource API offers a more
|
||||
comfortable handling of output-cache data. With the
|
||||
Smarty_CacheResource_Custom accessing databases is made simple. With
|
||||
the introduction of Smarty_CacheResource_KeyValueStore the
|
||||
implementation of resources like memcache or APC became a no-brainer;
|
||||
simple hash-based storage systems are now supporting hierarchical
|
||||
output-caches.
|
||||
|
||||
See demo/plugins/cacheresource.mysql.php for an example custom
|
||||
database CacheResource.
|
||||
See demo/plugins/cacheresource.memcache.php for an example custom
|
||||
memcache CacheResource using the KeyValueStore helper.
|
||||
|
||||
Note that old-fashioned registration of $cache_handler is not possible
|
||||
anymore. As the functionality had not been ported to Smarty 3.0.x
|
||||
properly, it has been dropped from 3.1 completely.
|
||||
|
||||
Locking facilities have been implemented to avoid concurrent cache
|
||||
generation. Enable cache locking by setting
|
||||
$smarty->cache_locking = true;
|
||||
|
||||
Relative Paths in Templates (File-Resource)
|
||||
|
||||
As of Smarty 3.1 {include file="../foo.tpl"} and {include
|
||||
file="./foo.tpl"} will resolve relative to the template they're in.
|
||||
Relative paths are available with {include file="..."} and
|
||||
{extends file="..."}. As $smarty->fetch('../foo.tpl') and
|
||||
$smarty->fetch('./foo.tpl') cannot be relative to a template, an
|
||||
exception is thrown.
|
||||
|
||||
Addressing a specific $template_dir
|
||||
|
||||
Smarty 3.1 introduces the $template_dir index notation.
|
||||
$smarty->fetch('[foo]bar.tpl') and {include file="[foo]bar.tpl"}
|
||||
require the template bar.tpl to be loaded from $template_dir['foo'];
|
||||
Smarty::setTemplateDir() and Smarty::addTemplateDir() offer ways to
|
||||
define indexes along with the actual directories.
|
||||
|
||||
Mixing Resources in extends-Resource
|
||||
|
||||
Taking the php extends: template resource one step further, it is now
|
||||
possible to mix resources within an extends: call like
|
||||
$smarty->fetch("extends:file:foo.tpl|db:bar.tpl");
|
||||
|
||||
To make eval: and string: resources available to the inheritance
|
||||
chain, eval:base64:TPL_STRING and eval:urlencode:TPL_STRING have been
|
||||
introduced. Supplying the base64 or urlencode flags will trigger
|
||||
decoding the TPL_STRING in with either base64_decode() or urldecode().
|
||||
|
||||
extends-Resource in template inheritance
|
||||
|
||||
Template based inheritance may now inherit from php's extends:
|
||||
resource like {extends file="extends:foo.tpl|db:bar.tpl"}.
|
||||
|
||||
New Smarty property escape_html
|
||||
|
||||
$smarty->escape_html = true will autoescape all template variable
|
||||
output by calling htmlspecialchars({$output}, ENT_QUOTES,
|
||||
SMARTY_RESOURCE_CHAR_SET).
|
||||
NOTE:
|
||||
This is a compile time option. If you change the setting you must make
|
||||
sure that the templates get recompiled.
|
||||
|
||||
New option at Smarty property compile_check
|
||||
|
||||
The automatic recompilation of modified templates can now be
|
||||
controlled by the following settings:
|
||||
$smarty->compile_check = COMPILECHECK_OFF (false) - template files
|
||||
will not be checked
|
||||
$smarty->compile_check = COMPILECHECK_ON (true) - template files will
|
||||
always be checked
|
||||
$smarty->compile_check = COMPILECHECK_CACHEMISS - template files will
|
||||
be checked if caching is enabled and there is no existing cache file
|
||||
or it has expired
|
||||
|
||||
Automatic recompilation on Smarty version change
|
||||
|
||||
Templates will now be automatically recompiled on Smarty version
|
||||
changes to avoide incompatibillities in the compiled code. Compiled
|
||||
template checked against the current setting of the SMARTY_VERSION
|
||||
constant.
|
||||
|
||||
default_config_handler_func()
|
||||
|
||||
Analogous to the default_template_handler_func()
|
||||
default_config_handler_func() has been introduced.
|
||||
|
||||
default_plugin_handler_func()
|
||||
|
||||
An optional default_plugin_handler_func() can be defined which gets called
|
||||
by the compiler on tags which can't be resolved internally or by plugins.
|
||||
The default_plugin_handler() can map tags to plugins on the fly.
|
||||
|
||||
New getters/setters
|
||||
|
||||
The following setters/getters will be part of the official
|
||||
documentation, and will be strongly recommended. Direct property
|
||||
access will still work for the foreseeable future... it will be
|
||||
transparently routed through the setters/getters, and consequently a
|
||||
bit slower.
|
||||
|
||||
array|string getTemplateDir( [string $index] )
|
||||
replaces $smarty->template_dir; and $smarty->template_dir[$index];
|
||||
Smarty setTemplateDir( array|string $path )
|
||||
replaces $smarty->template_dir = "foo"; and $smarty->template_dir =
|
||||
array("foo", "bar");
|
||||
Smarty addTemplateDir( array|string $path, [string $index])
|
||||
replaces $smarty->template_dir[] = "bar"; and
|
||||
$smarty->template_dir[$index] = "bar";
|
||||
|
||||
array|string getConfigDir( [string $index] )
|
||||
replaces $smarty->config_dir; and $smarty->config_dir[$index];
|
||||
Smarty setConfigDir( array|string $path )
|
||||
replaces $smarty->config_dir = "foo"; and $smarty->config_dir =
|
||||
array("foo", "bar");
|
||||
Smarty addConfigDir( array|string $path, [string $index])
|
||||
replaces $smarty->config_dir[] = "bar"; and
|
||||
$smarty->config_dir[$index] = "bar";
|
||||
|
||||
array getPluginsDir()
|
||||
replaces $smarty->plugins_dir;
|
||||
Smarty setPluginsDir( array|string $path )
|
||||
replaces $smarty->plugins_dir = "foo";
|
||||
Smarty addPluginsDir( array|string $path )
|
||||
replaces $smarty->plugins_dir[] = "bar";
|
||||
|
||||
string getCompileDir()
|
||||
replaces $smarty->compile_dir;
|
||||
Smarty setCompileDir( string $path )
|
||||
replaces $smarty->compile_dir = "foo";
|
||||
|
||||
string getCacheDir()
|
||||
replaces $smarty->cache_dir;
|
||||
Smarty setCacheDir( string $path )
|
||||
replaces $smarty->cache_dir;
|
||||
2864
zoesch.de/galerie/include/smarty/change_log.txt
Normal file
2864
zoesch.de/galerie/include/smarty/change_log.txt
Normal file
File diff suppressed because it is too large
Load Diff
43
zoesch.de/galerie/include/smarty/composer.json
Normal file
43
zoesch.de/galerie/include/smarty/composer.json
Normal file
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"name": "smarty/smarty",
|
||||
"type": "library",
|
||||
"description": "Smarty - the compiling PHP template engine",
|
||||
"keywords": ["templating"],
|
||||
"homepage": "http://www.smarty.net",
|
||||
"license": "LGPL-3.0",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Monte Ohrt",
|
||||
"email": "monte@ohrt.com"
|
||||
},
|
||||
{
|
||||
"name": "Uwe Tews",
|
||||
"email": "uwe.tews@googlemail.com"
|
||||
},
|
||||
{
|
||||
"name": "Rodney Rehm",
|
||||
"email": "rodney.rehm@medialize.de"
|
||||
}
|
||||
],
|
||||
"support": {
|
||||
"irc": "irc://irc.freenode.org/smarty",
|
||||
"issues": "https://github.com/smarty-php/smarty/issues",
|
||||
"forum": "http://www.smarty.net/forums/"
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.2"
|
||||
},
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
"libs/Smarty.class.php",
|
||||
"libs/SmartyBC.class.php",
|
||||
"libs/sysplugins/"
|
||||
]
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.1.x-dev"
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,318 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty Internal Plugin Configfilelexer
|
||||
*
|
||||
* This is the lexer to break the config file source into tokens
|
||||
* @package Smarty
|
||||
* @subpackage Config
|
||||
* @author Uwe Tews
|
||||
*/
|
||||
/**
|
||||
* Smarty_Internal_Configfilelexer
|
||||
*
|
||||
* This is the config file lexer.
|
||||
* It is generated from the smarty_internal_configfilelexer.plex file
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage Compiler
|
||||
* @author Uwe Tews
|
||||
*/
|
||||
class Smarty_Internal_Configfilelexer
|
||||
{
|
||||
/**
|
||||
* Source
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $data;
|
||||
/**
|
||||
* byte counter
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $counter;
|
||||
/**
|
||||
* token number
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $token;
|
||||
/**
|
||||
* token value
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $value;
|
||||
/**
|
||||
* current line
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $line;
|
||||
/**
|
||||
* state number
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $state = 1;
|
||||
/**
|
||||
* Smarty object
|
||||
*
|
||||
* @var Smarty
|
||||
*/
|
||||
public $smarty = null;
|
||||
/**
|
||||
* compiler object
|
||||
*
|
||||
* @var Smarty_Internal_Config_File_Compiler
|
||||
*/
|
||||
private $compiler = null;
|
||||
/**
|
||||
* copy of config_booleanize
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $configBooleanize = false;
|
||||
/**
|
||||
* trace file
|
||||
*
|
||||
* @var resource
|
||||
*/
|
||||
public $yyTraceFILE;
|
||||
/**
|
||||
* trace prompt
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $yyTracePrompt;
|
||||
/**
|
||||
* state names
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $state_name = array(1 => 'START', 2 => 'VALUE', 3 => 'NAKED_STRING_VALUE', 4 => 'COMMENT', 5 => 'SECTION', 6 => 'TRIPPLE');
|
||||
|
||||
/**
|
||||
* storage for assembled token patterns
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $yy_global_pattern1 = null;
|
||||
private $yy_global_pattern2 = null;
|
||||
private $yy_global_pattern3 = null;
|
||||
private $yy_global_pattern4 = null;
|
||||
private $yy_global_pattern5 = null;
|
||||
private $yy_global_pattern6 = null;
|
||||
|
||||
/**
|
||||
* token names
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $smarty_token_names = array( // Text for parser error messages
|
||||
);
|
||||
|
||||
/**
|
||||
* constructor
|
||||
*
|
||||
* @param string $data template source
|
||||
* @param Smarty_Internal_Config_File_Compiler $compiler
|
||||
*/
|
||||
function __construct($data, Smarty_Internal_Config_File_Compiler $compiler)
|
||||
{
|
||||
// set instance object
|
||||
self::instance($this);
|
||||
$this->data = $data . "\n"; //now all lines are \n-terminated
|
||||
$this->counter = 0;
|
||||
if (preg_match('/^\xEF\xBB\xBF/', $this->data, $match)) {
|
||||
$this->counter += strlen($match[0]);
|
||||
}
|
||||
$this->line = 1;
|
||||
$this->compiler = $compiler;
|
||||
$this->smarty = $compiler->smarty;
|
||||
$this->configBooleanize = $this->smarty->config_booleanize;
|
||||
}
|
||||
|
||||
public static function &instance($new_instance = null)
|
||||
{
|
||||
static $instance = null;
|
||||
if (isset($new_instance) && is_object($new_instance)) {
|
||||
$instance = $new_instance;
|
||||
}
|
||||
return $instance;
|
||||
}
|
||||
|
||||
public function PrintTrace()
|
||||
{
|
||||
$this->yyTraceFILE = fopen('php://output', 'w');
|
||||
$this->yyTracePrompt = '<br>';
|
||||
}
|
||||
|
||||
|
||||
/*!lex2php
|
||||
%input $this->data
|
||||
%counter $this->counter
|
||||
%token $this->token
|
||||
%value $this->value
|
||||
%line $this->line
|
||||
commentstart = /#|;/
|
||||
openB = /\[/
|
||||
closeB = /\]/
|
||||
section = /.*?(?=[\.=\[\]\r\n])/
|
||||
equal = /=/
|
||||
whitespace = /[ \t\r]+/
|
||||
dot = /\./
|
||||
id = /[0-9]*[a-zA-Z_]\w*/
|
||||
newline = /\n/
|
||||
single_quoted_string = /'[^'\\]*(?:\\.[^'\\]*)*'(?=[ \t\r]*[\n#;])/
|
||||
double_quoted_string = /"[^"\\]*(?:\\.[^"\\]*)*"(?=[ \t\r]*[\n#;])/
|
||||
tripple_quotes = /"""/
|
||||
tripple_quotes_end = /"""(?=[ \t\r]*[\n#;])/
|
||||
text = /[\S\s]/
|
||||
float = /\d+\.\d+(?=[ \t\r]*[\n#;])/
|
||||
int = /\d+(?=[ \t\r]*[\n#;])/
|
||||
maybe_bool = /[a-zA-Z]+(?=[ \t\r]*[\n#;])/
|
||||
naked_string = /[^\n]+?(?=[ \t\r]*\n)/
|
||||
*/
|
||||
|
||||
/*!lex2php
|
||||
%statename START
|
||||
|
||||
commentstart {
|
||||
$this->token = Smarty_Internal_Configfileparser::TPC_COMMENTSTART;
|
||||
$this->yypushstate(self::COMMENT);
|
||||
}
|
||||
openB {
|
||||
$this->token = Smarty_Internal_Configfileparser::TPC_OPENB;
|
||||
$this->yypushstate(self::SECTION);
|
||||
}
|
||||
closeB {
|
||||
$this->token = Smarty_Internal_Configfileparser::TPC_CLOSEB;
|
||||
}
|
||||
equal {
|
||||
$this->token = Smarty_Internal_Configfileparser::TPC_EQUAL;
|
||||
$this->yypushstate(self::VALUE);
|
||||
}
|
||||
whitespace {
|
||||
return false;
|
||||
}
|
||||
newline {
|
||||
$this->token = Smarty_Internal_Configfileparser::TPC_NEWLINE;
|
||||
}
|
||||
id {
|
||||
$this->token = Smarty_Internal_Configfileparser::TPC_ID;
|
||||
}
|
||||
text {
|
||||
$this->token = Smarty_Internal_Configfileparser::TPC_OTHER;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
/*!lex2php
|
||||
%statename VALUE
|
||||
|
||||
whitespace {
|
||||
return false;
|
||||
}
|
||||
float {
|
||||
$this->token = Smarty_Internal_Configfileparser::TPC_FLOAT;
|
||||
$this->yypopstate();
|
||||
}
|
||||
int {
|
||||
$this->token = Smarty_Internal_Configfileparser::TPC_INT;
|
||||
$this->yypopstate();
|
||||
}
|
||||
tripple_quotes {
|
||||
$this->token = Smarty_Internal_Configfileparser::TPC_TRIPPLE_QUOTES;
|
||||
$this->yypushstate(self::TRIPPLE);
|
||||
}
|
||||
single_quoted_string {
|
||||
$this->token = Smarty_Internal_Configfileparser::TPC_SINGLE_QUOTED_STRING;
|
||||
$this->yypopstate();
|
||||
}
|
||||
double_quoted_string {
|
||||
$this->token = Smarty_Internal_Configfileparser::TPC_DOUBLE_QUOTED_STRING;
|
||||
$this->yypopstate();
|
||||
}
|
||||
maybe_bool {
|
||||
if (!$this->configBooleanize || !in_array(strtolower($this->value), Array("true", "false", "on", "off", "yes", "no")) ) {
|
||||
$this->yypopstate();
|
||||
$this->yypushstate(self::NAKED_STRING_VALUE);
|
||||
return true; //reprocess in new state
|
||||
} else {
|
||||
$this->token = Smarty_Internal_Configfileparser::TPC_BOOL;
|
||||
$this->yypopstate();
|
||||
}
|
||||
}
|
||||
naked_string {
|
||||
$this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING;
|
||||
$this->yypopstate();
|
||||
}
|
||||
newline {
|
||||
$this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING;
|
||||
$this->value = "";
|
||||
$this->yypopstate();
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
/*!lex2php
|
||||
%statename NAKED_STRING_VALUE
|
||||
|
||||
naked_string {
|
||||
$this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING;
|
||||
$this->yypopstate();
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
/*!lex2php
|
||||
%statename COMMENT
|
||||
|
||||
whitespace {
|
||||
return false;
|
||||
}
|
||||
naked_string {
|
||||
$this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING;
|
||||
}
|
||||
newline {
|
||||
$this->token = Smarty_Internal_Configfileparser::TPC_NEWLINE;
|
||||
$this->yypopstate();
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
/*!lex2php
|
||||
%statename SECTION
|
||||
|
||||
dot {
|
||||
$this->token = Smarty_Internal_Configfileparser::TPC_DOT;
|
||||
}
|
||||
section {
|
||||
$this->token = Smarty_Internal_Configfileparser::TPC_SECTION;
|
||||
$this->yypopstate();
|
||||
}
|
||||
|
||||
*/
|
||||
/*!lex2php
|
||||
%statename TRIPPLE
|
||||
|
||||
tripple_quotes_end {
|
||||
$this->token = Smarty_Internal_Configfileparser::TPC_TRIPPLE_QUOTES_END;
|
||||
$this->yypopstate();
|
||||
$this->yypushstate(self::START);
|
||||
}
|
||||
text {
|
||||
$to = strlen($this->data);
|
||||
preg_match("/\"\"\"[ \t\r]*[\n#;]/",$this->data,$match,PREG_OFFSET_CAPTURE,$this->counter);
|
||||
if (isset($match[0][1])) {
|
||||
$to = $match[0][1];
|
||||
} else {
|
||||
$this->compiler->trigger_template_error ("missing or misspelled literal closing tag");
|
||||
}
|
||||
$this->value = substr($this->data,$this->counter,$to-$this->counter);
|
||||
$this->token = Smarty_Internal_Configfileparser::TPC_TRIPPLE_TEXT;
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
@@ -0,0 +1,362 @@
|
||||
/**
|
||||
* Smarty Internal Plugin Configfileparser
|
||||
*
|
||||
* This is the config file parser
|
||||
*
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage Config
|
||||
* @author Uwe Tews
|
||||
*/
|
||||
%name TPC_
|
||||
%declare_class {
|
||||
/**
|
||||
* Smarty Internal Plugin Configfileparse
|
||||
*
|
||||
* This is the config file parser.
|
||||
* It is generated from the smarty_internal_configfileparser.y file
|
||||
* @package Smarty
|
||||
* @subpackage Compiler
|
||||
* @author Uwe Tews
|
||||
*/
|
||||
class Smarty_Internal_Configfileparser
|
||||
}
|
||||
%include_class
|
||||
{
|
||||
/**
|
||||
* result status
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $successful = true;
|
||||
/**
|
||||
* return value
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
public $retvalue = 0;
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
public $yymajor;
|
||||
/**
|
||||
* lexer object
|
||||
*
|
||||
* @var Smarty_Internal_Configfilelexer
|
||||
*/
|
||||
private $lex;
|
||||
/**
|
||||
* internal error flag
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $internalError = false;
|
||||
/**
|
||||
* compiler object
|
||||
*
|
||||
* @var Smarty_Internal_Config_File_Compiler
|
||||
*/
|
||||
public $compiler = null;
|
||||
/**
|
||||
* smarty object
|
||||
*
|
||||
* @var Smarty
|
||||
*/
|
||||
public $smarty = null;
|
||||
/**
|
||||
* copy of config_overwrite property
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $configOverwrite = false;
|
||||
/**
|
||||
* copy of config_read_hidden property
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $configReadHidden = false;
|
||||
/**
|
||||
* helper map
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $escapes_single = Array('\\' => '\\',
|
||||
'\'' => '\'');
|
||||
|
||||
/**
|
||||
* constructor
|
||||
*
|
||||
* @param Smarty_Internal_Configfilelexer $lex
|
||||
* @param Smarty_Internal_Config_File_Compiler $compiler
|
||||
*/
|
||||
function __construct(Smarty_Internal_Configfilelexer $lex, Smarty_Internal_Config_File_Compiler $compiler)
|
||||
{
|
||||
// set instance object
|
||||
self::instance($this);
|
||||
$this->lex = $lex;
|
||||
$this->smarty = $compiler->smarty;
|
||||
$this->compiler = $compiler;
|
||||
$this->configOverwrite = $this->smarty->config_overwrite;
|
||||
$this->configReadHidden = $this->smarty->config_read_hidden;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null $new_instance
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public static function &instance($new_instance = null)
|
||||
{
|
||||
static $instance = null;
|
||||
if (isset($new_instance) && is_object($new_instance)) {
|
||||
$instance = $new_instance;
|
||||
}
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* parse optional boolean keywords
|
||||
*
|
||||
* @param string $str
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function parse_bool($str)
|
||||
{
|
||||
$str = strtolower($str);
|
||||
if (in_array($str, array('on', 'yes', 'true'))) {
|
||||
$res = true;
|
||||
} else {
|
||||
$res = false;
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* parse single quoted string
|
||||
* remove outer quotes
|
||||
* unescape inner quotes
|
||||
*
|
||||
* @param string $qstr
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function parse_single_quoted_string($qstr)
|
||||
{
|
||||
$escaped_string = substr($qstr, 1, strlen($qstr) - 2); //remove outer quotes
|
||||
|
||||
$ss = preg_split('/(\\\\.)/', $escaped_string, - 1, PREG_SPLIT_DELIM_CAPTURE);
|
||||
|
||||
$str = "";
|
||||
foreach ($ss as $s) {
|
||||
if (strlen($s) === 2 && $s[0] === '\\') {
|
||||
if (isset(self::$escapes_single[$s[1]])) {
|
||||
$s = self::$escapes_single[$s[1]];
|
||||
}
|
||||
}
|
||||
$str .= $s;
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* parse double quoted string
|
||||
*
|
||||
* @param string $qstr
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function parse_double_quoted_string($qstr)
|
||||
{
|
||||
$inner_str = substr($qstr, 1, strlen($qstr) - 2);
|
||||
return stripcslashes($inner_str);
|
||||
}
|
||||
|
||||
/**
|
||||
* parse triple quoted string
|
||||
*
|
||||
* @param string $qstr
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function parse_tripple_double_quoted_string($qstr)
|
||||
{
|
||||
return stripcslashes($qstr);
|
||||
}
|
||||
|
||||
/**
|
||||
* set a config variable in target array
|
||||
*
|
||||
* @param array $var
|
||||
* @param array $target_array
|
||||
*/
|
||||
private function set_var(Array $var, Array &$target_array)
|
||||
{
|
||||
$key = $var["key"];
|
||||
$value = $var["value"];
|
||||
|
||||
if ($this->configOverwrite || !isset($target_array['vars'][$key])) {
|
||||
$target_array['vars'][$key] = $value;
|
||||
} else {
|
||||
settype($target_array['vars'][$key], 'array');
|
||||
$target_array['vars'][$key][] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add config variable to global vars
|
||||
*
|
||||
* @param array $vars
|
||||
*/
|
||||
private function add_global_vars(Array $vars)
|
||||
{
|
||||
if (!isset($this->compiler->config_data['vars'])) {
|
||||
$this->compiler->config_data['vars'] = Array();
|
||||
}
|
||||
foreach ($vars as $var) {
|
||||
$this->set_var($var, $this->compiler->config_data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add config variable to section
|
||||
*
|
||||
* @param string $section_name
|
||||
* @param array $vars
|
||||
*/
|
||||
private function add_section_vars($section_name, Array $vars)
|
||||
{
|
||||
if (!isset($this->compiler->config_data['sections'][$section_name]['vars'])) {
|
||||
$this->compiler->config_data['sections'][$section_name]['vars'] = Array();
|
||||
}
|
||||
foreach ($vars as $var) {
|
||||
$this->set_var($var, $this->compiler->config_data['sections'][$section_name]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
%token_prefix TPC_
|
||||
|
||||
%parse_accept
|
||||
{
|
||||
$this->successful = !$this->internalError;
|
||||
$this->internalError = false;
|
||||
$this->retvalue = $this->_retvalue;
|
||||
}
|
||||
|
||||
%syntax_error
|
||||
{
|
||||
$this->internalError = true;
|
||||
$this->yymajor = $yymajor;
|
||||
$this->compiler->trigger_config_file_error();
|
||||
}
|
||||
|
||||
%stack_overflow
|
||||
{
|
||||
$this->internalError = true;
|
||||
$this->compiler->trigger_config_file_error("Stack overflow in configfile parser");
|
||||
}
|
||||
|
||||
// Complete config file
|
||||
start(res) ::= global_vars sections. {
|
||||
res = null;
|
||||
}
|
||||
|
||||
// Global vars
|
||||
global_vars(res) ::= var_list(vl). {
|
||||
$this->add_global_vars(vl);
|
||||
res = null;
|
||||
}
|
||||
|
||||
// Sections
|
||||
sections(res) ::= sections section. {
|
||||
res = null;
|
||||
}
|
||||
|
||||
sections(res) ::= . {
|
||||
res = null;
|
||||
}
|
||||
|
||||
section(res) ::= OPENB SECTION(i) CLOSEB newline var_list(vars). {
|
||||
$this->add_section_vars(i, vars);
|
||||
res = null;
|
||||
}
|
||||
|
||||
section(res) ::= OPENB DOT SECTION(i) CLOSEB newline var_list(vars). {
|
||||
if ($this->configReadHidden) {
|
||||
$this->add_section_vars(i, vars);
|
||||
}
|
||||
res = null;
|
||||
}
|
||||
|
||||
// Var list
|
||||
var_list(res) ::= var_list(vl) newline. {
|
||||
res = vl;
|
||||
}
|
||||
|
||||
var_list(res) ::= var_list(vl) var(v). {
|
||||
res = array_merge(vl, Array(v));
|
||||
}
|
||||
|
||||
var_list(res) ::= . {
|
||||
res = Array();
|
||||
}
|
||||
|
||||
|
||||
// Var
|
||||
var(res) ::= ID(id) EQUAL value(v). {
|
||||
res = Array("key" => id, "value" => v);
|
||||
}
|
||||
|
||||
|
||||
value(res) ::= FLOAT(i). {
|
||||
res = (float) i;
|
||||
}
|
||||
|
||||
value(res) ::= INT(i). {
|
||||
res = (int) i;
|
||||
}
|
||||
|
||||
value(res) ::= BOOL(i). {
|
||||
res = $this->parse_bool(i);
|
||||
}
|
||||
|
||||
value(res) ::= SINGLE_QUOTED_STRING(i). {
|
||||
res = self::parse_single_quoted_string(i);
|
||||
}
|
||||
|
||||
value(res) ::= DOUBLE_QUOTED_STRING(i). {
|
||||
res = self::parse_double_quoted_string(i);
|
||||
}
|
||||
|
||||
value(res) ::= TRIPPLE_QUOTES(i) TRIPPLE_TEXT(c) TRIPPLE_QUOTES_END(ii). {
|
||||
res = self::parse_tripple_double_quoted_string(c);
|
||||
}
|
||||
|
||||
value(res) ::= TRIPPLE_QUOTES(i) TRIPPLE_QUOTES_END(ii). {
|
||||
res = '';
|
||||
}
|
||||
|
||||
value(res) ::= NAKED_STRING(i). {
|
||||
res = i;
|
||||
}
|
||||
|
||||
// NOTE: this is not a valid rule
|
||||
// It is added hier to produce a usefull error message on a missing '=';
|
||||
value(res) ::= OTHER(i). {
|
||||
res = i;
|
||||
}
|
||||
|
||||
|
||||
// Newline and comments
|
||||
newline(res) ::= NEWLINE. {
|
||||
res = null;
|
||||
}
|
||||
|
||||
newline(res) ::= COMMENTSTART NEWLINE. {
|
||||
res = null;
|
||||
}
|
||||
|
||||
newline(res) ::= COMMENTSTART NAKED_STRING NEWLINE. {
|
||||
res = null;
|
||||
}
|
||||
@@ -0,0 +1,672 @@
|
||||
<?php
|
||||
/*
|
||||
* This file is part of Smarty.
|
||||
*
|
||||
* (c) 2015 Uwe Tews
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Smarty_Internal_Templatelexer
|
||||
* This is the template file lexer.
|
||||
* It is generated from the smarty_internal_templatelexer.plex file
|
||||
*
|
||||
*
|
||||
* @author Uwe Tews <uwe.tews@googlemail.com>
|
||||
*/
|
||||
class Smarty_Internal_Templatelexer
|
||||
{
|
||||
/**
|
||||
* Source
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $data;
|
||||
|
||||
/**
|
||||
* byte counter
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $counter;
|
||||
|
||||
/**
|
||||
* token number
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $token;
|
||||
|
||||
/**
|
||||
* token value
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $value;
|
||||
|
||||
/**
|
||||
* current line
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $line;
|
||||
|
||||
/**
|
||||
* tag start line
|
||||
*
|
||||
* @var
|
||||
*/
|
||||
public $taglineno;
|
||||
|
||||
/**
|
||||
* php code type
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $phpType = '';
|
||||
|
||||
/**
|
||||
* escaped left delimiter
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $ldel = '';
|
||||
|
||||
/**
|
||||
* escaped left delimiter length
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $ldel_length = 0;
|
||||
|
||||
/**
|
||||
* escaped right delimiter
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $rdel = '';
|
||||
|
||||
/**
|
||||
* escaped right delimiter length
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $rdel_length = 0;
|
||||
|
||||
/**
|
||||
* state number
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $state = 1;
|
||||
|
||||
/**
|
||||
* Smarty object
|
||||
*
|
||||
* @var Smarty
|
||||
*/
|
||||
public $smarty = null;
|
||||
|
||||
/**
|
||||
* compiler object
|
||||
*
|
||||
* @var Smarty_Internal_TemplateCompilerBase
|
||||
*/
|
||||
public $compiler = null;
|
||||
|
||||
/**
|
||||
* literal tag nesting level
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $literal_cnt = 0;
|
||||
|
||||
/**
|
||||
* PHP start tag string
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
|
||||
/**
|
||||
* trace file
|
||||
*
|
||||
* @var resource
|
||||
*/
|
||||
public $yyTraceFILE;
|
||||
|
||||
/**
|
||||
* trace prompt
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $yyTracePrompt;
|
||||
|
||||
/**
|
||||
* XML flag true while processing xml
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $is_xml = false;
|
||||
|
||||
/**
|
||||
* state names
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $state_name = array(1 => 'TEXT', 2 => 'TAG', 3 => 'TAGBODY', 4 => 'LITERAL', 5 => 'DOUBLEQUOTEDSTRING',);
|
||||
|
||||
/**
|
||||
* storage for assembled token patterns
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $yy_global_pattern1 = null;
|
||||
|
||||
private $yy_global_pattern2 = null;
|
||||
|
||||
private $yy_global_pattern3 = null;
|
||||
|
||||
private $yy_global_pattern4 = null;
|
||||
|
||||
private $yy_global_pattern5 = null;
|
||||
|
||||
/**
|
||||
* token names
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $smarty_token_names = array( // Text for parser error messages
|
||||
'NOT' => '(!,not)',
|
||||
'OPENP' => '(',
|
||||
'CLOSEP' => ')',
|
||||
'OPENB' => '[',
|
||||
'CLOSEB' => ']',
|
||||
'PTR' => '->',
|
||||
'APTR' => '=>',
|
||||
'EQUAL' => '=',
|
||||
'NUMBER' => 'number',
|
||||
'UNIMATH' => '+" , "-',
|
||||
'MATH' => '*" , "/" , "%',
|
||||
'INCDEC' => '++" , "--',
|
||||
'SPACE' => ' ',
|
||||
'DOLLAR' => '$',
|
||||
'SEMICOLON' => ';',
|
||||
'COLON' => ':',
|
||||
'DOUBLECOLON' => '::',
|
||||
'AT' => '@',
|
||||
'HATCH' => '#',
|
||||
'QUOTE' => '"',
|
||||
'BACKTICK' => '`',
|
||||
'VERT' => '"|" modifier',
|
||||
'DOT' => '.',
|
||||
'COMMA' => '","',
|
||||
'QMARK' => '"?"',
|
||||
'ID' => 'id, name',
|
||||
'TEXT' => 'text',
|
||||
'LDELSLASH' => '{/..} closing tag',
|
||||
'LDEL' => '{...} Smarty tag',
|
||||
'COMMENT' => 'comment',
|
||||
'AS' => 'as',
|
||||
'TO' => 'to',
|
||||
'PHP' => '"<?php", "<%", "{php}" tag',
|
||||
'LOGOP' => '"<", "==" ... logical operator',
|
||||
'TLOGOP' => '"lt", "eq" ... logical operator; "is div by" ... if condition',
|
||||
'SCOND' => '"is even" ... if condition',
|
||||
);
|
||||
|
||||
/**
|
||||
* constructor
|
||||
*
|
||||
* @param string $data template source
|
||||
* @param Smarty_Internal_TemplateCompilerBase $compiler
|
||||
*/
|
||||
function __construct($data, Smarty_Internal_TemplateCompilerBase $compiler)
|
||||
{
|
||||
$this->data = $data;
|
||||
$this->counter = 0;
|
||||
if (preg_match('~^\xEF\xBB\xBF~i', $this->data, $match)) {
|
||||
$this->counter += strlen($match[0]);
|
||||
}
|
||||
$this->line = 1;
|
||||
$this->smarty = $compiler->smarty;
|
||||
$this->compiler = $compiler;
|
||||
$this->ldel = preg_quote($this->smarty->left_delimiter, '~');
|
||||
$this->ldel_length = strlen($this->smarty->left_delimiter);
|
||||
$this->rdel = preg_quote($this->smarty->right_delimiter, '~');
|
||||
$this->rdel_length = strlen($this->smarty->right_delimiter);
|
||||
$this->smarty_token_names['LDEL'] = $this->smarty->left_delimiter;
|
||||
$this->smarty_token_names['RDEL'] = $this->smarty->right_delimiter;
|
||||
}
|
||||
|
||||
public function PrintTrace()
|
||||
{
|
||||
$this->yyTraceFILE = fopen('php://output', 'w');
|
||||
$this->yyTracePrompt = '<br>';
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if this tag is autoliteral
|
||||
*/
|
||||
public function isAutoLiteral ()
|
||||
{
|
||||
return $this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false;
|
||||
}
|
||||
|
||||
/*!lex2php
|
||||
%input $this->data
|
||||
%counter $this->counter
|
||||
%token $this->token
|
||||
%value $this->value
|
||||
%line $this->line
|
||||
linebreak = ~[\t ]*[\r\n]+[\t ]*~
|
||||
text = ~[\S\s]~
|
||||
textdoublequoted = ~([^"\\]*?)((?:\\.[^"\\]*?)*?)(?=(SMARTYldel|\$|`\$|"))~
|
||||
namespace = ~([0-9]*[a-zA-Z_]\w*)?(\\[0-9]*[a-zA-Z_]\w*)+~
|
||||
all = ~[\S\s]+~
|
||||
emptyjava = ~[{][}]~
|
||||
phptag = ~(SMARTYldel\s*php(.*?)SMARTYrdel)|(SMARTYldel\s*[/]phpSMARTYrdel)~
|
||||
phpstart = ~(<[?]((php\s+|=)|\s+))|(<[%])|(<[?]xml\s+)|(<script\s+language\s*=\s*["']?\s*php\s*["']?\s*>)|([?][>])|([%][>])~
|
||||
slash = ~[/]~
|
||||
ldel = ~SMARTYldel\s*~
|
||||
rdel = ~\s*SMARTYrdel~
|
||||
nocacherdel = ~(\s+nocache)?\s*SMARTYrdel~
|
||||
notblockid = ~(?:(?!block)[0-9]*[a-zA-Z_]\w*)~
|
||||
smartyblockchildparent = ~[\$]smarty\.block\.(child|parent)~
|
||||
integer = ~\d+~
|
||||
hex = ~0[xX][0-9a-fA-F]+~
|
||||
math = ~\s*([*]{1,2}|[%/^&]|[<>]{2})\s*~
|
||||
comment = ~SMARTYldel[*]~
|
||||
incdec = ~([+]|[-]){2}~
|
||||
unimath = ~\s*([+]|[-])\s*~
|
||||
openP = ~\s*[(]\s*~
|
||||
closeP = ~\s*[)]~
|
||||
openB = ~\[\s*~
|
||||
closeB = ~\s*\]~
|
||||
dollar = ~[$]~
|
||||
dot = ~[.]~
|
||||
comma = ~\s*[,]\s*~
|
||||
doublecolon = ~[:]{2}~
|
||||
colon = ~\s*[:]\s*~
|
||||
at = ~[@]~
|
||||
hatch = ~[#]~
|
||||
semicolon = ~\s*[;]\s*~
|
||||
equal = ~\s*[=]\s*~
|
||||
space = ~\s+~
|
||||
ptr = ~\s*[-][>]\s*~
|
||||
aptr = ~\s*[=][>]\s*~
|
||||
singlequotestring = ~'[^'\\]*(?:\\.[^'\\]*)*'~
|
||||
backtick = ~[`]~
|
||||
vert = ~[|]~
|
||||
qmark = ~\s*[?]\s*~
|
||||
constant = ~([_]+[A-Z0-9][0-9A-Z_]*|[A-Z][0-9A-Z_]*)(?![0-9A-Z_]*[a-z])~
|
||||
attr = ~\s+[0-9]*[a-zA-Z_][a-zA-Z0-9_\-:]*\s*[=]\s*~
|
||||
id = ~[0-9]*[a-zA-Z_]\w*~
|
||||
literal = ~literal~
|
||||
strip = ~strip~
|
||||
lop = ~\s*(([!=][=]{1,2})|([<][=>]?)|([>][=]?)|[&|]{2})\s*~
|
||||
tlop = ~\s+(eq|ne|neq|gt|ge|gte|lt|le|lte|mod|and|or|xor|(is\s+(not\s+)?(odd|even|div)\s+by))\s+~
|
||||
scond = ~\s+is\s+(not\s+)?(odd|even)~
|
||||
isin = ~\s+is\s+in\s+~
|
||||
as = ~\s+as\s+~
|
||||
to = ~\s+to\s+~
|
||||
step = ~\s+step\s+~
|
||||
block = ~block~
|
||||
if = ~(if|elseif|else if|while)\s+~
|
||||
for = ~for\s+~
|
||||
foreach = ~foreach(?![^\s])~
|
||||
setfilter = ~setfilter\s+~
|
||||
instanceof = ~\s+instanceof\s+~
|
||||
not = ~([!]\s*)|(not\s+)~
|
||||
typecast = ~[(](int(eger)?|bool(ean)?|float|double|real|string|binary|array|object)[)]\s*~
|
||||
double_quote = ~["]~
|
||||
single_quote = ~[']~
|
||||
*/
|
||||
/*!lex2php
|
||||
%statename TEXT
|
||||
emptyjava {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_TEXT;
|
||||
}
|
||||
comment {
|
||||
preg_match("~[*]{$this->rdel}~",$this->data,$match,PREG_OFFSET_CAPTURE,$this->counter);
|
||||
if (isset($match[0][1])) {
|
||||
$to = $match[0][1] + strlen($match[0][0]);
|
||||
} else {
|
||||
$this->compiler->trigger_template_error ("missing or misspelled comment closing tag '*{$this->smarty->right_delimiter}'");
|
||||
}
|
||||
$this->value = substr($this->data,$this->counter,$to-$this->counter);
|
||||
return false;
|
||||
}
|
||||
phptag {
|
||||
$obj = new Smarty_Internal_Compile_Private_Php();
|
||||
$obj->parsePhp($this);
|
||||
}
|
||||
ldel literal rdel {
|
||||
if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_TEXT;
|
||||
} else {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_LITERALSTART;
|
||||
$this->yypushstate(self::LITERAL);
|
||||
}
|
||||
}
|
||||
ldel {
|
||||
if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_TEXT;
|
||||
} else {
|
||||
$this->yypushstate(self::TAG);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
rdel {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_TEXT;
|
||||
}
|
||||
phpstart {
|
||||
$obj = new Smarty_Internal_Compile_Private_Php();
|
||||
$obj->parsePhp($this);
|
||||
}
|
||||
text {
|
||||
$to = strlen($this->data);
|
||||
preg_match("~($this->ldel)|(<[?]((php\s+|=)|\s+))|(<[%])|(<[?]xml\s+)|(<script\s+language\s*=\s*[\"']?\s*php\s*[\"']?\s*>)|([?][>])|([%][>])~i",$this->data,$match,PREG_OFFSET_CAPTURE,$this->counter);
|
||||
if (isset($match[0][1])) {
|
||||
$to = $match[0][1];
|
||||
}
|
||||
$this->value = substr($this->data,$this->counter,$to-$this->counter);
|
||||
$this->token = Smarty_Internal_Templateparser::TP_TEXT;
|
||||
}
|
||||
*/
|
||||
/*!lex2php
|
||||
%statename TAG
|
||||
ldel if {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_LDELIF;
|
||||
$this->yybegin(self::TAGBODY);
|
||||
$this->taglineno = $this->line;
|
||||
}
|
||||
ldel for {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_LDELFOR;
|
||||
$this->yybegin(self::TAGBODY);
|
||||
$this->taglineno = $this->line;
|
||||
}
|
||||
ldel foreach {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_LDELFOREACH;
|
||||
$this->yybegin(self::TAGBODY);
|
||||
$this->taglineno = $this->line;
|
||||
}
|
||||
ldel setfilter {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_LDELSETFILTER;
|
||||
$this->yybegin(self::TAGBODY);
|
||||
$this->taglineno = $this->line;
|
||||
}
|
||||
ldel id nocacherdel {
|
||||
$this->yypopstate();
|
||||
$this->token = Smarty_Internal_Templateparser::TP_SIMPLETAG;
|
||||
$this->taglineno = $this->line;
|
||||
}
|
||||
ldel slash notblockid rdel {
|
||||
$this->yypopstate();
|
||||
$this->token = Smarty_Internal_Templateparser::TP_CLOSETAG;
|
||||
$this->taglineno = $this->line;
|
||||
}
|
||||
ldel dollar id nocacherdel {
|
||||
if ($this->_yy_stack[count($this->_yy_stack)-1] == self::TEXT) {
|
||||
$this->yypopstate();
|
||||
$this->token = Smarty_Internal_Templateparser::TP_SIMPELOUTPUT;
|
||||
$this->taglineno = $this->line;
|
||||
} else {
|
||||
$this->value = $this->smarty->left_delimiter;
|
||||
$this->token = Smarty_Internal_Templateparser::TP_LDEL;
|
||||
$this->yybegin(self::TAGBODY);
|
||||
$this->taglineno = $this->line;
|
||||
}
|
||||
}
|
||||
ldel slash {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_LDELSLASH;
|
||||
$this->yybegin(self::TAGBODY);
|
||||
$this->taglineno = $this->line;
|
||||
}
|
||||
ldel {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_LDEL;
|
||||
$this->yybegin(self::TAGBODY);
|
||||
$this->taglineno = $this->line;
|
||||
}
|
||||
*/
|
||||
/*!lex2php
|
||||
%statename TAGBODY
|
||||
rdel {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_RDEL;
|
||||
$this->yypopstate();
|
||||
}
|
||||
ldel {
|
||||
if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_TEXT;
|
||||
} else {
|
||||
$this->yypushstate(self::TAG);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
double_quote {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_QUOTE;
|
||||
$this->yypushstate(self::DOUBLEQUOTEDSTRING);
|
||||
}
|
||||
singlequotestring {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_SINGLEQUOTESTRING;
|
||||
}
|
||||
smartyblockchildparent {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_SMARTYBLOCKCHILDPARENT;
|
||||
$this->taglineno = $this->line;
|
||||
}
|
||||
dollar id {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_DOLLARID;
|
||||
}
|
||||
dollar {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_DOLLAR;
|
||||
}
|
||||
isin {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_ISIN;
|
||||
}
|
||||
as {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_AS;
|
||||
}
|
||||
to {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_TO;
|
||||
}
|
||||
step {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_STEP;
|
||||
}
|
||||
instanceof {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_INSTANCEOF;
|
||||
}
|
||||
lop {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_LOGOP;
|
||||
}
|
||||
tlop {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_TLOGOP;
|
||||
}
|
||||
scond {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_SINGLECOND;
|
||||
}
|
||||
not{
|
||||
$this->token = Smarty_Internal_Templateparser::TP_NOT;
|
||||
}
|
||||
typecast {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_TYPECAST;
|
||||
}
|
||||
openP {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_OPENP;
|
||||
}
|
||||
closeP {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_CLOSEP;
|
||||
}
|
||||
openB {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_OPENB;
|
||||
}
|
||||
closeB {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_CLOSEB;
|
||||
}
|
||||
ptr {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_PTR;
|
||||
}
|
||||
aptr {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_APTR;
|
||||
}
|
||||
equal {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_EQUAL;
|
||||
}
|
||||
incdec {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_INCDEC;
|
||||
}
|
||||
unimath {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_UNIMATH;
|
||||
}
|
||||
math {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_MATH;
|
||||
}
|
||||
at {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_AT;
|
||||
}
|
||||
hatch {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_HATCH;
|
||||
}
|
||||
attr {
|
||||
// resolve conflicts with shorttag and right_delimiter starting with '='
|
||||
if (substr($this->data, $this->counter + strlen($this->value) - 1, $this->rdel_length) == $this->smarty->right_delimiter) {
|
||||
preg_match("~\s+~",$this->value,$match);
|
||||
$this->value = $match[0];
|
||||
$this->token = Smarty_Internal_Templateparser::TP_SPACE;
|
||||
} else {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_ATTR;
|
||||
}
|
||||
}
|
||||
namespace {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_NAMESPACE;
|
||||
}
|
||||
id {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_ID;
|
||||
}
|
||||
integer {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_INTEGER;
|
||||
}
|
||||
backtick {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_BACKTICK;
|
||||
$this->yypopstate();
|
||||
}
|
||||
vert {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_VERT;
|
||||
}
|
||||
dot {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_DOT;
|
||||
}
|
||||
comma {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_COMMA;
|
||||
}
|
||||
semicolon {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_SEMICOLON;
|
||||
}
|
||||
doublecolon {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_DOUBLECOLON;
|
||||
}
|
||||
colon {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_COLON;
|
||||
}
|
||||
qmark {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_QMARK;
|
||||
}
|
||||
hex {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_HEX;
|
||||
}
|
||||
space {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_SPACE;
|
||||
}
|
||||
text {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_TEXT;
|
||||
}
|
||||
*/
|
||||
|
||||
/*!lex2php
|
||||
%statename LITERAL
|
||||
ldel literal rdel {
|
||||
$this->literal_cnt++;
|
||||
$this->token = Smarty_Internal_Templateparser::TP_LITERAL;
|
||||
}
|
||||
ldel slash literal rdel {
|
||||
if ($this->literal_cnt) {
|
||||
$this->literal_cnt--;
|
||||
$this->token = Smarty_Internal_Templateparser::TP_LITERAL;
|
||||
} else {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_LITERALEND;
|
||||
$this->yypopstate();
|
||||
}
|
||||
}
|
||||
text {
|
||||
$to = strlen($this->data);
|
||||
preg_match("~{$this->ldel}[/]?literal{$this->rdel}~i",$this->data,$match,PREG_OFFSET_CAPTURE,$this->counter);
|
||||
if (isset($match[0][1])) {
|
||||
$to = $match[0][1];
|
||||
} else {
|
||||
$this->compiler->trigger_template_error ("missing or misspelled literal closing tag");
|
||||
}
|
||||
$this->value = substr($this->data,$this->counter,$to-$this->counter);
|
||||
$this->token = Smarty_Internal_Templateparser::TP_LITERAL;
|
||||
}
|
||||
*/
|
||||
/*!lex2php
|
||||
%statename DOUBLEQUOTEDSTRING
|
||||
ldel literal rdel {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_TEXT;
|
||||
}
|
||||
ldel slash literal rdel {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_TEXT;
|
||||
}
|
||||
ldel slash {
|
||||
if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_TEXT;
|
||||
} else {
|
||||
$this->yypushstate(self::TAG);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
ldel id {
|
||||
if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_TEXT;
|
||||
} else {
|
||||
$this->yypushstate(self::TAG);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
ldel {
|
||||
if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_TEXT;
|
||||
} else {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_LDEL;
|
||||
$this->taglineno = $this->line;
|
||||
$this->yypushstate(self::TAGBODY);
|
||||
}
|
||||
}
|
||||
double_quote {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_QUOTE;
|
||||
$this->yypopstate();
|
||||
}
|
||||
backtick dollar {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_BACKTICK;
|
||||
$this->value = substr($this->value,0,-1);
|
||||
$this->yypushstate(self::TAGBODY);
|
||||
$this->taglineno = $this->line;
|
||||
}
|
||||
dollar id {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_DOLLARID;
|
||||
}
|
||||
dollar {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_TEXT;
|
||||
}
|
||||
textdoublequoted {
|
||||
$this->token = Smarty_Internal_Templateparser::TP_TEXT;
|
||||
}
|
||||
text {
|
||||
$to = strlen($this->data);
|
||||
$this->value = substr($this->data,$this->counter,$to-$this->counter);
|
||||
$this->token = Smarty_Internal_Templateparser::TP_TEXT;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
124
zoesch.de/galerie/include/smarty/libs/Autoloader.php
Normal file
124
zoesch.de/galerie/include/smarty/libs/Autoloader.php
Normal file
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty Autoloader
|
||||
*
|
||||
* @package Smarty
|
||||
*/
|
||||
|
||||
/**
|
||||
* Smarty Autoloader
|
||||
*
|
||||
* @package Smarty
|
||||
* @author Uwe Tews
|
||||
* Usage:
|
||||
* require_once '...path/Autoloader.php';
|
||||
* Smarty_Autoloader::register();
|
||||
* $smarty = new Smarty();
|
||||
* Note: This autoloader is not needed if you use Composer.
|
||||
* Composer will automatically add the classes of the Smarty package to it common autoloader.
|
||||
*/
|
||||
class Smarty_Autoloader
|
||||
{
|
||||
/**
|
||||
* Filepath to Smarty root
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $SMARTY_DIR = '';
|
||||
|
||||
/**
|
||||
* Filepath to Smarty internal plugins
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $SMARTY_SYSPLUGINS_DIR = '';
|
||||
|
||||
/**
|
||||
* Array with Smarty core classes and their filename
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $rootClasses = array('smarty' => 'Smarty.class.php', 'smartybc' => 'SmartyBC.class.php',);
|
||||
|
||||
/**
|
||||
* Registers Smarty_Autoloader backward compatible to older installations.
|
||||
*
|
||||
* @param bool $prepend Whether to prepend the autoloader or not.
|
||||
*/
|
||||
public static function registerBC($prepend = false)
|
||||
{
|
||||
/**
|
||||
* register the class autoloader
|
||||
*/
|
||||
if (!defined('SMARTY_SPL_AUTOLOAD')) {
|
||||
define('SMARTY_SPL_AUTOLOAD', 0);
|
||||
}
|
||||
if (SMARTY_SPL_AUTOLOAD &&
|
||||
set_include_path(get_include_path() . PATH_SEPARATOR . SMARTY_SYSPLUGINS_DIR) !== false
|
||||
) {
|
||||
$registeredAutoLoadFunctions = spl_autoload_functions();
|
||||
if (!isset($registeredAutoLoadFunctions['spl_autoload'])) {
|
||||
spl_autoload_register();
|
||||
}
|
||||
} else {
|
||||
self::register($prepend);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers Smarty_Autoloader as an SPL autoloader.
|
||||
*
|
||||
* @param bool $prepend Whether to prepend the autoloader or not.
|
||||
*/
|
||||
public static function register($prepend = false)
|
||||
{
|
||||
self::$SMARTY_DIR = defined('SMARTY_DIR') ? SMARTY_DIR : dirname(__FILE__) . DIRECTORY_SEPARATOR;
|
||||
self::$SMARTY_SYSPLUGINS_DIR = defined('SMARTY_SYSPLUGINS_DIR') ? SMARTY_SYSPLUGINS_DIR :
|
||||
self::$SMARTY_DIR . 'sysplugins' . DIRECTORY_SEPARATOR;
|
||||
if (version_compare(phpversion(), '5.3.0', '>=')) {
|
||||
spl_autoload_register(array(__CLASS__, 'autoload'), true, $prepend);
|
||||
} else {
|
||||
spl_autoload_register(array(__CLASS__, 'autoload'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles auto loading of classes.
|
||||
*
|
||||
* @param string $class A class name.
|
||||
*/
|
||||
public static function autoload($class)
|
||||
{
|
||||
$_class = strtolower($class);
|
||||
$file = self::$SMARTY_SYSPLUGINS_DIR . $_class . '.php';
|
||||
if (strpos($_class, 'smarty_internal_') === 0) {
|
||||
if (strpos($_class, 'smarty_internal_compile_') === 0) {
|
||||
if (is_file($file)) {
|
||||
require $file;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@include $file;
|
||||
return;
|
||||
}
|
||||
if (preg_match('/^(smarty_(((template_(source|config|cache|compiled|resource_base))|((cached|compiled)?resource)|(variable|security)))|(smarty(bc)?)$)/',
|
||||
$_class, $match)) {
|
||||
if (!empty($match[3])) {
|
||||
@include $file;
|
||||
return;
|
||||
} elseif (!empty($match[9]) && isset(self::$rootClasses[$_class])) {
|
||||
$file = self::$rootClasses[$_class];
|
||||
require $file;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (0 !== strpos($_class, 'smarty')) {
|
||||
return;
|
||||
}
|
||||
if (is_file($file)) {
|
||||
require $file;
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
1482
zoesch.de/galerie/include/smarty/libs/Smarty.class.php
Normal file
1482
zoesch.de/galerie/include/smarty/libs/Smarty.class.php
Normal file
File diff suppressed because it is too large
Load Diff
455
zoesch.de/galerie/include/smarty/libs/SmartyBC.class.php
Normal file
455
zoesch.de/galerie/include/smarty/libs/SmartyBC.class.php
Normal file
@@ -0,0 +1,455 @@
|
||||
<?php
|
||||
/**
|
||||
* Project: Smarty: the PHP compiling template engine
|
||||
* File: SmartyBC.class.php
|
||||
* SVN: $Id: $
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* For questions, help, comments, discussion, etc., please join the
|
||||
* Smarty mailing list. Send a blank e-mail to
|
||||
* smarty-discussion-subscribe@googlegroups.com
|
||||
*
|
||||
* @link http://www.smarty.net/
|
||||
* @copyright 2008 New Digital Group, Inc.
|
||||
* @author Monte Ohrt <monte at ohrt dot com>
|
||||
* @author Uwe Tews
|
||||
* @author Rodney Rehm
|
||||
* @package Smarty
|
||||
*/
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/Smarty.class.php');
|
||||
|
||||
/**
|
||||
* Smarty Backward Compatability Wrapper Class
|
||||
*
|
||||
* @package Smarty
|
||||
*/
|
||||
class SmartyBC extends Smarty
|
||||
{
|
||||
/**
|
||||
* Smarty 2 BC
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $_version = self::SMARTY_VERSION;
|
||||
|
||||
/**
|
||||
* This is an array of directories where trusted php scripts reside.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $trusted_dir = array();
|
||||
|
||||
/**
|
||||
* Initialize new SmartyBC object
|
||||
*
|
||||
* @param array $options options to set during initialization, e.g. array( 'forceCompile' => false )
|
||||
*/
|
||||
public function __construct(array $options = array())
|
||||
{
|
||||
parent::__construct($options);
|
||||
}
|
||||
|
||||
/**
|
||||
* wrapper for assign_by_ref
|
||||
*
|
||||
* @param string $tpl_var the template variable name
|
||||
* @param mixed &$value the referenced value to assign
|
||||
*/
|
||||
public function assign_by_ref($tpl_var, &$value)
|
||||
{
|
||||
$this->assignByRef($tpl_var, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* wrapper for append_by_ref
|
||||
*
|
||||
* @param string $tpl_var the template variable name
|
||||
* @param mixed &$value the referenced value to append
|
||||
* @param boolean $merge flag if array elements shall be merged
|
||||
*/
|
||||
public function append_by_ref($tpl_var, &$value, $merge = false)
|
||||
{
|
||||
$this->appendByRef($tpl_var, $value, $merge);
|
||||
}
|
||||
|
||||
/**
|
||||
* clear the given assigned template variable.
|
||||
*
|
||||
* @param string $tpl_var the template variable to clear
|
||||
*/
|
||||
public function clear_assign($tpl_var)
|
||||
{
|
||||
$this->clearAssign($tpl_var);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers custom function to be used in templates
|
||||
*
|
||||
* @param string $function the name of the template function
|
||||
* @param string $function_impl the name of the PHP function to register
|
||||
* @param bool $cacheable
|
||||
* @param mixed $cache_attrs
|
||||
*/
|
||||
public function register_function($function, $function_impl, $cacheable = true, $cache_attrs = null)
|
||||
{
|
||||
$this->registerPlugin('function', $function, $function_impl, $cacheable, $cache_attrs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters custom function
|
||||
*
|
||||
* @param string $function name of template function
|
||||
*/
|
||||
public function unregister_function($function)
|
||||
{
|
||||
$this->unregisterPlugin('function', $function);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers object to be used in templates
|
||||
*
|
||||
* @param string $object name of template object
|
||||
* @param object $object_impl the referenced PHP object to register
|
||||
* @param array $allowed list of allowed methods (empty = all)
|
||||
* @param boolean $smarty_args smarty argument format, else traditional
|
||||
* @param array $block_methods list of methods that are block format
|
||||
*
|
||||
* @throws SmartyException
|
||||
* @internal param array $block_functs list of methods that are block format
|
||||
*/
|
||||
public function register_object($object, $object_impl, $allowed = array(), $smarty_args = true, $block_methods = array())
|
||||
{
|
||||
settype($allowed, 'array');
|
||||
settype($smarty_args, 'boolean');
|
||||
$this->registerObject($object, $object_impl, $allowed, $smarty_args, $block_methods);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters object
|
||||
*
|
||||
* @param string $object name of template object
|
||||
*/
|
||||
public function unregister_object($object)
|
||||
{
|
||||
$this->unregisterObject($object);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers block function to be used in templates
|
||||
*
|
||||
* @param string $block name of template block
|
||||
* @param string $block_impl PHP function to register
|
||||
* @param bool $cacheable
|
||||
* @param mixed $cache_attrs
|
||||
*/
|
||||
public function register_block($block, $block_impl, $cacheable = true, $cache_attrs = null)
|
||||
{
|
||||
$this->registerPlugin('block', $block, $block_impl, $cacheable, $cache_attrs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters block function
|
||||
*
|
||||
* @param string $block name of template function
|
||||
*/
|
||||
public function unregister_block($block)
|
||||
{
|
||||
$this->unregisterPlugin('block', $block);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers compiler function
|
||||
*
|
||||
* @param string $function name of template function
|
||||
* @param string $function_impl name of PHP function to register
|
||||
* @param bool $cacheable
|
||||
*/
|
||||
public function register_compiler_function($function, $function_impl, $cacheable = true)
|
||||
{
|
||||
$this->registerPlugin('compiler', $function, $function_impl, $cacheable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters compiler function
|
||||
*
|
||||
* @param string $function name of template function
|
||||
*/
|
||||
public function unregister_compiler_function($function)
|
||||
{
|
||||
$this->unregisterPlugin('compiler', $function);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers modifier to be used in templates
|
||||
*
|
||||
* @param string $modifier name of template modifier
|
||||
* @param string $modifier_impl name of PHP function to register
|
||||
*/
|
||||
public function register_modifier($modifier, $modifier_impl)
|
||||
{
|
||||
$this->registerPlugin('modifier', $modifier, $modifier_impl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters modifier
|
||||
*
|
||||
* @param string $modifier name of template modifier
|
||||
*/
|
||||
public function unregister_modifier($modifier)
|
||||
{
|
||||
$this->unregisterPlugin('modifier', $modifier);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a resource to fetch a template
|
||||
*
|
||||
* @param string $type name of resource
|
||||
* @param array $functions array of functions to handle resource
|
||||
*/
|
||||
public function register_resource($type, $functions)
|
||||
{
|
||||
$this->registerResource($type, $functions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters a resource
|
||||
*
|
||||
* @param string $type name of resource
|
||||
*/
|
||||
public function unregister_resource($type)
|
||||
{
|
||||
$this->unregisterResource($type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a prefilter function to apply
|
||||
* to a template before compiling
|
||||
*
|
||||
* @param callable $function
|
||||
*/
|
||||
public function register_prefilter($function)
|
||||
{
|
||||
$this->registerFilter('pre', $function);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters a prefilter function
|
||||
*
|
||||
* @param callable $function
|
||||
*/
|
||||
public function unregister_prefilter($function)
|
||||
{
|
||||
$this->unregisterFilter('pre', $function);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a postfilter function to apply
|
||||
* to a compiled template after compilation
|
||||
*
|
||||
* @param callable $function
|
||||
*/
|
||||
public function register_postfilter($function)
|
||||
{
|
||||
$this->registerFilter('post', $function);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters a postfilter function
|
||||
*
|
||||
* @param callable $function
|
||||
*/
|
||||
public function unregister_postfilter($function)
|
||||
{
|
||||
$this->unregisterFilter('post', $function);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers an output filter function to apply
|
||||
* to a template output
|
||||
*
|
||||
* @param callable $function
|
||||
*/
|
||||
public function register_outputfilter($function)
|
||||
{
|
||||
$this->registerFilter('output', $function);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters an outputfilter function
|
||||
*
|
||||
* @param callable $function
|
||||
*/
|
||||
public function unregister_outputfilter($function)
|
||||
{
|
||||
$this->unregisterFilter('output', $function);
|
||||
}
|
||||
|
||||
/**
|
||||
* load a filter of specified type and name
|
||||
*
|
||||
* @param string $type filter type
|
||||
* @param string $name filter name
|
||||
*/
|
||||
public function load_filter($type, $name)
|
||||
{
|
||||
$this->loadFilter($type, $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* clear cached content for the given template and cache id
|
||||
*
|
||||
* @param string $tpl_file name of template file
|
||||
* @param string $cache_id name of cache_id
|
||||
* @param string $compile_id name of compile_id
|
||||
* @param string $exp_time expiration time
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function clear_cache($tpl_file = null, $cache_id = null, $compile_id = null, $exp_time = null)
|
||||
{
|
||||
return $this->clearCache($tpl_file, $cache_id, $compile_id, $exp_time);
|
||||
}
|
||||
|
||||
/**
|
||||
* clear the entire contents of cache (all templates)
|
||||
*
|
||||
* @param string $exp_time expire time
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function clear_all_cache($exp_time = null)
|
||||
{
|
||||
return $this->clearCache(null, null, null, $exp_time);
|
||||
}
|
||||
|
||||
/**
|
||||
* test to see if valid cache exists for this template
|
||||
*
|
||||
* @param string $tpl_file name of template file
|
||||
* @param string $cache_id
|
||||
* @param string $compile_id
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function is_cached($tpl_file, $cache_id = null, $compile_id = null)
|
||||
{
|
||||
return $this->isCached($tpl_file, $cache_id, $compile_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* clear all the assigned template variables.
|
||||
*/
|
||||
public function clear_all_assign()
|
||||
{
|
||||
$this->clearAllAssign();
|
||||
}
|
||||
|
||||
/**
|
||||
* clears compiled version of specified template resource,
|
||||
* or all compiled template files if one is not specified.
|
||||
* This function is for advanced use only, not normally needed.
|
||||
*
|
||||
* @param string $tpl_file
|
||||
* @param string $compile_id
|
||||
* @param string $exp_time
|
||||
*
|
||||
* @return boolean results of {@link smarty_core_rm_auto()}
|
||||
*/
|
||||
public function clear_compiled_tpl($tpl_file = null, $compile_id = null, $exp_time = null)
|
||||
{
|
||||
return $this->clearCompiledTemplate($tpl_file, $compile_id, $exp_time);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether requested template exists.
|
||||
*
|
||||
* @param string $tpl_file
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function template_exists($tpl_file)
|
||||
{
|
||||
return $this->templateExists($tpl_file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array containing template variables
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_template_vars($name = null)
|
||||
{
|
||||
return $this->getTemplateVars($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array containing config variables
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_config_vars($name = null)
|
||||
{
|
||||
return $this->getConfigVars($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* load configuration values
|
||||
*
|
||||
* @param string $file
|
||||
* @param string $section
|
||||
* @param string $scope
|
||||
*/
|
||||
public function config_load($file, $section = null, $scope = 'global')
|
||||
{
|
||||
$this->ConfigLoad($file, $section, $scope);
|
||||
}
|
||||
|
||||
/**
|
||||
* return a reference to a registered object
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function get_registered_object($name)
|
||||
{
|
||||
return $this->getRegisteredObject($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* clear configuration values
|
||||
*
|
||||
* @param string $var
|
||||
*/
|
||||
public function clear_config($var = null)
|
||||
{
|
||||
$this->clearConfig($var);
|
||||
}
|
||||
|
||||
/**
|
||||
* trigger Smarty error
|
||||
*
|
||||
* @param string $error_msg
|
||||
* @param integer $error_type
|
||||
*/
|
||||
public function trigger_error($error_msg, $error_type = E_USER_WARNING)
|
||||
{
|
||||
trigger_error("Smarty error: $error_msg", $error_type);
|
||||
}
|
||||
}
|
||||
160
zoesch.de/galerie/include/smarty/libs/debug.tpl
Normal file
160
zoesch.de/galerie/include/smarty/libs/debug.tpl
Normal file
@@ -0,0 +1,160 @@
|
||||
{capture name='_smarty_debug' assign=debug_output}
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
||||
<head>
|
||||
<title>Smarty Debug Console</title>
|
||||
<style type="text/css">
|
||||
{literal}
|
||||
body, h1, h2, h3, td, th, p {
|
||||
font-family: sans-serif;
|
||||
font-weight: normal;
|
||||
font-size: 0.9em;
|
||||
margin: 1px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin: 0;
|
||||
text-align: left;
|
||||
padding: 2px;
|
||||
background-color: #f0c040;
|
||||
color: black;
|
||||
font-weight: bold;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
background-color: #9B410E;
|
||||
color: white;
|
||||
text-align: left;
|
||||
font-weight: bold;
|
||||
padding: 2px;
|
||||
border-top: 1px solid black;
|
||||
}
|
||||
h3 {
|
||||
text-align: left;
|
||||
font-weight: bold;
|
||||
color: black;
|
||||
font-size: 0.7em;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
body {
|
||||
background: black;
|
||||
}
|
||||
|
||||
p, table, div {
|
||||
background: #f0ead8;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
font-style: italic;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
th, td {
|
||||
font-family: monospace;
|
||||
vertical-align: top;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
td {
|
||||
color: green;
|
||||
}
|
||||
|
||||
.odd {
|
||||
background-color: #eeeeee;
|
||||
}
|
||||
|
||||
.even {
|
||||
background-color: #fafafa;
|
||||
}
|
||||
|
||||
.exectime {
|
||||
font-size: 0.8em;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
#bold div {
|
||||
color: black;
|
||||
font-weight: bold;
|
||||
}
|
||||
#blue h3 {
|
||||
color: blue;
|
||||
}
|
||||
#normal div {
|
||||
color: black;
|
||||
font-weight: normal;
|
||||
}
|
||||
#table_assigned_vars th {
|
||||
color: blue;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#table_config_vars th {
|
||||
color: maroon;
|
||||
}
|
||||
|
||||
{/literal}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1>Smarty {Smarty::SMARTY_VERSION} Debug Console
|
||||
- {if isset($template_name)}{$template_name|debug_print_var nofilter} {/if}{if !empty($template_data)}Total Time {$execution_time|string_format:"%.5f"}{/if}</h1>
|
||||
|
||||
{if !empty($template_data)}
|
||||
<h2>included templates & config files (load time in seconds)</h2>
|
||||
<div>
|
||||
{foreach $template_data as $template}
|
||||
<font color=brown>{$template.name}</font>
|
||||
<br> <span class="exectime">
|
||||
(compile {$template['compile_time']|string_format:"%.5f"}) (render {$template['render_time']|string_format:"%.5f"}) (cache {$template['cache_time']|string_format:"%.5f"})
|
||||
</span>
|
||||
<br>
|
||||
{/foreach}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<h2>assigned template variables</h2>
|
||||
|
||||
<table id="table_assigned_vars">
|
||||
{foreach $assigned_vars as $vars}
|
||||
<tr class="{if $vars@iteration % 2 eq 0}odd{else}even{/if}">
|
||||
<td><h3><font color=blue>${$vars@key}</font></h3>
|
||||
{if isset($vars['nocache'])}<b>Nocache</b></br>{/if}
|
||||
{if isset($vars['scope'])}<b>Origin:</b> {$vars['scope']|debug_print_var nofilter}{/if}
|
||||
</td>
|
||||
<td><h3>Value</h3>{$vars['value']|debug_print_var:10:80 nofilter}</td>
|
||||
<td>{if isset($vars['attributes'])}<h3>Attributes</h3>{$vars['attributes']|debug_print_var nofilter} {/if}</td>
|
||||
{/foreach}
|
||||
</table>
|
||||
|
||||
<h2>assigned config file variables</h2>
|
||||
|
||||
<table id="table_config_vars">
|
||||
{foreach $config_vars as $vars}
|
||||
<tr class="{if $vars@iteration % 2 eq 0}odd{else}even{/if}">
|
||||
<td><h3><font color=blue>#{$vars@key}#</font></h3>
|
||||
{if isset($vars['scope'])}<b>Origin:</b> {$vars['scope']|debug_print_var nofilter}{/if}
|
||||
</td>
|
||||
<td>{$vars['value']|debug_print_var:10:80 nofilter}</td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
{/capture}
|
||||
<script type="text/javascript">
|
||||
{$id = '__Smarty__'}
|
||||
{if $display_mode}{$id = "$offset$template_name"|md5}{/if}
|
||||
_smarty_console = window.open("", "console{$id}", "width=1024,height=600,left={$offset},top={$offset},resizable,scrollbars=yes");
|
||||
_smarty_console.document.write("{$debug_output|escape:'javascript' nofilter}");
|
||||
_smarty_console.document.close();
|
||||
</script>
|
||||
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin to format text blocks
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage PluginsBlock
|
||||
*/
|
||||
|
||||
/**
|
||||
* Smarty {textformat}{/textformat} block plugin
|
||||
* Type: block function<br>
|
||||
* Name: textformat<br>
|
||||
* Purpose: format text a certain way with preset styles
|
||||
* or custom wrap/indent settings<br>
|
||||
* Params:
|
||||
* <pre>
|
||||
* - style - string (email)
|
||||
* - indent - integer (0)
|
||||
* - wrap - integer (80)
|
||||
* - wrap_char - string ("\n")
|
||||
* - indent_char - string (" ")
|
||||
* - wrap_boundary - boolean (true)
|
||||
* </pre>
|
||||
*
|
||||
* @link http://www.smarty.net/manual/en/language.function.textformat.php {textformat}
|
||||
* (Smarty online manual)
|
||||
*
|
||||
* @param array $params parameters
|
||||
* @param string $content contents of the block
|
||||
* @param Smarty_Internal_Template $template template object
|
||||
* @param boolean &$repeat repeat flag
|
||||
*
|
||||
* @return string content re-formatted
|
||||
* @author Monte Ohrt <monte at ohrt dot com>
|
||||
*/
|
||||
function smarty_block_textformat($params, $content, $template, &$repeat)
|
||||
{
|
||||
if (is_null($content)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$style = null;
|
||||
$indent = 0;
|
||||
$indent_first = 0;
|
||||
$indent_char = ' ';
|
||||
$wrap = 80;
|
||||
$wrap_char = "\n";
|
||||
$wrap_cut = false;
|
||||
$assign = null;
|
||||
|
||||
foreach ($params as $_key => $_val) {
|
||||
switch ($_key) {
|
||||
case 'style':
|
||||
case 'indent_char':
|
||||
case 'wrap_char':
|
||||
case 'assign':
|
||||
$$_key = (string) $_val;
|
||||
break;
|
||||
|
||||
case 'indent':
|
||||
case 'indent_first':
|
||||
case 'wrap':
|
||||
$$_key = (int) $_val;
|
||||
break;
|
||||
|
||||
case 'wrap_cut':
|
||||
$$_key = (bool) $_val;
|
||||
break;
|
||||
|
||||
default:
|
||||
trigger_error("textformat: unknown attribute '$_key'");
|
||||
}
|
||||
}
|
||||
|
||||
if ($style == 'email') {
|
||||
$wrap = 72;
|
||||
}
|
||||
// split into paragraphs
|
||||
$_paragraphs = preg_split('![\r\n]{2}!', $content);
|
||||
|
||||
foreach ($_paragraphs as &$_paragraph) {
|
||||
if (!$_paragraph) {
|
||||
continue;
|
||||
}
|
||||
// convert mult. spaces & special chars to single space
|
||||
$_paragraph = preg_replace(array('!\s+!' . Smarty::$_UTF8_MODIFIER, '!(^\s+)|(\s+$)!' . Smarty::$_UTF8_MODIFIER), array(' ', ''), $_paragraph);
|
||||
// indent first line
|
||||
if ($indent_first > 0) {
|
||||
$_paragraph = str_repeat($indent_char, $indent_first) . $_paragraph;
|
||||
}
|
||||
// wordwrap sentences
|
||||
if (Smarty::$_MBSTRING) {
|
||||
require_once(SMARTY_PLUGINS_DIR . 'shared.mb_wordwrap.php');
|
||||
$_paragraph = smarty_mb_wordwrap($_paragraph, $wrap - $indent, $wrap_char, $wrap_cut);
|
||||
} else {
|
||||
$_paragraph = wordwrap($_paragraph, $wrap - $indent, $wrap_char, $wrap_cut);
|
||||
}
|
||||
// indent lines
|
||||
if ($indent > 0) {
|
||||
$_paragraph = preg_replace('!^!m', str_repeat($indent_char, $indent), $_paragraph);
|
||||
}
|
||||
}
|
||||
$_output = implode($wrap_char . $wrap_char, $_paragraphs);
|
||||
|
||||
if ($assign) {
|
||||
$template->assign($assign, $_output);
|
||||
} else {
|
||||
return $_output;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage PluginsFunction
|
||||
*/
|
||||
|
||||
/**
|
||||
* Smarty {counter} function plugin
|
||||
* Type: function<br>
|
||||
* Name: counter<br>
|
||||
* Purpose: print out a counter value
|
||||
*
|
||||
* @author Monte Ohrt <monte at ohrt dot com>
|
||||
* @link http://www.smarty.net/manual/en/language.function.counter.php {counter}
|
||||
* (Smarty online manual)
|
||||
*
|
||||
* @param array $params parameters
|
||||
* @param Smarty_Internal_Template $template template object
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
function smarty_function_counter($params, $template)
|
||||
{
|
||||
static $counters = array();
|
||||
|
||||
$name = (isset($params['name'])) ? $params['name'] : 'default';
|
||||
if (!isset($counters[$name])) {
|
||||
$counters[$name] = array(
|
||||
'start' => 1,
|
||||
'skip' => 1,
|
||||
'direction' => 'up',
|
||||
'count' => 1
|
||||
);
|
||||
}
|
||||
$counter =& $counters[$name];
|
||||
|
||||
if (isset($params['start'])) {
|
||||
$counter['start'] = $counter['count'] = (int) $params['start'];
|
||||
}
|
||||
|
||||
if (!empty($params['assign'])) {
|
||||
$counter['assign'] = $params['assign'];
|
||||
}
|
||||
|
||||
if (isset($counter['assign'])) {
|
||||
$template->assign($counter['assign'], $counter['count']);
|
||||
}
|
||||
|
||||
if (isset($params['print'])) {
|
||||
$print = (bool) $params['print'];
|
||||
} else {
|
||||
$print = empty($counter['assign']);
|
||||
}
|
||||
|
||||
if ($print) {
|
||||
$retval = $counter['count'];
|
||||
} else {
|
||||
$retval = null;
|
||||
}
|
||||
|
||||
if (isset($params['skip'])) {
|
||||
$counter['skip'] = $params['skip'];
|
||||
}
|
||||
|
||||
if (isset($params['direction'])) {
|
||||
$counter['direction'] = $params['direction'];
|
||||
}
|
||||
|
||||
if ($counter['direction'] == "down") {
|
||||
$counter['count'] -= $counter['skip'];
|
||||
} else {
|
||||
$counter['count'] += $counter['skip'];
|
||||
}
|
||||
|
||||
return $retval;
|
||||
}
|
||||
107
zoesch.de/galerie/include/smarty/libs/plugins/function.cycle.php
Normal file
107
zoesch.de/galerie/include/smarty/libs/plugins/function.cycle.php
Normal file
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage PluginsFunction
|
||||
*/
|
||||
|
||||
/**
|
||||
* Smarty {cycle} function plugin
|
||||
* Type: function<br>
|
||||
* Name: cycle<br>
|
||||
* Date: May 3, 2002<br>
|
||||
* Purpose: cycle through given values<br>
|
||||
* Params:
|
||||
* <pre>
|
||||
* - name - name of cycle (optional)
|
||||
* - values - comma separated list of values to cycle, or an array of values to cycle
|
||||
* (this can be left out for subsequent calls)
|
||||
* - reset - boolean - resets given var to true
|
||||
* - print - boolean - print var or not. default is true
|
||||
* - advance - boolean - whether or not to advance the cycle
|
||||
* - delimiter - the value delimiter, default is ","
|
||||
* - assign - boolean, assigns to template var instead of printed.
|
||||
* </pre>
|
||||
* Examples:<br>
|
||||
* <pre>
|
||||
* {cycle values="#eeeeee,#d0d0d0d"}
|
||||
* {cycle name=row values="one,two,three" reset=true}
|
||||
* {cycle name=row}
|
||||
* </pre>
|
||||
*
|
||||
* @link http://www.smarty.net/manual/en/language.function.cycle.php {cycle}
|
||||
* (Smarty online manual)
|
||||
* @author Monte Ohrt <monte at ohrt dot com>
|
||||
* @author credit to Mark Priatel <mpriatel@rogers.com>
|
||||
* @author credit to Gerard <gerard@interfold.com>
|
||||
* @author credit to Jason Sweat <jsweat_php@yahoo.com>
|
||||
* @version 1.3
|
||||
*
|
||||
* @param array $params parameters
|
||||
* @param Smarty_Internal_Template $template template object
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
|
||||
function smarty_function_cycle($params, $template)
|
||||
{
|
||||
static $cycle_vars;
|
||||
|
||||
$name = (empty($params['name'])) ? 'default' : $params['name'];
|
||||
$print = (isset($params['print'])) ? (bool) $params['print'] : true;
|
||||
$advance = (isset($params['advance'])) ? (bool) $params['advance'] : true;
|
||||
$reset = (isset($params['reset'])) ? (bool) $params['reset'] : false;
|
||||
|
||||
if (!isset($params['values'])) {
|
||||
if (!isset($cycle_vars[$name]['values'])) {
|
||||
trigger_error("cycle: missing 'values' parameter");
|
||||
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (isset($cycle_vars[$name]['values'])
|
||||
&& $cycle_vars[$name]['values'] != $params['values']
|
||||
) {
|
||||
$cycle_vars[$name]['index'] = 0;
|
||||
}
|
||||
$cycle_vars[$name]['values'] = $params['values'];
|
||||
}
|
||||
|
||||
if (isset($params['delimiter'])) {
|
||||
$cycle_vars[$name]['delimiter'] = $params['delimiter'];
|
||||
} elseif (!isset($cycle_vars[$name]['delimiter'])) {
|
||||
$cycle_vars[$name]['delimiter'] = ',';
|
||||
}
|
||||
|
||||
if (is_array($cycle_vars[$name]['values'])) {
|
||||
$cycle_array = $cycle_vars[$name]['values'];
|
||||
} else {
|
||||
$cycle_array = explode($cycle_vars[$name]['delimiter'], $cycle_vars[$name]['values']);
|
||||
}
|
||||
|
||||
if (!isset($cycle_vars[$name]['index']) || $reset) {
|
||||
$cycle_vars[$name]['index'] = 0;
|
||||
}
|
||||
|
||||
if (isset($params['assign'])) {
|
||||
$print = false;
|
||||
$template->assign($params['assign'], $cycle_array[$cycle_vars[$name]['index']]);
|
||||
}
|
||||
|
||||
if ($print) {
|
||||
$retval = $cycle_array[$cycle_vars[$name]['index']];
|
||||
} else {
|
||||
$retval = null;
|
||||
}
|
||||
|
||||
if ($advance) {
|
||||
if ($cycle_vars[$name]['index'] >= count($cycle_array) - 1) {
|
||||
$cycle_vars[$name]['index'] = 0;
|
||||
} else {
|
||||
$cycle_vars[$name]['index'] ++;
|
||||
}
|
||||
}
|
||||
|
||||
return $retval;
|
||||
}
|
||||
221
zoesch.de/galerie/include/smarty/libs/plugins/function.fetch.php
Normal file
221
zoesch.de/galerie/include/smarty/libs/plugins/function.fetch.php
Normal file
@@ -0,0 +1,221 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage PluginsFunction
|
||||
*/
|
||||
|
||||
/**
|
||||
* Smarty {fetch} plugin
|
||||
* Type: function<br>
|
||||
* Name: fetch<br>
|
||||
* Purpose: fetch file, web or ftp data and display results
|
||||
*
|
||||
* @link http://www.smarty.net/manual/en/language.function.fetch.php {fetch}
|
||||
* (Smarty online manual)
|
||||
* @author Monte Ohrt <monte at ohrt dot com>
|
||||
*
|
||||
* @param array $params parameters
|
||||
* @param Smarty_Internal_Template $template template object
|
||||
*
|
||||
* @throws SmartyException
|
||||
* @return string|null if the assign parameter is passed, Smarty assigns the result to a template variable
|
||||
*/
|
||||
function smarty_function_fetch($params, $template)
|
||||
{
|
||||
if (empty($params['file'])) {
|
||||
trigger_error("[plugin] fetch parameter 'file' cannot be empty", E_USER_NOTICE);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// strip file protocol
|
||||
if (stripos($params['file'], 'file://') === 0) {
|
||||
$params['file'] = substr($params['file'], 7);
|
||||
}
|
||||
|
||||
$protocol = strpos($params['file'], '://');
|
||||
if ($protocol !== false) {
|
||||
$protocol = strtolower(substr($params['file'], 0, $protocol));
|
||||
}
|
||||
|
||||
if (isset($template->smarty->security_policy)) {
|
||||
if ($protocol) {
|
||||
// remote resource (or php stream, …)
|
||||
if (!$template->smarty->security_policy->isTrustedUri($params['file'])) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// local file
|
||||
if (!$template->smarty->security_policy->isTrustedResourceDir($params['file'])) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$content = '';
|
||||
if ($protocol == 'http') {
|
||||
// http fetch
|
||||
if ($uri_parts = parse_url($params['file'])) {
|
||||
// set defaults
|
||||
$host = $server_name = $uri_parts['host'];
|
||||
$timeout = 30;
|
||||
$accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*";
|
||||
$agent = "Smarty Template Engine " . Smarty::SMARTY_VERSION;
|
||||
$referer = "";
|
||||
$uri = !empty($uri_parts['path']) ? $uri_parts['path'] : '/';
|
||||
$uri .= !empty($uri_parts['query']) ? '?' . $uri_parts['query'] : '';
|
||||
$_is_proxy = false;
|
||||
if (empty($uri_parts['port'])) {
|
||||
$port = 80;
|
||||
} else {
|
||||
$port = $uri_parts['port'];
|
||||
}
|
||||
if (!empty($uri_parts['user'])) {
|
||||
$user = $uri_parts['user'];
|
||||
}
|
||||
if (!empty($uri_parts['pass'])) {
|
||||
$pass = $uri_parts['pass'];
|
||||
}
|
||||
// loop through parameters, setup headers
|
||||
foreach ($params as $param_key => $param_value) {
|
||||
switch ($param_key) {
|
||||
case "file":
|
||||
case "assign":
|
||||
case "assign_headers":
|
||||
break;
|
||||
case "user":
|
||||
if (!empty($param_value)) {
|
||||
$user = $param_value;
|
||||
}
|
||||
break;
|
||||
case "pass":
|
||||
if (!empty($param_value)) {
|
||||
$pass = $param_value;
|
||||
}
|
||||
break;
|
||||
case "accept":
|
||||
if (!empty($param_value)) {
|
||||
$accept = $param_value;
|
||||
}
|
||||
break;
|
||||
case "header":
|
||||
if (!empty($param_value)) {
|
||||
if (!preg_match('![\w\d-]+: .+!', $param_value)) {
|
||||
trigger_error("[plugin] invalid header format '" . $param_value . "'", E_USER_NOTICE);
|
||||
|
||||
return;
|
||||
} else {
|
||||
$extra_headers[] = $param_value;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "proxy_host":
|
||||
if (!empty($param_value)) {
|
||||
$proxy_host = $param_value;
|
||||
}
|
||||
break;
|
||||
case "proxy_port":
|
||||
if (!preg_match('!\D!', $param_value)) {
|
||||
$proxy_port = (int) $param_value;
|
||||
} else {
|
||||
trigger_error("[plugin] invalid value for attribute '" . $param_key . "'", E_USER_NOTICE);
|
||||
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case "agent":
|
||||
if (!empty($param_value)) {
|
||||
$agent = $param_value;
|
||||
}
|
||||
break;
|
||||
case "referer":
|
||||
if (!empty($param_value)) {
|
||||
$referer = $param_value;
|
||||
}
|
||||
break;
|
||||
case "timeout":
|
||||
if (!preg_match('!\D!', $param_value)) {
|
||||
$timeout = (int) $param_value;
|
||||
} else {
|
||||
trigger_error("[plugin] invalid value for attribute '" . $param_key . "'", E_USER_NOTICE);
|
||||
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
trigger_error("[plugin] unrecognized attribute '" . $param_key . "'", E_USER_NOTICE);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!empty($proxy_host) && !empty($proxy_port)) {
|
||||
$_is_proxy = true;
|
||||
$fp = fsockopen($proxy_host, $proxy_port, $errno, $errstr, $timeout);
|
||||
} else {
|
||||
$fp = fsockopen($server_name, $port, $errno, $errstr, $timeout);
|
||||
}
|
||||
|
||||
if (!$fp) {
|
||||
trigger_error("[plugin] unable to fetch: $errstr ($errno)", E_USER_NOTICE);
|
||||
|
||||
return;
|
||||
} else {
|
||||
if ($_is_proxy) {
|
||||
fputs($fp, 'GET ' . $params['file'] . " HTTP/1.0\r\n");
|
||||
} else {
|
||||
fputs($fp, "GET $uri HTTP/1.0\r\n");
|
||||
}
|
||||
if (!empty($host)) {
|
||||
fputs($fp, "Host: $host\r\n");
|
||||
}
|
||||
if (!empty($accept)) {
|
||||
fputs($fp, "Accept: $accept\r\n");
|
||||
}
|
||||
if (!empty($agent)) {
|
||||
fputs($fp, "User-Agent: $agent\r\n");
|
||||
}
|
||||
if (!empty($referer)) {
|
||||
fputs($fp, "Referer: $referer\r\n");
|
||||
}
|
||||
if (isset($extra_headers) && is_array($extra_headers)) {
|
||||
foreach ($extra_headers as $curr_header) {
|
||||
fputs($fp, $curr_header . "\r\n");
|
||||
}
|
||||
}
|
||||
if (!empty($user) && !empty($pass)) {
|
||||
fputs($fp, "Authorization: BASIC " . base64_encode("$user:$pass") . "\r\n");
|
||||
}
|
||||
|
||||
fputs($fp, "\r\n");
|
||||
while (!feof($fp)) {
|
||||
$content .= fgets($fp, 4096);
|
||||
}
|
||||
fclose($fp);
|
||||
$csplit = preg_split("!\r\n\r\n!", $content, 2);
|
||||
|
||||
$content = $csplit[1];
|
||||
|
||||
if (!empty($params['assign_headers'])) {
|
||||
$template->assign($params['assign_headers'], preg_split("!\r\n!", $csplit[0]));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
trigger_error("[plugin fetch] unable to parse URL, check syntax", E_USER_NOTICE);
|
||||
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
$content = @file_get_contents($params['file']);
|
||||
if ($content === false) {
|
||||
throw new SmartyException("{fetch} cannot read resource '" . $params['file'] . "'");
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($params['assign'])) {
|
||||
$template->assign($params['assign'], $content);
|
||||
} else {
|
||||
return $content;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage PluginsFunction
|
||||
*/
|
||||
|
||||
/**
|
||||
* Smarty {html_checkboxes} function plugin
|
||||
* File: function.html_checkboxes.php<br>
|
||||
* Type: function<br>
|
||||
* Name: html_checkboxes<br>
|
||||
* Date: 24.Feb.2003<br>
|
||||
* Purpose: Prints out a list of checkbox input types<br>
|
||||
* Examples:
|
||||
* <pre>
|
||||
* {html_checkboxes values=$ids output=$names}
|
||||
* {html_checkboxes values=$ids name='box' separator='<br>' output=$names}
|
||||
* {html_checkboxes values=$ids checked=$checked separator='<br>' output=$names}
|
||||
* </pre>
|
||||
* Params:
|
||||
* <pre>
|
||||
* - name (optional) - string default "checkbox"
|
||||
* - values (required) - array
|
||||
* - options (optional) - associative array
|
||||
* - checked (optional) - array default not set
|
||||
* - separator (optional) - ie <br> or
|
||||
* - output (optional) - the output next to each checkbox
|
||||
* - assign (optional) - assign the output as an array to this variable
|
||||
* - escape (optional) - escape the content (not value), defaults to true
|
||||
* </pre>
|
||||
*
|
||||
* @link http://www.smarty.net/manual/en/language.function.html.checkboxes.php {html_checkboxes}
|
||||
* (Smarty online manual)
|
||||
* @author Christopher Kvarme <christopher.kvarme@flashjab.com>
|
||||
* @author credits to Monte Ohrt <monte at ohrt dot com>
|
||||
* @version 1.0
|
||||
*
|
||||
* @param array $params parameters
|
||||
* @param object $template template object
|
||||
*
|
||||
* @return string
|
||||
* @uses smarty_function_escape_special_chars()
|
||||
*/
|
||||
function smarty_function_html_checkboxes($params, $template)
|
||||
{
|
||||
require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php');
|
||||
|
||||
$name = 'checkbox';
|
||||
$values = null;
|
||||
$options = null;
|
||||
$selected = array();
|
||||
$separator = '';
|
||||
$escape = true;
|
||||
$labels = true;
|
||||
$label_ids = false;
|
||||
$output = null;
|
||||
|
||||
$extra = '';
|
||||
|
||||
foreach ($params as $_key => $_val) {
|
||||
switch ($_key) {
|
||||
case 'name':
|
||||
case 'separator':
|
||||
$$_key = (string) $_val;
|
||||
break;
|
||||
|
||||
case 'escape':
|
||||
case 'labels':
|
||||
case 'label_ids':
|
||||
$$_key = (bool) $_val;
|
||||
break;
|
||||
|
||||
case 'options':
|
||||
$$_key = (array) $_val;
|
||||
break;
|
||||
|
||||
case 'values':
|
||||
case 'output':
|
||||
$$_key = array_values((array) $_val);
|
||||
break;
|
||||
|
||||
case 'checked':
|
||||
case 'selected':
|
||||
if (is_array($_val)) {
|
||||
$selected = array();
|
||||
foreach ($_val as $_sel) {
|
||||
if (is_object($_sel)) {
|
||||
if (method_exists($_sel, "__toString")) {
|
||||
$_sel = smarty_function_escape_special_chars((string) $_sel->__toString());
|
||||
} else {
|
||||
trigger_error("html_checkboxes: selected attribute contains an object of class '" . get_class($_sel) . "' without __toString() method", E_USER_NOTICE);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
$_sel = smarty_function_escape_special_chars((string) $_sel);
|
||||
}
|
||||
$selected[$_sel] = true;
|
||||
}
|
||||
} elseif (is_object($_val)) {
|
||||
if (method_exists($_val, "__toString")) {
|
||||
$selected = smarty_function_escape_special_chars((string) $_val->__toString());
|
||||
} else {
|
||||
trigger_error("html_checkboxes: selected attribute is an object of class '" . get_class($_val) . "' without __toString() method", E_USER_NOTICE);
|
||||
}
|
||||
} else {
|
||||
$selected = smarty_function_escape_special_chars((string) $_val);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'checkboxes':
|
||||
trigger_error('html_checkboxes: the use of the "checkboxes" attribute is deprecated, use "options" instead', E_USER_WARNING);
|
||||
$options = (array) $_val;
|
||||
break;
|
||||
|
||||
case 'assign':
|
||||
break;
|
||||
|
||||
case 'strict':
|
||||
break;
|
||||
|
||||
case 'disabled':
|
||||
case 'readonly':
|
||||
if (!empty($params['strict'])) {
|
||||
if (!is_scalar($_val)) {
|
||||
trigger_error("html_options: $_key attribute must be a scalar, only boolean true or string '$_key' will actually add the attribute", E_USER_NOTICE);
|
||||
}
|
||||
|
||||
if ($_val === true || $_val === $_key) {
|
||||
$extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_key) . '"';
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
// omit break; to fall through!
|
||||
|
||||
default:
|
||||
if (!is_array($_val)) {
|
||||
$extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_val) . '"';
|
||||
} else {
|
||||
trigger_error("html_checkboxes: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($options) && !isset($values)) {
|
||||
return '';
|
||||
} /* raise error here? */
|
||||
|
||||
$_html_result = array();
|
||||
|
||||
if (isset($options)) {
|
||||
foreach ($options as $_key => $_val) {
|
||||
$_html_result[] = smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids, $escape);
|
||||
}
|
||||
} else {
|
||||
foreach ($values as $_i => $_key) {
|
||||
$_val = isset($output[$_i]) ? $output[$_i] : '';
|
||||
$_html_result[] = smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids, $escape);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($params['assign'])) {
|
||||
$template->assign($params['assign'], $_html_result);
|
||||
} else {
|
||||
return implode("\n", $_html_result);
|
||||
}
|
||||
}
|
||||
|
||||
function smarty_function_html_checkboxes_output($name, $value, $output, $selected, $extra, $separator, $labels, $label_ids, $escape = true)
|
||||
{
|
||||
$_output = '';
|
||||
|
||||
if (is_object($value)) {
|
||||
if (method_exists($value, "__toString")) {
|
||||
$value = (string) $value->__toString();
|
||||
} else {
|
||||
trigger_error("html_options: value is an object of class '" . get_class($value) . "' without __toString() method", E_USER_NOTICE);
|
||||
|
||||
return '';
|
||||
}
|
||||
} else {
|
||||
$value = (string) $value;
|
||||
}
|
||||
|
||||
if (is_object($output)) {
|
||||
if (method_exists($output, "__toString")) {
|
||||
$output = (string) $output->__toString();
|
||||
} else {
|
||||
trigger_error("html_options: output is an object of class '" . get_class($output) . "' without __toString() method", E_USER_NOTICE);
|
||||
|
||||
return '';
|
||||
}
|
||||
} else {
|
||||
$output = (string) $output;
|
||||
}
|
||||
|
||||
if ($labels) {
|
||||
if ($label_ids) {
|
||||
$_id = smarty_function_escape_special_chars(preg_replace('![^\w\-\.]!' . Smarty::$_UTF8_MODIFIER, '_', $name . '_' . $value));
|
||||
$_output .= '<label for="' . $_id . '">';
|
||||
} else {
|
||||
$_output .= '<label>';
|
||||
}
|
||||
}
|
||||
|
||||
$name = smarty_function_escape_special_chars($name);
|
||||
$value = smarty_function_escape_special_chars($value);
|
||||
if ($escape) {
|
||||
$output = smarty_function_escape_special_chars($output);
|
||||
}
|
||||
|
||||
$_output .= '<input type="checkbox" name="' . $name . '[]" value="' . $value . '"';
|
||||
|
||||
if ($labels && $label_ids) {
|
||||
$_output .= ' id="' . $_id . '"';
|
||||
}
|
||||
|
||||
if (is_array($selected)) {
|
||||
if (isset($selected[$value])) {
|
||||
$_output .= ' checked="checked"';
|
||||
}
|
||||
} elseif ($value === $selected) {
|
||||
$_output .= ' checked="checked"';
|
||||
}
|
||||
|
||||
$_output .= $extra . ' />' . $output;
|
||||
if ($labels) {
|
||||
$_output .= '</label>';
|
||||
}
|
||||
|
||||
$_output .= $separator;
|
||||
|
||||
return $_output;
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage PluginsFunction
|
||||
*/
|
||||
|
||||
/**
|
||||
* Smarty {html_image} function plugin
|
||||
* Type: function<br>
|
||||
* Name: html_image<br>
|
||||
* Date: Feb 24, 2003<br>
|
||||
* Purpose: format HTML tags for the image<br>
|
||||
* Examples: {html_image file="/images/masthead.gif"}<br>
|
||||
* Output: <img src="/images/masthead.gif" width=400 height=23><br>
|
||||
* Params:
|
||||
* <pre>
|
||||
* - file - (required) - file (and path) of image
|
||||
* - height - (optional) - image height (default actual height)
|
||||
* - width - (optional) - image width (default actual width)
|
||||
* - basedir - (optional) - base directory for absolute paths, default is environment variable DOCUMENT_ROOT
|
||||
* - path_prefix - prefix for path output (optional, default empty)
|
||||
* </pre>
|
||||
*
|
||||
* @link http://www.smarty.net/manual/en/language.function.html.image.php {html_image}
|
||||
* (Smarty online manual)
|
||||
* @author Monte Ohrt <monte at ohrt dot com>
|
||||
* @author credits to Duda <duda@big.hu>
|
||||
* @version 1.0
|
||||
*
|
||||
* @param array $params parameters
|
||||
* @param Smarty_Internal_Template $template template object
|
||||
*
|
||||
* @throws SmartyException
|
||||
* @return string
|
||||
* @uses smarty_function_escape_special_chars()
|
||||
*/
|
||||
function smarty_function_html_image($params, $template)
|
||||
{
|
||||
require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php');
|
||||
|
||||
$alt = '';
|
||||
$file = '';
|
||||
$height = '';
|
||||
$width = '';
|
||||
$extra = '';
|
||||
$prefix = '';
|
||||
$suffix = '';
|
||||
$path_prefix = '';
|
||||
$basedir = isset($_SERVER['DOCUMENT_ROOT']) ? $_SERVER['DOCUMENT_ROOT'] : '';
|
||||
foreach ($params as $_key => $_val) {
|
||||
switch ($_key) {
|
||||
case 'file':
|
||||
case 'height':
|
||||
case 'width':
|
||||
case 'dpi':
|
||||
case 'path_prefix':
|
||||
case 'basedir':
|
||||
$$_key = $_val;
|
||||
break;
|
||||
|
||||
case 'alt':
|
||||
if (!is_array($_val)) {
|
||||
$$_key = smarty_function_escape_special_chars($_val);
|
||||
} else {
|
||||
throw new SmartyException ("html_image: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'link':
|
||||
case 'href':
|
||||
$prefix = '<a href="' . $_val . '">';
|
||||
$suffix = '</a>';
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!is_array($_val)) {
|
||||
$extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_val) . '"';
|
||||
} else {
|
||||
throw new SmartyException ("html_image: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($file)) {
|
||||
trigger_error("html_image: missing 'file' parameter", E_USER_NOTICE);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($file[0] == '/') {
|
||||
$_image_path = $basedir . $file;
|
||||
} else {
|
||||
$_image_path = $file;
|
||||
}
|
||||
|
||||
// strip file protocol
|
||||
if (stripos($params['file'], 'file://') === 0) {
|
||||
$params['file'] = substr($params['file'], 7);
|
||||
}
|
||||
|
||||
$protocol = strpos($params['file'], '://');
|
||||
if ($protocol !== false) {
|
||||
$protocol = strtolower(substr($params['file'], 0, $protocol));
|
||||
}
|
||||
|
||||
if (isset($template->smarty->security_policy)) {
|
||||
if ($protocol) {
|
||||
// remote resource (or php stream, …)
|
||||
if (!$template->smarty->security_policy->isTrustedUri($params['file'])) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// local file
|
||||
if (!$template->smarty->security_policy->isTrustedResourceDir($_image_path)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($params['width']) || !isset($params['height'])) {
|
||||
// FIXME: (rodneyrehm) getimagesize() loads the complete file off a remote resource, use custom [jpg,png,gif]header reader!
|
||||
if (!$_image_data = @getimagesize($_image_path)) {
|
||||
if (!file_exists($_image_path)) {
|
||||
trigger_error("html_image: unable to find '$_image_path'", E_USER_NOTICE);
|
||||
|
||||
return;
|
||||
} elseif (!is_readable($_image_path)) {
|
||||
trigger_error("html_image: unable to read '$_image_path'", E_USER_NOTICE);
|
||||
|
||||
return;
|
||||
} else {
|
||||
trigger_error("html_image: '$_image_path' is not a valid image file", E_USER_NOTICE);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($params['width'])) {
|
||||
$width = $_image_data[0];
|
||||
}
|
||||
if (!isset($params['height'])) {
|
||||
$height = $_image_data[1];
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($params['dpi'])) {
|
||||
if (strstr($_SERVER['HTTP_USER_AGENT'], 'Mac')) {
|
||||
// FIXME: (rodneyrehm) wrong dpi assumption
|
||||
// don't know who thought this up… even if it was true in 1998, it's definitely wrong in 2011.
|
||||
$dpi_default = 72;
|
||||
} else {
|
||||
$dpi_default = 96;
|
||||
}
|
||||
$_resize = $dpi_default / $params['dpi'];
|
||||
$width = round($width * $_resize);
|
||||
$height = round($height * $_resize);
|
||||
}
|
||||
|
||||
return $prefix . '<img src="' . $path_prefix . $file . '" alt="' . $alt . '" width="' . $width . '" height="' . $height . '"' . $extra . ' />' . $suffix;
|
||||
}
|
||||
@@ -0,0 +1,196 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage PluginsFunction
|
||||
*/
|
||||
|
||||
/**
|
||||
* Smarty {html_options} function plugin
|
||||
* Type: function<br>
|
||||
* Name: html_options<br>
|
||||
* Purpose: Prints the list of <option> tags generated from
|
||||
* the passed parameters<br>
|
||||
* Params:
|
||||
* <pre>
|
||||
* - name (optional) - string default "select"
|
||||
* - values (required) - if no options supplied) - array
|
||||
* - options (required) - if no values supplied) - associative array
|
||||
* - selected (optional) - string default not set
|
||||
* - output (required) - if not options supplied) - array
|
||||
* - id (optional) - string default not set
|
||||
* - class (optional) - string default not set
|
||||
* </pre>
|
||||
*
|
||||
* @link http://www.smarty.net/manual/en/language.function.html.options.php {html_image}
|
||||
* (Smarty online manual)
|
||||
* @author Monte Ohrt <monte at ohrt dot com>
|
||||
* @author Ralf Strehle (minor optimization) <ralf dot strehle at yahoo dot de>
|
||||
*
|
||||
* @param array $params parameters
|
||||
*
|
||||
* @return string
|
||||
* @uses smarty_function_escape_special_chars()
|
||||
*/
|
||||
function smarty_function_html_options($params)
|
||||
{
|
||||
require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php');
|
||||
|
||||
$name = null;
|
||||
$values = null;
|
||||
$options = null;
|
||||
$selected = null;
|
||||
$output = null;
|
||||
$id = null;
|
||||
$class = null;
|
||||
|
||||
$extra = '';
|
||||
|
||||
foreach ($params as $_key => $_val) {
|
||||
switch ($_key) {
|
||||
case 'name':
|
||||
case 'class':
|
||||
case 'id':
|
||||
$$_key = (string) $_val;
|
||||
break;
|
||||
|
||||
case 'options':
|
||||
$options = (array) $_val;
|
||||
break;
|
||||
|
||||
case 'values':
|
||||
case 'output':
|
||||
$$_key = array_values((array) $_val);
|
||||
break;
|
||||
|
||||
case 'selected':
|
||||
if (is_array($_val)) {
|
||||
$selected = array();
|
||||
foreach ($_val as $_sel) {
|
||||
if (is_object($_sel)) {
|
||||
if (method_exists($_sel, "__toString")) {
|
||||
$_sel = smarty_function_escape_special_chars((string) $_sel->__toString());
|
||||
} else {
|
||||
trigger_error("html_options: selected attribute contains an object of class '" . get_class($_sel) . "' without __toString() method", E_USER_NOTICE);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
$_sel = smarty_function_escape_special_chars((string) $_sel);
|
||||
}
|
||||
$selected[$_sel] = true;
|
||||
}
|
||||
} elseif (is_object($_val)) {
|
||||
if (method_exists($_val, "__toString")) {
|
||||
$selected = smarty_function_escape_special_chars((string) $_val->__toString());
|
||||
} else {
|
||||
trigger_error("html_options: selected attribute is an object of class '" . get_class($_val) . "' without __toString() method", E_USER_NOTICE);
|
||||
}
|
||||
} else {
|
||||
$selected = smarty_function_escape_special_chars((string) $_val);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'strict':
|
||||
break;
|
||||
|
||||
case 'disabled':
|
||||
case 'readonly':
|
||||
if (!empty($params['strict'])) {
|
||||
if (!is_scalar($_val)) {
|
||||
trigger_error("html_options: $_key attribute must be a scalar, only boolean true or string '$_key' will actually add the attribute", E_USER_NOTICE);
|
||||
}
|
||||
|
||||
if ($_val === true || $_val === $_key) {
|
||||
$extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_key) . '"';
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
// omit break; to fall through!
|
||||
|
||||
default:
|
||||
if (!is_array($_val)) {
|
||||
$extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_val) . '"';
|
||||
} else {
|
||||
trigger_error("html_options: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($options) && !isset($values)) {
|
||||
/* raise error here? */
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
$_html_result = '';
|
||||
$_idx = 0;
|
||||
|
||||
if (isset($options)) {
|
||||
foreach ($options as $_key => $_val) {
|
||||
$_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected, $id, $class, $_idx);
|
||||
}
|
||||
} else {
|
||||
foreach ($values as $_i => $_key) {
|
||||
$_val = isset($output[$_i]) ? $output[$_i] : '';
|
||||
$_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected, $id, $class, $_idx);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($name)) {
|
||||
$_html_class = !empty($class) ? ' class="' . $class . '"' : '';
|
||||
$_html_id = !empty($id) ? ' id="' . $id . '"' : '';
|
||||
$_html_result = '<select name="' . $name . '"' . $_html_class . $_html_id . $extra . '>' . "\n" . $_html_result . '</select>' . "\n";
|
||||
}
|
||||
|
||||
return $_html_result;
|
||||
}
|
||||
|
||||
function smarty_function_html_options_optoutput($key, $value, $selected, $id, $class, &$idx)
|
||||
{
|
||||
if (!is_array($value)) {
|
||||
$_key = smarty_function_escape_special_chars($key);
|
||||
$_html_result = '<option value="' . $_key . '"';
|
||||
if (is_array($selected)) {
|
||||
if (isset($selected[$_key])) {
|
||||
$_html_result .= ' selected="selected"';
|
||||
}
|
||||
} elseif ($_key === $selected) {
|
||||
$_html_result .= ' selected="selected"';
|
||||
}
|
||||
$_html_class = !empty($class) ? ' class="' . $class . ' option"' : '';
|
||||
$_html_id = !empty($id) ? ' id="' . $id . '-' . $idx . '"' : '';
|
||||
if (is_object($value)) {
|
||||
if (method_exists($value, "__toString")) {
|
||||
$value = smarty_function_escape_special_chars((string) $value->__toString());
|
||||
} else {
|
||||
trigger_error("html_options: value is an object of class '" . get_class($value) . "' without __toString() method", E_USER_NOTICE);
|
||||
|
||||
return '';
|
||||
}
|
||||
} else {
|
||||
$value = smarty_function_escape_special_chars((string) $value);
|
||||
}
|
||||
$_html_result .= $_html_class . $_html_id . '>' . $value . '</option>' . "\n";
|
||||
$idx ++;
|
||||
} else {
|
||||
$_idx = 0;
|
||||
$_html_result = smarty_function_html_options_optgroup($key, $value, $selected, !empty($id) ? ($id . '-' . $idx) : null, $class, $_idx);
|
||||
$idx ++;
|
||||
}
|
||||
|
||||
return $_html_result;
|
||||
}
|
||||
|
||||
function smarty_function_html_options_optgroup($key, $values, $selected, $id, $class, &$idx)
|
||||
{
|
||||
$optgroup_html = '<optgroup label="' . smarty_function_escape_special_chars($key) . '">' . "\n";
|
||||
foreach ($values as $key => $value) {
|
||||
$optgroup_html .= smarty_function_html_options_optoutput($key, $value, $selected, $id, $class, $idx);
|
||||
}
|
||||
$optgroup_html .= "</optgroup>\n";
|
||||
|
||||
return $optgroup_html;
|
||||
}
|
||||
@@ -0,0 +1,221 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage PluginsFunction
|
||||
*/
|
||||
|
||||
/**
|
||||
* Smarty {html_radios} function plugin
|
||||
* File: function.html_radios.php<br>
|
||||
* Type: function<br>
|
||||
* Name: html_radios<br>
|
||||
* Date: 24.Feb.2003<br>
|
||||
* Purpose: Prints out a list of radio input types<br>
|
||||
* Params:
|
||||
* <pre>
|
||||
* - name (optional) - string default "radio"
|
||||
* - values (required) - array
|
||||
* - options (required) - associative array
|
||||
* - checked (optional) - array default not set
|
||||
* - separator (optional) - ie <br> or
|
||||
* - output (optional) - the output next to each radio button
|
||||
* - assign (optional) - assign the output as an array to this variable
|
||||
* - escape (optional) - escape the content (not value), defaults to true
|
||||
* </pre>
|
||||
* Examples:
|
||||
* <pre>
|
||||
* {html_radios values=$ids output=$names}
|
||||
* {html_radios values=$ids name='box' separator='<br>' output=$names}
|
||||
* {html_radios values=$ids checked=$checked separator='<br>' output=$names}
|
||||
* </pre>
|
||||
*
|
||||
* @link http://smarty.php.net/manual/en/language.function.html.radios.php {html_radios}
|
||||
* (Smarty online manual)
|
||||
* @author Christopher Kvarme <christopher.kvarme@flashjab.com>
|
||||
* @author credits to Monte Ohrt <monte at ohrt dot com>
|
||||
* @version 1.0
|
||||
*
|
||||
* @param array $params parameters
|
||||
* @param Smarty_Internal_Template $template template object
|
||||
*
|
||||
* @return string
|
||||
* @uses smarty_function_escape_special_chars()
|
||||
*/
|
||||
function smarty_function_html_radios($params, $template)
|
||||
{
|
||||
require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php');
|
||||
|
||||
$name = 'radio';
|
||||
$values = null;
|
||||
$options = null;
|
||||
$selected = null;
|
||||
$separator = '';
|
||||
$escape = true;
|
||||
$labels = true;
|
||||
$label_ids = false;
|
||||
$output = null;
|
||||
$extra = '';
|
||||
|
||||
foreach ($params as $_key => $_val) {
|
||||
switch ($_key) {
|
||||
case 'name':
|
||||
case 'separator':
|
||||
$$_key = (string) $_val;
|
||||
break;
|
||||
|
||||
case 'checked':
|
||||
case 'selected':
|
||||
if (is_array($_val)) {
|
||||
trigger_error('html_radios: the "' . $_key . '" attribute cannot be an array', E_USER_WARNING);
|
||||
} elseif (is_object($_val)) {
|
||||
if (method_exists($_val, "__toString")) {
|
||||
$selected = smarty_function_escape_special_chars((string) $_val->__toString());
|
||||
} else {
|
||||
trigger_error("html_radios: selected attribute is an object of class '" . get_class($_val) . "' without __toString() method", E_USER_NOTICE);
|
||||
}
|
||||
} else {
|
||||
$selected = (string) $_val;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'escape':
|
||||
case 'labels':
|
||||
case 'label_ids':
|
||||
$$_key = (bool) $_val;
|
||||
break;
|
||||
|
||||
case 'options':
|
||||
$$_key = (array) $_val;
|
||||
break;
|
||||
|
||||
case 'values':
|
||||
case 'output':
|
||||
$$_key = array_values((array) $_val);
|
||||
break;
|
||||
|
||||
case 'radios':
|
||||
trigger_error('html_radios: the use of the "radios" attribute is deprecated, use "options" instead', E_USER_WARNING);
|
||||
$options = (array) $_val;
|
||||
break;
|
||||
|
||||
case 'assign':
|
||||
break;
|
||||
|
||||
case 'strict':
|
||||
break;
|
||||
|
||||
case 'disabled':
|
||||
case 'readonly':
|
||||
if (!empty($params['strict'])) {
|
||||
if (!is_scalar($_val)) {
|
||||
trigger_error("html_options: $_key attribute must be a scalar, only boolean true or string '$_key' will actually add the attribute", E_USER_NOTICE);
|
||||
}
|
||||
|
||||
if ($_val === true || $_val === $_key) {
|
||||
$extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_key) . '"';
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
// omit break; to fall through!
|
||||
|
||||
default:
|
||||
if (!is_array($_val)) {
|
||||
$extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_val) . '"';
|
||||
} else {
|
||||
trigger_error("html_radios: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($options) && !isset($values)) {
|
||||
/* raise error here? */
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
$_html_result = array();
|
||||
|
||||
if (isset($options)) {
|
||||
foreach ($options as $_key => $_val) {
|
||||
$_html_result[] = smarty_function_html_radios_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids, $escape);
|
||||
}
|
||||
} else {
|
||||
foreach ($values as $_i => $_key) {
|
||||
$_val = isset($output[$_i]) ? $output[$_i] : '';
|
||||
$_html_result[] = smarty_function_html_radios_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids, $escape);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($params['assign'])) {
|
||||
$template->assign($params['assign'], $_html_result);
|
||||
} else {
|
||||
return implode("\n", $_html_result);
|
||||
}
|
||||
}
|
||||
|
||||
function smarty_function_html_radios_output($name, $value, $output, $selected, $extra, $separator, $labels, $label_ids, $escape)
|
||||
{
|
||||
$_output = '';
|
||||
|
||||
if (is_object($value)) {
|
||||
if (method_exists($value, "__toString")) {
|
||||
$value = (string) $value->__toString();
|
||||
} else {
|
||||
trigger_error("html_options: value is an object of class '" . get_class($value) . "' without __toString() method", E_USER_NOTICE);
|
||||
|
||||
return '';
|
||||
}
|
||||
} else {
|
||||
$value = (string) $value;
|
||||
}
|
||||
|
||||
if (is_object($output)) {
|
||||
if (method_exists($output, "__toString")) {
|
||||
$output = (string) $output->__toString();
|
||||
} else {
|
||||
trigger_error("html_options: output is an object of class '" . get_class($output) . "' without __toString() method", E_USER_NOTICE);
|
||||
|
||||
return '';
|
||||
}
|
||||
} else {
|
||||
$output = (string) $output;
|
||||
}
|
||||
|
||||
if ($labels) {
|
||||
if ($label_ids) {
|
||||
$_id = smarty_function_escape_special_chars(preg_replace('![^\w\-\.]!' . Smarty::$_UTF8_MODIFIER, '_', $name . '_' . $value));
|
||||
$_output .= '<label for="' . $_id . '">';
|
||||
} else {
|
||||
$_output .= '<label>';
|
||||
}
|
||||
}
|
||||
|
||||
$name = smarty_function_escape_special_chars($name);
|
||||
$value = smarty_function_escape_special_chars($value);
|
||||
if ($escape) {
|
||||
$output = smarty_function_escape_special_chars($output);
|
||||
}
|
||||
|
||||
$_output .= '<input type="radio" name="' . $name . '" value="' . $value . '"';
|
||||
|
||||
if ($labels && $label_ids) {
|
||||
$_output .= ' id="' . $_id . '"';
|
||||
}
|
||||
|
||||
if ($value === $selected) {
|
||||
$_output .= ' checked="checked"';
|
||||
}
|
||||
|
||||
$_output .= $extra . ' />' . $output;
|
||||
if ($labels) {
|
||||
$_output .= '</label>';
|
||||
}
|
||||
|
||||
$_output .= $separator;
|
||||
|
||||
return $_output;
|
||||
}
|
||||
@@ -0,0 +1,387 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage PluginsFunction
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php');
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
require_once(SMARTY_PLUGINS_DIR . 'shared.make_timestamp.php');
|
||||
|
||||
/**
|
||||
* Smarty {html_select_date} plugin
|
||||
* Type: function<br>
|
||||
* Name: html_select_date<br>
|
||||
* Purpose: Prints the dropdowns for date selection.
|
||||
* ChangeLog:
|
||||
* <pre>
|
||||
* - 1.0 initial release
|
||||
* - 1.1 added support for +/- N syntax for begin
|
||||
* and end year values. (Monte)
|
||||
* - 1.2 added support for yyyy-mm-dd syntax for
|
||||
* time value. (Jan Rosier)
|
||||
* - 1.3 added support for choosing format for
|
||||
* month values (Gary Loescher)
|
||||
* - 1.3.1 added support for choosing format for
|
||||
* day values (Marcus Bointon)
|
||||
* - 1.3.2 support negative timestamps, force year
|
||||
* dropdown to include given date unless explicitly set (Monte)
|
||||
* - 1.3.4 fix behaviour of 0000-00-00 00:00:00 dates to match that
|
||||
* of 0000-00-00 dates (cybot, boots)
|
||||
* - 2.0 complete rewrite for performance,
|
||||
* added attributes month_names, *_id
|
||||
* </pre>
|
||||
*
|
||||
* @link http://www.smarty.net/manual/en/language.function.html.select.date.php {html_select_date}
|
||||
* (Smarty online manual)
|
||||
* @version 2.0
|
||||
* @author Andrei Zmievski
|
||||
* @author Monte Ohrt <monte at ohrt dot com>
|
||||
* @author Rodney Rehm
|
||||
*
|
||||
* @param array $params parameters
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function smarty_function_html_select_date($params)
|
||||
{
|
||||
// generate timestamps used for month names only
|
||||
static $_month_timestamps = null;
|
||||
static $_current_year = null;
|
||||
if ($_month_timestamps === null) {
|
||||
$_current_year = date('Y');
|
||||
$_month_timestamps = array();
|
||||
for ($i = 1; $i <= 12; $i ++) {
|
||||
$_month_timestamps[$i] = mktime(0, 0, 0, $i, 1, 2000);
|
||||
}
|
||||
}
|
||||
|
||||
/* Default values. */
|
||||
$prefix = "Date_";
|
||||
$start_year = null;
|
||||
$end_year = null;
|
||||
$display_days = true;
|
||||
$display_months = true;
|
||||
$display_years = true;
|
||||
$month_format = "%B";
|
||||
/* Write months as numbers by default GL */
|
||||
$month_value_format = "%m";
|
||||
$day_format = "%02d";
|
||||
/* Write day values using this format MB */
|
||||
$day_value_format = "%d";
|
||||
$year_as_text = false;
|
||||
/* Display years in reverse order? Ie. 2000,1999,.... */
|
||||
$reverse_years = false;
|
||||
/* Should the select boxes be part of an array when returned from PHP?
|
||||
e.g. setting it to "birthday", would create "birthday[Day]",
|
||||
"birthday[Month]" & "birthday[Year]". Can be combined with prefix */
|
||||
$field_array = null;
|
||||
/* <select size>'s of the different <select> tags.
|
||||
If not set, uses default dropdown. */
|
||||
$day_size = null;
|
||||
$month_size = null;
|
||||
$year_size = null;
|
||||
/* Unparsed attributes common to *ALL* the <select>/<input> tags.
|
||||
An example might be in the template: all_extra ='class ="foo"'. */
|
||||
$all_extra = null;
|
||||
/* Separate attributes for the tags. */
|
||||
$day_extra = null;
|
||||
$month_extra = null;
|
||||
$year_extra = null;
|
||||
/* Order in which to display the fields.
|
||||
"D" -> day, "M" -> month, "Y" -> year. */
|
||||
$field_order = 'MDY';
|
||||
/* String printed between the different fields. */
|
||||
$field_separator = "\n";
|
||||
$option_separator = "\n";
|
||||
$time = null;
|
||||
// $all_empty = null;
|
||||
// $day_empty = null;
|
||||
// $month_empty = null;
|
||||
// $year_empty = null;
|
||||
$extra_attrs = '';
|
||||
$all_id = null;
|
||||
$day_id = null;
|
||||
$month_id = null;
|
||||
$year_id = null;
|
||||
|
||||
foreach ($params as $_key => $_value) {
|
||||
switch ($_key) {
|
||||
case 'time':
|
||||
if (!is_array($_value) && $_value !== null) {
|
||||
$time = smarty_make_timestamp($_value);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'month_names':
|
||||
if (is_array($_value) && count($_value) == 12) {
|
||||
$$_key = $_value;
|
||||
} else {
|
||||
trigger_error("html_select_date: month_names must be an array of 12 strings", E_USER_NOTICE);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'prefix':
|
||||
case 'field_array':
|
||||
case 'start_year':
|
||||
case 'end_year':
|
||||
case 'day_format':
|
||||
case 'day_value_format':
|
||||
case 'month_format':
|
||||
case 'month_value_format':
|
||||
case 'day_size':
|
||||
case 'month_size':
|
||||
case 'year_size':
|
||||
case 'all_extra':
|
||||
case 'day_extra':
|
||||
case 'month_extra':
|
||||
case 'year_extra':
|
||||
case 'field_order':
|
||||
case 'field_separator':
|
||||
case 'option_separator':
|
||||
case 'all_empty':
|
||||
case 'month_empty':
|
||||
case 'day_empty':
|
||||
case 'year_empty':
|
||||
case 'all_id':
|
||||
case 'month_id':
|
||||
case 'day_id':
|
||||
case 'year_id':
|
||||
$$_key = (string) $_value;
|
||||
break;
|
||||
|
||||
case 'display_days':
|
||||
case 'display_months':
|
||||
case 'display_years':
|
||||
case 'year_as_text':
|
||||
case 'reverse_years':
|
||||
$$_key = (bool) $_value;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!is_array($_value)) {
|
||||
$extra_attrs .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_value) . '"';
|
||||
} else {
|
||||
trigger_error("html_select_date: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Note: date() is faster than strftime()
|
||||
// Note: explode(date()) is faster than date() date() date()
|
||||
if (isset($params['time']) && is_array($params['time'])) {
|
||||
if (isset($params['time'][$prefix . 'Year'])) {
|
||||
// $_REQUEST[$field_array] given
|
||||
foreach (array('Y' => 'Year', 'm' => 'Month', 'd' => 'Day') as $_elementKey => $_elementName) {
|
||||
$_variableName = '_' . strtolower($_elementName);
|
||||
$$_variableName = isset($params['time'][$prefix . $_elementName])
|
||||
? $params['time'][$prefix . $_elementName]
|
||||
: date($_elementKey);
|
||||
}
|
||||
} elseif (isset($params['time'][$field_array][$prefix . 'Year'])) {
|
||||
// $_REQUEST given
|
||||
foreach (array('Y' => 'Year', 'm' => 'Month', 'd' => 'Day') as $_elementKey => $_elementName) {
|
||||
$_variableName = '_' . strtolower($_elementName);
|
||||
$$_variableName = isset($params['time'][$field_array][$prefix . $_elementName])
|
||||
? $params['time'][$field_array][$prefix . $_elementName]
|
||||
: date($_elementKey);
|
||||
}
|
||||
} else {
|
||||
// no date found, use NOW
|
||||
list($_year, $_month, $_day) = $time = explode('-', date('Y-m-d'));
|
||||
}
|
||||
} elseif ($time === null) {
|
||||
if (array_key_exists('time', $params)) {
|
||||
$_year = $_month = $_day = $time = null;
|
||||
} else {
|
||||
list($_year, $_month, $_day) = $time = explode('-', date('Y-m-d'));
|
||||
}
|
||||
} else {
|
||||
list($_year, $_month, $_day) = $time = explode('-', date('Y-m-d', $time));
|
||||
}
|
||||
|
||||
// make syntax "+N" or "-N" work with $start_year and $end_year
|
||||
// Note preg_match('!^(\+|\-)\s*(\d+)$!', $end_year, $match) is slower than trim+substr
|
||||
foreach (array('start', 'end') as $key) {
|
||||
$key .= '_year';
|
||||
$t = $$key;
|
||||
if ($t === null) {
|
||||
$$key = (int) $_current_year;
|
||||
} elseif ($t[0] == '+') {
|
||||
$$key = (int) ($_current_year + (int)trim(substr($t, 1)));
|
||||
} elseif ($t[0] == '-') {
|
||||
$$key = (int) ($_current_year - (int)trim(substr($t, 1)));
|
||||
} else {
|
||||
$$key = (int) $$key;
|
||||
}
|
||||
}
|
||||
|
||||
// flip for ascending or descending
|
||||
if (($start_year > $end_year && !$reverse_years) || ($start_year < $end_year && $reverse_years)) {
|
||||
$t = $end_year;
|
||||
$end_year = $start_year;
|
||||
$start_year = $t;
|
||||
}
|
||||
|
||||
// generate year <select> or <input>
|
||||
if ($display_years) {
|
||||
$_extra = '';
|
||||
$_name = $field_array ? ($field_array . '[' . $prefix . 'Year]') : ($prefix . 'Year');
|
||||
if ($all_extra) {
|
||||
$_extra .= ' ' . $all_extra;
|
||||
}
|
||||
if ($year_extra) {
|
||||
$_extra .= ' ' . $year_extra;
|
||||
}
|
||||
|
||||
if ($year_as_text) {
|
||||
$_html_years = '<input type="text" name="' . $_name . '" value="' . $_year . '" size="4" maxlength="4"' . $_extra . $extra_attrs . ' />';
|
||||
} else {
|
||||
$_html_years = '<select name="' . $_name . '"';
|
||||
if ($year_id !== null || $all_id !== null) {
|
||||
$_html_years .= ' id="' . smarty_function_escape_special_chars(
|
||||
$year_id !== null ? ($year_id ? $year_id : $_name) : ($all_id ? ($all_id . $_name) : $_name)
|
||||
) . '"';
|
||||
}
|
||||
if ($year_size) {
|
||||
$_html_years .= ' size="' . $year_size . '"';
|
||||
}
|
||||
$_html_years .= $_extra . $extra_attrs . '>' . $option_separator;
|
||||
|
||||
if (isset($year_empty) || isset($all_empty)) {
|
||||
$_html_years .= '<option value="">' . (isset($year_empty) ? $year_empty : $all_empty) . '</option>' . $option_separator;
|
||||
}
|
||||
|
||||
$op = $start_year > $end_year ? - 1 : 1;
|
||||
for ($i = $start_year; $op > 0 ? $i <= $end_year : $i >= $end_year; $i += $op) {
|
||||
$_html_years .= '<option value="' . $i . '"'
|
||||
. ($_year == $i ? ' selected="selected"' : '')
|
||||
. '>' . $i . '</option>' . $option_separator;
|
||||
}
|
||||
|
||||
$_html_years .= '</select>';
|
||||
}
|
||||
}
|
||||
|
||||
// generate month <select> or <input>
|
||||
if ($display_months) {
|
||||
$_extra = '';
|
||||
$_name = $field_array ? ($field_array . '[' . $prefix . 'Month]') : ($prefix . 'Month');
|
||||
if ($all_extra) {
|
||||
$_extra .= ' ' . $all_extra;
|
||||
}
|
||||
if ($month_extra) {
|
||||
$_extra .= ' ' . $month_extra;
|
||||
}
|
||||
|
||||
$_html_months = '<select name="' . $_name . '"';
|
||||
if ($month_id !== null || $all_id !== null) {
|
||||
$_html_months .= ' id="' . smarty_function_escape_special_chars(
|
||||
$month_id !== null ? ($month_id ? $month_id : $_name) : ($all_id ? ($all_id . $_name) : $_name)
|
||||
) . '"';
|
||||
}
|
||||
if ($month_size) {
|
||||
$_html_months .= ' size="' . $month_size . '"';
|
||||
}
|
||||
$_html_months .= $_extra . $extra_attrs . '>' . $option_separator;
|
||||
|
||||
if (isset($month_empty) || isset($all_empty)) {
|
||||
$_html_months .= '<option value="">' . (isset($month_empty) ? $month_empty : $all_empty) . '</option>' . $option_separator;
|
||||
}
|
||||
|
||||
for ($i = 1; $i <= 12; $i ++) {
|
||||
$_val = sprintf('%02d', $i);
|
||||
$_text = isset($month_names) ? smarty_function_escape_special_chars($month_names[$i]) : ($month_format == "%m" ? $_val : strftime($month_format, $_month_timestamps[$i]));
|
||||
$_value = $month_value_format == "%m" ? $_val : strftime($month_value_format, $_month_timestamps[$i]);
|
||||
$_html_months .= '<option value="' . $_value . '"'
|
||||
. ($_val == $_month ? ' selected="selected"' : '')
|
||||
. '>' . $_text . '</option>' . $option_separator;
|
||||
}
|
||||
|
||||
$_html_months .= '</select>';
|
||||
}
|
||||
|
||||
// generate day <select> or <input>
|
||||
if ($display_days) {
|
||||
$_extra = '';
|
||||
$_name = $field_array ? ($field_array . '[' . $prefix . 'Day]') : ($prefix . 'Day');
|
||||
if ($all_extra) {
|
||||
$_extra .= ' ' . $all_extra;
|
||||
}
|
||||
if ($day_extra) {
|
||||
$_extra .= ' ' . $day_extra;
|
||||
}
|
||||
|
||||
$_html_days = '<select name="' . $_name . '"';
|
||||
if ($day_id !== null || $all_id !== null) {
|
||||
$_html_days .= ' id="' . smarty_function_escape_special_chars(
|
||||
$day_id !== null ? ($day_id ? $day_id : $_name) : ($all_id ? ($all_id . $_name) : $_name)
|
||||
) . '"';
|
||||
}
|
||||
if ($day_size) {
|
||||
$_html_days .= ' size="' . $day_size . '"';
|
||||
}
|
||||
$_html_days .= $_extra . $extra_attrs . '>' . $option_separator;
|
||||
|
||||
if (isset($day_empty) || isset($all_empty)) {
|
||||
$_html_days .= '<option value="">' . (isset($day_empty) ? $day_empty : $all_empty) . '</option>' . $option_separator;
|
||||
}
|
||||
|
||||
for ($i = 1; $i <= 31; $i ++) {
|
||||
$_val = sprintf('%02d', $i);
|
||||
$_text = $day_format == '%02d' ? $_val : sprintf($day_format, $i);
|
||||
$_value = $day_value_format == '%02d' ? $_val : sprintf($day_value_format, $i);
|
||||
$_html_days .= '<option value="' . $_value . '"'
|
||||
. ($_val == $_day ? ' selected="selected"' : '')
|
||||
. '>' . $_text . '</option>' . $option_separator;
|
||||
}
|
||||
|
||||
$_html_days .= '</select>';
|
||||
}
|
||||
|
||||
// order the fields for output
|
||||
$_html = '';
|
||||
for ($i = 0; $i <= 2; $i ++) {
|
||||
switch ($field_order[$i]) {
|
||||
case 'Y':
|
||||
case 'y':
|
||||
if (isset($_html_years)) {
|
||||
if ($_html) {
|
||||
$_html .= $field_separator;
|
||||
}
|
||||
$_html .= $_html_years;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
case 'M':
|
||||
if (isset($_html_months)) {
|
||||
if ($_html) {
|
||||
$_html .= $field_separator;
|
||||
}
|
||||
$_html .= $_html_months;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
case 'D':
|
||||
if (isset($_html_days)) {
|
||||
if ($_html) {
|
||||
$_html .= $field_separator;
|
||||
}
|
||||
$_html .= $_html_days;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $_html;
|
||||
}
|
||||
@@ -0,0 +1,364 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage PluginsFunction
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php');
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
require_once(SMARTY_PLUGINS_DIR . 'shared.make_timestamp.php');
|
||||
|
||||
/**
|
||||
* Smarty {html_select_time} function plugin
|
||||
* Type: function<br>
|
||||
* Name: html_select_time<br>
|
||||
* Purpose: Prints the dropdowns for time selection
|
||||
*
|
||||
* @link http://www.smarty.net/manual/en/language.function.html.select.time.php {html_select_time}
|
||||
* (Smarty online manual)
|
||||
* @author Roberto Berto <roberto@berto.net>
|
||||
* @author Monte Ohrt <monte AT ohrt DOT com>
|
||||
*
|
||||
* @param array $params parameters
|
||||
*
|
||||
* @return string
|
||||
* @uses smarty_make_timestamp()
|
||||
*/
|
||||
function smarty_function_html_select_time($params)
|
||||
{
|
||||
$prefix = "Time_";
|
||||
$field_array = null;
|
||||
$field_separator = "\n";
|
||||
$option_separator = "\n";
|
||||
$time = null;
|
||||
|
||||
$display_hours = true;
|
||||
$display_minutes = true;
|
||||
$display_seconds = true;
|
||||
$display_meridian = true;
|
||||
|
||||
$hour_format = '%02d';
|
||||
$hour_value_format = '%02d';
|
||||
$minute_format = '%02d';
|
||||
$minute_value_format = '%02d';
|
||||
$second_format = '%02d';
|
||||
$second_value_format = '%02d';
|
||||
|
||||
$hour_size = null;
|
||||
$minute_size = null;
|
||||
$second_size = null;
|
||||
$meridian_size = null;
|
||||
|
||||
$all_empty = null;
|
||||
$hour_empty = null;
|
||||
$minute_empty = null;
|
||||
$second_empty = null;
|
||||
$meridian_empty = null;
|
||||
|
||||
$all_id = null;
|
||||
$hour_id = null;
|
||||
$minute_id = null;
|
||||
$second_id = null;
|
||||
$meridian_id = null;
|
||||
|
||||
$use_24_hours = true;
|
||||
$minute_interval = 1;
|
||||
$second_interval = 1;
|
||||
|
||||
$extra_attrs = '';
|
||||
$all_extra = null;
|
||||
$hour_extra = null;
|
||||
$minute_extra = null;
|
||||
$second_extra = null;
|
||||
$meridian_extra = null;
|
||||
|
||||
foreach ($params as $_key => $_value) {
|
||||
switch ($_key) {
|
||||
case 'time':
|
||||
if (!is_array($_value) && $_value !== null) {
|
||||
$time = smarty_make_timestamp($_value);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'prefix':
|
||||
case 'field_array':
|
||||
|
||||
case 'field_separator':
|
||||
case 'option_separator':
|
||||
|
||||
case 'all_extra':
|
||||
case 'hour_extra':
|
||||
case 'minute_extra':
|
||||
case 'second_extra':
|
||||
case 'meridian_extra':
|
||||
|
||||
case 'all_empty':
|
||||
case 'hour_empty':
|
||||
case 'minute_empty':
|
||||
case 'second_empty':
|
||||
case 'meridian_empty':
|
||||
|
||||
case 'all_id':
|
||||
case 'hour_id':
|
||||
case 'minute_id':
|
||||
case 'second_id':
|
||||
case 'meridian_id':
|
||||
|
||||
case 'hour_format':
|
||||
case 'hour_value_format':
|
||||
case 'minute_format':
|
||||
case 'minute_value_format':
|
||||
case 'second_format':
|
||||
case 'second_value_format':
|
||||
$$_key = (string) $_value;
|
||||
break;
|
||||
|
||||
case 'display_hours':
|
||||
case 'display_minutes':
|
||||
case 'display_seconds':
|
||||
case 'display_meridian':
|
||||
case 'use_24_hours':
|
||||
$$_key = (bool) $_value;
|
||||
break;
|
||||
|
||||
case 'minute_interval':
|
||||
case 'second_interval':
|
||||
|
||||
case 'hour_size':
|
||||
case 'minute_size':
|
||||
case 'second_size':
|
||||
case 'meridian_size':
|
||||
$$_key = (int) $_value;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!is_array($_value)) {
|
||||
$extra_attrs .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_value) . '"';
|
||||
} else {
|
||||
trigger_error("html_select_date: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($params['time']) && is_array($params['time'])) {
|
||||
if (isset($params['time'][$prefix . 'Hour'])) {
|
||||
// $_REQUEST[$field_array] given
|
||||
foreach (array('H' => 'Hour', 'i' => 'Minute', 's' => 'Second') as $_elementKey => $_elementName) {
|
||||
$_variableName = '_' . strtolower($_elementName);
|
||||
$$_variableName = isset($params['time'][$prefix . $_elementName])
|
||||
? $params['time'][$prefix . $_elementName]
|
||||
: date($_elementKey);
|
||||
}
|
||||
$_meridian = isset($params['time'][$prefix . 'Meridian'])
|
||||
? (' ' . $params['time'][$prefix . 'Meridian'])
|
||||
: '';
|
||||
$time = strtotime($_hour . ':' . $_minute . ':' . $_second . $_meridian);
|
||||
list($_hour, $_minute, $_second) = $time = explode('-', date('H-i-s', $time));
|
||||
} elseif (isset($params['time'][$field_array][$prefix . 'Hour'])) {
|
||||
// $_REQUEST given
|
||||
foreach (array('H' => 'Hour', 'i' => 'Minute', 's' => 'Second') as $_elementKey => $_elementName) {
|
||||
$_variableName = '_' . strtolower($_elementName);
|
||||
$$_variableName = isset($params['time'][$field_array][$prefix . $_elementName])
|
||||
? $params['time'][$field_array][$prefix . $_elementName]
|
||||
: date($_elementKey);
|
||||
}
|
||||
$_meridian = isset($params['time'][$field_array][$prefix . 'Meridian'])
|
||||
? (' ' . $params['time'][$field_array][$prefix . 'Meridian'])
|
||||
: '';
|
||||
$time = strtotime($_hour . ':' . $_minute . ':' . $_second . $_meridian);
|
||||
list($_hour, $_minute, $_second) = $time = explode('-', date('H-i-s', $time));
|
||||
} else {
|
||||
// no date found, use NOW
|
||||
list($_year, $_month, $_day) = $time = explode('-', date('Y-m-d'));
|
||||
}
|
||||
} elseif ($time === null) {
|
||||
if (array_key_exists('time', $params)) {
|
||||
$_hour = $_minute = $_second = $time = null;
|
||||
} else {
|
||||
list($_hour, $_minute, $_second) = $time = explode('-', date('H-i-s'));
|
||||
}
|
||||
} else {
|
||||
list($_hour, $_minute, $_second) = $time = explode('-', date('H-i-s', $time));
|
||||
}
|
||||
|
||||
// generate hour <select>
|
||||
if ($display_hours) {
|
||||
$_html_hours = '';
|
||||
$_extra = '';
|
||||
$_name = $field_array ? ($field_array . '[' . $prefix . 'Hour]') : ($prefix . 'Hour');
|
||||
if ($all_extra) {
|
||||
$_extra .= ' ' . $all_extra;
|
||||
}
|
||||
if ($hour_extra) {
|
||||
$_extra .= ' ' . $hour_extra;
|
||||
}
|
||||
|
||||
$_html_hours = '<select name="' . $_name . '"';
|
||||
if ($hour_id !== null || $all_id !== null) {
|
||||
$_html_hours .= ' id="' . smarty_function_escape_special_chars(
|
||||
$hour_id !== null ? ($hour_id ? $hour_id : $_name) : ($all_id ? ($all_id . $_name) : $_name)
|
||||
) . '"';
|
||||
}
|
||||
if ($hour_size) {
|
||||
$_html_hours .= ' size="' . $hour_size . '"';
|
||||
}
|
||||
$_html_hours .= $_extra . $extra_attrs . '>' . $option_separator;
|
||||
|
||||
if (isset($hour_empty) || isset($all_empty)) {
|
||||
$_html_hours .= '<option value="">' . (isset($hour_empty) ? $hour_empty : $all_empty) . '</option>' . $option_separator;
|
||||
}
|
||||
|
||||
$start = $use_24_hours ? 0 : 1;
|
||||
$end = $use_24_hours ? 23 : 12;
|
||||
for ($i = $start; $i <= $end; $i ++) {
|
||||
$_val = sprintf('%02d', $i);
|
||||
$_text = $hour_format == '%02d' ? $_val : sprintf($hour_format, $i);
|
||||
$_value = $hour_value_format == '%02d' ? $_val : sprintf($hour_value_format, $i);
|
||||
|
||||
if (!$use_24_hours) {
|
||||
$_hour12 = $_hour == 0
|
||||
? 12
|
||||
: ($_hour <= 12 ? $_hour : $_hour - 12);
|
||||
}
|
||||
|
||||
$selected = $_hour !== null ? ($use_24_hours ? $_hour == $_val : $_hour12 == $_val) : null;
|
||||
$_html_hours .= '<option value="' . $_value . '"'
|
||||
. ($selected ? ' selected="selected"' : '')
|
||||
. '>' . $_text . '</option>' . $option_separator;
|
||||
}
|
||||
|
||||
$_html_hours .= '</select>';
|
||||
}
|
||||
|
||||
// generate minute <select>
|
||||
if ($display_minutes) {
|
||||
$_html_minutes = '';
|
||||
$_extra = '';
|
||||
$_name = $field_array ? ($field_array . '[' . $prefix . 'Minute]') : ($prefix . 'Minute');
|
||||
if ($all_extra) {
|
||||
$_extra .= ' ' . $all_extra;
|
||||
}
|
||||
if ($minute_extra) {
|
||||
$_extra .= ' ' . $minute_extra;
|
||||
}
|
||||
|
||||
$_html_minutes = '<select name="' . $_name . '"';
|
||||
if ($minute_id !== null || $all_id !== null) {
|
||||
$_html_minutes .= ' id="' . smarty_function_escape_special_chars(
|
||||
$minute_id !== null ? ($minute_id ? $minute_id : $_name) : ($all_id ? ($all_id . $_name) : $_name)
|
||||
) . '"';
|
||||
}
|
||||
if ($minute_size) {
|
||||
$_html_minutes .= ' size="' . $minute_size . '"';
|
||||
}
|
||||
$_html_minutes .= $_extra . $extra_attrs . '>' . $option_separator;
|
||||
|
||||
if (isset($minute_empty) || isset($all_empty)) {
|
||||
$_html_minutes .= '<option value="">' . (isset($minute_empty) ? $minute_empty : $all_empty) . '</option>' . $option_separator;
|
||||
}
|
||||
|
||||
$selected = $_minute !== null ? ($_minute - $_minute % $minute_interval) : null;
|
||||
for ($i = 0; $i <= 59; $i += $minute_interval) {
|
||||
$_val = sprintf('%02d', $i);
|
||||
$_text = $minute_format == '%02d' ? $_val : sprintf($minute_format, $i);
|
||||
$_value = $minute_value_format == '%02d' ? $_val : sprintf($minute_value_format, $i);
|
||||
$_html_minutes .= '<option value="' . $_value . '"'
|
||||
. ($selected === $i ? ' selected="selected"' : '')
|
||||
. '>' . $_text . '</option>' . $option_separator;
|
||||
}
|
||||
|
||||
$_html_minutes .= '</select>';
|
||||
}
|
||||
|
||||
// generate second <select>
|
||||
if ($display_seconds) {
|
||||
$_html_seconds = '';
|
||||
$_extra = '';
|
||||
$_name = $field_array ? ($field_array . '[' . $prefix . 'Second]') : ($prefix . 'Second');
|
||||
if ($all_extra) {
|
||||
$_extra .= ' ' . $all_extra;
|
||||
}
|
||||
if ($second_extra) {
|
||||
$_extra .= ' ' . $second_extra;
|
||||
}
|
||||
|
||||
$_html_seconds = '<select name="' . $_name . '"';
|
||||
if ($second_id !== null || $all_id !== null) {
|
||||
$_html_seconds .= ' id="' . smarty_function_escape_special_chars(
|
||||
$second_id !== null ? ($second_id ? $second_id : $_name) : ($all_id ? ($all_id . $_name) : $_name)
|
||||
) . '"';
|
||||
}
|
||||
if ($second_size) {
|
||||
$_html_seconds .= ' size="' . $second_size . '"';
|
||||
}
|
||||
$_html_seconds .= $_extra . $extra_attrs . '>' . $option_separator;
|
||||
|
||||
if (isset($second_empty) || isset($all_empty)) {
|
||||
$_html_seconds .= '<option value="">' . (isset($second_empty) ? $second_empty : $all_empty) . '</option>' . $option_separator;
|
||||
}
|
||||
|
||||
$selected = $_second !== null ? ($_second - $_second % $second_interval) : null;
|
||||
for ($i = 0; $i <= 59; $i += $second_interval) {
|
||||
$_val = sprintf('%02d', $i);
|
||||
$_text = $second_format == '%02d' ? $_val : sprintf($second_format, $i);
|
||||
$_value = $second_value_format == '%02d' ? $_val : sprintf($second_value_format, $i);
|
||||
$_html_seconds .= '<option value="' . $_value . '"'
|
||||
. ($selected === $i ? ' selected="selected"' : '')
|
||||
. '>' . $_text . '</option>' . $option_separator;
|
||||
}
|
||||
|
||||
$_html_seconds .= '</select>';
|
||||
}
|
||||
|
||||
// generate meridian <select>
|
||||
if ($display_meridian && !$use_24_hours) {
|
||||
$_html_meridian = '';
|
||||
$_extra = '';
|
||||
$_name = $field_array ? ($field_array . '[' . $prefix . 'Meridian]') : ($prefix . 'Meridian');
|
||||
if ($all_extra) {
|
||||
$_extra .= ' ' . $all_extra;
|
||||
}
|
||||
if ($meridian_extra) {
|
||||
$_extra .= ' ' . $meridian_extra;
|
||||
}
|
||||
|
||||
$_html_meridian = '<select name="' . $_name . '"';
|
||||
if ($meridian_id !== null || $all_id !== null) {
|
||||
$_html_meridian .= ' id="' . smarty_function_escape_special_chars(
|
||||
$meridian_id !== null ? ($meridian_id ? $meridian_id : $_name) : ($all_id ? ($all_id . $_name) : $_name)
|
||||
) . '"';
|
||||
}
|
||||
if ($meridian_size) {
|
||||
$_html_meridian .= ' size="' . $meridian_size . '"';
|
||||
}
|
||||
$_html_meridian .= $_extra . $extra_attrs . '>' . $option_separator;
|
||||
|
||||
if (isset($meridian_empty) || isset($all_empty)) {
|
||||
$_html_meridian .= '<option value="">' . (isset($meridian_empty) ? $meridian_empty : $all_empty) . '</option>' . $option_separator;
|
||||
}
|
||||
|
||||
$_html_meridian .= '<option value="am"' . ($_hour > 0 && $_hour < 12 ? ' selected="selected"' : '') . '>AM</option>' . $option_separator
|
||||
. '<option value="pm"' . ($_hour < 12 ? '' : ' selected="selected"') . '>PM</option>' . $option_separator
|
||||
. '</select>';
|
||||
}
|
||||
|
||||
$_html = '';
|
||||
foreach (array('_html_hours', '_html_minutes', '_html_seconds', '_html_meridian') as $k) {
|
||||
if (isset($$k)) {
|
||||
if ($_html) {
|
||||
$_html .= $field_separator;
|
||||
}
|
||||
$_html .= $$k;
|
||||
}
|
||||
}
|
||||
|
||||
return $_html;
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage PluginsFunction
|
||||
*/
|
||||
|
||||
/**
|
||||
* Smarty {html_table} function plugin
|
||||
* Type: function<br>
|
||||
* Name: html_table<br>
|
||||
* Date: Feb 17, 2003<br>
|
||||
* Purpose: make an html table from an array of data<br>
|
||||
* Params:
|
||||
* <pre>
|
||||
* - loop - array to loop through
|
||||
* - cols - number of columns, comma separated list of column names
|
||||
* or array of column names
|
||||
* - rows - number of rows
|
||||
* - table_attr - table attributes
|
||||
* - th_attr - table heading attributes (arrays are cycled)
|
||||
* - tr_attr - table row attributes (arrays are cycled)
|
||||
* - td_attr - table cell attributes (arrays are cycled)
|
||||
* - trailpad - value to pad trailing cells with
|
||||
* - caption - text for caption element
|
||||
* - vdir - vertical direction (default: "down", means top-to-bottom)
|
||||
* - hdir - horizontal direction (default: "right", means left-to-right)
|
||||
* - inner - inner loop (default "cols": print $loop line by line,
|
||||
* $loop will be printed column by column otherwise)
|
||||
* </pre>
|
||||
* Examples:
|
||||
* <pre>
|
||||
* {table loop=$data}
|
||||
* {table loop=$data cols=4 tr_attr='"bgcolor=red"'}
|
||||
* {table loop=$data cols="first,second,third" tr_attr=$colors}
|
||||
* </pre>
|
||||
*
|
||||
* @author Monte Ohrt <monte at ohrt dot com>
|
||||
* @author credit to Messju Mohr <messju at lammfellpuschen dot de>
|
||||
* @author credit to boots <boots dot smarty at yahoo dot com>
|
||||
* @version 1.1
|
||||
* @link http://www.smarty.net/manual/en/language.function.html.table.php {html_table}
|
||||
* (Smarty online manual)
|
||||
*
|
||||
* @param array $params parameters
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function smarty_function_html_table($params)
|
||||
{
|
||||
$table_attr = 'border="1"';
|
||||
$tr_attr = '';
|
||||
$th_attr = '';
|
||||
$td_attr = '';
|
||||
$cols = $cols_count = 3;
|
||||
$rows = 3;
|
||||
$trailpad = ' ';
|
||||
$vdir = 'down';
|
||||
$hdir = 'right';
|
||||
$inner = 'cols';
|
||||
$caption = '';
|
||||
$loop = null;
|
||||
|
||||
if (!isset($params['loop'])) {
|
||||
trigger_error("html_table: missing 'loop' parameter", E_USER_WARNING);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($params as $_key => $_value) {
|
||||
switch ($_key) {
|
||||
case 'loop':
|
||||
$$_key = (array) $_value;
|
||||
break;
|
||||
|
||||
case 'cols':
|
||||
if (is_array($_value) && !empty($_value)) {
|
||||
$cols = $_value;
|
||||
$cols_count = count($_value);
|
||||
} elseif (!is_numeric($_value) && is_string($_value) && !empty($_value)) {
|
||||
$cols = explode(',', $_value);
|
||||
$cols_count = count($cols);
|
||||
} elseif (!empty($_value)) {
|
||||
$cols_count = (int) $_value;
|
||||
} else {
|
||||
$cols_count = $cols;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'rows':
|
||||
$$_key = (int) $_value;
|
||||
break;
|
||||
|
||||
case 'table_attr':
|
||||
case 'trailpad':
|
||||
case 'hdir':
|
||||
case 'vdir':
|
||||
case 'inner':
|
||||
case 'caption':
|
||||
$$_key = (string) $_value;
|
||||
break;
|
||||
|
||||
case 'tr_attr':
|
||||
case 'td_attr':
|
||||
case 'th_attr':
|
||||
$$_key = $_value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$loop_count = count($loop);
|
||||
if (empty($params['rows'])) {
|
||||
/* no rows specified */
|
||||
$rows = ceil($loop_count / $cols_count);
|
||||
} elseif (empty($params['cols'])) {
|
||||
if (!empty($params['rows'])) {
|
||||
/* no cols specified, but rows */
|
||||
$cols_count = ceil($loop_count / $rows);
|
||||
}
|
||||
}
|
||||
|
||||
$output = "<table $table_attr>\n";
|
||||
|
||||
if (!empty($caption)) {
|
||||
$output .= '<caption>' . $caption . "</caption>\n";
|
||||
}
|
||||
|
||||
if (is_array($cols)) {
|
||||
$cols = ($hdir == 'right') ? $cols : array_reverse($cols);
|
||||
$output .= "<thead><tr>\n";
|
||||
|
||||
for ($r = 0; $r < $cols_count; $r ++) {
|
||||
$output .= '<th' . smarty_function_html_table_cycle('th', $th_attr, $r) . '>';
|
||||
$output .= $cols[$r];
|
||||
$output .= "</th>\n";
|
||||
}
|
||||
$output .= "</tr></thead>\n";
|
||||
}
|
||||
|
||||
$output .= "<tbody>\n";
|
||||
for ($r = 0; $r < $rows; $r ++) {
|
||||
$output .= "<tr" . smarty_function_html_table_cycle('tr', $tr_attr, $r) . ">\n";
|
||||
$rx = ($vdir == 'down') ? $r * $cols_count : ($rows - 1 - $r) * $cols_count;
|
||||
|
||||
for ($c = 0; $c < $cols_count; $c ++) {
|
||||
$x = ($hdir == 'right') ? $rx + $c : $rx + $cols_count - 1 - $c;
|
||||
if ($inner != 'cols') {
|
||||
/* shuffle x to loop over rows*/
|
||||
$x = floor($x / $cols_count) + ($x % $cols_count) * $rows;
|
||||
}
|
||||
|
||||
if ($x < $loop_count) {
|
||||
$output .= "<td" . smarty_function_html_table_cycle('td', $td_attr, $c) . ">" . $loop[$x] . "</td>\n";
|
||||
} else {
|
||||
$output .= "<td" . smarty_function_html_table_cycle('td', $td_attr, $c) . ">$trailpad</td>\n";
|
||||
}
|
||||
}
|
||||
$output .= "</tr>\n";
|
||||
}
|
||||
$output .= "</tbody>\n";
|
||||
$output .= "</table>\n";
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
function smarty_function_html_table_cycle($name, $var, $no)
|
||||
{
|
||||
if (!is_array($var)) {
|
||||
$ret = $var;
|
||||
} else {
|
||||
$ret = $var[$no % count($var)];
|
||||
}
|
||||
|
||||
return ($ret) ? ' ' . $ret : '';
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user