1
0
mirror of https://e.coding.net/circlecloud/MinecraftAccount.git synced 2026-02-15 10:59:22 +00:00

首次提交...

Signed-off-by: j502647092 <jtb1@163.com>
This commit is contained in:
j502647092
2015-11-01 22:25:03 +08:00
commit 2003fda7cb
409 changed files with 77938 additions and 0 deletions

174
ThinkPHP/Library/Vendor/Boris/Boris.php vendored Normal file
View File

@@ -0,0 +1,174 @@
<?php
/* vim: set shiftwidth=2 expandtab softtabstop=2: */
namespace Boris;
/**
* Boris is a tiny REPL for PHP.
*/
class Boris {
const VERSION = "1.0.8";
private $_prompt;
private $_historyFile;
private $_exports = array();
private $_startHooks = array();
private $_failureHooks = array();
private $_inspector;
/**
* Create a new REPL, which consists of an evaluation worker and a readline client.
*
* @param string $prompt, optional
* @param string $historyFile, optional
*/
public function __construct($prompt = 'boris> ', $historyFile = null) {
$this->setPrompt($prompt);
$this->_historyFile = $historyFile
? $historyFile
: sprintf('%s/.boris_history', getenv('HOME'))
;
$this->_inspector = new ColoredInspector();
}
/**
* Add a new hook to run in the context of the REPL when it starts.
*
* @param mixed $hook
*
* The hook is either a string of PHP code to eval(), or a Closure accepting
* the EvalWorker object as its first argument and the array of defined
* local variables in the second argument.
*
* If the hook is a callback and needs to set any local variables in the
* REPL's scope, it should invoke $worker->setLocal($var_name, $value) to
* do so.
*
* Hooks are guaranteed to run in the order they were added and the state
* set by each hook is available to the next hook (either through global
* resources, such as classes and interfaces, or through the 2nd parameter
* of the callback, if any local variables were set.
*
* @example Contrived example where one hook sets the date and another
* prints it in the REPL.
*
* $boris->onStart(function($worker, $vars){
* $worker->setLocal('date', date('Y-m-d'));
* });
*
* $boris->onStart('echo "The date is $date\n";');
*/
public function onStart($hook) {
$this->_startHooks[] = $hook;
}
/**
* Add a new hook to run in the context of the REPL when a fatal error occurs.
*
* @param mixed $hook
*
* The hook is either a string of PHP code to eval(), or a Closure accepting
* the EvalWorker object as its first argument and the array of defined
* local variables in the second argument.
*
* If the hook is a callback and needs to set any local variables in the
* REPL's scope, it should invoke $worker->setLocal($var_name, $value) to
* do so.
*
* Hooks are guaranteed to run in the order they were added and the state
* set by each hook is available to the next hook (either through global
* resources, such as classes and interfaces, or through the 2nd parameter
* of the callback, if any local variables were set.
*
* @example An example if your project requires some database connection cleanup:
*
* $boris->onFailure(function($worker, $vars){
* DB::reset();
* });
*/
public function onFailure($hook){
$this->_failureHooks[] = $hook;
}
/**
* Set a local variable, or many local variables.
*
* @example Setting a single variable
* $boris->setLocal('user', $bob);
*
* @example Setting many variables at once
* $boris->setLocal(array('user' => $bob, 'appContext' => $appContext));
*
* This method can safely be invoked repeatedly.
*
* @param array|string $local
* @param mixed $value, optional
*/
public function setLocal($local, $value = null) {
if (!is_array($local)) {
$local = array($local => $value);
}
$this->_exports = array_merge($this->_exports, $local);
}
/**
* Sets the Boris prompt text
*
* @param string $prompt
*/
public function setPrompt($prompt) {
$this->_prompt = $prompt;
}
/**
* Set an Inspector object for Boris to output return values with.
*
* @param object $inspector any object the responds to inspect($v)
*/
public function setInspector($inspector) {
$this->_inspector = $inspector;
}
/**
* Start the REPL (display the readline prompt).
*
* This method never returns.
*/
public function start() {
declare(ticks = 1);
pcntl_signal(SIGINT, SIG_IGN, true);
if (!$pipes = stream_socket_pair(
STREAM_PF_UNIX, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP)) {
throw new \RuntimeException('Failed to create socket pair');
}
$pid = pcntl_fork();
if ($pid > 0) {
if (function_exists('setproctitle')) {
setproctitle('boris (master)');
}
fclose($pipes[0]);
$client = new ReadlineClient($pipes[1]);
$client->start($this->_prompt, $this->_historyFile);
} elseif ($pid < 0) {
throw new \RuntimeException('Failed to fork child process');
} else {
if (function_exists('setproctitle')) {
setproctitle('boris (worker)');
}
fclose($pipes[1]);
$worker = new EvalWorker($pipes[0]);
$worker->setLocal($this->_exports);
$worker->setStartHooks($this->_startHooks);
$worker->setFailureHooks($this->_failureHooks);
$worker->setInspector($this->_inspector);
$worker->start();
}
}
}

View File

@@ -0,0 +1,85 @@
<?php
/* vim: set shiftwidth=2 expandtab softtabstop=2: */
namespace Boris;
/**
* Processes available command line flags.
*/
class CLIOptionsHandler {
/**
* Accept the REPL object and perform any setup necessary from the CLI flags.
*
* @param Boris $boris
*/
public function handle($boris) {
$args = getopt('hvr:', array('help', 'version', 'require:'));
foreach ($args as $option => $value) {
switch ($option) {
/*
* Sets files to load at startup, may be used multiple times,
* i.e: boris -r test.php,foo/bar.php -r ba/foo.php --require hey.php
*/
case 'r':
case 'require':
$this->_handleRequire($boris, $value);
break;
/*
* Show Usage info
*/
case 'h':
case 'help':
$this->_handleUsageInfo();
break;
/*
* Show version
*/
case 'v':
case 'version':
$this->_handleVersion();
break;
}
}
}
// -- Private Methods
private function _handleRequire($boris, $paths) {
$require = array_reduce(
(array) $paths,
function($acc, $v) { return array_merge($acc, explode(',', $v)); },
array()
);
$boris->onStart(function($worker, $scope) use($require) {
foreach($require as $path) {
require $path;
}
$worker->setLocal(get_defined_vars());
});
}
private function _handleUsageInfo() {
echo <<<USAGE
Usage: boris [options]
boris is a tiny REPL for PHP
Options:
-h, --help show this help message and exit
-r, --require a comma-separated list of files to require on startup
-v, --version show Boris version
USAGE;
exit(0);
}
private function _handleVersion() {
printf("Boris %s\n", Boris::VERSION);
exit(0);
}
}

View File

@@ -0,0 +1,273 @@
<?php
/* vim: set shiftwidth=2 expandtab softtabstop=2: */
/**
* @author Rob Morris <rob@irongaze.com>
* @author Chris Corbyn <chris@w3style.co.uk>
*
* Copyright © 2013-2014 Rob Morris.
*/
namespace Boris;
/**
* Identifies data types in data structures and syntax highlights them.
*/
class ColoredInspector implements Inspector {
static $TERM_COLORS = array(
'black' => "\033[0;30m",
'white' => "\033[1;37m",
'none' => "\033[1;30m",
'dark_grey' => "\033[1;30m",
'light_grey' => "\033[0;37m",
'dark_red' => "\033[0;31m",
'light_red' => "\033[1;31m",
'dark_green' => "\033[0;32m",
'light_green' => "\033[1;32m",
'dark_yellow' => "\033[0;33m",
'light_yellow' => "\033[1;33m",
'dark_blue' => "\033[0;34m",
'light_blue' => "\033[1;34m",
'dark_purple' => "\033[0;35m",
'light_purple' => "\033[1;35m",
'dark_cyan' => "\033[0;36m",
'light_cyan' => "\033[1;36m",
);
private $_fallback;
private $_colorMap = array();
/**
* Initialize a new ColoredInspector, using $colorMap.
*
* The colors should be an associative array with the keys:
*
* - 'integer'
* - 'float'
* - 'keyword'
* - 'string'
* - 'boolean'
* - 'default'
*
* And the values, one of the following colors:
*
* - 'none'
* - 'black'
* - 'white'
* - 'dark_grey'
* - 'light_grey'
* - 'dark_red'
* - 'light_red'
* - 'dark_green'
* - 'light_green'
* - 'dark_yellow'
* - 'light_yellow'
* - 'dark_blue'
* - 'light_blue'
* - 'dark_purple'
* - 'light_purple'
* - 'dark_cyan'
* - 'light_cyan'
*
* An empty $colorMap array effectively means 'none' for all types.
*
* @param array $colorMap
*/
public function __construct($colorMap = null) {
$this->_fallback = new DumpInspector();
if (isset($colorMap)) {
$this->_colorMap = $colorMap;
} else {
$this->_colorMap = $this->_defaultColorMap();
}
}
public function inspect($variable) {
return preg_replace(
'/^/m',
$this->_colorize('comment', '// '),
$this->_dump($variable)
);
}
/**
* Returns an associative array of an object's properties.
*
* This method is public so that subclasses may override it.
*
* @param object $value
* @return array
* */
public function objectVars($value) {
return get_object_vars($value);
}
// -- Private Methods
public function _dump($value) {
$tests = array(
'is_null' => '_dumpNull',
'is_string' => '_dumpString',
'is_bool' => '_dumpBoolean',
'is_integer' => '_dumpInteger',
'is_float' => '_dumpFloat',
'is_array' => '_dumpArray',
'is_object' => '_dumpObject'
);
foreach ($tests as $predicate => $outputMethod) {
if (call_user_func($predicate, $value))
return call_user_func(array($this, $outputMethod), $value);
}
return $this->_fallback->inspect($value);
}
private function _dumpNull($value) {
return $this->_colorize('keyword', 'NULL');
}
private function _dumpString($value) {
return $this->_colorize('string', var_export($value, true));
}
private function _dumpBoolean($value) {
return $this->_colorize('bool', var_export($value, true));
}
private function _dumpInteger($value) {
return $this->_colorize('integer', var_export($value, true));
}
private function _dumpFloat($value) {
return $this->_colorize('float', var_export($value, true));
}
private function _dumpArray($value) {
return $this->_dumpStructure('array', $value);
}
private function _dumpObject($value) {
return $this->_dumpStructure(
sprintf('object(%s)', get_class($value)),
$this->objectVars($value)
);
}
private function _dumpStructure($type, $value) {
return $this->_astToString($this->_buildAst($type, $value));
}
public function _buildAst($type, $value, $seen = array()) {
// FIXME: Improve this AST so it doesn't require access to dump() or colorize()
if ($this->_isSeen($value, $seen)) {
return $this->_colorize('default', '*** RECURSION ***');
} else {
$nextSeen = array_merge($seen, array($value));
}
if (is_object($value)) {
$vars = $this->objectVars($value);
} else {
$vars = $value;
}
$self = $this;
return array(
'name' => $this->_colorize('keyword', $type),
'children' => empty($vars) ? array() : array_combine(
array_map(array($this, '_dump'), array_keys($vars)),
array_map(
function($v) use($self, $nextSeen) {
if (is_object($v)) {
return $self->_buildAst(
sprintf('object(%s)', get_class($v)),
$v,
$nextSeen
);
} elseif (is_array($v)) {
return $self->_buildAst('array', $v, $nextSeen);
} else {
return $self->_dump($v);
}
},
array_values($vars)
)
)
);
}
public function _astToString($node, $indent = 0) {
$children = $node['children'];
$self = $this;
return implode(
"\n",
array(
sprintf('%s(', $node['name']),
implode(
",\n",
array_map(
function($k) use($self, $children, $indent) {
if (is_array($children[$k])) {
return sprintf(
'%s%s => %s',
str_repeat(' ', ($indent + 1) * 2),
$k,
$self->_astToString($children[$k], $indent + 1)
);
} else {
return sprintf(
'%s%s => %s',
str_repeat(' ', ($indent + 1) * 2),
$k,
$children[$k]
);
}
},
array_keys($children)
)
),
sprintf('%s)', str_repeat(' ', $indent * 2))
)
);
}
private function _defaultColorMap() {
return array(
'integer' => 'light_green',
'float' => 'light_yellow',
'string' => 'light_red',
'bool' => 'light_purple',
'keyword' => 'light_cyan',
'comment' => 'dark_grey',
'default' => 'none'
);
}
private function _colorize($type, $value) {
if (!empty($this->_colorMap[$type])) {
$colorName = $this->_colorMap[$type];
} else {
$colorName = $this->_colorMap['default'];
}
return sprintf(
"%s%s\033[0m",
static::$TERM_COLORS[$colorName],
$value
);
}
private function _isSeen($value, $seen) {
foreach ($seen as $v) {
if ($v === $value)
return true;
}
return false;
}
}

View File

@@ -0,0 +1,85 @@
<?php
/* vim: set shiftwidth=2 expandtab softtabstop=2: */
namespace Boris;
/**
* Config handles loading configuration files for boris
*/
class Config {
private $_searchPaths;
private $_cascade = false;
private $_files = array();
/**
* Create a new Config instance, optionally with an array
* of paths to search for configuration files.
*
* Additionally, if the second, optional boolean argument is
* true, all existing configuration files will be loaded, and
* effectively merged.
*
* @param array $searchPaths
* @param bool $cascade
*/
public function __construct($searchPaths = null, $cascade = false) {
if (is_null($searchPaths)) {
$searchPaths = array();
if ($userHome = getenv('HOME')) {
$searchPaths[] = "{$userHome}/.borisrc";
}
$searchPaths[] = getcwd() . '/.borisrc';
}
$this->_cascade = $cascade;
$this->_searchPaths = $searchPaths;
}
/**
* Searches for configuration files in the available
* search paths, and applies them to the provided
* boris instance.
*
* Returns true if any configuration files were found.
*
* @param Boris\Boris $boris
* @return bool
*/
public function apply(Boris $boris) {
$applied = false;
foreach($this->_searchPaths as $path) {
if (is_readable($path)) {
$this->_loadInIsolation($path, $boris);
$applied = true;
$this->_files[] = $path;
if (!$this->_cascade) {
break;
}
}
}
return $applied;
}
/**
* Returns an array of files that were loaded
* for this Config
*
* @return array
*/
public function loadedFiles() {
return $this->_files;
}
// -- Private Methods
private function _loadInIsolation($path, $boris) {
require $path;
}
}

View File

@@ -0,0 +1,16 @@
<?php
/* vim: set shiftwidth=2 expandtab softtabstop=2: */
namespace Boris;
/**
* Passes values through var_dump() to inspect them.
*/
class DumpInspector implements Inspector {
public function inspect($variable) {
ob_start();
var_dump($variable);
return sprintf(" → %s", trim(ob_get_clean()));
}
}

View File

@@ -0,0 +1,247 @@
<?php
/* vim: set shiftwidth=2 expandtab softtabstop=2: */
namespace Boris;
/**
* EvalWorker is responsible for evaluating PHP expressions in forked processes.
*/
class EvalWorker {
const ABNORMAL_EXIT = 255;
const DONE = "\0";
const EXITED = "\1";
const FAILED = "\2";
const READY = "\3";
private $_socket;
private $_exports = array();
private $_startHooks = array();
private $_failureHooks = array();
private $_ppid;
private $_pid;
private $_cancelled;
private $_inspector;
private $_exceptionHandler;
/**
* Create a new worker using the given socket for communication.
*
* @param resource $socket
*/
public function __construct($socket) {
$this->_socket = $socket;
$this->_inspector = new DumpInspector();
stream_set_blocking($socket, 0);
}
/**
* Set local variables to be placed in the workers's scope.
*
* @param array|string $local
* @param mixed $value, if $local is a string
*/
public function setLocal($local, $value = null) {
if (!is_array($local)) {
$local = array($local => $value);
}
$this->_exports = array_merge($this->_exports, $local);
}
/**
* Set hooks to run inside the worker before it starts looping.
*
* @param array $hooks
*/
public function setStartHooks($hooks) {
$this->_startHooks = $hooks;
}
/**
* Set hooks to run inside the worker after a fatal error is caught.
*
* @param array $hooks
*/
public function setFailureHooks($hooks) {
$this->_failureHooks = $hooks;
}
/**
* Set an Inspector object for Boris to output return values with.
*
* @param object $inspector any object the responds to inspect($v)
*/
public function setInspector($inspector) {
$this->_inspector = $inspector;
}
/**
* Start the worker.
*
* This method never returns.
*/
public function start() {
$__scope = $this->_runHooks($this->_startHooks);
extract($__scope);
$this->_write($this->_socket, self::READY);
/* Note the naming of the local variables due to shared scope with the user here */
for (;;) {
declare(ticks = 1);
// don't exit on ctrl-c
pcntl_signal(SIGINT, SIG_IGN, true);
$this->_cancelled = false;
$__input = $this->_transform($this->_read($this->_socket));
if ($__input === null) {
continue;
}
$__response = self::DONE;
$this->_ppid = posix_getpid();
$this->_pid = pcntl_fork();
if ($this->_pid < 0) {
throw new \RuntimeException('Failed to fork child labourer');
} elseif ($this->_pid > 0) {
// kill the child on ctrl-c
pcntl_signal(SIGINT, array($this, 'cancelOperation'), true);
pcntl_waitpid($this->_pid, $__status);
if (!$this->_cancelled && $__status != (self::ABNORMAL_EXIT << 8)) {
$__response = self::EXITED;
} else {
$this->_runHooks($this->_failureHooks);
$__response = self::FAILED;
}
} else {
// user exception handlers normally cause a clean exit, so Boris will exit too
if (!$this->_exceptionHandler =
set_exception_handler(array($this, 'delegateExceptionHandler'))) {
restore_exception_handler();
}
// undo ctrl-c signal handling ready for user code execution
pcntl_signal(SIGINT, SIG_DFL, true);
$__pid = posix_getpid();
$__result = eval($__input);
if (posix_getpid() != $__pid) {
// whatever the user entered caused a forked child
// (totally valid, but we don't want that child to loop and wait for input)
exit(0);
}
if (preg_match('/\s*return\b/i', $__input)) {
fwrite(STDOUT, sprintf("%s\n", $this->_inspector->inspect($__result)));
}
$this->_expungeOldWorker();
}
$this->_write($this->_socket, $__response);
if ($__response == self::EXITED) {
exit(0);
}
}
}
/**
* While a child process is running, terminate it immediately.
*/
public function cancelOperation() {
printf("Cancelling...\n");
$this->_cancelled = true;
posix_kill($this->_pid, SIGKILL);
pcntl_signal_dispatch();
}
/**
* If any user-defined exception handler is present, call it, but be sure to exit correctly.
*/
public function delegateExceptionHandler($ex) {
call_user_func($this->_exceptionHandler, $ex);
exit(self::ABNORMAL_EXIT);
}
// -- Private Methods
private function _runHooks($hooks) {
extract($this->_exports);
foreach ($hooks as $__hook) {
if (is_string($__hook)) {
eval($__hook);
} elseif (is_callable($__hook)) {
call_user_func($__hook, $this, get_defined_vars());
} else {
throw new \RuntimeException(
sprintf(
'Hooks must be closures or strings of PHP code. Got [%s].',
gettype($__hook)
)
);
}
// hooks may set locals
extract($this->_exports);
}
return get_defined_vars();
}
private function _expungeOldWorker() {
posix_kill($this->_ppid, SIGTERM);
pcntl_signal_dispatch();
}
private function _write($socket, $data) {
if (!fwrite($socket, $data)) {
throw new \RuntimeException('Socket error: failed to write data');
}
}
private function _read($socket)
{
$read = array($socket);
$except = array($socket);
if ($this->_select($read, $except) > 0) {
if ($read) {
return stream_get_contents($read[0]);
} else if ($except) {
throw new \UnexpectedValueException("Socket error: closed");
}
}
}
private function _select(&$read, &$except) {
$write = null;
set_error_handler(function(){return true;}, E_WARNING);
$result = stream_select($read, $write, $except, 10);
restore_error_handler();
return $result;
}
private function _transform($input) {
if ($input === null) {
return null;
}
$transforms = array(
'exit' => 'exit(0)'
);
foreach ($transforms as $from => $to) {
$input = preg_replace('/^\s*' . preg_quote($from, '/') . '\s*;?\s*$/', $to . ';', $input);
}
return $input;
}
}

View File

@@ -0,0 +1,14 @@
<?php
/* vim: set shiftwidth=2 expandtab softtabstop=2: */
namespace Boris;
/**
* Passes values through var_export() to inspect them.
*/
class ExportInspector implements Inspector {
public function inspect($variable) {
return sprintf(" → %s", var_export($variable, true));
}
}

View File

@@ -0,0 +1,19 @@
<?php
/* vim: set shiftwidth=2 expandtab softtabstop=2: */
namespace Boris;
/**
* Something that is capable of returning a useful representation of a variable.
*/
interface Inspector {
/**
* Return a debug-friendly string representation of $variable.
*
* @param mixed $variable
*
* @return string
*/
public function inspect($variable);
}

View File

@@ -0,0 +1,109 @@
<?php
/* vim: set shiftwidth=2 expandtab softtabstop=2: */
namespace Boris;
/**
* The Readline client is what the user spends their time entering text into.
*
* Input is collected and sent to {@link \Boris\EvalWorker} for processing.
*/
class ReadlineClient {
private $_socket;
private $_prompt;
private $_historyFile;
private $_clear = false;
/**
* Create a new ReadlineClient using $socket for communication.
*
* @param resource $socket
*/
public function __construct($socket) {
$this->_socket = $socket;
}
/**
* Start the client with an prompt and readline history path.
*
* This method never returns.
*
* @param string $prompt
* @param string $historyFile
*/
public function start($prompt, $historyFile) {
readline_read_history($historyFile);
declare(ticks = 1);
pcntl_signal(SIGCHLD, SIG_IGN);
pcntl_signal(SIGINT, array($this, 'clear'), true);
// wait for the worker to finish executing hooks
if (fread($this->_socket, 1) != EvalWorker::READY) {
throw new \RuntimeException('EvalWorker failed to start');
}
$parser = new ShallowParser();
$buf = '';
$lineno = 1;
for (;;) {
$this->_clear = false;
$line = readline(
sprintf(
'[%d] %s',
$lineno,
($buf == ''
? $prompt
: str_pad('*> ', strlen($prompt), ' ', STR_PAD_LEFT))
)
);
if ($this->_clear) {
$buf = '';
continue;
}
if (false === $line) {
$buf = 'exit(0);'; // ctrl-d acts like exit
}
if (strlen($line) > 0) {
readline_add_history($line);
}
$buf .= sprintf("%s\n", $line);
if ($statements = $parser->statements($buf)) {
++$lineno;
$buf = '';
foreach ($statements as $stmt) {
if (false === $written = fwrite($this->_socket, $stmt)) {
throw new \RuntimeException('Socket error: failed to write data');
}
if ($written > 0) {
$status = fread($this->_socket, 1);
if ($status == EvalWorker::EXITED) {
readline_write_history($historyFile);
echo "\n";
exit(0);
} elseif ($status == EvalWorker::FAILED) {
break;
}
}
}
}
}
}
/**
* Clear the input buffer.
*/
public function clear() {
// FIXME: I'd love to have this send \r to readline so it puts the user on a blank line
$this->_clear = true;
}
}

View File

@@ -0,0 +1,233 @@
<?php
/* vim: set shiftwidth=2 expandtab softtabstop=2: */
namespace Boris;
/**
* The ShallowParser takes whatever is currently buffered and chunks it into individual statements.
*/
class ShallowParser {
private $_pairs = array(
'(' => ')',
'{' => '}',
'[' => ']',
'"' => '"',
"'" => "'",
'//' => "\n",
'#' => "\n",
'/*' => '*/',
'<<<' => '_heredoc_special_case_'
);
private $_initials;
public function __construct() {
$this->_initials = '/^(' . implode('|', array_map(array($this, 'quote'), array_keys($this->_pairs))) . ')/';
}
/**
* Break the $buffer into chunks, with one for each highest-level construct possible.
*
* If the buffer is incomplete, returns an empty array.
*
* @param string $buffer
*
* @return array
*/
public function statements($buffer) {
$result = $this->_createResult($buffer);
while (strlen($result->buffer) > 0) {
$this->_resetResult($result);
if ($result->state == '<<<') {
if (!$this->_initializeHeredoc($result)) {
continue;
}
}
$rules = array('_scanEscapedChar', '_scanRegion', '_scanStateEntrant', '_scanWsp', '_scanChar');
foreach ($rules as $method) {
if ($this->$method($result)) {
break;
}
}
if ($result->stop) {
break;
}
}
if (!empty($result->statements) && trim($result->stmt) === '' && strlen($result->buffer) == 0) {
$this->_combineStatements($result);
$this->_prepareForDebug($result);
return $result->statements;
}
}
public function quote($token) {
return preg_quote($token, '/');
}
// -- Private Methods
private function _createResult($buffer) {
$result = new \stdClass();
$result->buffer = $buffer;
$result->stmt = '';
$result->state = null;
$result->states = array();
$result->statements = array();
$result->stop = false;
return $result;
}
private function _resetResult($result) {
$result->stop = false;
$result->state = end($result->states);
$result->terminator = $result->state
? '/^(.*?' . preg_quote($this->_pairs[$result->state], '/') . ')/s'
: null
;
}
private function _combineStatements($result) {
$combined = array();
foreach ($result->statements as $scope) {
if (trim($scope) == ';' || substr(trim($scope), -1) != ';') {
$combined[] = ((string) array_pop($combined)) . $scope;
} else {
$combined[] = $scope;
}
}
$result->statements = $combined;
}
private function _prepareForDebug($result) {
$result->statements []= $this->_prepareDebugStmt(array_pop($result->statements));
}
private function _initializeHeredoc($result) {
if (preg_match('/^([\'"]?)([a-z_][a-z0-9_]*)\\1/i', $result->buffer, $match)) {
$docId = $match[2];
$result->stmt .= $match[0];
$result->buffer = substr($result->buffer, strlen($match[0]));
$result->terminator = '/^(.*?\n' . $docId . ');?\n/s';
return true;
} else {
return false;
}
}
private function _scanWsp($result) {
if (preg_match('/^\s+/', $result->buffer, $match)) {
if (!empty($result->statements) && $result->stmt === '') {
$result->statements[] = array_pop($result->statements) . $match[0];
} else {
$result->stmt .= $match[0];
}
$result->buffer = substr($result->buffer, strlen($match[0]));
return true;
} else {
return false;
}
}
private function _scanEscapedChar($result) {
if (($result->state == '"' || $result->state == "'")
&& preg_match('/^[^' . $result->state . ']*?\\\\./s', $result->buffer, $match)) {
$result->stmt .= $match[0];
$result->buffer = substr($result->buffer, strlen($match[0]));
return true;
} else {
return false;
}
}
private function _scanRegion($result) {
if (in_array($result->state, array('"', "'", '<<<', '//', '#', '/*'))) {
if (preg_match($result->terminator, $result->buffer, $match)) {
$result->stmt .= $match[1];
$result->buffer = substr($result->buffer, strlen($match[1]));
array_pop($result->states);
} else {
$result->stop = true;
}
return true;
} else {
return false;
}
}
private function _scanStateEntrant($result) {
if (preg_match($this->_initials, $result->buffer, $match)) {
$result->stmt .= $match[0];
$result->buffer = substr($result->buffer, strlen($match[0]));
$result->states[] = $match[0];
return true;
} else {
return false;
}
}
private function _scanChar($result) {
$chr = substr($result->buffer, 0, 1);
$result->stmt .= $chr;
$result->buffer = substr($result->buffer, 1);
if ($result->state && $chr == $this->_pairs[$result->state]) {
array_pop($result->states);
}
if (empty($result->states) && ($chr == ';' || $chr == '}')) {
if (!$this->_isLambda($result->stmt) || $chr == ';') {
$result->statements[] = $result->stmt;
$result->stmt = '';
}
}
return true;
}
private function _isLambda($input) {
return preg_match(
'/^([^=]*?=\s*)?function\s*\([^\)]*\)\s*(use\s*\([^\)]*\)\s*)?\s*\{.*\}\s*;?$/is',
trim($input)
);
}
private function _isReturnable($input) {
$input = trim($input);
if (substr($input, -1) == ';' && substr($input, 0, 1) != '{') {
return $this->_isLambda($input) || !preg_match(
'/^(' .
'echo|print|exit|die|goto|global|include|include_once|require|require_once|list|' .
'return|do|for|foreach|while|if|function|namespace|class|interface|abstract|switch|' .
'declare|throw|try|unset' .
')\b/i',
$input
);
} else {
return false;
}
}
private function _prepareDebugStmt($input) {
if ($this->_isReturnable($input) && !preg_match('/^\s*return/i', $input)) {
$input = sprintf('return %s', $input);
}
return $input;
}
}

View File

@@ -0,0 +1,970 @@
<?php
/*
* Edition: ET080708
* Desc: Core Engine 3 (Memcache/Compile/Replace)
* File: template.core.php
* Author: David Meng
* Site: http://www.systn.com
* Email: mdchinese@gmail.com
*
*/
error_reporting(0);
define("ET3!",TRUE);
class ETCore{
var $ThisFile = ''; //当前文件
var $IncFile = ''; //引入文件
var $ThisValue = array(); //当前数值
var $FileList = array(); //载入文件列表
var $IncList = array(); //引入文件列表
var $ImgDir = array('images'); //图片地址目录
var $HtmDir = 'cache_htm/'; //静态存放的目录
var $HtmID = ''; //静态文件ID
var $HtmTime = '180'; //秒为单位,默认三分钟
var $AutoImage = 1; //自动解析图片目录开关默认值
var $Hacker = "<?php if(!defined('ET3!')){die('You are Hacker!<br>Power by Ease Template!');}";
var $Compile = array();
var $Analysis = array();
var $Emc = array();
/**
* 声明模板用法
*/
function ETCoreStart(
$set = array(
'ID' =>'1', //缓存ID
'TplType' =>'htm', //模板格式
'CacheDir' =>'cache', //缓存目录
'TemplateDir'=>'template' , //模板存放目录
'AutoImage' =>'on' , //自动解析图片目录开关 on表示开放 off表示关闭
'LangDir' =>'language' , //语言文件存放的目录
'Language' =>'default' , //语言的默认文件
'Copyright' =>'off' , //版权保护
'MemCache' =>'' , //Memcache服务器地址例如:127.0.0.1:11211
)
){
$this->TplID = (defined('TemplateID')?TemplateID:( ((int)@$set['ID']<=1)?1:(int)$set['ID']) ).'_';
$this->CacheDir = (defined('NewCache')?NewCache:( (trim($set['CacheDir']) != '')?$set['CacheDir']:'cache') ).'/';
$this->TemplateDir = (defined('NewTemplate')?NewTemplate:( (trim($set['TemplateDir']) != '')?$set['TemplateDir']:'template') ).'/';
$this->Ext = (@$set['TplType'] != '')?$set['TplType']:'htm';
$this->AutoImage = (@$set['AutoImage']=='off')?0:1;
$this->Copyright = (@$set['Copyright']=='off')?0:1;
$this->Server = (is_array($GLOBALS['_SERVER']))?$GLOBALS['_SERVER']:$_SERVER;
$this->version = (trim($_GET['EaseTemplateVer']))?die('Ease Templae E3!'):'';
//载入语言文件
$this->LangDir = (defined('LangDir')?LangDir:( ((@$set['LangDir']!='language' && @$set['LangDir'])?$set['LangDir']:'language') )).'/';
if(is_dir($this->LangDir)){
$this->Language = (defined('Language')?Language:( (($set['Language']!='default' && $set['Language'])?$set['Language']:'default') ));
if(@is_file($this->LangDir.$this->Language.'.php')){
$lang = array();
@include_once $this->LangDir.$this->Language.'.php';
$this->LangData = $lang;
}
}else{
$this->Language = 'default';
}
//缓存目录检测以及运行模式
if(@ereg(':',$set['MemCache'])){
$this->RunType = 'MemCache';
$memset = explode(":",$set['MemCache']);
$this->Emc = memcache_connect($memset[0], $memset[1]) OR die("Could not connect!");
}else{
$this->RunType = (@substr(@sprintf('%o', @fileperms($this->CacheDir)), -3)==777 && is_dir($this->CacheDir))?'Cache':'Replace';
}
$CompileBasic = array(
'/(\{\s*|<!--\s*)inc_php:([a-zA-Z0-9_\[\]\.\,\/\?\=\#\:\;\-\|\^]{5,200})(\s*\}|\s*-->)/eis',
'/<!--\s*DEL\s*-->/is',
'/<!--\s*IF(\[|\()(.+?)(\]|\))\s*-->/is',
'/<!--\s*ELSEIF(\[|\()(.+?)(\]|\))\s*-->/is',
'/<!--\s*ELSE\s*-->/is',
'/<!--\s*END\s*-->/is',
'/<!--\s*([a-zA-Z0-9_\$\[\]\'\"]{2,60})\s*(AS|as)\s*(.+?)\s*-->/',
'/<!--\s*while\:\s*(.+?)\s*-->/is',
'/(\{\s*|<!--\s*)lang\:(.+?)(\s*\}|\s*-->)/eis',
'/(\{\s*|<!--\s*)row\:(.+?)(\s*\}|\s*-->)/eis',
'/(\{\s*|<!--\s*)color\:\s*([\#0-9A-Za-z]+\,[\#0-9A-Za-z]+)(\s*\}|\s*-->)/eis',
'/(\{\s*|<!--\s*)dir\:([^\{\}]{1,100})(\s*\}|\s*-->)/eis',
'/(\{\s*|<!--\s*)run\:(\}|\s*-->)\s*(.+?)\s*(\{|<!--\s*)\/run(\s*\}|\s*-->)/is',
'/(\{\s*|<!--\s*)run\:(.+?)(\s*\}|\s*-->)/is',
'/\{([a-zA-Z0-9_\'\"\[\]\$]{1,100})\}/',
);
$this->Compile = (is_array($this->Compile))?array_merge($this->Compile,$CompileBasic):$CompileBasic;
$AnalysisBasic = array(
'$this->inc_php("\\2")',
'";if($ET_Del==true){echo"',
'";if(\\2){echo"',
'";}elseif(\\2){echo"',
'";}else{echo"',
'";}echo"',
'";\$_i=0;foreach((array)\\1 AS \\3){\$_i++;echo"',
'";\$_i=0;while(\\1){\$_i++;echo"',
'$this->lang("\\2")',
'$this->Row("\\2")',
'$this->Color("\\2")',
'$this->Dirs("\\2")',
'";\\3;echo"',
'";\\2;echo"',
'";echo \$\\1;echo"',
);
$this->Analysis = (is_array($this->Analysis))?array_merge($this->Analysis,$AnalysisBasic):$AnalysisBasic;
}
/**
* 设置数值
* set_var(变量名或是数组,设置数值[数组不设置此值]);
*/
function set_var(
$name,
$value = ''
){
if (is_array($name)){
$this->ThisValue = @array_merge($this->ThisValue,$name);
}else{
$this->ThisValue[$name] = $value;
}
}
/**
* 设置模板文件
* set_file(文件名,设置目录);
*/
function set_file(
$FileName,
$NewDir = ''
){
//当前模板名
$this->ThisFile = $FileName.'.'.$this->Ext;
//目录地址检测
$this->FileDir[$this->ThisFile] = (trim($NewDir) != '')?$NewDir.'/':$this->TemplateDir;
$this->IncFile[$FileName] = $this->FileDir[$this->ThisFile].$this->ThisFile;
if(!is_file($this->IncFile[$FileName]) && $this->Copyright==1){
die('Sorry, The file <b>'.$this->IncFile[$FileName].'</b> does not exist.');
}
//bug 系统
$this->IncList[] = $this->ThisFile;
}
//解析替换程序
function ParseCode(
$FileList = '',
$CacheFile = ''
){
//模板数据
$ShowTPL = '';
//解析续载
if (@is_array($FileList) && $FileList!='include_page'){
foreach ($FileList AS $K=>$V) {
$ShowTPL .= $this->reader($V.$K);
}
}else{
//如果指定文件地址则载入
$SourceFile = ($FileList!='')?$FileList:$this->FileDir[$this->ThisFile].$this->ThisFile;
if(!is_file($SourceFile) && $this->Copyright==1){
die('Sorry, The file <b>'.$SourceFile.'</b> does not exist.');
}
$ShowTPL = $this->reader($SourceFile);
}
//引用模板处理
$ShowTPL = $this->inc_preg($ShowTPL);
//检测run方法
$run = 0;
if (eregi("run:",$ShowTPL)){
$run = 1;
//Fix =
$ShowTPL = preg_replace('/(\{|<!--\s*)run:(\}|\s*-->)\s*=/','{run:}echo ',$ShowTPL);
$ShowTPL = preg_replace('/(\{|<!--\s*)run:\s*=/','{run:echo ',$ShowTPL);
//Fix Run 1
$ShowTPL = preg_replace('/(\{|<!--\s*)run:(\}|\s*-->)\s*(.+?)\s*(\{|<!--\s*)\/run(\}|\s*-->)/is', '(T_T)\\3;(T_T!)',$ShowTPL);
}
//Fix XML
if (eregi("<?xml",$ShowTPL)){
$ShowTPL = @preg_replace('/<\?(xml.+?)\?>/is', '<ET>\\1</ET>', $ShowTPL);
}
//修复代码中\n换行错误
$ShowTPL = str_replace('\\','\\\\',$ShowTPL);
//修复双引号问题
$ShowTPL = str_replace('"','\"',$ShowTPL);
//编译运算
$ShowTPL = @preg_replace($this->Compile, $this->Analysis, $ShowTPL);
//分析图片地址
$ShowTPL = $this->ImgCheck($ShowTPL);
//Fix 模板中金钱符号
$ShowTPL = str_replace('$','\$',$ShowTPL);
//修复php运行错误
$ShowTPL = @preg_replace("/\";(.+?)echo\"/e", '$this->FixPHP(\'\\1\')', $ShowTPL);
//Fix Run 2
if ($run==1){
$ShowTPL = preg_replace("/\(T_T\)(.+?)\(T_T!\)/ise", '$this->FixPHP(\'\\1\')', $ShowTPL);
}
//还原xml
$ShowTPL = (strrpos($ShowTPL,'<ET>'))?@preg_replace('/ET>(.+?)<\/ET/is', '?\\1?', $ShowTPL):$ShowTPL;
//修复"问题
$ShowTPL = str_replace('echo ""','echo "\"',$ShowTPL);
//从数组中将变量导入到当前的符号表
@extract($this->Value());
ob_start();
ob_implicit_flush(0);
@eval('echo "'.$ShowTPL.'";');
$contents = ob_get_contents();
ob_end_clean();
//Cache htm
if($this->HtmID){
$this->writer($this->HtmDir.$this->HtmID,$this->Hacker."?>".$contents);
}
//编译模板
if ($this->RunType=='Cache'){
$this->CompilePHP($ShowTPL,$CacheFile);
}
//错误检查
if(strlen($contents)<=0){
//echo $ShowTPL;
die('<br>Sorry, Error or complicated syntax error exists in '.$SourceFile.' file.');
}
return $contents;
}
/**
* 多语言
*/
function lang(
$str = ''
){
if (is_dir($this->LangDir)){
//采用MD5效验
$id = md5($str);
//不存在数据则写入
if($this->LangData[$id]=='' && $this->Language=='default'){
//语言包文件
if (@is_file($this->LangDir.$this->Language.'.php')){
unset($lang);
@include($this->LangDir.$this->Language.'.php');
}
//如果检测到有数据则输出
if ($lang[$id]){
$out = str_replace('\\','\\\\',$lang[$id]);
return str_replace('"','\"',$out);
}
//修复'多\问题
$str = str_replace("\\'","'",$str);
//语言文件过大时采取建立新文件
if(strlen($docs)>400){
$this->writer($this->LangDir.$this->Language.'.'.$id.'.php','<? $etl = "'.$str.'";?>');
$docs= substr($str,0,40); //简要说明
$docs = str_replace('\"','"',$docs);
$docs = str_replace('\\\\','\\',$docs);
$str = 'o(O_O)o.ET Lang.o(*_*)o'; //语言新文件
}else{
$docs = str_replace('\"','"',$str);
$docs = str_replace('\\\\','\\',$docs);
}
//文件安全处理
$data = (!is_file($this->LangDir.'default.php'))?"<?\n/**\n/* SYSTN ET Language For ".$this->Language."\n*/\n\n\n":'';
if (trim($str)){
//写入数据
$data .= "/**".date("Y.m.d",time())."\n";
$data.= $docs."\n";
$data.= "*/\n";
$data.= '$lang["'.$id.'"] = "'.$str.'";'."\n\n";
$this->writer($this->LangDir.'default.php',$data,'a+');
}
}
//单独语言文件包
if($this->LangData[$id]=='o(O_O)o.ET Lang.o(*_*)o'){
unset($etl);
include($this->LangDir.$this->Language.".".$id.".php");
$this->LangData[$id] = $etl;
}
$out = ($this->LangData[$id])?$this->LangData[$id]:$str;
//输出部分要做处理
if(($this->RunType=='Replace' || $this->RunType!='Replace') && $data==''){
$out = str_replace('\\','\\\\',$out);
$out = str_replace('"','\"',$out);
}
return $out;
}else{
return $str;
}
}
/**
* inc引用函数
*/
function inc_preg(
$content
){
return preg_replace('/<\!--\s*\#include\s*file\s*=(\"|\')([a-zA-Z0-9_\.\|]{1,100})(\"|\')\s*-->/eis', '$this->inc("\\2")', preg_replace('/(\{\s*|<!--\s*)inc\:([^\{\} ]{1,100})(\s*\}|\s*-->)/eis', '$this->inc("\\2")', $content));
}
/**
* 引用函数运算
*/
function inc(
$Files = ''
){
if($Files){
if (!strrpos($Files,$this->Ext)){
$Files = $Files.".".$this->Ext;
}
$FileLs = $this->TemplateDir.$Files;
$contents =$this->ParseCode($FileLs,$Files);
if($this->RunType=='Cache'){
//引用模板
$this->IncList[] = $Files;
$cache_file = $this->CacheDir.$this->TplID.$Files.".".$this->Language.".php";
return "<!-- ET_inc_cache[".$Files."] -->
<!-- IF(@is_file('".$cache_file."')) -->{inc_php:".$cache_file."}
<!-- IF(\$EaseTemplate3_Cache) -->{run:@eval('echo \"'.\$EaseTemplate3_Cache.'\";')}<!-- END -->
<!-- END -->";
}elseif($this->RunType=='MemCache'){
//cache date
memcache_set($this->Emc,$Files.'_date', time()) OR die("Failed to save data at the server.");
memcache_set($this->Emc,$Files, $contents) OR die("Failed to save data at the server");
return "<!-- ET_inc_cache[".$Files."] -->".$contents;
}else{
//引用模板
$this->IncList[] = $Files;
return $contents;
}
}
}
/**
* 编译解析处理
*/
function CompilePHP(
$content='',
$cachename = ''
){
if ($content){
//如果没有安全文件则自动创建
if($this->RunType=='Cache' && !is_file($this->CacheDir.'index.htm')){
$Ease_name = 'Ease Template!';
$Ease_base = "<title>$Ease_name</title><a href='http://www.systn.com'>$Ease_name</a>";
$this->writer($this->CacheDir.'index.htm',$Ease_base);
$this->writer($this->CacheDir.'index.html',$Ease_base);
$this->writer($this->CacheDir.'default.htm',$Ease_base);
}
//编译记录
$content = str_replace("\\","\\\\",$content);
$content = str_replace("'","\'",$content);
$content = str_replace('echo"";',"",$content); //替换多余数据
$wfile = ($cachename)?$cachename:$this->ThisFile;
$this->writer($this->FileName($wfile,$this->TplID) ,$this->Hacker.'$EaseTemplate3_Cache = \''.$content.'\';');
}
}
//修复PHP执行时产生的错误
function FixPHP(
$content=''
){
$content = str_replace('\\\\','\\',$content);
return '";'.str_replace('\\"','"',str_replace('\$','$',$content)).'echo"';
}
/**
* 检测缓存是否要更新
* filename 缓存文件名
* settime 指定事件则提供更新只用于memcache
*/
function FileUpdate($filname,$settime=0){
//检测设置模板文件
if (is_array($this->IncFile)){
unset($k,$v);
$update = 0;
$settime = ($settime>0)?$settime:@filemtime($filname);
foreach ($this->IncFile AS $k=>$v) {
if (@filemtime($v)>$settime){$update = 1;}
}
//更新缓存
if($update==1){
return false;
}else {
return $filname;
}
}else{
return $filname;
}
}
/**
* 输出运算
* Filename 连载编译输出文件名
*/
function output(
$Filename = ''
){
switch($this->RunType){
//Mem编译模式
case'MemCache':
if ($Filename=='include_page'){
//直接输出文件
return $this->reader($this->FileDir[$this->ThisFile].$this->ThisFile);
}else{
$FileNames = ($Filename)?$Filename:$this->ThisFile;
$CacheFile = $this->FileName($FileNames,$this->TplID);
//检测记录时间
$updateT = memcache_get($this->Emc,$CacheFile.'_date');
$update = $this->FileUpdate($CacheFile,$updateT);
$CacheData = memcache_get($this->Emc,$CacheFile);
if(trim($CacheData) && $update){
//获得列表文件
unset($ks,$vs);
preg_match_all('/<\!-- ET\_inc\_cache\[(.+?)\] -->/',$CacheData, $IncFile);
if (is_array($IncFile[1])){
foreach ($IncFile[1] AS $ks=>$vs) {
$this->IncList[] = $vs;
$listDate = memcache_get($this->Emc,$vs.'_date');
echo @filemtime($this->TemplateDir.$vs).' - '.$listDate.'<br>';
//更新inc缓存
if (@filemtime($this->TemplateDir.$vs)>$listDate){
$update = 1;
$this->inc($vs);
}
}
//更新数据
if ($update == 1){
$CacheData = $this->ParseCode($this->FileList,$Filename);
//cache date
@memcache_set($this->Emc,$CacheFile.'_date', time()) OR die("Failed to save data at the server.");
@memcache_set($this->Emc,$CacheFile, $CacheData) OR die("Failed to save data at the server.");
}
}
//Close
memcache_close($this->Emc);
return $CacheData;
}else{
if ($Filename){
$CacheData = $this->ParseCode($this->FileList,$Filename);
//cache date
@memcache_set($this->Emc,$CacheFile.'_date', time()) OR die("Failed to save data at the server.");
@memcache_set($this->Emc,$CacheFile, $CacheData) OR die("Failed to save data at the server.");
//Close
memcache_close($this->Emc);
return $CacheData;
}else{
$CacheData = $this->ParseCode();
//cache date
@memcache_set($this->Emc,$CacheFile.'_date', time()) OR die("Failed to save data at the server.");
@memcache_set($this->Emc,$CacheFile, $CacheData) OR die("Failed to save data at the server2");
//Close
memcache_close($this->Emc);
return $CacheData;
}
}
}
break;
//编译模式
case'Cache':
if ($Filename=='include_page'){
//直接输出文件
return $this->reader($this->FileDir[$this->ThisFile].$this->ThisFile);
}else{
$FileNames = ($Filename)?$Filename:$this->ThisFile;
$CacheFile = $this->FileName($FileNames,$this->TplID);
$CacheFile = $this->FileUpdate($CacheFile);
if (@is_file($CacheFile)){
@extract($this->Value());
ob_start();
ob_implicit_flush(0);
include $CacheFile;
//获得列表文件
if($EaseTemplate3_Cache!=''){
unset($ks,$vs);
preg_match_all('/<\!-- ET\_inc\_cache\[(.+?)\] -->/',$EaseTemplate3_Cache, $IncFile);
if (is_array($IncFile[1])){
foreach ($IncFile[1] AS $ks=>$vs) {
$this->IncList[] = $vs;
//更新inc缓存
if (@filemtime($this->TemplateDir.$vs)>@filemtime($this->CacheDir.$this->TplID.$vs.'.'.$this->Language.'.php')){
$this->inc($vs);
}
}
}
@eval('echo "'.$EaseTemplate3_Cache.'";');
$contents = ob_get_contents();
ob_end_clean();
return $contents;
}
}else{
if ($Filename){
return $this->ParseCode($this->FileList,$Filename);
}else{
return $this->ParseCode();
}
}
}
break;
//替换引擎
default:
if($Filename){
if ($Filename=='include_page'){
//直接输出文件
return $this->reader($this->FileDir[$this->ThisFile].$this->ThisFile);
}else {
return $this->ParseCode($this->FileList);
}
}else{
return $this->ParseCode();
}
}
}
/**
* 连载函数
*/
function n(){
//连载模板
$this->FileList[$this->ThisFile] = $this->FileDir[$this->ThisFile];
}
/**
* 输出模板内容
* Filename 连载编译输出文件名
*/
function r(
$Filename = ''
){
return $this->output($Filename);
}
/**
* 打印模板内容
* Filename 连载编译输出文件名
*/
function p(
$Filename = ''
){
echo $this->output($Filename);
}
/**
* 分析图片地址
*/
function ImgCheck(
$content
){
//Check Image Dir
if($this->AutoImage==1){
$NewFileDir = $this->FileDir[$this->ThisFile];
//FIX img
if(is_array($this->ImgDir)){
foreach($this->ImgDir AS $rep){
$rep = trim($rep);
//检测是否执行替换
if(strrpos($content,$rep."/")){
if(substr($rep,-1)=='/'){
$rep = substr($rep,0,strlen($rep)-1);
}
$content = str_replace($rep.'/',$NewFileDir.$rep.'/',$content);
}
}
}
//FIX Dir
$NewFileDirs = $NewFileDir.$NewFileDir;
if(strrpos($content,$NewFileDirs)){
$content = str_replace($NewFileDirs,$NewFileDir,$content);
}
}
return $content;
}
/**
* 获得所有设置与公共变量
*/
function Value(){
return (is_array($this->ThisValue))?array_merge($this->ThisValue,$GLOBALS):$GLOBALS;
}
/**
* 清除设置
*/
function clear(){
$this->RunType = 'Replace';
}
/**
* 静态文件写入
*/
function htm_w(
$w_dir = '',
$w_filename = '',
$w_content = ''
){
$dvs = '';
if($w_dir && $w_filename && $w_content){
//目录检测数量
$w_dir_ex = explode('/',$w_dir);
$w_new_dir = ''; //处理后的写入目录
unset($dvs,$fdk,$fdv,$w_dir_len);
foreach((array)$w_dir_ex AS $dvs){
if(trim($dvs) && $dvs!='..'){
$w_dir_len .= '../';
$w_new_dir .= $dvs.'/';
if (!@is_dir($w_new_dir)) @mkdir($w_new_dir, 0777);
}
}
//获得需要更改的目录数
foreach((array)$this->FileDir AS $fdk=>$fdv){
$w_content = str_replace($fdv,$w_dir_len.str_replace('../','',$fdv),$w_content);
}
$this->writer($w_dir.$w_filename,$w_content);
}
}
/**
* 改变静态刷新时间
*/
function htm_time($times=0){
if((int)$times>0){
$this->HtmTime = (int)$times;
}
}
/**
* 静态文件存放的绝对目录
*/
function htm_dir($Name = ''){
if(trim($Name)){
$this->HtmDir = trim($Name).'/';
}
}
/**
* 产生静态文件输出
*/
function HtmCheck(
$Name = ''
){
$this->HtmID = md5(trim($Name)? trim($Name).'.php' : $this->Server['REQUEST_URI'].'.php' );
//检测时间
if(is_file($this->HtmDir.$this->HtmID) && (time() - @filemtime($this->HtmDir.$this->HtmID)<=$this->HtmTime)){
ob_start();
ob_implicit_flush(0);
include $this->HtmDir.$this->HtmID;
$HtmContent = ob_get_contents();
ob_end_clean();
return $HtmContent;
}
}
/**
* 打印静态内容
*/
function htm_p(
$Name = ''
){
$output = $this->HtmCheck($Name);
if ($output){
die($this->HtmCheck($Name));
}
}
/**
* 输出静态内容
*/
function htm_r(
$Name = ''
){
return $this->HtmCheck($Name);
}
/**
* 解析文件
*/
function FileName(
$name,
$id = '1'
){
$extdir = explode("/",$name);
$dircnt = @count($extdir) - 1;
$extdir[$dircnt] = $id.$extdir[$dircnt];
return $this->CacheDir.implode("_",$extdir).".".$this->Language.'.php';
}
/**
* 检测引入文件
*/
function inc_php(
$url = ''
){
$parse = parse_url($url);
unset($vals,$code_array);
foreach((array)explode('&',$parse['query']) AS $vals){
$code_array .= preg_replace('/(.+)=(.+)/',"\$_GET['\\1']= \$\\1 ='\\2';",$vals);
}
return '";'.$code_array.' @include(\''.$parse['path'].'\');echo"';
}
/**
* 换行函数
* Row(换行数,换行颜色);
* Row("5,#ffffff:#e1e1e1");
*/
function Row(
$Num = ''
){
$Num = trim($Num);
if($Num != ''){
$Nums = explode(",",$Num);
$Numr = ((int)$Nums[0]>0)?(int)$Nums[0]:2;
$input = (trim($Nums[1]) == '')?'</tr><tr>':$Nums[1];
if(trim($Nums[1]) != ''){
$Co = explode(":",$Nums[1]);
$OutStr = "if(\$_i%$Numr===0){\$row_count++;echo(\$row_count%2===0)?'</tr><tr bgcolor=\"$Co[0]\">':'</tr><tr bgcolor=\"$Co[1]\">';}";
}else{
$OutStr = "if(\$_i%$Numr===0){echo '$input';}";
}
return '";'.$OutStr.'echo "';
}
}
/**
* 间隔变色
* Color(两组颜色代码);
* Color('#FFFFFF,#DCDCDC');
*/
function Color(
$color = ''
){
if($color != ''){
$OutStr = preg_replace("/(.+),(.+)/","_i%2===0)?'\\1':'\\2';",$color);
if(strrpos($OutStr,"%2")){
return '";echo(\$'.$OutStr.'echo "';
}
}
}
/**
* 映射图片地址
*/
function Dirs(
$adds = ''
){
$adds_ary = explode(",",$adds);
if(is_array($adds_ary)){
$this->ImgDir = (is_array($this->ImgDir))?@array_merge($adds_ary, $this->ImgDir):$adds_ary;
}
}
/**
* 读取函数
* reader(文件名);
*/
function reader(
$filename
){
$get_fun = @get_defined_functions();
return (in_array('file_get_contents',$get_fun['internal']))?@file_get_contents($filename):@implode("", @file($filename));
}
/**
* 写入函数
* writer(文件名,写入数据, 写入数据方式);
*/
function writer(
$filename,
$data = '',
$mode='w'
){
if(trim($filename)){
$file = @fopen($filename, $mode);
$filedata = @fwrite($file, $data);
@fclose($file);
}
if(!is_file($filename)){
die('Sorry,'.$filename.' file write in failed!');
}
}
/**
* 引入模板系统
* 察看当前使用的模板以及调试信息
*/
function inc_list(){
if(is_array($this->IncList)){
$EXTS = explode("/",$this->Server['REQUEST_URI']);
$Last = count($EXTS) -1;
//处理清除工作 START
if(strrpos($EXTS[$Last],'Ease_Templatepage=Clear') && trim($EXTS[$Last]) != ''){
$dir_name = $this->CacheDir;
if(file_exists($dir_name)){
$handle=@opendir($dir_name);
while($tmp_file=@readdir($handle)){
if(@file_exists($dir_name.$tmp_file)){
@unlink($dir_name.$tmp_file);
}
}
@closedir($handle);
}
$GoURL = urldecode(preg_replace("/.+?REFERER=(.+?)!!!/","\\1",$EXTS[$Last]));
die('<script language="javascript" type="text/javascript">location="'.urldecode($GoURL).'";</script>');
}
//处理清除工作 END
$list_file = array();
$file_nums = count($this->IncList);
$AllSize = 0;
foreach($this->IncList AS $Ks=>$Vs){
$FSize[$Ks] = @filesize($this->TemplateDir.$Vs);
$AllSize += $FSize[$Ks];
}
foreach($this->IncList AS $K=>$V){
$File_Size = @round($FSize[$K] / 1024 * 100) / 100 . 'KB';
$Fwidth = @floor(100*$FSize[$K]/$AllSize);
$list_file[] = "<tr><td colspan=\"2\" bgcolor=\"#F7F7F7\" title='".$Fwidth."%'><a href='".$this->TemplateDir.$V."' target='_blank'><font color='#6F7D84' style='font-size:14px;'>".$this->TemplateDir.$V."</font></a>
<font color='#B4B4B4' style='font-size:10px;'>".$File_Size."</font>
<table border='1' width='".$Fwidth."%' style='border-collapse: collapse' bordercolor='#89A3ED' bgcolor='#4886B3'><tr><td></td></tr></table></td></tr>";
}
//连接地址
$BackURL = preg_replace("/.+\//","\\1",$this->Server['REQUEST_URI']);
$NowPAGE = 'http://'.$this->Server['HTTP_HOST'].$this->Server['SCRIPT_NAME'];
$clear_link = $NowPAGE."?Ease_Templatepage=Clear&REFERER=".urlencode($BackURL)."!!!";
$sf13 = ' style="font-size:13px;color:#666666"';
echo '<br><table border="1" width="100%" cellpadding="3" style="border-collapse: collapse" bordercolor="#DCDCDC">
<tr bgcolor="#B5BDC1"><td><font color=#000000 style="font-size:16px;"><b>Include Templates (Num:'.count($this-> IncList).')</b></font></td>
<td align="right">';
if($this->RunType=='Cache'){
echo '[<a onclick="alert(\'Cache file is successfully deleted\');location=\''.$clear_link.'\';return false;" href="'.$clear_link.'"><font'.$sf13.'>Clear Cache</font></a>]';
}
echo '</td></tr><tr><td colspan="2" bgcolor="#F7F7F7"><table border="0" width="100%" cellpadding="0" style="border-collapse: collapse">
<tr><td'.$sf13.'>Cache File ID: <b>'.substr($this->TplID,0,-1).'</b></td>
<td'.$sf13.'>Index: <b>'.((count($this->FileList)==0)?'False':'True').'</b></td>
<td'.$sf13.'>Format: <b>'.$this->Ext.'</b></td>
<td'.$sf13.'>Cache: <b>'.($this->RunType=='MemCache'?'Memcache Engine':($this->RunType == 'Replace'?'Replace Engine':$this->CacheDir)).'</b></td>
<td'.$sf13.'>Template: <b>'.$this->TemplateDir.'</b></td></tr>
</table></td></tr>'.implode("",$list_file)."</table>";
}
}
}
?>

View File

@@ -0,0 +1,42 @@
<?php
/*
* Edition: ET080708
* Desc: ET Template
* File: template.ease.php
* Author: David Meng
* Site: http://www.systn.com
* Email: mdchinese@gmail.com
*
*/
//引入核心文件
if (is_file(dirname(__FILE__).'/template.core.php')){
include dirname(__FILE__).'/template.core.php';
}else {
die('Sorry. Not load core file.');
}
Class template extends ETCore{
/**
* 声明模板用法
*/
function template(
$set = array(
'ID' =>'1', //缓存ID
'TplType' =>'htm', //模板格式
'CacheDir' =>'cache', //缓存目录
'TemplateDir'=>'template' , //模板存放目录
'AutoImage' =>'on' , //自动解析图片目录开关 on表示开放 off表示关闭
'LangDir' =>'language' , //语言文件存放的目录
'Language' =>'default' , //语言的默认文件
'Copyright' =>'off' , //版权保护
'MemCache' =>'' , //Memcache服务器地址例如:127.0.0.1:11211
)
){
parent::ETCoreStart($set);
}
}
?>

View File

@@ -0,0 +1,53 @@
<?php
/**********************************************************\
| |
| hprose |
| |
| Official WebSite: http://www.hprose.com/ |
| http://www.hprose.net/ |
| http://www.hprose.org/ |
| |
\**********************************************************/
/**********************************************************\
* *
* HproseClassManager.php *
* *
* hprose class manager library for php5. *
* *
* LastModified: Nov 12, 2013 *
* Author: Ma Bingyao <andot@hprfc.com> *
* *
\**********************************************************/
class HproseClassManager {
private static $classCache1 = array();
private static $classCache2 = array();
public static function register($class, $alias) {
self::$classCache1[$alias] = $class;
self::$classCache2[$class] = $alias;
}
public static function getClassAlias($class) {
if (array_key_exists($class, self::$classCache2)) {
return self::$classCache2[$class];
}
$alias = str_replace('\\', '_', $class);
self::register($class, $alias);
return $alias;
}
public static function getClass($alias) {
if (array_key_exists($alias, self::$classCache1)) {
return self::$classCache1[$alias];
}
if (!class_exists($alias)) {
$class = str_replace('_', '\\', $alias);
if (class_exists($class)) {
self::register($class, $alias);
return $class;
}
eval("class " . $alias . " { }");
}
return $alias;
}
}
?>

View File

@@ -0,0 +1,134 @@
<?php
/**********************************************************\
| |
| hprose |
| |
| Official WebSite: http://www.hprose.com/ |
| http://www.hprose.net/ |
| http://www.hprose.org/ |
| |
\**********************************************************/
/**********************************************************\
* *
* HproseClient.php *
* *
* hprose client library for php5. *
* *
* LastModified: Nov 13, 2013 *
* Author: Ma Bingyao <andot@hprfc.com> *
* *
\**********************************************************/
require_once('HproseCommon.php');
require_once('HproseIO.php');
abstract class HproseClient {
protected $url;
private $filter;
private $simple;
protected abstract function send($request);
public function __construct($url = '') {
$this->useService($url);
$this->filter = NULL;
$this->simple = false;
}
public function useService($url = '', $namespace = '') {
if ($url) {
$this->url = $url;
}
return new HproseProxy($this, $namespace);
}
public function invoke($functionName, &$arguments = array(), $byRef = false, $resultMode = HproseResultMode::Normal, $simple = NULL) {
if ($simple === NULL) $simple = $this->simple;
$stream = new HproseStringStream(HproseTags::TagCall);
$hproseWriter = ($simple ? new HproseSimpleWriter($stream) : new HproseWriter($stream));
$hproseWriter->writeString($functionName);
if (count($arguments) > 0 || $byRef) {
$hproseWriter->reset();
$hproseWriter->writeList($arguments);
if ($byRef) {
$hproseWriter->writeBoolean(true);
}
}
$stream->write(HproseTags::TagEnd);
$request = $stream->toString();
if ($this->filter) $request = $this->filter->outputFilter($request);
$stream->close();
$response = $this->send($request);
if ($this->filter) $response = $this->filter->inputFilter($response);
if ($resultMode == HproseResultMode::RawWithEndTag) {
return $response;
}
if ($resultMode == HproseResultMode::Raw) {
return substr($response, 0, -1);
}
$stream = new HproseStringStream($response);
$hproseReader = new HproseReader($stream);
$result = NULL;
while (($tag = $hproseReader->checkTags(
array(HproseTags::TagResult,
HproseTags::TagArgument,
HproseTags::TagError,
HproseTags::TagEnd))) !== HproseTags::TagEnd) {
switch ($tag) {
case HproseTags::TagResult:
if ($resultMode == HproseResultMode::Serialized) {
$result = $hproseReader->readRaw()->toString();
}
else {
$hproseReader->reset();
$result = &$hproseReader->unserialize();
}
break;
case HproseTags::TagArgument:
$hproseReader->reset();
$args = &$hproseReader->readList(true);
for ($i = 0; $i < count($arguments); $i++) {
$arguments[$i] = &$args[$i];
}
break;
case HproseTags::TagError:
$hproseReader->reset();
throw new HproseException($hproseReader->readString(true));
break;
}
}
return $result;
}
public function getFilter() {
return $this->filter;
}
public function setFilter($filter) {
$this->filter = $filter;
}
public function getSimpleMode() {
return $this->simple;
}
public function setSimpleMode($simple = true) {
$this->simple = $simple;
}
public function __call($function, $arguments) {
return $this->invoke($function, $arguments);
}
public function __get($name) {
return new HproseProxy($this, $name . '_');
}
}
class HproseProxy {
private $client;
private $namespace;
public function __construct($client, $namespace = '') {
$this->client = $client;
$this->namespace = $namespace;
}
public function __call($function, $arguments) {
$function = $this->namespace . $function;
return $this->client->invoke($function, $arguments);
}
public function __get($name) {
return new HproseProxy($this->client, $this->namespace . $name . '_');
}
}
?>

View File

@@ -0,0 +1,816 @@
<?php
/**********************************************************\
| |
| hprose |
| |
| Official WebSite: http://www.hprose.com/ |
| http://www.hprose.net/ |
| http://www.hprose.org/ |
| |
\**********************************************************/
/**********************************************************\
* *
* HproseCommon.php *
* *
* hprose common library for php5. *
* *
* LastModified: Nov 15, 2013 *
* Author: Ma Bingyao <andot@hprfc.com> *
* *
\**********************************************************/
class HproseResultMode {
const Normal = 0;
const Serialized = 1;
const Raw = 2;
const RawWithEndTag = 3;
}
class HproseException extends Exception {}
interface HproseFilter {
function inputFilter($data);
function outputFilter($data);
}
class HproseDate {
public $year;
public $month;
public $day;
public $utc = false;
public function __construct() {
$args_num = func_num_args();
$args = func_get_args();
switch ($args_num) {
case 0:
$time = getdate();
$this->year = $time['year'];
$this->month = $time['mon'];
$this->day = $time['mday'];
break;
case 1:
$time = false;
if (is_int($args[0])) {
$time = getdate($args[0]);
}
elseif (is_string($args[0])) {
$time = getdate(strtotime($args[0]));
}
if (is_array($time)) {
$this->year = $time['year'];
$this->month = $time['mon'];
$this->day = $time['mday'];
}
elseif ($args[0] instanceof HproseDate) {
$this->year = $args[0]->year;
$this->month = $args[0]->month;
$this->day = $args[0]->day;
}
else {
throw new HproseException('Unexpected arguments');
}
break;
case 4:
$this->utc = $args[3];
case 3:
if (!self::isValidDate($args[0], $args[1], $args[2])) {
throw new HproseException('Unexpected arguments');
}
$this->year = $args[0];
$this->month = $args[1];
$this->day = $args[2];
break;
default:
throw new HproseException('Unexpected arguments');
}
}
public function addDays($days) {
if (!is_int($days)) return false;
$year = $this->year;
if ($days == 0) return true;
if ($days >= 146097 || $days <= -146097) {
$remainder = $days % 146097;
if ($remainder < 0) {
$remainder += 146097;
}
$years = 400 * (int)(($days - $remainder) / 146097);
$year += $years;
if ($year < 1 || $year > 9999) return false;
$days = $remainder;
}
if ($days >= 36524 || $days <= -36524) {
$remainder = $days % 36524;
if ($remainder < 0) {
$remainder += 36524;
}
$years = 100 * (int)(($days - $remainder) / 36524);
$year += $years;
if ($year < 1 || $year > 9999) return false;
$days = $remainder;
}
if ($days >= 1461 || $days <= -1461) {
$remainder = $days % 1461;
if ($remainder < 0) {
$remainder += 1461;
}
$years = 4 * (int)(($days - $remainder) / 1461);
$year += $years;
if ($year < 1 || $year > 9999) return false;
$days = $remainder;
}
$month = $this->month;
while ($days >= 365) {
if ($year >= 9999) return false;
if ($month <= 2) {
if ((($year % 4) == 0) ? (($year % 100) == 0) ? (($year % 400) == 0) : true : false) {
$days -= 366;
}
else {
$days -= 365;
}
$year++;
}
else {
$year++;
if ((($year % 4) == 0) ? (($year % 100) == 0) ? (($year % 400) == 0) : true : false) {
$days -= 366;
}
else {
$days -= 365;
}
}
}
while ($days < 0) {
if ($year <= 1) return false;
if ($month <= 2) {
$year--;
if ((($year % 4) == 0) ? (($year % 100) == 0) ? (($year % 400) == 0) : true : false) {
$days += 366;
}
else {
$days += 365;
}
}
else {
if ((($year % 4) == 0) ? (($year % 100) == 0) ? (($year % 400) == 0) : true : false) {
$days += 366;
}
else {
$days += 365;
}
$year--;
}
}
$daysInMonth = cal_days_in_month(CAL_GREGORIAN, $month, $year);
$day = $this->day;
while ($day + $days > $daysInMonth) {
$days -= $daysInMonth - $day + 1;
$month++;
if ($month > 12) {
if ($year >= 9999) return false;
$year++;
$month = 1;
}
$day = 1;
$daysInMonth = cal_days_in_month(CAL_GREGORIAN, $month, $year);
}
$day += $days;
$this->year = $year;
$this->month = $month;
$this->day = $day;
return true;
}
public function addMonths($months) {
if (!is_int($months)) return false;
if ($months == 0) return true;
$month = $this->month + $months;
$months = ($month - 1) % 12 + 1;
if ($months < 1) {
$months += 12;
}
$years = (int)(($month - $months) / 12);
if ($this->addYears($years)) {
$daysInMonth = cal_days_in_month(CAL_GREGORIAN, $months, $this->year);
if ($this->day > $daysInMonth) {
$months++;
$this->day -= $daysInMonth;
}
$this->month = (int)$months;
return true;
}
else {
return false;
}
}
public function addYears($years) {
if (!is_int($years)) return false;
if ($years == 0) return true;
$year = $this->year + $years;
if ($year < 1 || $year > 9999) return false;
$this->year = $year;
return true;
}
public function timestamp() {
if ($this->utc) {
return gmmktime(0, 0, 0, $this->month, $this->day, $this->year);
}
else {
return mktime(0, 0, 0, $this->month, $this->day, $this->year);
}
}
public function toString($fullformat = true) {
$format = ($fullformat ? '%04d-%02d-%02d': '%04d%02d%02d');
$str = sprintf($format, $this->year, $this->month, $this->day);
if ($this->utc) {
$str .= 'Z';
}
return $str;
}
public function __toString() {
return $this->toString();
}
public static function isLeapYear($year) {
return (($year % 4) == 0) ? (($year % 100) == 0) ? (($year % 400) == 0) : true : false;
}
public static function daysInMonth($year, $month) {
if (($month < 1) || ($month > 12)) {
return false;
}
return cal_days_in_month(CAL_GREGORIAN, $month, $year);
}
public static function isValidDate($year, $month, $day) {
if (($year >= 1) && ($year <= 9999)) {
return checkdate($month, $day, $year);
}
return false;
}
public function dayOfWeek() {
$num = func_num_args();
if ($num == 3) {
$args = func_get_args();
$y = $args[0];
$m = $args[1];
$d = $args[2];
}
else {
$y = $this->year;
$m = $this->month;
$d = $this->day;
}
$d += $m < 3 ? $y-- : $y - 2;
return ((int)(23 * $m / 9) + $d + 4 + (int)($y / 4) - (int)($y / 100) + (int)($y / 400)) % 7;
}
public function dayOfYear() {
static $daysToMonth365 = array(0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365);
static $daysToMonth366 = array(0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366);
$num = func_num_args();
if ($num == 3) {
$args = func_get_args();
$y = $args[0];
$m = $args[1];
$d = $args[2];
}
else {
$y = $this->year;
$m = $this->month;
$d = $this->day;
}
$days = self::isLeapYear($y) ? $daysToMonth365 : $daysToMonth366;
return $days[$m - 1] + $d;
}
}
class HproseTime {
public $hour;
public $minute;
public $second;
public $microsecond = 0;
public $utc = false;
public function __construct() {
$args_num = func_num_args();
$args = func_get_args();
switch ($args_num) {
case 0:
$time = getdate();
$timeofday = gettimeofday();
$this->hour = $time['hours'];
$this->minute = $time['minutes'];
$this->second = $time['seconds'];
$this->microsecond = $timeofday['usec'];
break;
case 1:
$time = false;
if (is_int($args[0])) {
$time = getdate($args[0]);
}
elseif (is_string($args[0])) {
$time = getdate(strtotime($args[0]));
}
if (is_array($time)) {
$this->hour = $time['hours'];
$this->minute = $time['minutes'];
$this->second = $time['seconds'];
}
elseif ($args[0] instanceof HproseTime) {
$this->hour = $args[0]->hour;
$this->minute = $args[0]->minute;
$this->second = $args[0]->second;
$this->microsecond = $args[0]->microsecond;
}
else {
throw new HproseException('Unexpected arguments');
}
break;
case 5:
$this->utc = $args[4];
case 4:
if (($args[3] < 0) || ($args[3] > 999999)) {
throw new HproseException('Unexpected arguments');
}
$this->microsecond = $args[3];
case 3:
if (!self::isValidTime($args[0], $args[1], $args[2])) {
throw new HproseException('Unexpected arguments');
}
$this->hour = $args[0];
$this->minute = $args[1];
$this->second = $args[2];
break;
default:
throw new HproseException('Unexpected arguments');
}
}
public function timestamp() {
if ($this->utc) {
return gmmktime($this->hour, $this->minute, $this->second) +
($this->microsecond / 1000000);
}
else {
return mktime($this->hour, $this->minute, $this->second) +
($this->microsecond / 1000000);
}
}
public function toString($fullformat = true) {
if ($this->microsecond == 0) {
$format = ($fullformat ? '%02d:%02d:%02d': '%02d%02d%02d');
$str = sprintf($format, $this->hour, $this->minute, $this->second);
}
if ($this->microsecond % 1000 == 0) {
$format = ($fullformat ? '%02d:%02d:%02d.%03d': '%02d%02d%02d.%03d');
$str = sprintf($format, $this->hour, $this->minute, $this->second, (int)($this->microsecond / 1000));
}
else {
$format = ($fullformat ? '%02d:%02d:%02d.%06d': '%02d%02d%02d.%06d');
$str = sprintf($format, $this->hour, $this->minute, $this->second, $this->microsecond);
}
if ($this->utc) {
$str .= 'Z';
}
return $str;
}
public function __toString() {
return $this->toString();
}
public static function isValidTime($hour, $minute, $second, $microsecond = 0) {
return !(($hour < 0) || ($hour > 23) ||
($minute < 0) || ($minute > 59) ||
($second < 0) || ($second > 59) ||
($microsecond < 0) || ($microsecond > 999999));
}
}
class HproseDateTime extends HproseDate {
public $hour;
public $minute;
public $second;
public $microsecond = 0;
public function __construct() {
$args_num = func_num_args();
$args = func_get_args();
switch ($args_num) {
case 0:
$time = getdate();
$timeofday = gettimeofday();
$this->year = $time['year'];
$this->month = $time['mon'];
$this->day = $time['mday'];
$this->hour = $time['hours'];
$this->minute = $time['minutes'];
$this->second = $time['seconds'];
$this->microsecond = $timeofday['usec'];
break;
case 1:
$time = false;
if (is_int($args[0])) {
$time = getdate($args[0]);
}
elseif (is_string($args[0])) {
$time = getdate(strtotime($args[0]));
}
if (is_array($time)) {
$this->year = $time['year'];
$this->month = $time['mon'];
$this->day = $time['mday'];
$this->hour = $time['hours'];
$this->minute = $time['minutes'];
$this->second = $time['seconds'];
}
elseif ($args[0] instanceof HproseDate) {
$this->year = $args[0]->year;
$this->month = $args[0]->month;
$this->day = $args[0]->day;
$this->hour = 0;
$this->minute = 0;
$this->second = 0;
}
elseif ($args[0] instanceof HproseTime) {
$this->year = 1970;
$this->month = 1;
$this->day = 1;
$this->hour = $args[0]->hour;
$this->minute = $args[0]->minute;
$this->second = $args[0]->second;
$this->microsecond = $args[0]->microsecond;
}
elseif ($args[0] instanceof HproseDateTime) {
$this->year = $args[0]->year;
$this->month = $args[0]->month;
$this->day = $args[0]->day;
$this->hour = $args[0]->hour;
$this->minute = $args[0]->minute;
$this->second = $args[0]->second;
$this->microsecond = $args[0]->microsecond;
}
else {
throw new HproseException('Unexpected arguments');
}
break;
case 2:
if (($args[0] instanceof HproseDate) && ($args[1] instanceof HproseTime)) {
$this->year = $args[0]->year;
$this->month = $args[0]->month;
$this->day = $args[0]->day;
$this->hour = $args[1]->hour;
$this->minute = $args[1]->minute;
$this->second = $args[1]->second;
$this->microsecond = $args[1]->microsecond;
}
else {
throw new HproseException('Unexpected arguments');
}
break;
case 3:
if (!self::isValidDate($args[0], $args[1], $args[2])) {
throw new HproseException('Unexpected arguments');
}
$this->year = $args[0];
$this->month = $args[1];
$this->day = $args[2];
$this->hour = 0;
$this->minute = 0;
$this->second = 0;
break;
case 8:
$this->utc = $args[7];
case 7:
if (($args[6] < 0) || ($args[6] > 999999)) {
throw new HproseException('Unexpected arguments');
}
$this->microsecond = $args[6];
case 6:
if (!self::isValidDate($args[0], $args[1], $args[2])) {
throw new HproseException('Unexpected arguments');
}
if (!self::isValidTime($args[3], $args[4], $args[5])) {
throw new HproseException('Unexpected arguments');
}
$this->year = $args[0];
$this->month = $args[1];
$this->day = $args[2];
$this->hour = $args[3];
$this->minute = $args[4];
$this->second = $args[5];
break;
default:
throw new HproseException('Unexpected arguments');
}
}
public function addMicroseconds($microseconds) {
if (!is_int($microseconds)) return false;
if ($microseconds == 0) return true;
$microsecond = $this->microsecond + $microseconds;
$microseconds = $microsecond % 1000000;
if ($microseconds < 0) {
$microseconds += 1000000;
}
$seconds = (int)(($microsecond - $microseconds) / 1000000);
if ($this->addSeconds($seconds)) {
$this->microsecond = (int)$microseconds;
return true;
}
else {
return false;
}
}
public function addSeconds($seconds) {
if (!is_int($seconds)) return false;
if ($seconds == 0) return true;
$second = $this->second + $seconds;
$seconds = $second % 60;
if ($seconds < 0) {
$seconds += 60;
}
$minutes = (int)(($second - $seconds) / 60);
if ($this->addMinutes($minutes)) {
$this->second = (int)$seconds;
return true;
}
else {
return false;
}
}
public function addMinutes($minutes) {
if (!is_int($minutes)) return false;
if ($minutes == 0) return true;
$minute = $this->minute + $minutes;
$minutes = $minute % 60;
if ($minutes < 0) {
$minutes += 60;
}
$hours = (int)(($minute - $minutes) / 60);
if ($this->addHours($hours)) {
$this->minute = (int)$minutes;
return true;
}
else {
return false;
}
}
public function addHours($hours) {
if (!is_int($hours)) return false;
if ($hours == 0) return true;
$hour = $this->hour + $hours;
$hours = $hour % 24;
if ($hours < 0) {
$hours += 24;
}
$days = (int)(($hour - $hours) / 24);
if ($this->addDays($days)) {
$this->hour = (int)$hours;
return true;
}
else {
return false;
}
}
public function after($when) {
if (!($when instanceof HproseDateTime)) {
$when = new HproseDateTime($when);
}
if ($this->utc != $when->utc) return ($this->timestamp() > $when->timestamp());
if ($this->year < $when->year) return false;
if ($this->year > $when->year) return true;
if ($this->month < $when->month) return false;
if ($this->month > $when->month) return true;
if ($this->day < $when->day) return false;
if ($this->day > $when->day) return true;
if ($this->hour < $when->hour) return false;
if ($this->hour > $when->hour) return true;
if ($this->minute < $when->minute) return false;
if ($this->minute > $when->minute) return true;
if ($this->second < $when->second) return false;
if ($this->second > $when->second) return true;
if ($this->microsecond < $when->microsecond) return false;
if ($this->microsecond > $when->microsecond) return true;
return false;
}
public function before($when) {
if (!($when instanceof HproseDateTime)) {
$when = new HproseDateTime($when);
}
if ($this->utc != $when->utc) return ($this->timestamp() < $when->timestamp());
if ($this->year < $when->year) return true;
if ($this->year > $when->year) return false;
if ($this->month < $when->month) return true;
if ($this->month > $when->month) return false;
if ($this->day < $when->day) return true;
if ($this->day > $when->day) return false;
if ($this->hour < $when->hour) return true;
if ($this->hour > $when->hour) return false;
if ($this->minute < $when->minute) return true;
if ($this->minute > $when->minute) return false;
if ($this->second < $when->second) return true;
if ($this->second > $when->second) return false;
if ($this->microsecond < $when->microsecond) return true;
if ($this->microsecond > $when->microsecond) return false;
return false;
}
public function equals($when) {
if (!($when instanceof HproseDateTime)) {
$when = new HproseDateTime($when);
}
if ($this->utc != $when->utc) return ($this->timestamp() == $when->timestamp());
return (($this->year == $when->year) &&
($this->month == $when->month) &&
($this->day == $when->day) &&
($this->hour == $when->hour) &&
($this->minute == $when->minute) &&
($this->second == $when->second) &&
($this->microsecond == $when->microsecond));
}
public function timestamp() {
if ($this->utc) {
return gmmktime($this->hour,
$this->minute,
$this->second,
$this->month,
$this->day,
$this->year) +
($this->microsecond / 1000000);
}
else {
return mktime($this->hour,
$this->minute,
$this->second,
$this->month,
$this->day,
$this->year) +
($this->microsecond / 1000000);
}
}
public function toString($fullformat = true) {
if ($this->microsecond == 0) {
$format = ($fullformat ? '%04d-%02d-%02dT%02d:%02d:%02d'
: '%04d%02d%02dT%02d%02d%02d');
$str = sprintf($format,
$this->year, $this->month, $this->day,
$this->hour, $this->minute, $this->second);
}
if ($this->microsecond % 1000 == 0) {
$format = ($fullformat ? '%04d-%02d-%02dT%02d:%02d:%02d.%03d'
: '%04d%02d%02dT%02d%02d%02d.%03d');
$str = sprintf($format,
$this->year, $this->month, $this->day,
$this->hour, $this->minute, $this->second,
(int)($this->microsecond / 1000));
}
else {
$format = ($fullformat ? '%04d-%02d-%02dT%02d:%02d:%02d.%06d'
: '%04d%02d%02dT%02d%02d%02d.%06d');
$str = sprintf($format,
$this->year, $this->month, $this->day,
$this->hour, $this->minute, $this->second,
$this->microsecond);
}
if ($this->utc) {
$str .= 'Z';
}
return $str;
}
public function __toString() {
return $this->toString();
}
public static function isValidTime($hour, $minute, $second, $microsecond = 0) {
return HproseTime::isValidTime($hour, $minute, $second, $microsecond);
}
}
/*
integer is_utf8(string $s)
if $s is UTF-8 String, return 1 else 0
*/
if (function_exists('mb_detect_encoding')) {
function is_utf8($s) {
return mb_detect_encoding($s, 'UTF-8', true) === 'UTF-8';
}
}
elseif (function_exists('iconv')) {
function is_utf8($s) {
return iconv('UTF-8', 'UTF-8//IGNORE', $s) === $s;
}
}
else {
function is_utf8($s) {
$len = strlen($s);
for($i = 0; $i < $len; ++$i){
$c = ord($s{$i});
switch ($c >> 4) {
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
break;
case 12:
case 13:
if ((ord($s{++$i}) >> 6) != 0x2) return false;
break;
case 14:
if ((ord($s{++$i}) >> 6) != 0x2) return false;
if ((ord($s{++$i}) >> 6) != 0x2) return false;
break;
case 15:
$b = $s{++$i};
if ((ord($b) >> 6) != 0x2) return false;
if ((ord($s{++$i}) >> 6) != 0x2) return false;
if ((ord($s{++$i}) >> 6) != 0x2) return false;
if (((($c & 0xf) << 2) | (($b >> 4) & 0x3)) > 0x10) return false;
break;
default:
return false;
}
}
return true;
}
}
/*
integer ustrlen(string $s)
$s must be a UTF-8 String, return the Unicode code unit (not code point) length
*/
if (function_exists('iconv')) {
function ustrlen($s) {
return strlen(iconv('UTF-8', 'UTF-16LE', $s)) >> 1;
}
}
elseif (function_exists('mb_convert_encoding')) {
function ustrlen($s) {
return strlen(mb_convert_encoding($s, "UTF-16LE", "UTF-8")) >> 1;
}
}
else {
function ustrlen($s) {
$pos = 0;
$length = strlen($s);
$len = $length;
while ($pos < $length) {
$a = ord($s{$pos++});
if ($a < 0x80) {
continue;
}
elseif (($a & 0xE0) == 0xC0) {
++$pos;
--$len;
}
elseif (($a & 0xF0) == 0xE0) {
$pos += 2;
$len -= 2;
}
elseif (($a & 0xF8) == 0xF0) {
$pos += 3;
$len -= 2;
}
}
return $len;
}
}
/*
bool is_list(array $a)
if $a is list, return true else false
*/
function is_list(array $a) {
$count = count($a);
if ($count === 0) return true;
return !array_diff_key($a, array_fill(0, $count, NULL));
}
/*
mixed array_ref_search(mixed &$value, array $array)
if $value ref in $array, return the index else false
*/
function array_ref_search(&$value, &$array) {
if (!is_array($value)) return array_search($value, $array, true);
$temp = $value;
foreach ($array as $i => &$ref) {
if (($ref === ($value = 1)) && ($ref === ($value = 0))) {
$value = $temp;
return $i;
}
}
$value = $temp;
return false;
}
/*
string spl_object_hash(object $obj)
This function returns a unique identifier for the object.
This id can be used as a hash key for storing objects or for identifying an object.
*/
if (!function_exists('spl_object_hash')) {
function spl_object_hash($object) {
ob_start();
var_dump($object);
preg_match('[#(\d+)]', ob_get_clean(), $match);
return $match[1];
}
}
?>

View File

@@ -0,0 +1,40 @@
<?php
/**********************************************************\
| |
| hprose |
| |
| Official WebSite: http://www.hprose.com/ |
| http://www.hprose.net/ |
| http://www.hprose.org/ |
| |
\**********************************************************/
/**********************************************************\
* *
* HproseFormatter.php *
* *
* hprose formatter library for php5. *
* *
* LastModified: Nov 12, 2013 *
* Author: Ma Bingyao <andot@hprfc.com> *
* *
\**********************************************************/
require_once('HproseIOStream.php');
require_once('HproseReader.php');
require_once('HproseWriter.php');
class HproseFormatter {
public static function serialize(&$var, $simple = false) {
$stream = new HproseStringStream();
$hproseWriter = ($simple ? new HproseSimpleWriter($stream) : new HproseWriter($stream));
$hproseWriter->serialize($var);
return $stream->toString();
}
public static function &unserialize($data, $simple = false) {
$stream = new HproseStringStream($data);
$hproseReader = ($simple ? new HproseSimpleReader($stream) : new HproseReader($stream));
return $hproseReader->unserialize();
}
}
?>

View File

@@ -0,0 +1,314 @@
<?php
/**********************************************************\
| |
| hprose |
| |
| Official WebSite: http://www.hprose.com/ |
| http://www.hprose.net/ |
| http://www.hprose.org/ |
| |
\**********************************************************/
/**********************************************************\
* *
* HproseHttpClient.php *
* *
* hprose http client library for php5. *
* *
* LastModified: Nov 12, 2013 *
* Author: Ma Bingyao <andot@hprfc.com> *
* *
\**********************************************************/
require_once('HproseCommon.php');
require_once('HproseIO.php');
require_once('HproseClient.php');
abstract class HproseBaseHttpClient extends HproseClient {
protected $host;
protected $path;
protected $secure;
protected $proxy;
protected $header;
protected $timeout;
protected $keepAlive;
protected $keepAliveTimeout;
protected static $cookieManager = array();
static function hproseKeepCookieInSession() {
$_SESSION['HPROSE_COOKIE_MANAGER'] = self::$cookieManager;
}
public static function keepSession() {
if (array_key_exists('HPROSE_COOKIE_MANAGER', $_SESSION)) {
self::$cookieManager = $_SESSION['HPROSE_COOKIE_MANAGER'];
}
register_shutdown_function(array('HproseBaseHttpClient', 'hproseKeepCookieInSession'));
}
protected function setCookie($headers) {
foreach ($headers as $header) {
@list($name, $value) = explode(':', $header, 2);
if (strtolower($name) == 'set-cookie' ||
strtolower($name) == 'set-cookie2') {
$cookies = explode(';', trim($value));
$cookie = array();
list($name, $value) = explode('=', trim($cookies[0]), 2);
$cookie['name'] = $name;
$cookie['value'] = $value;
for ($i = 1; $i < count($cookies); $i++) {
list($name, $value) = explode('=', trim($cookies[$i]), 2);
$cookie[strtoupper($name)] = $value;
}
// Tomcat can return SetCookie2 with path wrapped in "
if (array_key_exists('PATH', $cookie)) {
$cookie['PATH'] = trim($cookie['PATH'], '"');
}
else {
$cookie['PATH'] = '/';
}
if (array_key_exists('EXPIRES', $cookie)) {
$cookie['EXPIRES'] = strtotime($cookie['EXPIRES']);
}
if (array_key_exists('DOMAIN', $cookie)) {
$cookie['DOMAIN'] = strtolower($cookie['DOMAIN']);
}
else {
$cookie['DOMAIN'] = $this->host;
}
$cookie['SECURE'] = array_key_exists('SECURE', $cookie);
if (!array_key_exists($cookie['DOMAIN'], self::$cookieManager)) {
self::$cookieManager[$cookie['DOMAIN']] = array();
}
self::$cookieManager[$cookie['DOMAIN']][$cookie['name']] = $cookie;
}
}
}
protected abstract function formatCookie($cookies);
protected function getCookie() {
$cookies = array();
foreach (self::$cookieManager as $domain => $cookieList) {
if (strpos($this->host, $domain) !== false) {
$names = array();
foreach ($cookieList as $cookie) {
if (array_key_exists('EXPIRES', $cookie) && (time() > $cookie['EXPIRES'])) {
$names[] = $cookie['name'];
}
elseif (strpos($this->path, $cookie['PATH']) === 0) {
if ((($this->secure && $cookie['SECURE']) ||
!$cookie['SECURE']) && !is_null($cookie['value'])) {
$cookies[] = $cookie['name'] . '=' . $cookie['value'];
}
}
}
foreach ($names as $name) {
unset(self::$cookieManager[$domain][$name]);
}
}
}
return $this->formatCookie($cookies);
}
public function __construct($url = '') {
parent::__construct($url);
$this->header = array('Content-type' => 'application/hprose');
}
public function useService($url = '', $namespace = '') {
$serviceProxy = parent::useService($url, $namespace);
if ($url) {
$url = parse_url($url);
$this->secure = (strtolower($url['scheme']) == 'https');
$this->host = strtolower($url['host']);
$this->path = $url['path'];
$this->timeout = 30000;
$this->keepAlive = false;
$this->keepAliveTimeout = 300;
}
return $serviceProxy;
}
public function setHeader($name, $value) {
$lname = strtolower($name);
if ($lname != 'content-type' &&
$lname != 'content-length' &&
$lname != 'host') {
if ($value) {
$this->header[$name] = $value;
}
else {
unset($this->header[$name]);
}
}
}
public function setProxy($proxy = NULL) {
$this->proxy = $proxy;
}
public function setTimeout($timeout) {
$this->timeout = $timeout;
}
public function getTimeout() {
return $this->timeout;
}
public function setKeepAlive($keepAlive = true) {
$this->keepAlive = $keepAlive;
}
public function getKeepAlive() {
return $this->keeepAlive;
}
public function setKeepAliveTimeout($timeout) {
$this->keepAliveTimeout = $timeout;
}
public function getKeepAliveTimeout() {
return $this->keepAliveTimeout;
}
}
if (class_exists('SaeFetchurl')) {
class HproseHttpClient extends HproseBaseHttpClient {
protected function formatCookie($cookies) {
if (count($cookies) > 0) {
return implode('; ', $cookies);
}
return '';
}
protected function send($request) {
$f = new SaeFetchurl();
$cookie = $this->getCookie();
if ($cookie != '') {
$f->setHeader("Cookie", $cookie);
}
if ($this->keepAlive) {
$f->setHeader("Connection", "keep-alive");
$f->setHeader("Keep-Alive", $this->keepAliveTimeout);
}
else {
$f->setHeader("Connection", "close");
}
foreach ($this->header as $name => $value) {
$f->setHeader($name, $value);
}
$f->setMethod("post");
$f->setPostData($request);
$f->setConnectTimeout($this->timeout);
$f->setSendTimeout($this->timeout);
$f->setReadTimeout($this->timeout);
$response = $f->fetch($this->url);
if ($f->errno()) {
throw new HproseException($f->errno() . ": " . $f->errmsg());
}
$http_response_header = $f->responseHeaders(false);
$this->setCookie($http_response_header);
return $response;
}
}
}
elseif (function_exists('curl_init')) {
class HproseHttpClient extends HproseBaseHttpClient {
private $curl;
protected function formatCookie($cookies) {
if (count($cookies) > 0) {
return "Cookie: " . implode('; ', $cookies);
}
return '';
}
public function __construct($url = '') {
parent::__construct($url);
$this->curl = curl_init();
}
protected function send($request) {
curl_setopt($this->curl, CURLOPT_URL, $this->url);
curl_setopt($this->curl, CURLOPT_HEADER, TRUE);
curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($this->curl, CURLOPT_POST, TRUE);
curl_setopt($this->curl, CURLOPT_POSTFIELDS, $request);
$headers_array = array($this->getCookie(),
"Content-Length: " . strlen($request));
if ($this->keepAlive) {
$headers_array[] = "Connection: keep-alive";
$headers_array[] = "Keep-Alive: " . $this->keepAliveTimeout;
}
else {
$headers_array[] = "Connection: close";
}
foreach ($this->header as $name => $value) {
$headers_array[] = $name . ": " . $value;
}
curl_setopt($this->curl, CURLOPT_HTTPHEADER, $headers_array);
if ($this->proxy) {
curl_setopt($this->curl, CURLOPT_PROXY, $this->proxy);
}
if (defined(CURLOPT_TIMEOUT_MS)) {
curl_setopt($this->curl, CURLOPT_TIMEOUT_MS, $this->timeout);
}
else {
curl_setopt($this->curl, CURLOPT_TIMEOUT, $this->timeout / 1000);
}
$response = curl_exec($this->curl);
$errno = curl_errno($this->curl);
if ($errno) {
throw new HproseException($errno . ": " . curl_error($this->curl));
}
do {
list($response_headers, $response) = explode("\r\n\r\n", $response, 2);
$http_response_header = explode("\r\n", $response_headers);
$http_response_firstline = array_shift($http_response_header);
if (preg_match('@^HTTP/[0-9]\.[0-9]\s([0-9]{3})\s(.*)@',
$http_response_firstline, $matches)) {
$response_code = $matches[1];
$response_status = trim($matches[2]);
}
else {
$response_code = "500";
$response_status = "Unknown Error.";
}
} while (substr($response_code, 0, 1) == "1");
if ($response_code != '200') {
throw new HproseException($response_code . ": " . $response_status);
}
$this->setCookie($http_response_header);
return $response;
}
public function __destruct() {
curl_close($this->curl);
}
}
}
else {
class HproseHttpClient extends HproseBaseHttpClient {
protected function formatCookie($cookies) {
if (count($cookies) > 0) {
return "Cookie: " . implode('; ', $cookies) . "\r\n";
}
return '';
}
public function __errorHandler($errno, $errstr, $errfile, $errline) {
throw new Exception($errstr, $errno);
}
protected function send($request) {
$opts = array (
'http' => array (
'method' => 'POST',
'header'=> $this->getCookie() .
"Content-Length: " . strlen($request) . "\r\n" .
($this->keepAlive ?
"Connection: keep-alive\r\n" .
"Keep-Alive: " . $this->keepAliveTimeout . "\r\n" :
"Connection: close\r\n"),
'content' => $request,
'timeout' => $this->timeout / 1000.0,
),
);
foreach ($this->header as $name => $value) {
$opts['http']['header'] .= "$name: $value\r\n";
}
if ($this->proxy) {
$opts['http']['proxy'] = $this->proxy;
$opts['http']['request_fulluri'] = true;
}
$context = stream_context_create($opts);
set_error_handler(array(&$this, '__errorHandler'));
$response = file_get_contents($this->url, false, $context);
restore_error_handler();
$this->setCookie($http_response_header);
return $response;
}
}
}
?>

View File

@@ -0,0 +1,483 @@
<?php
/**********************************************************\
| |
| hprose |
| |
| Official WebSite: http://www.hprose.com/ |
| http://www.hprose.net/ |
| http://www.hprose.org/ |
| |
\**********************************************************/
/**********************************************************\
* *
* HproseHttpServer.php *
* *
* hprose http server library for php5. *
* *
* LastModified: Nov 13, 2013 *
* Author: Ma Bingyao <andot@hprfc.com> *
* *
\**********************************************************/
require_once('HproseCommon.php');
require_once('HproseIO.php');
class HproseHttpServer {
private $errorTable = array(E_ERROR => 'Error',
E_WARNING => 'Warning',
E_PARSE => 'Parse Error',
E_NOTICE => 'Notice',
E_CORE_ERROR => 'Core Error',
E_CORE_WARNING => 'Core Warning',
E_COMPILE_ERROR => 'Compile Error',
E_COMPILE_WARNING => 'Compile Warning',
E_USER_ERROR => 'User Error',
E_USER_WARNING => 'User Warning',
E_USER_NOTICE => 'User Notice',
E_STRICT => 'Run-time Notice',
E_RECOVERABLE_ERROR => 'Error');
private $functions;
private $funcNames;
private $resultModes;
private $simpleModes;
private $debug;
private $crossDomain;
private $P3P;
private $get;
private $input;
private $output;
private $error;
private $filter;
private $simple;
public $onBeforeInvoke;
public $onAfterInvoke;
public $onSendHeader;
public $onSendError;
public function __construct() {
$this->functions = array();
$this->funcNames = array();
$this->resultModes = array();
$this->simpleModes = array();
$this->debug = false;
$this->crossDomain = false;
$this->P3P = false;
$this->get = true;
$this->filter = NULL;
$this->simple = false;
$this->error_types = E_ALL & ~E_NOTICE;
$this->onBeforeInvoke = NULL;
$this->onAfterInvoke = NULL;
$this->onSendHeader = NULL;
$this->onSendError = NULL;
}
/*
__filterHandler & __errorHandler must be public,
however we should never call them directly.
*/
public function __filterHandler($data) {
if (preg_match('/<b>.*? error<\/b>:(.*?)<br/', $data, $match)) {
if ($this->debug) {
$error = preg_replace('/<.*?>/', '', $match[1]);
}
else {
$error = preg_replace('/ in <b>.*<\/b>$/', '', $match[1]);
}
$data = HproseTags::TagError .
HproseFormatter::serialize(trim($error), true) .
HproseTags::TagEnd;
}
if ($this->filter) $data = $this->filter->outputFilter($data);
return $data;
}
public function __errorHandler($errno, $errstr, $errfile, $errline) {
if ($this->debug) {
$errstr .= " in $errfile on line $errline";
}
$this->error = $this->errorTable[$errno] . ": " . $errstr;
$this->sendError();
return true;
}
private function sendHeader() {
if ($this->onSendHeader) {
call_user_func($this->onSendHeader);
}
header("Content-Type: text/plain");
if ($this->P3P) {
header('P3P: CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi ' .
'CONi TELo OTPi OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL ' .
'UNI PUR FIN COM NAV INT DEM CNT STA POL HEA PRE GOV"');
}
if ($this->crossDomain) {
if (array_key_exists('HTTP_ORIGIN', $_SERVER) && $_SERVER['HTTP_ORIGIN'] != "null") {
header("Access-Control-Allow-Origin: " . $_SERVER['HTTP_ORIGIN']);
header("Access-Control-Allow-Credentials: true");
}
else {
header('Access-Control-Allow-Origin: *');
}
}
}
private function sendError() {
if ($this->onSendError) {
call_user_func($this->onSendError, $this->error);
}
ob_clean();
$this->output->write(HproseTags::TagError);
$writer = new HproseSimpleWriter($this->output);
$writer->writeString($this->error);
$this->output->write(HproseTags::TagEnd);
ob_end_flush();
}
private function doInvoke() {
$simpleReader = new HproseSimpleReader($this->input);
do {
$functionName = $simpleReader->readString(true);
$aliasName = strtolower($functionName);
$resultMode = HproseResultMode::Normal;
if (array_key_exists($aliasName, $this->functions)) {
$function = $this->functions[$aliasName];
$resultMode = $this->resultModes[$aliasName];
$simple = $this->simpleModes[$aliasName];
}
elseif (array_key_exists('*', $this->functions)) {
$function = $this->functions['*'];
$resultMode = $this->resultModes['*'];
$simple = $this->resultModes['*'];
}
else {
throw new HproseException("Can't find this function " . $functionName . "().");
}
if ($simple === NULL) $simple = $this->simple;
$writer = ($simple ? new HproseSimpleWriter($this->output) : new HproseWriter($this->output));
$args = array();
$byref = false;
$tag = $simpleReader->checkTags(array(HproseTags::TagList,
HproseTags::TagEnd,
HproseTags::TagCall));
if ($tag == HproseTags::TagList) {
$reader = new HproseReader($this->input);
$args = &$reader->readList();
$tag = $reader->checkTags(array(HproseTags::TagTrue,
HproseTags::TagEnd,
HproseTags::TagCall));
if ($tag == HproseTags::TagTrue) {
$byref = true;
$tag = $reader->checkTags(array(HproseTags::TagEnd,
HproseTags::TagCall));
}
}
if ($this->onBeforeInvoke) {
call_user_func($this->onBeforeInvoke, $functionName, $args, $byref);
}
if (array_key_exists('*', $this->functions) && ($function === $this->functions['*'])) {
$arguments = array($functionName, &$args);
}
elseif ($byref) {
$arguments = array();
for ($i = 0; $i < count($args); $i++) {
$arguments[$i] = &$args[$i];
}
}
else {
$arguments = $args;
}
$result = call_user_func_array($function, $arguments);
if ($this->onAfterInvoke) {
call_user_func($this->onAfterInvoke, $functionName, $args, $byref, $result);
}
// some service functions/methods may echo content, we need clean it
ob_clean();
if ($resultMode == HproseResultMode::RawWithEndTag) {
$this->output->write($result);
return;
}
elseif ($resultMode == HproseResultMode::Raw) {
$this->output->write($result);
}
else {
$this->output->write(HproseTags::TagResult);
if ($resultMode == HproseResultMode::Serialized) {
$this->output->write($result);
}
else {
$writer->reset();
$writer->serialize($result);
}
if ($byref) {
$this->output->write(HproseTags::TagArgument);
$writer->reset();
$writer->writeList($args);
}
}
} while ($tag == HproseTags::TagCall);
$this->output->write(HproseTags::TagEnd);
ob_end_flush();
}
private function doFunctionList() {
$functions = array_values($this->funcNames);
$writer = new HproseSimpleWriter($this->output);
$this->output->write(HproseTags::TagFunctions);
$writer->writeList($functions);
$this->output->write(HproseTags::TagEnd);
ob_end_flush();
}
private function getDeclaredOnlyMethods($class) {
$all = get_class_methods($class);
if ($parent_class = get_parent_class($class)) {
$inherit = get_class_methods($parent_class);
$result = array_diff($all, $inherit);
}
else {
$result = $all;
}
return $result;
}
public function addMissingFunction($function, $resultMode = HproseResultMode::Normal, $simple = NULL) {
$this->addFunction($function, '*', $resultMode, $simple);
}
public function addFunction($function, $alias = NULL, $resultMode = HproseResultMode::Normal, $simple = NULL) {
if (is_callable($function)) {
if ($alias === NULL) {
if (is_string($function)) {
$alias = $function;
}
else {
$alias = $function[1];
}
}
if (is_string($alias)) {
$aliasName = strtolower($alias);
$this->functions[$aliasName] = $function;
$this->funcNames[$aliasName] = $alias;
$this->resultModes[$aliasName] = $resultMode;
$this->simpleModes[$aliasName] = $simple;
}
else {
throw new HproseException('Argument alias is not a string');
}
}
else {
throw new HproseException('Argument function is not a callable variable');
}
}
public function addFunctions($functions, $aliases = NULL, $resultMode = HproseResultMode::Normal, $simple = NULL) {
$aliases_is_null = ($aliases === NULL);
$count = count($functions);
if (!$aliases_is_null && $count != count($aliases)) {
throw new HproseException('The count of functions is not matched with aliases');
}
for ($i = 0; $i < $count; $i++) {
$function = $functions[$i];
if ($aliases_is_null) {
$this->addFunction($function, NULL, $resultMode, $simple);
}
else {
$this->addFunction($function, $aliases[$i], $resultMode, $simple);
}
}
}
public function addMethod($methodname, $belongto, $alias = NULL, $resultMode = HproseResultMode::Normal, $simple = NULL) {
if ($alias === NULL) {
$alias = $methodname;
}
if (is_string($belongto)) {
$this->addFunction(array($belongto, $methodname), $alias, $resultMode, $simple);
}
else {
$this->addFunction(array(&$belongto, $methodname), $alias, $resultMode, $simple);
}
}
public function addMethods($methods, $belongto, $aliases = NULL, $resultMode = HproseResultMode::Normal, $simple = NULL) {
$aliases_is_null = ($aliases === NULL);
$count = count($methods);
if (is_string($aliases)) {
$aliasPrefix = $aliases;
$aliases = array();
foreach ($methods as $name) {
$aliases[] = $aliasPrefix . '_' . $name;
}
}
if (!$aliases_is_null && $count != count($aliases)) {
throw new HproseException('The count of methods is not matched with aliases');
}
for ($i = 0; $i < $count; $i++) {
$method = $methods[$i];
if (is_string($belongto)) {
$function = array($belongto, $method);
}
else {
$function = array(&$belongto, $method);
}
if ($aliases_is_null) {
$this->addFunction($function, $method, $resultMode, $simple);
}
else {
$this->addFunction($function, $aliases[$i], $resultMode, $simple);
}
}
}
public function addInstanceMethods($object, $class = NULL, $aliasPrefix = NULL, $resultMode = HproseResultMode::Normal, $simple = NULL) {
if ($class === NULL) $class = get_class($object);
$this->addMethods($this->getDeclaredOnlyMethods($class), $object, $aliasPrefix, $resultMode, $simple);
}
public function addClassMethods($class, $execclass = NULL, $aliasPrefix = NULL, $resultMode = HproseResultMode::Normal, $simple = NULL) {
if ($execclass === NULL) $execclass = $class;
$this->addMethods($this->getDeclaredOnlyMethods($class), $execclass, $aliasPrefix, $resultMode, $simple);
}
public function add() {
$args_num = func_num_args();
$args = func_get_args();
switch ($args_num) {
case 1: {
if (is_callable($args[0])) {
return $this->addFunction($args[0]);
}
elseif (is_array($args[0])) {
return $this->addFunctions($args[0]);
}
elseif (is_object($args[0])) {
return $this->addInstanceMethods($args[0]);
}
elseif (is_string($args[0])) {
return $this->addClassMethods($args[0]);
}
break;
}
case 2: {
if (is_callable($args[0]) && is_string($args[1])) {
return $this->addFunction($args[0], $args[1]);
}
elseif (is_string($args[0])) {
if (is_string($args[1]) && !is_callable(array($args[1], $args[0]))) {
if (class_exists($args[1])) {
return $this->addClassMethods($args[0], $args[1]);
}
else {
return $this->addClassMethods($args[0], NULL, $args[1]);
}
}
return $this->addMethod($args[0], $args[1]);
}
elseif (is_array($args[0])) {
if (is_array($args[1])) {
return $this->addFunctions($args[0], $args[1]);
}
else {
return $this->addMethods($args[0], $args[1]);
}
}
elseif (is_object($args[0])) {
return $this->addInstanceMethods($args[0], $args[1]);
}
break;
}
case 3: {
if (is_callable($args[0]) && is_null($args[1]) && is_string($args[2])) {
return $this->addFunction($args[0], $args[2]);
}
elseif (is_string($args[0]) && is_string($args[2])) {
if (is_string($args[1]) && !is_callable(array($args[0], $args[1]))) {
return $this->addClassMethods($args[0], $args[1], $args[2]);
}
else {
return $this->addMethod($args[0], $args[1], $args[2]);
}
}
elseif (is_array($args[0])) {
if (is_null($args[1]) && is_array($args[2])) {
return $this->addFunctions($args[0], $args[2]);
}
else {
return $this->addMethods($args[0], $args[1], $args[2]);
}
}
elseif (is_object($args[0])) {
return $this->addInstanceMethods($args[0], $args[1], $args[2]);
}
break;
}
throw new HproseException('Wrong arguments');
}
}
public function isDebugEnabled() {
return $this->debug;
}
public function setDebugEnabled($enable = true) {
$this->debug = $enable;
}
public function isCrossDomainEnabled() {
return $this->crossDomain;
}
public function setCrossDomainEnabled($enable = true) {
$this->crossDomain = $enable;
}
public function isP3PEnabled() {
return $this->P3P;
}
public function setP3PEnabled($enable = true) {
$this->P3P = $enable;
}
public function isGetEnabled() {
return $this->get;
}
public function setGetEnabled($enable = true) {
$this->get = $enable;
}
public function getFilter() {
return $this->filter;
}
public function setFilter($filter) {
$this->filter = $filter;
}
public function getSimpleMode() {
return $this->simple;
}
public function setSimpleMode($simple = true) {
$this->simple = $simple;
}
public function getErrorTypes() {
return $this->error_types;
}
public function setErrorTypes($error_types) {
$this->error_types = $error_types;
}
public function handle() {
if (!isset($HTTP_RAW_POST_DATA)) $HTTP_RAW_POST_DATA = file_get_contents("php://input");
if ($this->filter) $HTTP_RAW_POST_DATA = $this->filter->inputFilter($HTTP_RAW_POST_DATA);
$this->input = new HproseStringStream($HTTP_RAW_POST_DATA);
$this->output = new HproseFileStream(fopen('php://output', 'wb'));
set_error_handler(array(&$this, '__errorHandler'), $this->error_types);
ob_start(array(&$this, "__filterHandler"));
ob_implicit_flush(0);
ob_clean();
$this->sendHeader();
if (($_SERVER['REQUEST_METHOD'] == 'GET') and $this->get) {
return $this->doFunctionList();
}
elseif ($_SERVER['REQUEST_METHOD'] == 'POST') {
try {
switch ($this->input->getc()) {
case HproseTags::TagCall: return $this->doInvoke();
case HproseTags::TagEnd: return $this->doFunctionList();
default: throw new HproseException("Wrong Request: \r\n" . $HTTP_RAW_POST_DATA);
}
}
catch (Exception $e) {
$this->error = $e->getMessage();
if ($this->debug) {
$this->error .= "\nfile: " . $e->getFile() .
"\nline: " . $e->getLine() .
"\ntrace: " . $e->getTraceAsString();
}
$this->sendError();
}
}
$this->input->close();
$this->output->close();
}
public function start() {
$this->handle();
}
}
?>

View File

@@ -0,0 +1,29 @@
<?php
/**********************************************************\
| |
| hprose |
| |
| Official WebSite: http://www.hprose.com/ |
| http://www.hprose.net/ |
| http://www.hprose.org/ |
| |
\**********************************************************/
/**********************************************************\
* *
* HproseIO.php *
* *
* hprose io library for php5. *
* *
* LastModified: Nov 10, 2013 *
* Author: Ma Bingyao <andot@hprfc.com> *
* *
\**********************************************************/
require_once('HproseTags.php');
require_once('HproseClassManager.php');
require_once('HproseReader.php');
require_once('HproseWriter.php');
require_once('HproseFormatter.php');
?>

View File

@@ -0,0 +1,349 @@
<?php
/**********************************************************\
| |
| hprose |
| |
| Official WebSite: http://www.hprose.com/ |
| http://www.hprose.net/ |
| http://www.hprose.org/ |
| |
\**********************************************************/
/**********************************************************\
* *
* HproseIOStream.php *
* *
* hprose io stream library for php5. *
* *
* LastModified: Nov 12, 2013 *
* Author: Ma Bingyao <andot@hprfc.com> *
* *
\**********************************************************/
abstract class HproseAbstractStream {
public abstract function close();
public abstract function getc();
public abstract function read($length);
public abstract function readuntil($char);
public abstract function seek($offset, $whence = SEEK_SET);
public abstract function mark();
public abstract function unmark();
public abstract function reset();
public abstract function skip($n);
public abstract function eof();
public abstract function write($string, $length = -1);
}
class HproseStringStream extends HproseAbstractStream {
protected $buffer;
protected $pos;
protected $mark;
protected $length;
public function __construct($string = '') {
$this->buffer = $string;
$this->pos = 0;
$this->mark = -1;
$this->length = strlen($string);
}
public function close() {
$this->buffer = NULL;
$this->pos = 0;
$this->mark = -1;
$this->length = 0;
}
public function length() {
return $this->length;
}
public function getc() {
return $this->buffer{$this->pos++};
}
public function read($length) {
$s = substr($this->buffer, $this->pos, $length);
$this->skip($length);
return $s;
}
public function readuntil($tag) {
$pos = strpos($this->buffer, $tag, $this->pos);
if ($pos !== false) {
$s = substr($this->buffer, $this->pos, $pos - $this->pos);
$this->pos = $pos + strlen($tag);
}
else {
$s = substr($this->buffer, $this->pos);
$this->pos = $this->length;
}
return $s;
}
public function seek($offset, $whence = SEEK_SET) {
switch ($whence) {
case SEEK_SET:
$this->pos = $offset;
break;
case SEEK_CUR:
$this->pos += $offset;
break;
case SEEK_END:
$this->pos = $this->length + $offset;
break;
}
$this->mark = -1;
return 0;
}
public function mark() {
$this->mark = $this->pos;
}
public function unmark() {
$this->mark = -1;
}
public function reset() {
if ($this->mark != -1) {
$this->pos = $this->mark;
}
}
public function skip($n) {
$this->pos += $n;
}
public function eof() {
return ($this->pos >= $this->length);
}
public function write($string, $length = -1) {
if ($length == -1) {
$this->buffer .= $string;
$length = strlen($string);
}
else {
$this->buffer .= substr($string, 0, $length);
}
$this->length += $length;
}
public function toString() {
return $this->buffer;
}
}
class HproseFileStream extends HproseAbstractStream {
protected $fp;
protected $buf;
protected $unmark;
protected $pos;
protected $length;
public function __construct($fp) {
$this->fp = $fp;
$this->buf = "";
$this->unmark = true;
$this->pos = -1;
$this->length = 0;
}
public function close() {
return fclose($this->fp);
}
public function getc() {
if ($this->pos == -1) {
return fgetc($this->fp);
}
elseif ($this->pos < $this->length) {
return $this->buf{$this->pos++};
}
elseif ($this->unmark) {
$this->buf = "";
$this->pos = -1;
$this->length = 0;
return fgetc($this->fp);
}
elseif (($c = fgetc($this->fp)) !== false) {
$this->buf .= $c;
$this->pos++;
$this->length++;
}
return $c;
}
public function read($length) {
if ($this->pos == -1) {
return fread($this->fp, $length);
}
elseif ($this->pos < $this->length) {
$len = $this->length - $this->pos;
if ($len < $length) {
$s = fread($this->fp, $length - $len);
$this->buf .= $s;
$this->length += strlen($s);
}
$s = substr($this->buf, $this->pos, $length);
$this->pos += strlen($s);
}
elseif ($this->unmark) {
$this->buf = "";
$this->pos = -1;
$this->length = 0;
return fread($this->fp, $length);
}
elseif (($s = fread($this->fp, $length)) !== "") {
$this->buf .= $s;
$len = strlen($s);
$this->pos += $len;
$this->length += $len;
}
return $s;
}
public function readuntil($char) {
$s = '';
while ((($c = $this->getc()) != $char) && $c !== false) $s .= $c;
return $s;
}
public function seek($offset, $whence = SEEK_SET) {
if (fseek($this->fp, $offset, $whence) == 0) {
$this->buf = "";
$this->unmark = true;
$this->pos = -1;
$this->length = 0;
return 0;
}
return -1;
}
public function mark() {
$this->unmark = false;
if ($this->pos == -1) {
$this->buf = "";
$this->pos = 0;
$this->length = 0;
}
elseif ($this->pos > 0) {
$this->buf = substr($this->buf, $this->pos);
$this->length -= $this->pos;
$this->pos = 0;
}
}
public function unmark() {
$this->unmark = true;
}
public function reset() {
$this->pos = 0;
}
public function skip($n) {
$this->read($n);
}
public function eof() {
if (($this->pos != -1) && ($this->pos < $this->length)) return false;
return feof($this->fp);
}
public function write($string, $length = -1) {
if ($length == -1) $length = strlen($string);
return fwrite($this->fp, $string, $length);
}
}
class HproseProcStream extends HproseAbstractStream {
protected $process;
protected $pipes;
protected $buf;
protected $unmark;
protected $pos;
protected $length;
public function __construct($process, $pipes) {
$this->process = $process;
$this->pipes = $pipes;
$this->buf = "";
$this->unmark = true;
$this->pos = -1;
$this->length = 0;
}
public function close() {
fclose($this->pipes[0]);
fclose($this->pipes[1]);
proc_close($this->process);
}
public function getc() {
if ($this->pos == -1) {
return fgetc($this->pipes[1]);
}
elseif ($this->pos < $this->length) {
return $this->buf{$this->pos++};
}
elseif ($this->unmark) {
$this->buf = "";
$this->pos = -1;
$this->length = 0;
return fgetc($this->pipes[1]);
}
elseif (($c = fgetc($this->pipes[1])) !== false) {
$this->buf .= $c;
$this->pos++;
$this->length++;
}
return $c;
}
public function read($length) {
if ($this->pos == -1) {
return fread($this->pipes[1], $length);
}
elseif ($this->pos < $this->length) {
$len = $this->length - $this->pos;
if ($len < $length) {
$s = fread($this->pipes[1], $length - $len);
$this->buf .= $s;
$this->length += strlen($s);
}
$s = substr($this->buf, $this->pos, $length);
$this->pos += strlen($s);
}
elseif ($this->unmark) {
$this->buf = "";
$this->pos = -1;
$this->length = 0;
return fread($this->pipes[1], $length);
}
elseif (($s = fread($this->pipes[1], $length)) !== "") {
$this->buf .= $s;
$len = strlen($s);
$this->pos += $len;
$this->length += $len;
}
return $s;
}
public function readuntil($char) {
$s = '';
while ((($c = $this->getc()) != $char) && $c !== false) $s .= $c;
return $s;
}
public function seek($offset, $whence = SEEK_SET) {
if (fseek($this->pipes[1], $offset, $whence) == 0) {
$this->buf = "";
$this->unmark = true;
$this->pos = -1;
$this->length = 0;
return 0;
}
return -1;
}
public function mark() {
$this->unmark = false;
if ($this->pos == -1) {
$this->buf = "";
$this->pos = 0;
$this->length = 0;
}
elseif ($this->pos > 0) {
$this->buf = substr($this->buf, $this->pos);
$this->length -= $this->pos;
$this->pos = 0;
}
}
public function unmark() {
$this->unmark = true;
}
public function reset() {
$this->pos = 0;
}
public function skip($n) {
$this->read($n);
}
public function eof() {
if (($this->pos != -1) && ($this->pos < $this->length)) return false;
return feof($this->pipes[1]);
}
public function write($string, $length = -1) {
if ($length == -1) $length = strlen($string);
return fwrite($this->pipes[0], $string, $length);
}
}
?>

View File

@@ -0,0 +1,672 @@
<?php
/**********************************************************\
| |
| hprose |
| |
| Official WebSite: http://www.hprose.com/ |
| http://www.hprose.net/ |
| http://www.hprose.org/ |
| |
\**********************************************************/
/**********************************************************\
* *
* HproseReader.php *
* *
* hprose reader library for php5. *
* *
* LastModified: Nov 12, 2013 *
* Author: Ma Bingyao <andot@hprfc.com> *
* *
\**********************************************************/
require_once('HproseCommon.php');
require_once('HproseTags.php');
require_once('HproseClassManager.php');
class HproseRawReader {
public $stream;
function __construct(&$stream) {
$this->stream = &$stream;
}
public function readRaw($ostream = NULL, $tag = NULL) {
if (is_null($ostream)) {
$ostream = new HproseStringStream();
}
if (is_null($tag)) {
$tag = $this->stream->getc();
}
switch ($tag) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case HproseTags::TagNull:
case HproseTags::TagEmpty:
case HproseTags::TagTrue:
case HproseTags::TagFalse:
case HproseTags::TagNaN:
$ostream->write($tag);
break;
case HproseTags::TagInfinity:
$ostream->write($tag);
$ostream->write($this->stream->getc());
break;
case HproseTags::TagInteger:
case HproseTags::TagLong:
case HproseTags::TagDouble:
case HproseTags::TagRef:
$this->readNumberRaw($ostream, $tag);
break;
case HproseTags::TagDate:
case HproseTags::TagTime:
$this->readDateTimeRaw($ostream, $tag);
break;
case HproseTags::TagUTF8Char:
$this->readUTF8CharRaw($ostream, $tag);
break;
case HproseTags::TagBytes:
$this->readBytesRaw($ostream, $tag);
break;
case HproseTags::TagString:
$this->readStringRaw($ostream, $tag);
break;
case HproseTags::TagGuid:
$this->readGuidRaw($ostream, $tag);
break;
case HproseTags::TagList:
case HproseTags::TagMap:
case HproseTags::TagObject:
$this->readComplexRaw($ostream, $tag);
break;
case HproseTags::TagClass:
$this->readComplexRaw($ostream, $tag);
$this->readRaw($ostream);
break;
case HproseTags::TagError:
$ostream->write($tag);
$this->readRaw($ostream);
break;
case false:
throw new HproseException("No byte found in stream");
default:
throw new HproseException("Unexpected serialize tag '" + $tag + "' in stream");
}
return $ostream;
}
private function readNumberRaw($ostream, $tag) {
$s = $tag .
$this->stream->readuntil(HproseTags::TagSemicolon) .
HproseTags::TagSemicolon;
$ostream->write($s);
}
private function readDateTimeRaw($ostream, $tag) {
$s = $tag;
do {
$tag = $this->stream->getc();
$s .= $tag;
} while ($tag != HproseTags::TagSemicolon &&
$tag != HproseTags::TagUTC);
$ostream->write($s);
}
private function readUTF8CharRaw($ostream, $tag) {
$s = $tag;
$tag = $this->stream->getc();
$s .= $tag;
$a = ord($tag);
if (($a & 0xE0) == 0xC0) {
$s .= $this->stream->getc();
}
elseif (($a & 0xF0) == 0xE0) {
$s .= $this->stream->read(2);
}
elseif ($a > 0x7F) {
throw new HproseException("bad utf-8 encoding");
}
$ostream->write($s);
}
private function readBytesRaw($ostream, $tag) {
$len = $this->stream->readuntil(HproseTags::TagQuote);
$s = $tag . $len . HproseTags::TagQuote . $this->stream->read((int)$len) . HproseTags::TagQuote;
$this->stream->skip(1);
$ostream->write($s);
}
private function readStringRaw($ostream, $tag) {
$len = $this->stream->readuntil(HproseTags::TagQuote);
$s = $tag . $len . HproseTags::TagQuote;
$len = (int)$len;
$this->stream->mark();
$utf8len = 0;
for ($i = 0; $i < $len; ++$i) {
switch (ord($this->stream->getc()) >> 4) {
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7: {
// 0xxx xxxx
$utf8len++;
break;
}
case 12:
case 13: {
// 110x xxxx 10xx xxxx
$this->stream->skip(1);
$utf8len += 2;
break;
}
case 14: {
// 1110 xxxx 10xx xxxx 10xx xxxx
$this->stream->skip(2);
$utf8len += 3;
break;
}
case 15: {
// 1111 0xxx 10xx xxxx 10xx xxxx 10xx xxxx
$this->stream->skip(3);
$utf8len += 4;
++$i;
break;
}
default: {
throw new HproseException('bad utf-8 encoding');
}
}
}
$this->stream->reset();
$this->stream->unmark();
$s .= $this->stream->read($utf8len) . HproseTags::TagQuote;
$this->stream->skip(1);
$ostream->write($s);
}
private function readGuidRaw($ostream, $tag) {
$s = $tag . $this->stream->read(38);
$ostream->write($s);
}
private function readComplexRaw($ostream, $tag) {
$s = $tag .
$this->stream->readuntil(HproseTags::TagOpenbrace) .
HproseTags::TagOpenbrace;
$ostream->write($s);
while (($tag = $this->stream->getc()) != HproseTags::TagClosebrace) {
$this->readRaw($ostream, $tag);
}
$ostream->write($tag);
}
}
class HproseSimpleReader extends HproseRawReader {
private $classref;
function __construct(&$stream) {
parent::__construct($stream);
$this->classref = array();
}
public function &unserialize($tag = NULL) {
if (is_null($tag)) {
$tag = $this->stream->getc();
}
$result = NULL;
switch ($tag) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
$result = (int)$tag; break;
case HproseTags::TagInteger: $result = $this->readInteger(); break;
case HproseTags::TagLong: $result = $this->readLong(); break;
case HproseTags::TagDouble: $result = $this->readDouble(); break;
case HproseTags::TagNull: break;
case HproseTags::TagEmpty: $result = ''; break;
case HproseTags::TagTrue: $result = true; break;
case HproseTags::TagFalse: $result = false; break;
case HproseTags::TagNaN: $result = log(-1); break;
case HproseTags::TagInfinity: $result = $this->readInfinity(); break;
case HproseTags::TagDate: $result = $this->readDate(); break;
case HproseTags::TagTime: $result = $this->readTime(); break;
case HproseTags::TagBytes: $result = $this->readBytes(); break;
case HproseTags::TagUTF8Char: $result = $this->readUTF8Char(); break;
case HproseTags::TagString: $result = $this->readString(); break;
case HproseTags::TagGuid: $result = $this->readGuid(); break;
case HproseTags::TagList: $result = &$this->readList(); break;
case HproseTags::TagMap: $result = &$this->readMap(); break;
case HproseTags::TagClass: $this->readClass(); $result = &$this->unserialize(); break;
case HproseTags::TagObject: $result = $this->readObject(); break;
case HproseTags::TagError: throw new HproseException($this->readString(true));
case false: throw new HproseException('No byte found in stream');
default: throw new HproseException("Unexpected serialize tag '$tag' in stream");
}
return $result;
}
public function checkTag($expectTag, $tag = NULL) {
if (is_null($tag)) $tag = $this->stream->getc();
if ($tag != $expectTag) {
throw new HproseException("Tag '$expectTag' expected, but '$tag' found in stream");
}
}
public function checkTags($expectTags, $tag = NULL) {
if (is_null($tag)) $tag = $this->stream->getc();
if (!in_array($tag, $expectTags)) {
$expectTags = implode('', $expectTags);
throw new HproseException("Tag '$expectTags' expected, but '$tag' found in stream");
}
return $tag;
}
public function readInteger($includeTag = false) {
if ($includeTag) {
$tag = $this->stream->getc();
if (($tag >= '0') && ($tag <= '9')) {
return (int)$tag;
}
$this->checkTag(HproseTags::TagInteger, $tag);
}
return (int)($this->stream->readuntil(HproseTags::TagSemicolon));
}
public function readLong($includeTag = false) {
if ($includeTag) {
$tag = $this->stream->getc();
if (($tag >= '0') && ($tag <= '9')) {
return $tag;
}
$this->checkTag(HproseTags::TagLong, $tag);
}
return $this->stream->readuntil(HproseTags::TagSemicolon);
}
public function readDouble($includeTag = false) {
if ($includeTag) {
$tag = $this->stream->getc();
if (($tag >= '0') && ($tag <= '9')) {
return (double)$tag;
}
$this->checkTag(HproseTags::TagDouble, $tag);
}
return (double)($this->stream->readuntil(HproseTags::TagSemicolon));
}
public function readNaN() {
$this->checkTag(HproseTags::TagNaN);
return log(-1);
}
public function readInfinity($includeTag = false) {
if ($includeTag) $this->checkTag(HproseTags::TagInfinity);
return (($this->stream->getc() == HproseTags::TagNeg) ? log(0) : -log(0));
}
public function readNull() {
$this->checkTag(HproseTags::TagNull);
return NULL;
}
public function readEmpty() {
$this->checkTag(HproseTags::TagEmpty);
return '';
}
public function readBoolean() {
$tag = $this->checkTags(array(HproseTags::TagTrue, HproseTags::TagFalse));
return ($tag == HproseTags::TagTrue);
}
public function readDate($includeTag = false) {
if ($includeTag) $this->checkTag(HproseTags::TagDate);
$year = (int)($this->stream->read(4));
$month = (int)($this->stream->read(2));
$day = (int)($this->stream->read(2));
$tag = $this->stream->getc();
if ($tag == HproseTags::TagTime) {
$hour = (int)($this->stream->read(2));
$minute = (int)($this->stream->read(2));
$second = (int)($this->stream->read(2));
$microsecond = 0;
$tag = $this->stream->getc();
if ($tag == HproseTags::TagPoint) {
$microsecond = (int)($this->stream->read(3)) * 1000;
$tag = $this->stream->getc();
if (($tag >= '0') && ($tag <= '9')) {
$microsecond += (int)($tag) * 100 + (int)($this->stream->read(2));
$tag = $this->stream->getc();
if (($tag >= '0') && ($tag <= '9')) {
$this->stream->skip(2);
$tag = $this->stream->getc();
}
}
}
if ($tag == HproseTags::TagUTC) {
$date = new HproseDateTime($year, $month, $day,
$hour, $minute, $second,
$microsecond, true);
}
else {
$date = new HproseDateTime($year, $month, $day,
$hour, $minute, $second,
$microsecond);
}
}
elseif ($tag == HproseTags::TagUTC) {
$date = new HproseDate($year, $month, $day, true);
}
else {
$date = new HproseDate($year, $month, $day);
}
return $date;
}
public function readTime($includeTag = false) {
if ($includeTag) $this->checkTag(HproseTags::TagTime);
$hour = (int)($this->stream->read(2));
$minute = (int)($this->stream->read(2));
$second = (int)($this->stream->read(2));
$microsecond = 0;
$tag = $this->stream->getc();
if ($tag == HproseTags::TagPoint) {
$microsecond = (int)($this->stream->read(3)) * 1000;
$tag = $this->stream->getc();
if (($tag >= '0') && ($tag <= '9')) {
$microsecond += (int)($tag) * 100 + (int)($this->stream->read(2));
$tag = $this->stream->getc();
if (($tag >= '0') && ($tag <= '9')) {
$this->stream->skip(2);
$tag = $this->stream->getc();
}
}
}
if ($tag == HproseTags::TagUTC) {
$time = new HproseTime($hour, $minute, $second, $microsecond, true);
}
else {
$time = new HproseTime($hour, $minute, $second, $microsecond);
}
return $time;
}
public function readBytes($includeTag = false) {
if ($includeTag) $this->checkTag(HproseTags::TagBytes);
$count = (int)($this->stream->readuntil(HproseTags::TagQuote));
$bytes = $this->stream->read($count);
$this->stream->skip(1);
return $bytes;
}
public function readUTF8Char($includeTag = false) {
if ($includeTag) $this->checkTag(HproseTags::TagUTF8Char);
$c = $this->stream->getc();
$s = $c;
$a = ord($c);
if (($a & 0xE0) == 0xC0) {
$s .= $this->stream->getc();
}
elseif (($a & 0xF0) == 0xE0) {
$s .= $this->stream->read(2);
}
elseif ($a > 0x7F) {
throw new HproseException("bad utf-8 encoding");
}
return $s;
}
public function readString($includeTag = false) {
if ($includeTag) $this->checkTag(HproseTags::TagString);
$len = (int)$this->stream->readuntil(HproseTags::TagQuote);
$this->stream->mark();
$utf8len = 0;
for ($i = 0; $i < $len; ++$i) {
switch (ord($this->stream->getc()) >> 4) {
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7: {
// 0xxx xxxx
$utf8len++;
break;
}
case 12:
case 13: {
// 110x xxxx 10xx xxxx
$this->stream->skip(1);
$utf8len += 2;
break;
}
case 14: {
// 1110 xxxx 10xx xxxx 10xx xxxx
$this->stream->skip(2);
$utf8len += 3;
break;
}
case 15: {
// 1111 0xxx 10xx xxxx 10xx xxxx 10xx xxxx
$this->stream->skip(3);
$utf8len += 4;
++$i;
break;
}
default: {
throw new HproseException('bad utf-8 encoding');
}
}
}
$this->stream->reset();
$this->stream->unmark();
$s = $this->stream->read($utf8len);
$this->stream->skip(1);
return $s;
}
public function readGuid($includeTag = false) {
if ($includeTag) $this->checkTag(HproseTags::TagGuid);
$this->stream->skip(1);
$s = $this->stream->read(36);
$this->stream->skip(1);
return $s;
}
protected function &readListBegin() {
$list = array();
return $list;
}
protected function &readListEnd(&$list) {
$count = (int)$this->stream->readuntil(HproseTags::TagOpenbrace);
for ($i = 0; $i < $count; ++$i) {
$list[] = &$this->unserialize();
}
$this->stream->skip(1);
return $list;
}
public function &readList($includeTag = false) {
if ($includeTag) $this->checkTag(HproseTags::TagList);
$list = &$this->readListBegin();
return $this->readListEnd($list);
}
protected function &readMapBegin() {
$map = array();
return $map;
}
protected function &readMapEnd(&$map) {
$count = (int)$this->stream->readuntil(HproseTags::TagOpenbrace);
for ($i = 0; $i < $count; ++$i) {
$key = &$this->unserialize();
$map[$key] = &$this->unserialize();
}
$this->stream->skip(1);
return $map;
}
public function &readMap($includeTag = false) {
if ($includeTag) $this->checkTag(HproseTags::TagMap);
$map = &$this->readMapBegin();
return $this->readMapEnd($map);
}
protected function readObjectBegin() {
list($classname, $fields) = $this->classref[(int)$this->stream->readuntil(HproseTags::TagOpenbrace)];
$object = new $classname;
return array($object, $fields);
}
protected function readObjectEnd($object, $fields) {
$count = count($fields);
if (class_exists('ReflectionClass')) {
$reflector = new ReflectionClass($object);
for ($i = 0; $i < $count; ++$i) {
$field = $fields[$i];
if ($reflector->hasProperty($field)) {
$property = $reflector->getProperty($field);
$property->setAccessible(true);
$property->setValue($object, $this->unserialize());
}
else {
$object->$field = &$this->unserialize();
}
}
}
else {
for ($i = 0; $i < $count; ++$i) {
$object->$fields[$i] = &$this->unserialize();
}
}
$this->stream->skip(1);
return $object;
}
public function readObject($includeTag = false) {
if ($includeTag) {
$tag = $this->checkTags(array(HproseTags::TagClass, HproseTags::TagObject));
if ($tag == HproseTags::TagClass) {
$this->readClass();
return $this->readObject(true);
}
}
list($object, $fields) = $this->readObjectBegin();
return $this->readObjectEnd($object, $fields);
}
protected function readClass() {
$classname = HproseClassManager::getClass(self::readString());
$count = (int)$this->stream->readuntil(HproseTags::TagOpenbrace);
$fields = array();
for ($i = 0; $i < $count; ++$i) {
$fields[] = $this->readString(true);
}
$this->stream->skip(1);
$this->classref[] = array($classname, $fields);
}
public function reset() {
$this->classref = array();
}
}
class HproseReader extends HproseSimpleReader {
private $ref;
function __construct(&$stream) {
parent::__construct($stream);
$this->ref = array();
}
public function &unserialize($tag = NULL) {
if (is_null($tag)) {
$tag = $this->stream->getc();
}
if ($tag == HproseTags::TagRef) {
return $this->readRef();
}
return parent::unserialize($tag);
}
public function readDate($includeTag = false) {
if ($includeTag) {
$tag = $this->checkTags(array(HproseTags::TagDate, HproseTags::TagRef));
if ($tag == HproseTags::TagRef) return $this->readRef();
}
$date = parent::readDate();
$this->ref[] = $date;
return $date;
}
public function readTime($includeTag = false) {
if ($includeTag) {
$tag = $this->checkTags(array(HproseTags::TagTime, HproseTags::TagRef));
if ($tag == HproseTags::TagRef) return $this->readRef();
}
$time = parent::readTime();
$this->ref[] = $time;
return $time;
}
public function readBytes($includeTag = false) {
if ($includeTag) {
$tag = $this->checkTags(array(HproseTags::TagBytes, HproseTags::TagRef));
if ($tag == HproseTags::TagRef) return $this->readRef();
}
$bytes = parent::readBytes();
$this->ref[] = $bytes;
return $bytes;
}
public function readString($includeTag = false) {
if ($includeTag) {
$tag = $this->checkTags(array(HproseTags::TagString, HproseTags::TagRef));
if ($tag == HproseTags::TagRef) return $this->readRef();
}
$str = parent::readString();
$this->ref[] = $str;
return $str;
}
public function readGuid($includeTag = false) {
if ($includeTag) {
$tag = $this->checkTags(array(HproseTags::TagGuid, HproseTags::TagRef));
if ($tag == HproseTags::TagRef) return $this->readRef();
}
$guid = parent::readGuid();
$this->ref[] = $guid;
return $guid;
}
public function &readList($includeTag = false) {
if ($includeTag) {
$tag = $this->checkTags(array(HproseTags::TagList, HproseTags::TagRef));
if ($tag == HproseTags::TagRef) return $this->readRef();
}
$list = &$this->readListBegin();
$this->ref[] = &$list;
return $this->readListEnd($list);
}
public function &readMap($includeTag = false) {
if ($includeTag) {
$tag = $this->checkTags(array(HproseTags::TagMap, HproseTags::TagRef));
if ($tag == HproseTags::TagRef) return $this->readRef();
}
$map = &$this->readMapBegin();
$this->ref[] = &$map;
return $this->readMapEnd($map);
}
public function readObject($includeTag = false) {
if ($includeTag) {
$tag = $this->checkTags(array(HproseTags::TagClass, HproseTags::TagObject, HproseTags::TagRef));
if ($tag == HproseTags::TagRef) return $this->readRef();
if ($tag == HproseTags::TagClass) {
$this->readClass();
return $this->readObject(true);
}
}
list($object, $fields) = $this->readObjectBegin();
$this->ref[] = $object;
return $this->readObjectEnd($object, $fields);
}
private function &readRef() {
$ref = &$this->ref[(int)$this->stream->readuntil(HproseTags::TagSemicolon)];
if (gettype($ref) == 'array') {
$result = &$ref;
}
else {
$result = $ref;
}
return $result;
}
public function reset() {
parent::reset();
$this->ref = array();
}
}
?>

View File

@@ -0,0 +1,62 @@
<?php
/**********************************************************\
| |
| hprose |
| |
| Official WebSite: http://www.hprose.com/ |
| http://www.hprose.net/ |
| http://www.hprose.org/ |
| |
\**********************************************************/
/**********************************************************\
* *
* HproseTags.php *
* *
* hprose tags library for php5. *
* *
* LastModified: Nov 10, 2010 *
* Author: Ma Bingyao <andot@hprfc.com> *
* *
\**********************************************************/
class HproseTags {
/* Serialize Tags */
const TagInteger = 'i';
const TagLong = 'l';
const TagDouble = 'd';
const TagNull = 'n';
const TagEmpty = 'e';
const TagTrue = 't';
const TagFalse = 'f';
const TagNaN = 'N';
const TagInfinity = 'I';
const TagDate = 'D';
const TagTime = 'T';
const TagUTC = 'Z';
const TagBytes = 'b';
const TagUTF8Char = 'u';
const TagString = 's';
const TagGuid = 'g';
const TagList = 'a';
const TagMap = 'm';
const TagClass = 'c';
const TagObject = 'o';
const TagRef = 'r';
/* Serialize Marks */
const TagPos = '+';
const TagNeg = '-';
const TagSemicolon = ';';
const TagOpenbrace = '{';
const TagClosebrace = '}';
const TagQuote = '"';
const TagPoint = '.';
/* Protocol Tags */
const TagFunctions = 'F';
const TagCall = 'C';
const TagResult = 'R';
const TagArgument = 'A';
const TagError = 'E';
const TagEnd = 'z';
}
?>

View File

@@ -0,0 +1,301 @@
<?php
/**********************************************************\
| |
| hprose |
| |
| Official WebSite: http://www.hprose.com/ |
| http://www.hprose.net/ |
| http://www.hprose.org/ |
| |
\**********************************************************/
/**********************************************************\
* *
* HproseWriter.php *
* *
* hprose writer library for php5. *
* *
* LastModified: Nov 13, 2013 *
* Author: Ma Bingyao <andot@hprfc.com> *
* *
\**********************************************************/
require_once('HproseCommon.php');
require_once('HproseTags.php');
require_once('HproseClassManager.php');
class HproseSimpleWriter {
public $stream;
private $classref;
private $fieldsref;
function __construct(&$stream) {
$this->stream = &$stream;
$this->classref = array();
$this->fieldsref = array();
}
public function serialize(&$var) {
if ((!isset($var)) || ($var === NULL)) {
$this->writeNull();
}
elseif (is_scalar($var)) {
if (is_int($var)) {
$this->writeInteger($var);
}
elseif (is_bool($var)) {
$this->writeBoolean($var);
}
elseif (is_float($var)) {
$this->writeDouble($var);
}
elseif (is_string($var)) {
if ($var === '') {
$this->writeEmpty();
}
elseif ((strlen($var) < 4) && is_utf8($var) && (ustrlen($var) == 1)) {
$this->writeUTF8Char($var);
}
elseif (is_utf8($var)) {
$this->writeString($var, true);
}
else {
$this->writeBytes($var, true);
}
}
}
elseif (is_array($var)) {
if (is_list($var)) {
$this->writeList($var, true);
}
else {
$this->writeMap($var, true);
}
}
elseif (is_object($var)) {
if ($var instanceof stdClass) {
$this->writeStdObject($var, true);
}
elseif (($var instanceof HproseDate) || ($var instanceof HproseDateTime)) {
$this->writeDate($var, true);
}
elseif ($var instanceof HproseTime) {
$this->writeTime($var, true);
}
else {
$this->writeObject($var, true);
}
}
else {
throw new HproseException('Not support to serialize this data');
}
}
public function writeInteger($integer) {
if ($integer >= 0 && $integer <= 9) {
$this->stream->write((string)$integer);
}
else {
$this->stream->write(HproseTags::TagInteger . $integer . HproseTags::TagSemicolon);
}
}
public function writeLong($long) {
if ($long >= '0' && $long <= '9') {
$this->stream->write($long);
}
else {
$this->stream->write(HproseTags::TagLong . $long . HproseTags::TagSemicolon);
}
}
public function writeDouble($double) {
if (is_nan($double)) {
$this->writeNaN();
}
elseif (is_infinite($double)) {
$this->writeInfinity($double > 0);
}
else {
$this->stream->write(HproseTags::TagDouble . $double . HproseTags::TagSemicolon);
}
}
public function writeNaN() {
$this->stream->write(HproseTags::TagNaN);
}
public function writeInfinity($positive = true) {
$this->stream->write(HproseTags::TagInfinity . ($positive ? HproseTags::TagPos : HproseTags::TagNeg));
}
public function writeNull() {
$this->stream->write(HproseTags::TagNull);
}
public function writeEmpty() {
$this->stream->write(HproseTags::TagEmpty);
}
public function writeBoolean($bool) {
$this->stream->write($bool ? HproseTags::TagTrue : HproseTags::TagFalse);
}
public function writeDate($date, $checkRef = false) {
if ($date->utc) {
$this->stream->write(HproseTags::TagDate . $date->toString(false));
}
else {
$this->stream->write(HproseTags::TagDate . $date->toString(false) . HproseTags::TagSemicolon);
}
}
public function writeTime($time, $checkRef = false) {
if ($time->utc) {
$this->stream->write(HproseTags::TagTime . $time->toString(false));
}
else {
$this->stream->write(HproseTags::TagTime . $time->toString(false) . HproseTags::TagSemicolon);
}
}
public function writeBytes($bytes, $checkRef = false) {
$len = strlen($bytes);
$this->stream->write(HproseTags::TagBytes);
if ($len > 0) $this->stream->write((string)$len);
$this->stream->write(HproseTags::TagQuote . $bytes . HproseTags::TagQuote);
}
public function writeUTF8Char($char) {
$this->stream->write(HproseTags::TagUTF8Char . $char);
}
public function writeString($str, $checkRef = false) {
$len = ustrlen($str);
$this->stream->write(HproseTags::TagString);
if ($len > 0) $this->stream->write((string)$len);
$this->stream->write(HproseTags::TagQuote . $str . HproseTags::TagQuote);
}
public function writeList(&$list, $checkRef = false) {
$count = count($list);
$this->stream->write(HproseTags::TagList);
if ($count > 0) $this->stream->write((string)$count);
$this->stream->write(HproseTags::TagOpenbrace);
for ($i = 0; $i < $count; ++$i) {
$this->serialize($list[$i]);
}
$this->stream->write(HproseTags::TagClosebrace);
}
public function writeMap(&$map, $checkRef = false) {
$count = count($map);
$this->stream->write(HproseTags::TagMap);
if ($count > 0) $this->stream->write((string)$count);
$this->stream->write(HproseTags::TagOpenbrace);
foreach ($map as $key => &$value) {
$this->serialize($key);
$this->serialize($value);
}
$this->stream->write(HproseTags::TagClosebrace);
}
public function writeStdObject($obj, $checkRef = false) {
$map = (array)$obj;
self::writeMap($map);
}
protected function writeObjectBegin($obj) {
$class = get_class($obj);
$alias = HproseClassManager::getClassAlias($class);
$fields = array_keys((array)$obj);
if (array_key_exists($alias, $this->classref)) {
$index = $this->classref[$alias];
}
else {
$index = $this->writeClass($alias, $fields);
}
return $index;
}
protected function writeObjectEnd($obj, $index) {
$fields = $this->fieldsref[$index];
$count = count($fields);
$this->stream->write(HproseTags::TagObject . $index . HproseTags::TagOpenbrace);
$array = (array)$obj;
for ($i = 0; $i < $count; ++$i) {
$this->serialize($array[$fields[$i]]);
}
$this->stream->write(HproseTags::TagClosebrace);
}
public function writeObject($obj, $checkRef = false) {
$this->writeObjectEnd($obj, $this->writeObjectBegin($obj));
}
protected function writeClass($alias, $fields) {
$len = ustrlen($alias);
$this->stream->write(HproseTags::TagClass . $len .
HproseTags::TagQuote . $alias . HproseTags::TagQuote);
$count = count($fields);
if ($count > 0) $this->stream->write((string)$count);
$this->stream->write(HproseTags::TagOpenbrace);
for ($i = 0; $i < $count; ++$i) {
$field = $fields[$i];
if ($field{0} === "\0") {
$field = substr($field, strpos($field, "\0", 1) + 1);
}
$this->writeString($field);
}
$this->stream->write(HproseTags::TagClosebrace);
$index = count($this->fieldsref);
$this->classref[$alias] = $index;
$this->fieldsref[$index] = $fields;
return $index;
}
public function reset() {
$this->classref = array();
$this->fieldsref = array();
}
}
class HproseWriter extends HproseSimpleWriter {
private $ref;
private $arrayref;
function __construct(&$stream) {
parent::__construct($stream);
$this->ref = array();
$this->arrayref = array();
}
private function writeRef(&$obj, $checkRef, $writeBegin, $writeEnd) {
if (is_string($obj)) {
$key = 's_' . $obj;
}
elseif (is_array($obj)) {
if (($i = array_ref_search($obj, $this->arrayref)) === false) {
$i = count($this->arrayref);
$this->arrayref[$i] = &$obj;
}
$key = 'a_' . $i;
}
else {
$key = 'o_' . spl_object_hash($obj);
}
if ($checkRef && array_key_exists($key, $this->ref)) {
$this->stream->write(HproseTags::TagRef . $this->ref[$key] . HproseTags::TagSemicolon);
}
else {
$result = $writeBegin ? call_user_func_array($writeBegin, array(&$obj)) : false;
$index = count($this->ref);
$this->ref[$key] = $index;
call_user_func_array($writeEnd, array(&$obj, $result));
}
}
public function writeDate($date, $checkRef = false) {
$this->writeRef($date, $checkRef, NULL, array(&$this, 'parent::writeDate'));
}
public function writeTime($time, $checkRef = false) {
$this->writeRef($time, $checkRef, NULL, array(&$this, 'parent::writeTime'));
}
public function writeBytes($bytes, $checkRef = false) {
$this->writeRef($bytes, $checkRef, NULL, array(&$this, 'parent::writeBytes'));
}
public function writeString($str, $checkRef = false) {
$this->writeRef($str, $checkRef, NULL, array(&$this, 'parent::writeString'));
}
public function writeList(&$list, $checkRef = false) {
$this->writeRef($list, $checkRef, NULL, array(&$this, 'parent::writeList'));
}
public function writeMap(&$map, $checkRef = false) {
$this->writeRef($map, $checkRef, NULL, array(&$this, 'parent::writeMap'));
}
public function writeStdObject($obj, $checkRef = false) {
$this->writeRef($obj, $checkRef, NULL, array(&$this, 'parent::writeStdObject'));
}
public function writeObject($obj, $checkRef = false) {
$this->writeRef($obj, $checkRef, array(&$this, 'writeObjectBegin'), array(&$this, 'writeObjectEnd'));
}
public function reset() {
parent::reset();
$this->ref = array();
$this->arrayref = array();
}
}
?>

1
ThinkPHP/Library/Vendor/README.txt vendored Normal file
View File

@@ -0,0 +1 @@
第三方类库包目录

View File

@@ -0,0 +1,392 @@
<?php
/**
* SmartTemplate Class
*
* 'Compiles' HTML-Templates to PHP Code
*
*
* Usage Example I:
*
* $page = new SmartTemplate( "template.html" );
* $page->assign( 'TITLE', 'TemplateDemo - Userlist' );
* $page->assign( 'user', DB_read_all( 'select * from ris_user' ) );
* $page->output();
*
* Usage Example II:
*
* $data = array(
* 'TITLE' => 'TemplateDemo - Userlist',
* 'user' => DB_read_all( 'select * from ris_user' )
* );
* $page = new SmartTemplate( "template.html" );
* $page->output( $data );
*
*
* @author Philipp v. Criegern philipp@criegern.com
* @author Manuel 'EndelWar' Dalla Lana endelwar@aregar.it
* @version 1.2.1 03.07.2006
*
* CVS ID: $Id: class.smarttemplate.php 2504 2011-12-28 07:35:29Z liu21st $
*/
class SmartTemplate
{
/**
* Whether to store compiled php code or not (for debug purpose)
*
* @access public
*/
var $reuse_code = true;
/**
* Directory where all templates are stored
* Can be overwritten by global configuration array $_CONFIG['template_dir']
*
* @access public
*/
var $template_dir = 'templates/';
/**
* Where to store compiled templates
* Can be overwritten by global configuration array $_CONFIG['smarttemplate_compiled']
*
* @access public
*/
var $temp_dir = 'templates_c/';
/**
* Temporary folder for output cache storage
* Can be overwritten by global configuration array $_CONFIG['smarttemplate_cache']
*
* @access public
*/
var $cache_dir = 'templates_c/';
/**
* Default Output Cache Lifetime in Seconds
* Can be overwritten by global configuration array $_CONFIG['cache_lifetime']
*
* @access public
*/
var $cache_lifetime = 600;
/**
* Temporary file for output cache storage
*
* @access private
*/
var $cache_filename;
/**
* The template filename
*
* @access private
*/
var $tpl_file;
/**
* The compiled template filename
*
* @access private
*/
var $cpl_file;
/**
* Template content array
*
* @access private
*/
var $data = array();
/**
* Parser Class
*
* @access private
*/
var $parser;
/**
* Debugger Class
*
* @access private
*/
var $debugger;
/**
* SmartTemplate Constructor
*
* @access public
* @param string $template_filename Template Filename
*/
function SmartTemplate ( $template_filename = '' )
{
global $_CONFIG;
if (!empty($_CONFIG['smarttemplate_compiled']))
{
$this->temp_dir = $_CONFIG['smarttemplate_compiled'];
}
if (!empty($_CONFIG['smarttemplate_cache']))
{
$this->cache_dir = $_CONFIG['smarttemplate_cache'];
}
if (is_numeric($_CONFIG['cache_lifetime']))
{
$this->cache_lifetime = $_CONFIG['cache_lifetime'];
}
if (!empty($_CONFIG['template_dir']) && is_file($_CONFIG['template_dir'] . '/' . $template_filename))
{
$this->template_dir = $_CONFIG['template_dir'];
}
$this->tpl_file = $template_filename;
}
// DEPRECATED METHODS
// Methods used in older parser versions, soon will be removed
function set_templatefile ($template_filename) { $this->tpl_file = $template_filename; }
function add_value ($name, $value ) { $this->assign($name, $value); }
function add_array ($name, $value ) { $this->append($name, $value); }
/**
* Assign Template Content
*
* Usage Example:
* $page->assign( 'TITLE', 'My Document Title' );
* $page->assign( 'userlist', array(
* array( 'ID' => 123, 'NAME' => 'John Doe' ),
* array( 'ID' => 124, 'NAME' => 'Jack Doe' ),
* );
*
* @access public
* @param string $name Parameter Name
* @param mixed $value Parameter Value
* @desc Assign Template Content
*/
function assign ( $name, $value = '' )
{
if (is_array($name))
{
foreach ($name as $k => $v)
{
$this->data[$k] = $v;
}
}
else
{
$this->data[$name] = $value;
}
}
/**
* Assign Template Content
*
* Usage Example:
* $page->append( 'userlist', array( 'ID' => 123, 'NAME' => 'John Doe' ) );
* $page->append( 'userlist', array( 'ID' => 124, 'NAME' => 'Jack Doe' ) );
*
* @access public
* @param string $name Parameter Name
* @param mixed $value Parameter Value
* @desc Assign Template Content
*/
function append ( $name, $value )
{
if (is_array($value))
{
$this->data[$name][] = $value;
}
elseif (!is_array($this->data[$name]))
{
$this->data[$name] .= $value;
}
}
/**
* Parser Wrapper
* Returns Template Output as a String
*
* @access public
* @param array $_top Content Array
* @return string Parsed Template
* @desc Output Buffer Parser Wrapper
*/
function result ( $_top = '' )
{
ob_start();
$this->output( $_top );
$result = ob_get_contents();
ob_end_clean();
return $result;
}
/**
* Execute parsed Template
* Prints Parsing Results to Standard Output
*
* @access public
* @param array $_top Content Array
* @desc Execute parsed Template
*/
function output ( $_top = '' )
{
global $_top;
// Make sure that folder names have a trailing '/'
if (strlen($this->template_dir) && substr($this->template_dir, -1) != '/')
{
$this->template_dir .= '/';
}
if (strlen($this->temp_dir) && substr($this->temp_dir, -1) != '/')
{
$this->temp_dir .= '/';
}
// Prepare Template Content
if (!is_array($_top))
{
if (strlen($_top))
{
$this->tpl_file = $_top;
}
$_top = $this->data;
}
$_obj = &$_top;
$_stack_cnt = 0;
$_stack[$_stack_cnt++] = $_obj;
// Check if template is already compiled
$cpl_file_name = preg_replace('/[:\/.\\\\]/', '_', $this->tpl_file);
if (strlen($cpl_file_name) > 0)
{
$this->cpl_file = $this->temp_dir . $cpl_file_name . '.php';
$compile_template = true;
if ($this->reuse_code)
{
if (is_file($this->cpl_file))
{
if ($this->mtime($this->cpl_file) > $this->mtime($this->template_dir . $this->tpl_file))
{
$compile_template = false;
}
}
}
if ($compile_template)
{
if (@include_once("class.smarttemplateparser.php"))
{
$this->parser = new SmartTemplateParser($this->template_dir . $this->tpl_file);
if (!$this->parser->compile($this->cpl_file))
{
exit( "SmartTemplate Parser Error: " . $this->parser->error );
}
}
else
{
exit( "SmartTemplate Error: Cannot find class.smarttemplateparser.php; check SmartTemplate installation");
}
}
// Execute Compiled Template
include($this->cpl_file);
}
else
{
exit( "SmartTemplate Error: You must set a template file name");
}
// Delete Global Content Array in order to allow multiple use of SmartTemplate class in one script
unset ($_top);
}
/**
* Debug Template
*
* @access public
* @param array $_top Content Array
* @desc Debug Template
*/
function debug ( $_top = '' )
{
// Prepare Template Content
if (!$_top)
{
$_top = $this->data;
}
if (@include_once("class.smarttemplatedebugger.php"))
{
$this->debugger = new SmartTemplateDebugger($this->template_dir . $this->tpl_file);
$this->debugger->start($_top);
}
else
{
exit( "SmartTemplate Error: Cannot find class.smarttemplatedebugger.php; check SmartTemplate installation");
}
}
/**
* Start Ouput Content Buffering
*
* Usage Example:
* $page = new SmartTemplate('template.html');
* $page->use_cache();
* ...
*
* @access public
* @desc Output Cache
*/
function use_cache ( $key = '' )
{
if (empty($_POST))
{
$this->cache_filename = $this->cache_dir . 'cache_' . md5($_SERVER['REQUEST_URI'] . serialize($key)) . '.ser';
if (($_SERVER['HTTP_CACHE_CONTROL'] != 'no-cache') && ($_SERVER['HTTP_PRAGMA'] != 'no-cache') && @is_file($this->cache_filename))
{
if ((time() - filemtime($this->cache_filename)) < $this->cache_lifetime)
{
readfile($this->cache_filename);
exit;
}
}
ob_start( array( &$this, 'cache_callback' ) );
}
}
/**
* Output Buffer Callback Function
*
* @access private
* @param string $output
* @return string $output
*/
function cache_callback ( $output )
{
if ($hd = @fopen($this->cache_filename, 'w'))
{
fputs($hd, $output);
fclose($hd);
}
return $output;
}
/**
* Determine Last Filechange Date (if File exists)
*
* @access private
* @param string $filename
* @return mixed
* @desc Determine Last Filechange Date
*/
function mtime ( $filename )
{
if (@is_file($filename))
{
$ret = filemtime($filename);
return $ret;
}
}
}
?>

View File

@@ -0,0 +1,456 @@
<?php
/**
* SmartTemplateDebugger Class
* Used by SmartTemplate Class
*
* @desc Used by SmartTemplate Class
* @author Philipp v. Criegern philipp@criegern.com
* @author Manuel 'EndelWar' Dalla Lana endelwar@aregar.it
* @version 1.2.1 03.07.2006
*
* CVS ID: $Id: class.smarttemplatedebugger.php 2504 2011-12-28 07:35:29Z liu21st $
*/
class SmartTemplateDebugger
{
/**
* The template Filename
*
* @access private
*/
var $filename;
/**
* The template itself
*
* @access private
*/
var $template;
/**
* SmartTemplateParser Constructor
*
* @param string $template_filename HTML Template Filename
*/
function SmartTemplateDebugger ( $template_filename )
{
$this->filename = $template_filename;
// Load Template
if ($hd = @fopen($template_filename, "r"))
{
$this->template = fread($hd, filesize($template_filename));
fclose($hd);
}
else
{
$this->template = "SmartTemplate Debugger Error: File not found: '$template_filename'";
}
$this->tab[0] = '';
for ($i=1; $i < 10; $i++) {
$this->tab[$i] = str_repeat(' ', $i);
}
}
/**
* Main Template Parser
*
* @param string $compiled_template_filename Compiled Template Filename
* @desc Creates Compiled PHP Template
*/
function start ( $vars )
{
$page = $this->template;
$page = preg_replace("/(<!-- BEGIN [ a-zA-Z0-9_.]* -->)/", "\n$1\n", $page);
$page = preg_replace("/(<!-- IF .+? -->)/", "\n$1\n", $page);
$page = preg_replace("/(<!-- END.*? -->)/", "\n$1\n", $page);
$page = preg_replace("/(<!-- ELSEIF .+? -->)/", "\n$1\n", $page);
$page = preg_replace("/(<!-- ELSE [ a-zA-Z0-9_.]*-->)/", "\n$1\n", $page);
$page = $this->highlight_html($page);
$rows = explode("\n", $page);
$page_arr = array();
$level = 0;
$blocklvl = 0;
$rowcnt = 0;
$spancnt = 0;
$offset = 22;
$lvl_block = array();
$lvl_row = array();
$lvl_typ = array();
foreach ($rows as $row)
{
if ($row = trim($row))
{
$closespan = false;
if (substr($row, $offset, 12) == '&lt;!-- END ')
{
if ($level < 1)
{
$level++;
$error[$rowcnt] = "END Without BEGIN";
}
elseif ($lvl_typ[$level] != 'BEGIN')
{
$error[$lvl_row[$level]] = "IF without ENDIF";
$error[$rowcnt] = "END Without BEGIN";
}
$blocklvl--;
$level--;
$closespan = true;
}
if (substr($row, $offset, 14) == '&lt;!-- ENDIF ')
{
if ($level < 1)
{
$level++;
$error[$rowcnt] = "ENDIF Without IF";
}
elseif ($lvl_typ[$level] != 'IF')
{
$error[$lvl_row[$level]] = "BEGIN without END";
$error[$rowcnt] = "ENDIF Without IF";
}
$closespan = true;
$level--;
}
if ($closespan)
{
$page_arr[$rowcnt-1] .= '</span>';
}
$this_row = $this->tab[$level] . $row;
if (substr($row, $offset, 12) == '&lt;!-- ELSE')
{
if ($level < 1)
{
$error[$rowcnt] = "ELSE Without IF";
}
elseif ($lvl_typ[$level] != 'IF')
{
$error[$rowcnt] = "ELSE Without IF";
}
else
{
$this_row = $this->tab[$level-1] . $row;
}
}
if (substr($row, $offset, 14) == '&lt;!-- BEGIN ')
{
if ($blocklvl == 0)
{
if ($lp = strpos($row, '--&gt;'))
{
if ($blockname = trim(substr($row, $offset + 14, $lp -$offset -14)))
{
if ($nr = count($vars[$blockname]))
{
$this_row .= $this->toggleview("$nr Entries");
}
else
{
$this_row .= $this->toggleview("Emtpy");
}
}
}
}
else
{
$this_row .= $this->toggleview('[');
}
$blocklvl++;
$level++;
$lvl_row[$level] = $rowcnt;
$lvl_typ[$level] = 'BEGIN';
}
elseif (substr($row, $offset, 11) == '&lt;!-- IF ')
{
$level++;
$lvl_row[$level] = $rowcnt;
$lvl_typ[$level] = 'IF';
$this_row .= $this->toggleview();
}
$page_arr[] = $this_row;
$lvl_block[$rowcnt] = $blocklvl;
$rowcnt++;
}
}
if ($level > 0)
{
$error[$lvl_row[$level]] = "Block not closed";
}
$page = join("\n", $page_arr);
$rows = explode("\n", $page);
$cnt = count($rows);
for ($i = 0; $i < $cnt; $i++)
{
// Add Errortext
if (isset($error))
{
if ($err = $error[$i])
{
$rows[$i] = '<b>' . $rows[$i] . ' ERROR: ' . $err . '!</b>';
}
}
// Replace Scalars
if (preg_match_all('/{([a-zA-Z0-9_. &;]+)}/', $rows[$i], $var))
{
foreach ($var[1] as $tag)
{
$fulltag = $tag;
if ($delim = strpos($tag, ' &gt; '))
{
$tag = substr($tag, 0, $delim);
}
if (substr($tag, 0, 4) == 'top.')
{
$title = $this->tip($vars[substr($tag, 4)]);
}
elseif ($lvl_block[$i] == 0)
{
$title = $this->tip($vars[$tag]);
}
else
{
$title = '[BLOCK?]';
}
$code = '<b title="' . $title . '">{' . $fulltag . '}</b>';
$rows[$i] = str_replace('{'.$fulltag.'}', $code, $rows[$i]);
}
}
// Replace Extensions
if (preg_match_all('/{([a-zA-Z0-9_]+):([^}]*)}/', $rows[$i], $var))
{
foreach ($var[2] as $tmpcnt => $tag)
{
$fulltag = $tag;
if ($delim = strpos($tag, ' &gt; '))
{
$tag = substr($tag, 0, $delim);
}
if (strpos($tag, ','))
{
list($tag, $addparam) = explode(',', $tag, 2);
}
$extension = $var[1][$tmpcnt];
if (substr($tag, 0, 4) == 'top.')
{
$title = $this->tip($vars[substr($tag, 4)]);
}
elseif ($lvl_block[$i] == 0)
{
$title = $this->tip($vars[$tag]);
}
else
{
$title = '[BLOCK?]';
}
$code = '<b title="' . $title . '">{' . $extension . ':' . $fulltag . '}</b>';
$rows[$i] = str_replace('{'.$extension . ':' . $fulltag .'}', $code, $rows[$i]);
}
}
// 'IF nnn' Blocks
if (preg_match_all('/&lt;!-- IF ([a-zA-Z0-9_.]+) --&gt;/', $rows[$i], $var))
{
foreach ($var[1] as $tag)
{
if (substr($tag, 0, 4) == 'top.')
{
$title = $this->tip($vars[substr($tag, 4)]);
}
elseif ($lvl_block[$i] == 0)
{
$title = $this->tip($vars[$tag]);
}
else
{
$title = '[BLOCK?]';
}
$code = '<span title="' . $title . '">&lt;!-- IF ' . $tag . ' --&gt;</span>';
$rows[$i] = str_replace("&lt;!-- IF $tag --&gt;", $code, $rows[$i]);
if ($title == '[NULL]')
{
$rows[$i] = str_replace('Hide', 'Show', $rows[$i]);
$rows[$i] = str_replace('block', 'none', $rows[$i]);
}
}
}
}
$page = join("<br>", $rows);
// Print Header
echo '<html><head><script type="text/javascript">
function toggleVisibility(el, src) {
var v = el.style.display == "block";
var str = src.innerHTML;
el.style.display = v ? "none" : "block";
src.innerHTML = v ? str.replace(/Hide/, "Show") : str.replace(/Show/, "Hide");}
</script></head><body>';
// Print Index
echo '<font face="Arial" Size="3"><b>';
echo 'SmartTemplate Debugger<br>';
echo '<font size="2"><li>PHP-Script: ' . $_SERVER['PATH_TRANSLATED'] . '</li><li>Template: ' . $this->filename . '</li></font><hr>';
echo '<li><a href="#template_code">Template</a></li>';
echo '<li><a href="#compiled_code">Compiled Template</a></li>';
echo '<li><a href="#data_code">Data</a></li>';
echo '</b></font><hr>';
// Print Template
echo '<a name="template_code"><br><font face="Arial" Size="3"><b>Template:</b>&nbsp;[<a href="javascript:void(\'\');" onclick="toggleVisibility(document.getElementById(\'Template\'), this); return false">Hide Ouptut</a>]</font><br>';
echo '<table border="0" cellpadding="4" cellspacing="1" width="100%" bgcolor="#C6D3EF"><tr><td bgcolor="#F0F0F0"><pre id="Template" style="display:block">';
echo $page;
echo '</pre></td></tr></table>';
// Print Compiled Template
if (@include_once ("class.smarttemplateparser.php"))
{
$parser = new SmartTemplateParser($this->filename);
$compiled = $parser->compile();
echo '<a name="compiled_code"><br><br><font face="Arial" Size="3"><b>Compiled Template:</b>&nbsp;[<a href="javascript:void(\'\');" onclick="toggleVisibility(document.getElementById(\'Compiled\'), this); return false">Hide Ouptut</a>]</font><br>';
echo '<table border="0" cellpadding="4" cellspacing="1" width="100%" bgcolor="#C6D3EF"><tr><td bgcolor="#F0F0F0"><pre id="Compiled" style="display:block">';
highlight_string($compiled);
echo '</pre></td></tr></table>';
}
else
{
exit( "SmartTemplate Error: Cannot find class.smarttemplateparser.php; check SmartTemplate installation");
}
// Print Data
echo '<a name="data_code"><br><br><font face="Arial" Size="3"><b>Data:</b>&nbsp;[<a href="javascript:void(\'\');" onclick="toggleVisibility(document.getElementById(\'Data\'), this); return false">Hide Ouptut</a>]</font><br>';
echo '<table border="0" cellpadding="4" cellspacing="1" width="100%" bgcolor="#C6D3EF"><tr><td bgcolor="#F0F0F0"><pre id="Data" style="display:block">';
echo $this->vardump($vars);
echo '</pre></td></tr></table></body></html>';
}
/**
* Insert Hide/Show Layer Switch
*
* @param string $suffix Additional Text
* @desc Insert Hide/Show Layer Switch
*/
function toggleview ( $suffix = '')
{
global $spancnt;
$spancnt++;
if ($suffix)
{
$suffix .= ':';
}
$ret = '[' . $suffix . '<a href="javascript:void(\'\');" onclick="toggleVisibility(document.getElementById(\'Block' . $spancnt . '\'), this); return false">Hide Block</a>]<span id="Block' . $spancnt . '" style="display:block">';
return $ret;
}
/**
* Create Title Text
*
* @param string $value Content
* @desc Create Title Text
*/
function tip ( $value )
{
if (empty($value))
{
return "[NULL]";
}
else
{
$ret = htmlentities(substr($value,0,200));
return $ret;
}
}
/**
* Recursive Variable Display Output
*
* @param mixed $var Content
* @param int $depth Incremented Indent Counter for Recursive Calls
* @return string Variable Content
* @access private
* @desc Recursive Variable Display Output
*/
function vardump($var, $depth = 0)
{
if (is_array($var))
{
$result = "Array (" . count($var) . ")<BR>";
foreach(array_keys($var) as $key)
{
$result .= $this->tab[$depth] . "<B>$key</B>: " . $this->vardump($var[$key], $depth+1);
}
return $result;
}
else
{
$ret = htmlentities($var) . "<BR>";
return $ret;
}
}
/**
* Splits Template-Style Variable Names into an Array-Name/Key-Name Components
*
* @param string $tag Variale Name used in Template
* @return array Array Name, Key Name
* @access private
* @desc Splits Template-Style Variable Names into an Array-Name/Key-Name Components
*/
function var_name($tag)
{
$parent_level = 0;
while (substr($tag, 0, 7) == 'parent.')
{
$tag = substr($tag, 7);
$parent_level++;
}
if (substr($tag, 0, 4) == 'top.')
{
$ret = array('_stack[0]', substr($tag,4));
return $ret;
}
elseif ($parent_level)
{
$ret = array('_stack[$_stack_cnt-'.$parent_level.']', $tag);
return $ret;
}
else
{
$ret = array('_obj', $tag);
return $ret;
}
}
/**
* Highlight HTML Source
*
* @param string $code HTML Source
* @return string Hightlighte HTML Source
* @access private
* @desc Highlight HTML Source
*/
function highlight_html ( $code )
{
$code = htmlentities($code);
$code = preg_replace('/([a-zA-Z_]+)=/', '<font color="#FF0000">$1=</font>', $code);
$code = preg_replace('/(&lt;[\/a-zA-Z0-9&;]+)/', '<font color="#0000FF">$1</font>', $code);
$code = str_replace('&lt;!--', '<font color="#008080">&lt;!--', $code);
$code = str_replace('--&gt;', '--&gt;</font>', $code);
$code = preg_replace('/[\r\n]+/', "\n", $code);
return $code;
}
}
?>

View File

@@ -0,0 +1,365 @@
<?php
/**
* SmartTemplateParser Class
* Used by SmartTemplate Class
*
* @desc Used by SmartTemplate Class
* @author Philipp v. Criegern philipp@criegern.com
* @author Manuel 'EndelWar' Dalla Lana endelwar@aregar.it
* @version 1.2.1 03.07.2006
*
* CVS ID: $Id: class.smarttemplateparser.php 2504 2011-12-28 07:35:29Z liu21st $
*/
class SmartTemplateParser
{
/**
* The template itself
*
* @access private
*/
var $template;
/**
* The template filename used to extract the dirname for subtemplates
*
* @access private
*/
var $template_dir;
/**
* List of used SmartTemplate Extensions
*
* @access private
*/
var $extension_tagged = array();
/**
* Error messages
*
* @access public
*/
var $error;
/**
* SmartTemplateParser Constructor
*
* @param string $template_filename HTML Template Filename
*/
function SmartTemplateParser ( $template_filename )
{
// Load Template
if ($hd = @fopen($template_filename, "r"))
{
if (filesize($template_filename))
{
$this->template = fread($hd, filesize($template_filename));
}
else
{
$this->template = "SmartTemplate Parser Error: File size is zero byte: '$template_filename'";
}
fclose($hd);
// Extract the name of the template directory
$this->template_dir = dirname($template_filename);
}
else
{
$this->template = "SmartTemplate Parser Error: File not found: '$template_filename'";
}
}
/**
* Main Template Parser
*
* @param string $compiled_template_filename Compiled Template Filename
* @desc Creates Compiled PHP Template
*/
function compile( $compiled_template_filename = '' )
{
if (empty($this->template))
{
return;
}
/* Quick hack to allow subtemplates */
if(eregi("<!-- INCLUDE", $this->template))
{
while ($this->count_subtemplates() > 0)
{
preg_match_all('/<!-- INCLUDE ([a-zA-Z0-9_.]+) -->/', $this->template, $tvar);
foreach($tvar[1] as $subfile)
{
if(file_exists($this->template_dir . "/$subfile"))
{
$subst = implode('',file($this->template_dir . "/$subfile"));
}
else
{
$subst = 'SmartTemplate Parser Error: Subtemplate not found: \''.$subfile.'\'';
}
$this->template = str_replace("<!-- INCLUDE $subfile -->", $subst, $this->template);
}
}
}
// END, ELSE Blocks
$page = preg_replace("/<!-- ENDIF.+?-->/", "<?php\n}\n?>", $this->template);
$page = preg_replace("/<!-- END[ a-zA-Z0-9_.]* -->/", "<?php\n}\n\$_obj=\$_stack[--\$_stack_cnt];}\n?>", $page);
$page = str_replace("<!-- ELSE -->", "<?php\n} else {\n?>", $page);
// 'BEGIN - END' Blocks
if (preg_match_all('/<!-- BEGIN ([a-zA-Z0-9_.]+) -->/', $page, $var))
{
foreach ($var[1] as $tag)
{
list($parent, $block) = $this->var_name($tag);
$code = "<?php\n"
. "if (!empty(\$$parent"."['$block'])){\n"
. "if (!is_array(\$$parent"."['$block']))\n"
. "\$$parent"."['$block']=array(array('$block'=>\$$parent"."['$block']));\n"
. "\$_tmp_arr_keys=array_keys(\$$parent"."['$block']);\n"
. "if (\$_tmp_arr_keys[0]!='0')\n"
. "\$$parent"."['$block']=array(0=>\$$parent"."['$block']);\n"
. "\$_stack[\$_stack_cnt++]=\$_obj;\n"
. "foreach (\$$parent"."['$block'] as \$rowcnt=>\$$block) {\n"
. "\$$block"."['ROWCNT']=\$rowcnt;\n"
. "\$$block"."['ALTROW']=\$rowcnt%2;\n"
. "\$$block"."['ROWBIT']=\$rowcnt%2;\n"
. "\$_obj=&\$$block;\n?>";
$page = str_replace("<!-- BEGIN $tag -->", $code, $page);
}
}
// 'IF nnn=mmm' Blocks
if (preg_match_all('/<!-- (ELSE)?IF ([a-zA-Z0-9_.]+)[ ]*([!=<>]+)[ ]*(["]?[^"]*["]?) -->/', $page, $var))
{
foreach ($var[2] as $cnt => $tag)
{
list($parent, $block) = $this->var_name($tag);
$cmp = $var[3][$cnt];
$val = $var[4][$cnt];
$else = ($var[1][$cnt] == 'ELSE') ? '} else' : '';
if ($cmp == '=')
{
$cmp = '==';
}
if (preg_match('/"([^"]*)"/',$val,$matches))
{
$code = "<?php\n$else"."if (\$$parent"."['$block'] $cmp \"".$matches[1]."\"){\n?>";
}
elseif (preg_match('/([^"]*)/',$val,$matches))
{
list($parent_right, $block_right) = $this->var_name($matches[1]);
$code = "<?php\n$else"."if (\$$parent"."['$block'] $cmp \$$parent_right"."['$block_right']){\n?>";
}
$page = str_replace($var[0][$cnt], $code, $page);
}
}
// 'IF nnn' Blocks
if (preg_match_all('/<!-- (ELSE)?IF ([a-zA-Z0-9_.]+) -->/', $page, $var))
{
foreach ($var[2] as $cnt => $tag)
{
$else = ($var[1][$cnt] == 'ELSE') ? '} else' : '';
list($parent, $block) = $this->var_name($tag);
$code = "<?php\n$else"."if (!empty(\$$parent"."['$block'])){\n?>";
$page = str_replace($var[0][$cnt], $code, $page);
}
}
// Replace Scalars
if (preg_match_all('/{([a-zA-Z0-9_. >]+)}/', $page, $var))
{
foreach ($var[1] as $fulltag)
{
// Determin Command (echo / $obj[n]=)
list($cmd, $tag) = $this->cmd_name($fulltag);
list($block, $skalar) = $this->var_name($tag);
$code = "<?php\n$cmd \$$block"."['$skalar'];\n?>\n";
$page = str_replace('{'.$fulltag.'}', $code, $page);
}
}
// ROSI Special: Replace Translations
if (preg_match_all('/<"([a-zA-Z0-9_.]+)">/', $page, $var))
{
foreach ($var[1] as $tag)
{
list($block, $skalar) = $this->var_name($tag);
$code = "<?php\necho gettext('$skalar');\n?>\n";
$page = str_replace('<"'.$tag.'">', $code, $page);
}
}
// Include Extensions
$header = '';
if (preg_match_all('/{([a-zA-Z0-9_]+):([^}]*)}/', $page, $var))
{
foreach ($var[2] as $cnt => $tag)
{
// Determin Command (echo / $obj[n]=)
list($cmd, $tag) = $this->cmd_name($tag);
$extension = $var[1][$cnt];
if (!isset($this->extension_tagged[$extension]))
{
$header .= "include_once \"smarttemplate_extensions/smarttemplate_extension_$extension.php\";\n";
$this->extension_tagged[$extension] = true;
}
if (!strlen($tag))
{
$code = "<?php\n$cmd smarttemplate_extension_$extension();\n?>\n";
}
elseif (substr($tag, 0, 1) == '"')
{
$code = "<?php\n$cmd smarttemplate_extension_$extension($tag);\n?>\n";
}
elseif (strpos($tag, ','))
{
list($tag, $addparam) = explode(',', $tag, 2);
list($block, $skalar) = $this->var_name($tag);
if (preg_match('/^([a-zA-Z_]+)/', $addparam, $match))
{
$nexttag = $match[1];
list($nextblock, $nextskalar) = $this->var_name($nexttag);
$addparam = substr($addparam, strlen($nexttag));
$code = "<?php\n$cmd smarttemplate_extension_$extension(\$$block"."['$skalar'],\$$nextblock"."['$nextskalar']"."$addparam);\n?>\n";
}
else
{
$code = "<?php\n$cmd smarttemplate_extension_$extension(\$$block"."['$skalar'],$addparam);\n?>\n";
}
}
else
{
list($block, $skalar) = $this->var_name($tag);
$code = "<?php\n$cmd smarttemplate_extension_$extension(\$$block"."['$skalar']);\n?>\n";
}
$page = str_replace($var[0][$cnt], $code, $page);
}
}
// Add Include Header
if (isset($header) && !empty($header))
{
$page = "<?php\n$header\n?>$page";
}
// Store Code to Temp Dir
if (strlen($compiled_template_filename))
{
if ($hd = fopen($compiled_template_filename, "w"))
{
fwrite($hd, $page);
fclose($hd);
return true;
}
else
{
$this->error = "Could not write compiled file.";
return false;
}
}
else
{
return $page;
}
}
/**
* Splits Template-Style Variable Names into an Array-Name/Key-Name Components
* {example} : array( "_obj", "example" ) -> $_obj['example']
* {example.value} : array( "_obj['example']", "value" ) -> $_obj['example']['value']
* {example.0.value} : array( "_obj['example'][0]", "value" ) -> $_obj['example'][0]['value']
* {top.example} : array( "_stack[0]", "example" ) -> $_stack[0]['example']
* {parent.example} : array( "_stack[$_stack_cnt-1]", "example" ) -> $_stack[$_stack_cnt-1]['example']
* {parent.parent.example} : array( "_stack[$_stack_cnt-2]", "example" ) -> $_stack[$_stack_cnt-2]['example']
*
* @param string $tag Variale Name used in Template
* @return array Array Name, Key Name
* @access private
* @desc Splits Template-Style Variable Names into an Array-Name/Key-Name Components
*/
function var_name($tag)
{
$parent_level = 0;
while (substr($tag, 0, 7) == 'parent.')
{
$tag = substr($tag, 7);
$parent_level++;
}
if (substr($tag, 0, 4) == 'top.')
{
$obj = '_stack[0]';
$tag = substr($tag,4);
}
elseif ($parent_level)
{
$obj = '_stack[$_stack_cnt-'.$parent_level.']';
}
else
{
$obj = '_obj';
}
while (is_int(strpos($tag, '.')))
{
list($parent, $tag) = explode('.', $tag, 2);
if (is_numeric($parent))
{
$obj .= "[" . $parent . "]";
}
else
{
$obj .= "['" . $parent . "']";
}
}
$ret = array($obj, $tag);
return $ret;
}
/**
* Determine Template Command from Variable Name
* {variable} : array( "echo", "variable" ) -> echo $_obj['variable']
* {variable > new_name} : array( "_obj['new_name']=", "variable" ) -> $_obj['new_name']= $_obj['variable']
*
* @param string $tag Variale Name used in Template
* @return array Array Command, Variable
* @access private
* @desc Determine Template Command from Variable Name
*/
function cmd_name($tag)
{
if (preg_match('/^(.+) > ([a-zA-Z0-9_.]+)$/', $tag, $tagvar))
{
$tag = $tagvar[1];
list($newblock, $newskalar) = $this->var_name($tagvar[2]);
$cmd = "\$$newblock"."['$newskalar']=";
}
else
{
$cmd = "echo";
}
$ret = array($cmd, $tag);
return $ret;
}
/**
* @return int Number of subtemplate included
* @access private
* @desc Count number of subtemplates included in current template
*/
function count_subtemplates()
{
preg_match_all('/<!-- INCLUDE ([a-zA-Z0-9_.]+) -->/', $this->template, $tvar);
$count_subtemplates = count($tvar[1]);
$ret = intval($count_subtemplates);
return $ret;
}
}
?>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,460 @@
<?php
/**
* Project: Smarty: the PHP compiling template engine
* File: SmartyBC.class.php
* SVN: $Id: SmartyBC.class.php 2504 2011-12-28 07:35:29Z liu21st $
*
* 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(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;
/**
* 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);
// register {php} tag
$this->registerPlugin('block', 'php', 'smarty_php_tag');
}
/**
* 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_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);
}
}
/**
* Smarty {php}{/php} block function
*
* @param array $params parameter list
* @param string $content contents of the block
* @param object $template template object
* @param boolean &$repeat repeat flag
* @return string content re-formatted
*/
function smarty_php_tag($params, $content, $template, &$repeat)
{
eval($content);
return '';
}
?>

133
ThinkPHP/Library/Vendor/Smarty/debug.tpl vendored Normal file
View File

@@ -0,0 +1,133 @@
{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, 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;
}
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;
width: 50%;
}
td {
color: green;
}
.odd {
background-color: #eeeeee;
}
.even {
background-color: #fafafa;
}
.exectime {
font-size: 0.8em;
font-style: italic;
}
#table_assigned_vars th {
color: blue;
}
#table_config_vars th {
color: maroon;
}
{/literal}
</style>
</head>
<body>
<h1>Smarty Debug Console - {if isset($template_name)}{$template_name|debug_print_var nofilter}{else}Total Time {$execution_time|string_format:"%.5f"}{/if}</h1>
{if !empty($template_data)}
<h2>included templates &amp; config files (load time in seconds)</h2>
<div>
{foreach $template_data as $template}
<font color=brown>{$template.name}</font>
<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}">
<th>${$vars@key|escape:'html'}</th>
<td>{$vars|debug_print_var nofilter}</td></tr>
{/foreach}
</table>
<h2>assigned config file variables (outer template scope)</h2>
<table id="table_config_vars">
{foreach $config_vars as $vars}
<tr class="{if $vars@iteration % 2 eq 0}odd{else}even{/if}">
<th>{$vars@key|escape:'html'}</th>
<td>{$vars|debug_print_var nofilter}</td></tr>
{/foreach}
</table>
</body>
</html>
{/capture}
<script type="text/javascript">
{$id = $template_name|default:''|md5}
_smarty_console = window.open("","console{$id}","width=680,height=600,resizable,scrollbars=yes");
_smarty_console.document.write("{$debug_output|escape:'javascript' nofilter}");
_smarty_console.document.close();
</script>

View File

@@ -0,0 +1,113 @@
<?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);
$_output = '';
foreach ($_paragraphs as &$_paragraph) {
if (!$_paragraph) {
continue;
}
// convert mult. spaces & special chars to single space
$_paragraph = preg_replace(array('!\s+!u', '!(^\s+)|(\s+$)!u'), array(' ', ''), $_paragraph);
// indent first line
if ($indent_first > 0) {
$_paragraph = str_repeat($indent_char, $indent_first) . $_paragraph;
}
// wordwrap sentences
if (SMARTY_MBSTRING /* ^phpunit */&&empty($_SERVER['SMARTY_PHPUNIT_DISABLE_MBSTRING'])/* phpunit$ */) {
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;
}
}
?>

View File

@@ -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;
}
?>

View File

@@ -0,0 +1,106 @@
<?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;
}
?>

View File

@@ -0,0 +1,216 @@
<?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
* @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;
}
$content = '';
if (isset($template->smarty->security_policy) && !preg_match('!^(http|ftp)://!i', $params['file'])) {
if(!$template->smarty->security_policy->isTrustedResourceDir($params['file'])) {
return;
}
// fetch the file
if($fp = @fopen($params['file'],'r')) {
while(!feof($fp)) {
$content .= fgets ($fp,4096);
}
fclose($fp);
} else {
trigger_error('[plugin] fetch cannot read file \'' . $params['file'] . '\'',E_USER_NOTICE);
return;
}
} else {
// not a local file
if(preg_match('!^http://!i',$params['file'])) {
// 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 {
// ftp fetch
if($fp = @fopen($params['file'],'r')) {
while(!feof($fp)) {
$content .= fgets ($fp,4096);
}
fclose($fp);
} else {
trigger_error('[plugin] fetch cannot read file \'' . $params['file'] .'\'',E_USER_NOTICE);
return;
}
}
}
if (!empty($params['assign'])) {
$template->assign($params['assign'],$content);
} else {
return $content;
}
}
?>

View File

@@ -0,0 +1,216 @@
<?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 &nbsp;
* - 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;
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\-\.]!u', '_', $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;
}
?>

View File

@@ -0,0 +1,138 @@
<?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
* @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 = '';
$server_vars = $_SERVER;
$basedir = isset($server_vars['DOCUMENT_ROOT']) ? $server_vars['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 (substr($file, 0, 1) == '/') {
$_image_path = $basedir . $file;
} else {
$_image_path = $file;
}
if (!isset($params['width']) || !isset($params['height'])) {
if (!$_image_data = @getimagesize($_image_path)) {
if (!file_exists($_image_path)) {
trigger_error("html_image: unable to find '$_image_path'", E_USER_NOTICE);
return;
} else if (!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($template->smarty->security_policy)) {
if (!$template->smarty->security_policy->isTrustedResourceDir($_image_path)) {
return;
}
}
if (!isset($params['width'])) {
$width = $_image_data[0];
}
if (!isset($params['height'])) {
$height = $_image_data[1];
}
}
if (isset($params['dpi'])) {
if (strstr($server_vars['HTTP_USER_AGENT'], 'Mac')) {
$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;
}
?>

View File

@@ -0,0 +1,174 @@
<?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
* @param Smarty_Internal_Template $template template object
* @return string
* @uses smarty_function_escape_special_chars()
*/
function smarty_function_html_options($params, $template)
{
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;
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 '';
}
}
$_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;
}
?>

View File

@@ -0,0 +1,200 @@
<?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 &nbsp;
* - 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;
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\-\.]!u', '_', $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;
}
?>

View File

@@ -0,0 +1,394 @@
<?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
* @param Smarty_Internal_Template $template template object
* @return string
*/
function smarty_function_html_select_date($params, $template)
{
// 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);
}
$time = mktime(0, 0, 0, $_month, $_day, $_year);
} 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);
}
$time = mktime(0, 0, 0, $_month, $_day, $_year);
} 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;
} else if ($t[0] == '+') {
$$key = (int)($_current_year + trim(substr($t, 1)));
} else if ($t[0] == '-') {
$$key = (int)($_current_year - 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) {
$_html_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) {
$_html_month = '';
$_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) {
$_html_day = '';
$_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;
}
?>

View File

@@ -0,0 +1,366 @@
<?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
* @param Smarty_Internal_Template $template template object
* @return string
* @uses smarty_make_timestamp()
*/
function smarty_function_html_select_time($params, $template)
{
$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 < 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;
}
?>

View File

@@ -0,0 +1,177 @@
<?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
* @param Smarty_Internal_Template $template template object
* @return string
*/
function smarty_function_html_table($params, $template)
{
$table_attr = 'border="1"';
$tr_attr = '';
$th_attr = '';
$td_attr = '';
$cols = $cols_count = 3;
$rows = 3;
$trailpad = '&nbsp;';
$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 : '';
}
?>

View File

@@ -0,0 +1,152 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsFunction
*/
/**
* Smarty {mailto} function plugin
*
* Type: function<br>
* Name: mailto<br>
* Date: May 21, 2002
* Purpose: automate mailto address link creation, and optionally encode them.<br>
* Params:
* <pre>
* - address - (required) - e-mail address
* - text - (optional) - text to display, default is address
* - encode - (optional) - can be one of:
* * none : no encoding (default)
* * javascript : encode with javascript
* * javascript_charcode : encode with javascript charcode
* * hex : encode with hexidecimal (no javascript)
* - cc - (optional) - address(es) to carbon copy
* - bcc - (optional) - address(es) to blind carbon copy
* - subject - (optional) - e-mail subject
* - newsgroups - (optional) - newsgroup(s) to post to
* - followupto - (optional) - address(es) to follow up to
* - extra - (optional) - extra tags for the href link
* </pre>
* Examples:
* <pre>
* {mailto address="me@domain.com"}
* {mailto address="me@domain.com" encode="javascript"}
* {mailto address="me@domain.com" encode="hex"}
* {mailto address="me@domain.com" subject="Hello to you!"}
* {mailto address="me@domain.com" cc="you@domain.com,they@domain.com"}
* {mailto address="me@domain.com" extra='class="mailto"'}
* </pre>
*
* @link http://www.smarty.net/manual/en/language.function.mailto.php {mailto}
* (Smarty online manual)
* @version 1.2
* @author Monte Ohrt <monte at ohrt dot com>
* @author credits to Jason Sweat (added cc, bcc and subject functionality)
* @param array $params parameters
* @param Smarty_Internal_Template $template template object
* @return string
*/
function smarty_function_mailto($params, $template)
{
static $_allowed_encoding = array('javascript' => true, 'javascript_charcode' => true, 'hex' => true, 'none' => true);
$extra = '';
if (empty($params['address'])) {
trigger_error("mailto: missing 'address' parameter",E_USER_WARNING);
return;
} else {
$address = $params['address'];
}
$text = $address;
// netscape and mozilla do not decode %40 (@) in BCC field (bug?)
// so, don't encode it.
$search = array('%40', '%2C');
$replace = array('@', ',');
$mail_parms = array();
foreach ($params as $var => $value) {
switch ($var) {
case 'cc':
case 'bcc':
case 'followupto':
if (!empty($value))
$mail_parms[] = $var . '=' . str_replace($search, $replace, rawurlencode($value));
break;
case 'subject':
case 'newsgroups':
$mail_parms[] = $var . '=' . rawurlencode($value);
break;
case 'extra':
case 'text':
$$var = $value;
default:
}
}
if ($mail_parms) {
$address .= '?' . join('&', $mail_parms);
}
$encode = (empty($params['encode'])) ? 'none' : $params['encode'];
if (!isset($_allowed_encoding[$encode])) {
trigger_error("mailto: 'encode' parameter must be none, javascript, javascript_charcode or hex", E_USER_WARNING);
return;
}
// FIXME: (rodneyrehm) document.write() excues me what? 1998 has passed!
if ($encode == 'javascript') {
$string = 'document.write(\'<a href="mailto:' . $address . '" ' . $extra . '>' . $text . '</a>\');';
$js_encode = '';
for ($x = 0, $_length = strlen($string); $x < $_length; $x++) {
$js_encode .= '%' . bin2hex($string[$x]);
}
return '<script type="text/javascript">eval(unescape(\'' . $js_encode . '\'))</script>';
} elseif ($encode == 'javascript_charcode') {
$string = '<a href="mailto:' . $address . '" ' . $extra . '>' . $text . '</a>';
for($x = 0, $y = strlen($string); $x < $y; $x++) {
$ord[] = ord($string[$x]);
}
$_ret = "<script type=\"text/javascript\" language=\"javascript\">\n"
. "{document.write(String.fromCharCode("
. implode(',', $ord)
. "))"
. "}\n"
. "</script>\n";
return $_ret;
} elseif ($encode == 'hex') {
preg_match('!^(.*)(\?.*)$!', $address, $match);
if (!empty($match[2])) {
trigger_error("mailto: hex encoding does not work with extra attributes. Try javascript.",E_USER_WARNING);
return;
}
$address_encode = '';
for ($x = 0, $_length = strlen($address); $x < $_length; $x++) {
if (preg_match('!\w!u', $address[$x])) {
$address_encode .= '%' . bin2hex($address[$x]);
} else {
$address_encode .= $address[$x];
}
}
$text_encode = '';
for ($x = 0, $_length = strlen($text); $x < $_length; $x++) {
$text_encode .= '&#x' . bin2hex($text[$x]) . ';';
}
$mailto = "&#109;&#97;&#105;&#108;&#116;&#111;&#58;";
return '<a href="' . $mailto . $address_encode . '" ' . $extra . '>' . $text_encode . '</a>';
} else {
// no encoding
return '<a href="mailto:' . $address . '" ' . $extra . '>' . $text . '</a>';
}
}
?>

View File

@@ -0,0 +1,87 @@
<?php
/**
* Smarty plugin
*
* This plugin is only for Smarty2 BC
* @package Smarty
* @subpackage PluginsFunction
*/
/**
* Smarty {math} function plugin
*
* Type: function<br>
* Name: math<br>
* Purpose: handle math computations in template
*
* @link http://www.smarty.net/manual/en/language.function.math.php {math}
* (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
* @param array $params parameters
* @param Smarty_Internal_Template $template template object
* @return string|null
*/
function smarty_function_math($params, $template)
{
static $_allowed_funcs = array(
'int' => true, 'abs' => true, 'ceil' => true, 'cos' => true, 'exp' => true, 'floor' => true,
'log' => true, 'log10' => true, 'max' => true, 'min' => true, 'pi' => true, 'pow' => true,
'rand' => true, 'round' => true, 'sin' => true, 'sqrt' => true, 'srand' => true ,'tan' => true
);
// be sure equation parameter is present
if (empty($params['equation'])) {
trigger_error("math: missing equation parameter",E_USER_WARNING);
return;
}
$equation = $params['equation'];
// make sure parenthesis are balanced
if (substr_count($equation,"(") != substr_count($equation,")")) {
trigger_error("math: unbalanced parenthesis",E_USER_WARNING);
return;
}
// match all vars in equation, make sure all are passed
preg_match_all("!(?:0x[a-fA-F0-9]+)|([a-zA-Z][a-zA-Z0-9_]*)!",$equation, $match);
foreach($match[1] as $curr_var) {
if ($curr_var && !isset($params[$curr_var]) && !isset($_allowed_funcs[$curr_var])) {
trigger_error("math: function call $curr_var not allowed",E_USER_WARNING);
return;
}
}
foreach($params as $key => $val) {
if ($key != "equation" && $key != "format" && $key != "assign") {
// make sure value is not empty
if (strlen($val)==0) {
trigger_error("math: parameter $key is empty",E_USER_WARNING);
return;
}
if (!is_numeric($val)) {
trigger_error("math: parameter $key: is not numeric",E_USER_WARNING);
return;
}
$equation = preg_replace("/\b$key\b/", " \$params['$key'] ", $equation);
}
}
$smarty_math_result = null;
eval("\$smarty_math_result = ".$equation.";");
if (empty($params['format'])) {
if (empty($params['assign'])) {
return $smarty_math_result;
} else {
$template->assign($params['assign'],$smarty_math_result);
}
} else {
if (empty($params['assign'])){
printf($params['format'],$smarty_math_result);
} else {
$template->assign($params['assign'],sprintf($params['format'],$smarty_math_result));
}
}
}
?>

View File

@@ -0,0 +1,65 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsModifier
*/
/**
* Smarty capitalize modifier plugin
*
* Type: modifier<br>
* Name: capitalize<br>
* Purpose: capitalize words in the string
*
* {@internal {$string|capitalize:true:true} is the fastest option for MBString enabled systems }}
*
* @param string $string string to capitalize
* @param boolean $uc_digits also capitalize "x123" to "X123"
* @param boolean $lc_rest capitalize first letters, lowercase all following letters "aAa" to "Aaa"
* @return string capitalized string
* @author Monte Ohrt <monte at ohrt dot com>
* @author Rodney Rehm
*/
function smarty_modifier_capitalize($string, $uc_digits = false, $lc_rest = false)
{
if (SMARTY_MBSTRING /* ^phpunit */&&empty($_SERVER['SMARTY_PHPUNIT_DISABLE_MBSTRING'])/* phpunit$ */) {
if ($lc_rest) {
// uppercase (including hyphenated words)
$upper_string = mb_convert_case( $string, MB_CASE_TITLE, SMARTY_RESOURCE_CHAR_SET );
} else {
// uppercase word breaks
$upper_string = preg_replace("!(^|[^\p{L}'])([\p{Ll}])!ueS", "stripslashes('\\1').mb_convert_case(stripslashes('\\2'),MB_CASE_UPPER, SMARTY_RESOURCE_CHAR_SET)", $string);
}
// check uc_digits case
if (!$uc_digits) {
if (preg_match_all("!\b([\p{L}]*[\p{N}]+[\p{L}]*)\b!u", $string, $matches, PREG_OFFSET_CAPTURE)) {
foreach($matches[1] as $match) {
$upper_string = substr_replace($upper_string, mb_strtolower($match[0], SMARTY_RESOURCE_CHAR_SET), $match[1], strlen($match[0]));
}
}
}
$upper_string = preg_replace("!((^|\s)['\"])(\w)!ue", "stripslashes('\\1').mb_convert_case(stripslashes('\\3'),MB_CASE_UPPER, SMARTY_RESOURCE_CHAR_SET)", $upper_string);
return $upper_string;
}
// lowercase first
if ($lc_rest) {
$string = strtolower($string);
}
// uppercase (including hyphenated words)
$upper_string = preg_replace("!(^|[^\p{L}'])([\p{Ll}])!ueS", "stripslashes('\\1').ucfirst(stripslashes('\\2'))", $string);
// check uc_digits case
if (!$uc_digits) {
if (preg_match_all("!\b([\p{L}]*[\p{N}]+[\p{L}]*)\b!u", $string, $matches, PREG_OFFSET_CAPTURE)) {
foreach($matches[1] as $match) {
$upper_string = substr_replace($upper_string, strtolower($match[0]), $match[1], strlen($match[0]));
}
}
}
$upper_string = preg_replace("!((^|\s)['\"])(\w)!ue", "stripslashes('\\1').strtoupper(stripslashes('\\3'))", $upper_string);
return $upper_string;
}
?>

View File

@@ -0,0 +1,62 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsModifier
*/
/**
* Smarty date_format modifier plugin
*
* Type: modifier<br>
* Name: date_format<br>
* Purpose: format datestamps via strftime<br>
* Input:<br>
* - string: input date string
* - format: strftime format for output
* - default_date: default date if $string is empty
*
* @link http://www.smarty.net/manual/en/language.modifier.date.format.php date_format (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
* @param string $string input date string
* @param string $format strftime format for output
* @param string $default_date default date if $string is empty
* @param string $formatter either 'strftime' or 'auto'
* @return string |void
* @uses smarty_make_timestamp()
*/
function smarty_modifier_date_format($string, $format = SMARTY_RESOURCE_DATE_FORMAT, $default_date = '',$formatter='auto')
{
/**
* Include the {@link shared.make_timestamp.php} plugin
*/
require_once(SMARTY_PLUGINS_DIR . 'shared.make_timestamp.php');
if ($string != '') {
$timestamp = smarty_make_timestamp($string);
} elseif ($default_date != '') {
$timestamp = smarty_make_timestamp($default_date);
} else {
return;
}
if($formatter=='strftime'||($formatter=='auto'&&strpos($format,'%')!==false)) {
if (DS == '\\') {
$_win_from = array('%D', '%h', '%n', '%r', '%R', '%t', '%T');
$_win_to = array('%m/%d/%y', '%b', "\n", '%I:%M:%S %p', '%H:%M', "\t", '%H:%M:%S');
if (strpos($format, '%e') !== false) {
$_win_from[] = '%e';
$_win_to[] = sprintf('%\' 2d', date('j', $timestamp));
}
if (strpos($format, '%l') !== false) {
$_win_from[] = '%l';
$_win_to[] = sprintf('%\' 2d', date('h', $timestamp));
}
$format = str_replace($_win_from, $_win_to, $format);
}
return strftime($format, $timestamp);
} else {
return date($format, $timestamp);
}
}
?>

View File

@@ -0,0 +1,105 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage Debug
*/
/**
* Smarty debug_print_var modifier plugin
*
* Type: modifier<br>
* Name: debug_print_var<br>
* Purpose: formats variable contents for display in the console
*
* @author Monte Ohrt <monte at ohrt dot com>
* @param array|object $var variable to be formatted
* @param integer $depth maximum recursion depth if $var is an array
* @param integer $length maximum string length if $var is a string
* @return string
*/
function smarty_modifier_debug_print_var ($var, $depth = 0, $length = 40)
{
$_replace = array("\n" => '<i>\n</i>',
"\r" => '<i>\r</i>',
"\t" => '<i>\t</i>'
);
switch (gettype($var)) {
case 'array' :
$results = '<b>Array (' . count($var) . ')</b>';
foreach ($var as $curr_key => $curr_val) {
$results .= '<br>' . str_repeat('&nbsp;', $depth * 2)
. '<b>' . strtr($curr_key, $_replace) . '</b> =&gt; '
. smarty_modifier_debug_print_var($curr_val, ++$depth, $length);
$depth--;
}
break;
case 'object' :
$object_vars = get_object_vars($var);
$results = '<b>' . get_class($var) . ' Object (' . count($object_vars) . ')</b>';
foreach ($object_vars as $curr_key => $curr_val) {
$results .= '<br>' . str_repeat('&nbsp;', $depth * 2)
. '<b> -&gt;' . strtr($curr_key, $_replace) . '</b> = '
. smarty_modifier_debug_print_var($curr_val, ++$depth, $length);
$depth--;
}
break;
case 'boolean' :
case 'NULL' :
case 'resource' :
if (true === $var) {
$results = 'true';
} elseif (false === $var) {
$results = 'false';
} elseif (null === $var) {
$results = 'null';
} else {
$results = htmlspecialchars((string) $var);
}
$results = '<i>' . $results . '</i>';
break;
case 'integer' :
case 'float' :
$results = htmlspecialchars((string) $var);
break;
case 'string' :
$results = strtr($var, $_replace);
if (SMARTY_MBSTRING /* ^phpunit */&&empty($_SERVER['SMARTY_PHPUNIT_DISABLE_MBSTRING'])/* phpunit$ */) {
if (mb_strlen($var, SMARTY_RESOURCE_CHAR_SET) > $length) {
$results = mb_substr($var, 0, $length - 3, SMARTY_RESOURCE_CHAR_SET) . '...';
}
} else {
if (isset($var[$length])) {
$results = substr($var, 0, $length - 3) . '...';
}
}
$results = htmlspecialchars('"' . $results . '"');
break;
case 'unknown type' :
default :
$results = strtr((string) $var, $_replace);
if (SMARTY_MBSTRING /* ^phpunit */&&empty($_SERVER['SMARTY_PHPUNIT_DISABLE_MBSTRING'])/* phpunit$ */) {
if (mb_strlen($results, SMARTY_RESOURCE_CHAR_SET) > $length) {
$results = mb_substr($results, 0, $length - 3, SMARTY_RESOURCE_CHAR_SET) . '...';
}
} else {
if (strlen($results) > $length) {
$results = substr($results, 0, $length - 3) . '...';
}
}
$results = htmlspecialchars($results);
}
return $results;
}
?>

View File

@@ -0,0 +1,143 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsModifier
*/
/**
* Smarty escape modifier plugin
*
* Type: modifier<br>
* Name: escape<br>
* Purpose: escape string for output
*
* @link http://www.smarty.net/manual/en/language.modifier.count.characters.php count_characters (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
* @param string $string input string
* @param string $esc_type escape type
* @param string $char_set character set, used for htmlspecialchars() or htmlentities()
* @param boolean $double_encode encode already encoded entitites again, used for htmlspecialchars() or htmlentities()
* @return string escaped input string
*/
function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $double_encode = true)
{
if (!$char_set) {
$char_set = SMARTY_RESOURCE_CHAR_SET;
}
switch ($esc_type) {
case 'html':
return htmlspecialchars($string, ENT_QUOTES, $char_set, $double_encode);
case 'htmlall':
if (SMARTY_MBSTRING /* ^phpunit */ && empty($_SERVER['SMARTY_PHPUNIT_DISABLE_MBSTRING'])/* phpunit$ */) {
// mb_convert_encoding ignores htmlspecialchars()
$string = htmlspecialchars($string, ENT_QUOTES, $char_set, $double_encode);
// htmlentities() won't convert everything, so use mb_convert_encoding
return mb_convert_encoding($string, 'HTML-ENTITIES', $char_set);
}
// no MBString fallback
return htmlentities($string, ENT_QUOTES, $char_set, $double_encode);
case 'url':
return rawurlencode($string);
case 'urlpathinfo':
return str_replace('%2F', '/', rawurlencode($string));
case 'quotes':
// escape unescaped single quotes
return preg_replace("%(?<!\\\\)'%", "\\'", $string);
case 'hex':
// escape every byte into hex
// Note that the UTF-8 encoded character ä will be represented as %c3%a4
$return = '';
$_length = strlen($string);
for ($x = 0; $x < $_length; $x++) {
$return .= '%' . bin2hex($string[$x]);
}
return $return;
case 'hexentity':
$return = '';
if (SMARTY_MBSTRING /* ^phpunit */ && empty($_SERVER['SMARTY_PHPUNIT_DISABLE_MBSTRING'])/* phpunit$ */) {
require_once(SMARTY_PLUGINS_DIR . 'shared.mb_unicode.php');
$return = '';
foreach (smarty_mb_to_unicode($string, SMARTY_RESOURCE_CHAR_SET) as $unicode) {
$return .= '&#x' . strtoupper(dechex($unicode)) . ';';
}
return $return;
}
// no MBString fallback
$_length = strlen($string);
for ($x = 0; $x < $_length; $x++) {
$return .= '&#x' . bin2hex($string[$x]) . ';';
}
return $return;
case 'decentity':
$return = '';
if (SMARTY_MBSTRING /* ^phpunit */ && empty($_SERVER['SMARTY_PHPUNIT_DISABLE_MBSTRING'])/* phpunit$ */) {
require_once(SMARTY_PLUGINS_DIR . 'shared.mb_unicode.php');
$return = '';
foreach (smarty_mb_to_unicode($string, SMARTY_RESOURCE_CHAR_SET) as $unicode) {
$return .= '&#' . $unicode . ';';
}
return $return;
}
// no MBString fallback
$_length = strlen($string);
for ($x = 0; $x < $_length; $x++) {
$return .= '&#' . ord($string[$x]) . ';';
}
return $return;
case 'javascript':
// escape quotes and backslashes, newlines, etc.
return strtr($string, array('\\' => '\\\\', "'" => "\\'", '"' => '\\"', "\r" => '\\r', "\n" => '\\n', '</' => '<\/'));
case 'mail':
if (SMARTY_MBSTRING /* ^phpunit */ && empty($_SERVER['SMARTY_PHPUNIT_DISABLE_MBSTRING'])/* phpunit$ */) {
require_once(SMARTY_PLUGINS_DIR . 'shared.mb_str_replace.php');
return smarty_mb_str_replace(array('@', '.'), array(' [AT] ', ' [DOT] '), $string);
}
// no MBString fallback
return str_replace(array('@', '.'), array(' [AT] ', ' [DOT] '), $string);
case 'nonstd':
// escape non-standard chars, such as ms document quotes
$return = '';
if (SMARTY_MBSTRING /* ^phpunit */ && empty($_SERVER['SMARTY_PHPUNIT_DISABLE_MBSTRING'])/* phpunit$ */) {
require_once(SMARTY_PLUGINS_DIR . 'shared.mb_unicode.php');
foreach (smarty_mb_to_unicode($string, SMARTY_RESOURCE_CHAR_SET) as $unicode) {
if ($unicode >= 126) {
$return .= '&#' . $unicode . ';';
} else {
$return .= chr($unicode);
}
}
return $return;
}
$_length = strlen($string);
for ($_i = 0; $_i < $_length; $_i++) {
$_ord = ord(substr($string, $_i, 1));
// non-standard char, escape it
if ($_ord >= 126) {
$return .= '&#' . $_ord . ';';
} else {
$return .= substr($string, $_i, 1);
}
}
return $return;
default:
return $string;
}
}
?>

View File

@@ -0,0 +1,55 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsModifier
*/
/**
* Smarty regex_replace modifier plugin
*
* Type: modifier<br>
* Name: regex_replace<br>
* Purpose: regular expression search/replace
*
* @link http://smarty.php.net/manual/en/language.modifier.regex.replace.php
* regex_replace (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
* @param string $string input string
* @param string|array $search regular expression(s) to search for
* @param string|array $replace string(s) that should be replaced
* @return string
*/
function smarty_modifier_regex_replace($string, $search, $replace)
{
if(is_array($search)) {
foreach($search as $idx => $s) {
$search[$idx] = _smarty_regex_replace_check($s);
}
} else {
$search = _smarty_regex_replace_check($search);
}
return preg_replace($search, $replace, $string);
}
/**
* @param string $search string(s) that should be replaced
* @return string
* @ignore
*/
function _smarty_regex_replace_check($search)
{
// null-byte injection detection
// anything behind the first null-byte is ignored
if (($pos = strpos($search,"\0")) !== false) {
$search = substr($search,0,$pos);
}
// remove eval-modifier from $search
if (preg_match('!([a-zA-Z\s]+)$!s', $search, $match) && (strpos($match[1], 'e') !== false)) {
$search = substr($search, 0, -strlen($match[1])) . preg_replace('![e\s]+!', '', $match[1]);
}
return $search;
}
?>

View File

@@ -0,0 +1,33 @@
<?php
/**
* Smarty plugin
* @package Smarty
* @subpackage PluginsModifier
*/
/**
* Smarty replace modifier plugin
*
* Type: modifier<br>
* Name: replace<br>
* Purpose: simple search/replace
*
* @link http://smarty.php.net/manual/en/language.modifier.replace.php replace (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
* @author Uwe Tews
* @param string $string input string
* @param string $search text to search for
* @param string $replace replacement text
* @return string
*/
function smarty_modifier_replace($string, $search, $replace)
{
if (SMARTY_MBSTRING /* ^phpunit */&&empty($_SERVER['SMARTY_PHPUNIT_DISABLE_MBSTRING'])/* phpunit$ */) {
require_once(SMARTY_PLUGINS_DIR . 'shared.mb_str_replace.php');
return smarty_mb_str_replace($search, $replace, $string);
}
return str_replace($search, $replace, $string);
}
?>

View File

@@ -0,0 +1,27 @@
<?php
/**
* Smarty plugin
* @package Smarty
* @subpackage PluginsModifier
*/
/**
* Smarty spacify modifier plugin
*
* Type: modifier<br>
* Name: spacify<br>
* Purpose: add spaces between characters in a string
*
* @link http://smarty.php.net/manual/en/language.modifier.spacify.php spacify (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
* @param string $string input string
* @param string $spacify_char string to insert between characters.
* @return string
*/
function smarty_modifier_spacify($string, $spacify_char = ' ')
{
// well… what about charsets besides latin and UTF-8?
return implode($spacify_char, preg_split('//u', $string, -1, PREG_SPLIT_NO_EMPTY));
}
?>

View File

@@ -0,0 +1,59 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsModifier
*/
/**
* Smarty truncate modifier plugin
*
* Type: modifier<br>
* Name: truncate<br>
* Purpose: Truncate a string to a certain length if necessary,
* optionally splitting in the middle of a word, and
* appending the $etc string or inserting $etc into the middle.
*
* @link http://smarty.php.net/manual/en/language.modifier.truncate.php truncate (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
* @param string $string input string
* @param integer $length length of truncated text
* @param string $etc end string
* @param boolean $break_words truncate at word boundary
* @param boolean $middle truncate in the middle of text
* @return string truncated string
*/
function smarty_modifier_truncate($string, $length = 80, $etc = '...', $break_words = false, $middle = false) {
if ($length == 0)
return '';
if (SMARTY_MBSTRING /* ^phpunit */&&empty($_SERVER['SMARTY_PHPUNIT_DISABLE_MBSTRING'])/* phpunit$ */) {
if (mb_strlen($string, SMARTY_RESOURCE_CHAR_SET) > $length) {
$length -= min($length, mb_strlen($etc, SMARTY_RESOURCE_CHAR_SET));
if (!$break_words && !$middle) {
$string = preg_replace('/\s+?(\S+)?$/u', '', mb_substr($string, 0, $length + 1, SMARTY_RESOURCE_CHAR_SET));
}
if (!$middle) {
return mb_substr($string, 0, $length, SMARTY_RESOURCE_CHAR_SET) . $etc;
}
return mb_substr($string, 0, $length / 2, SMARTY_RESOURCE_CHAR_SET) . $etc . mb_substr($string, - $length / 2, $length, SMARTY_RESOURCE_CHAR_SET);
}
return $string;
}
// no MBString fallback
if (isset($string[$length])) {
$length -= min($length, strlen($etc));
if (!$break_words && !$middle) {
$string = preg_replace('/\s+?(\S+)?$/', '', substr($string, 0, $length + 1));
}
if (!$middle) {
return substr($string, 0, $length) . $etc;
}
return substr($string, 0, $length / 2) . $etc . substr($string, - $length / 2);
}
return $string;
}
?>

View File

@@ -0,0 +1,30 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsModifierCompiler
*/
/**
* Smarty cat modifier plugin
*
* Type: modifier<br>
* Name: cat<br>
* Date: Feb 24, 2003<br>
* Purpose: catenate a value to a variable<br>
* Input: string to catenate<br>
* Example: {$var|cat:"foo"}
*
* @link http://smarty.php.net/manual/en/language.modifier.cat.php cat
* (Smarty online manual)
* @author Uwe Tews
* @param array $params parameters
* @return string with compiled code
*/
function smarty_modifiercompiler_cat($params, $compiler)
{
return '('.implode(').(', $params).')';
}
?>

View File

@@ -0,0 +1,33 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsModifierCompiler
*/
/**
* Smarty count_characters modifier plugin
*
* Type: modifier<br>
* Name: count_characteres<br>
* Purpose: count the number of characters in a text
*
* @link http://www.smarty.net/manual/en/language.modifier.count.characters.php count_characters (Smarty online manual)
* @author Uwe Tews
* @param array $params parameters
* @return string with compiled code
*/
function smarty_modifiercompiler_count_characters($params, $compiler)
{
if (!isset($params[1]) || $params[1] != 'true') {
return 'preg_match_all(\'/[^\s]/u\',' . $params[0] . ', $tmp)';
}
if (SMARTY_MBSTRING /* ^phpunit */&&empty($_SERVER['SMARTY_PHPUNIT_DISABLE_MBSTRING'])/* phpunit$ */) {
return 'mb_strlen(' . $params[0] . ', SMARTY_RESOURCE_CHAR_SET)';
}
// no MBString fallback
return 'strlen(' . $params[0] . ')';
}
?>

View File

@@ -0,0 +1,28 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsModifierCompiler
*/
/**
* Smarty count_paragraphs modifier plugin
*
* Type: modifier<br>
* Name: count_paragraphs<br>
* Purpose: count the number of paragraphs in a text
*
* @link http://www.smarty.net/manual/en/language.modifier.count.paragraphs.php
* count_paragraphs (Smarty online manual)
* @author Uwe Tews
* @param array $params parameters
* @return string with compiled code
*/
function smarty_modifiercompiler_count_paragraphs($params, $compiler)
{
// count \r or \n characters
return '(preg_match_all(\'#[\r\n]+#\', ' . $params[0] . ', $tmp)+1)';
}
?>

View File

@@ -0,0 +1,28 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsModifierCompiler
*/
/**
* Smarty count_sentences modifier plugin
*
* Type: modifier<br>
* Name: count_sentences
* Purpose: count the number of sentences in a text
*
* @link http://www.smarty.net/manual/en/language.modifier.count.paragraphs.php
* count_sentences (Smarty online manual)
* @author Uwe Tews
* @param array $params parameters
* @return string with compiled code
*/
function smarty_modifiercompiler_count_sentences($params, $compiler)
{
// find periods, question marks, exclamation marks with a word before but not after.
return 'preg_match_all("#\w[\.\?\!](\W|$)#uS", ' . $params[0] . ', $tmp)';
}
?>

View File

@@ -0,0 +1,32 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsModifierCompiler
*/
/**
* Smarty count_words modifier plugin
*
* Type: modifier<br>
* Name: count_words<br>
* Purpose: count the number of words in a text
*
* @link http://www.smarty.net/manual/en/language.modifier.count.words.php count_words (Smarty online manual)
* @author Uwe Tews
* @param array $params parameters
* @return string with compiled code
*/
function smarty_modifiercompiler_count_words($params, $compiler)
{
if (SMARTY_MBSTRING /* ^phpunit */&&empty($_SERVER['SMARTY_PHPUNIT_DISABLE_MBSTRING'])/* phpunit$ */) {
// return 'preg_match_all(\'#[\w\pL]+#u\', ' . $params[0] . ', $tmp)';
// expression taken from http://de.php.net/manual/en/function.str-word-count.php#85592
return 'preg_match_all(\'/\p{L}[\p{L}\p{Mn}\p{Pd}\\\'\x{2019}]*/u\', ' . $params[0] . ', $tmp)';
}
// no MBString fallback
return 'str_word_count(' . $params[0] . ')';
}
?>

View File

@@ -0,0 +1,35 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsModifierCompiler
*/
/**
* Smarty default modifier plugin
*
* Type: modifier<br>
* Name: default<br>
* Purpose: designate default value for empty variables
*
* @link http://www.smarty.net/manual/en/language.modifier.default.php default (Smarty online manual)
* @author Uwe Tews
* @param array $params parameters
* @return string with compiled code
*/
function smarty_modifiercompiler_default ($params, $compiler)
{
$output = $params[0];
if (!isset($params[1])) {
$params[1] = "''";
}
array_shift($params);
foreach ($params as $param) {
$output = '(($tmp = @' . $output . ')===null||$tmp===\'\' ? ' . $param . ' : $tmp)';
}
return $output;
}
?>

View File

@@ -0,0 +1,90 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsModifierCompiler
*/
/**
* @ignore
*/
require_once( SMARTY_PLUGINS_DIR .'shared.literal_compiler_param.php' );
/**
* Smarty escape modifier plugin
*
* Type: modifier<br>
* Name: escape<br>
* Purpose: escape string for output
*
* @link http://www.smarty.net/docsv2/en/language.modifier.escape count_characters (Smarty online manual)
* @author Rodney Rehm
* @param array $params parameters
* @return string with compiled code
*/
function smarty_modifiercompiler_escape($params, $compiler)
{
try {
$esc_type = smarty_literal_compiler_param($params, 1, 'html');
$char_set = smarty_literal_compiler_param($params, 2, SMARTY_RESOURCE_CHAR_SET);
$double_encode = smarty_literal_compiler_param($params, 3, true);
if (!$char_set) {
$char_set = SMARTY_RESOURCE_CHAR_SET;
}
switch ($esc_type) {
case 'html':
return 'htmlspecialchars('
. $params[0] .', ENT_QUOTES, '
. var_export($char_set, true) . ', '
. var_export($double_encode, true) . ')';
case 'htmlall':
if (SMARTY_MBSTRING /* ^phpunit */&&empty($_SERVER['SMARTY_PHPUNIT_DISABLE_MBSTRING'])/* phpunit$ */) {
return 'mb_convert_encoding(htmlspecialchars('
. $params[0] .', ENT_QUOTES, '
. var_export($char_set, true) . ', '
. var_export($double_encode, true)
. '), "HTML-ENTITIES", '
. var_export($char_set, true) . ')';
}
// no MBString fallback
return 'htmlentities('
. $params[0] .', ENT_QUOTES, '
. var_export($char_set, true) . ', '
. var_export($double_encode, true) . ')';
case 'url':
return 'rawurlencode(' . $params[0] . ')';
case 'urlpathinfo':
return 'str_replace("%2F", "/", rawurlencode(' . $params[0] . '))';
case 'quotes':
// escape unescaped single quotes
return 'preg_replace("%(?<!\\\\\\\\)\'%", "\\\'",' . $params[0] . ')';
case 'javascript':
// escape quotes and backslashes, newlines, etc.
return 'strtr(' . $params[0] . ', array("\\\\" => "\\\\\\\\", "\'" => "\\\\\'", "\"" => "\\\\\"", "\\r" => "\\\\r", "\\n" => "\\\n", "</" => "<\/" ))';
}
} catch(SmartyException $e) {
// pass through to regular plugin fallback
}
// could not optimize |escape call, so fallback to regular plugin
if ($compiler->tag_nocache | $compiler->nocache) {
$compiler->template->required_plugins['nocache']['escape']['modifier']['file'] = SMARTY_PLUGINS_DIR .'modifier.escape.php';
$compiler->template->required_plugins['nocache']['escape']['modifier']['function'] = 'smarty_modifier_escape';
} else {
$compiler->template->required_plugins['compiled']['escape']['modifier']['file'] = SMARTY_PLUGINS_DIR .'modifier.escape.php';
$compiler->template->required_plugins['compiled']['escape']['modifier']['function'] = 'smarty_modifier_escape';
}
return 'smarty_modifier_escape(' . join( ', ', $params ) . ')';
}
?>

View File

@@ -0,0 +1,34 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsModifierCompiler
*/
/**
* Smarty from_charset modifier plugin
*
* Type: modifier<br>
* Name: from_charset<br>
* Purpose: convert character encoding from $charset to internal encoding
*
* @author Rodney Rehm
* @param array $params parameters
* @return string with compiled code
*/
function smarty_modifiercompiler_from_charset($params, $compiler)
{
if (!SMARTY_MBSTRING /* ^phpunit */&&empty($_SERVER['SMARTY_PHPUNIT_DISABLE_MBSTRING'])/* phpunit$ */) {
// FIXME: (rodneyrehm) shouldn't this throw an error?
return $params[0];
}
if (!isset($params[1])) {
$params[1] = '"ISO-8859-1"';
}
return 'mb_convert_encoding(' . $params[0] . ', SMARTY_RESOURCE_CHAR_SET, ' . $params[1] . ')';
}
?>

View File

@@ -0,0 +1,32 @@
<?php
/**
* Smarty plugin
* @package Smarty
* @subpackage PluginsModifierCompiler
*/
/**
* Smarty indent modifier plugin
*
* Type: modifier<br>
* Name: indent<br>
* Purpose: indent lines of text
*
* @link http://www.smarty.net/manual/en/language.modifier.indent.php indent (Smarty online manual)
* @author Uwe Tews
* @param array $params parameters
* @return string with compiled code
*/
function smarty_modifiercompiler_indent($params, $compiler)
{
if (!isset($params[1])) {
$params[1] = 4;
}
if (!isset($params[2])) {
$params[2] = "' '";
}
return 'preg_replace(\'!^!m\',str_repeat(' . $params[2] . ',' . $params[1] . '),' . $params[0] . ')';
}
?>

View File

@@ -0,0 +1,31 @@
<?php
/**
* Smarty plugin
* @package Smarty
* @subpackage PluginsModifierCompiler
*/
/**
* Smarty lower modifier plugin
*
* Type: modifier<br>
* Name: lower<br>
* Purpose: convert string to lowercase
*
* @link http://www.smarty.net/manual/en/language.modifier.lower.php lower (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
* @author Uwe Tews
* @param array $params parameters
* @return string with compiled code
*/
function smarty_modifiercompiler_lower($params, $compiler)
{
if (SMARTY_MBSTRING /* ^phpunit */&&empty($_SERVER['SMARTY_PHPUNIT_DISABLE_MBSTRING'])/* phpunit$ */) {
return 'mb_strtolower(' . $params[0] . ',SMARTY_RESOURCE_CHAR_SET)' ;
}
// no MBString fallback
return 'strtolower(' . $params[0] . ')';
}
?>

View File

@@ -0,0 +1,25 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsModifierCompiler
*/
/**
* Smarty noprint modifier plugin
*
* Type: modifier<br>
* Name: noprint<br>
* Purpose: return an empty string
*
* @author Uwe Tews
* @param array $params parameters
* @return string with compiled code
*/
function smarty_modifiercompiler_noprint($params, $compiler)
{
return "''";
}
?>

View File

@@ -0,0 +1,26 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsModifierCompiler
*/
/**
* Smarty string_format modifier plugin
*
* Type: modifier<br>
* Name: string_format<br>
* Purpose: format strings via sprintf
*
* @link http://www.smarty.net/manual/en/language.modifier.string.format.php string_format (Smarty online manual)
* @author Uwe Tews
* @param array $params parameters
* @return string with compiled code
*/
function smarty_modifiercompiler_string_format($params, $compiler)
{
return 'sprintf(' . $params[1] . ',' . $params[0] . ')';
}
?>

View File

@@ -0,0 +1,33 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsModifierCompiler
*/
/**
* Smarty strip modifier plugin
*
* Type: modifier<br>
* Name: strip<br>
* Purpose: Replace all repeated spaces, newlines, tabs
* with a single space or supplied replacement string.<br>
* Example: {$var|strip} {$var|strip:"&nbsp;"}<br>
* Date: September 25th, 2002
*
* @link http://www.smarty.net/manual/en/language.modifier.strip.php strip (Smarty online manual)
* @author Uwe Tews
* @param array $params parameters
* @return string with compiled code
*/
function smarty_modifiercompiler_strip($params, $compiler)
{
if (!isset($params[1])) {
$params[1] = "' '";
}
return "preg_replace('!\s+!u', {$params[1]},{$params[0]})";
}
?>

View File

@@ -0,0 +1,33 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsModifierCompiler
*/
/**
* Smarty strip_tags modifier plugin
*
* Type: modifier<br>
* Name: strip_tags<br>
* Purpose: strip html tags from text
*
* @link http://www.smarty.net/manual/en/language.modifier.strip.tags.php strip_tags (Smarty online manual)
* @author Uwe Tews
* @param array $params parameters
* @return string with compiled code
*/
function smarty_modifiercompiler_strip_tags($params, $compiler)
{
if (!isset($params[1])) {
$params[1] = true;
}
if ($params[1] === true) {
return "preg_replace('!<[^>]*?>!', ' ', {$params[0]})";
} else {
return 'strip_tags(' . $params[0] . ')';
}
}
?>

View File

@@ -0,0 +1,34 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsModifierCompiler
*/
/**
* Smarty to_charset modifier plugin
*
* Type: modifier<br>
* Name: to_charset<br>
* Purpose: convert character encoding from internal encoding to $charset
*
* @author Rodney Rehm
* @param array $params parameters
* @return string with compiled code
*/
function smarty_modifiercompiler_to_charset($params, $compiler)
{
if (!SMARTY_MBSTRING /* ^phpunit */&&empty($_SERVER['SMARTY_PHPUNIT_DISABLE_MBSTRING'])/* phpunit$ */) {
// FIXME: (rodneyrehm) shouldn't this throw an error?
return $params[0];
}
if (!isset($params[1])) {
$params[1] = '"ISO-8859-1"';
}
return 'mb_convert_encoding(' . $params[0] . ', ' . $params[1] . ', SMARTY_RESOURCE_CHAR_SET)';
}
?>

View File

@@ -0,0 +1,48 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsModifierCompiler
*/
/**
* Smarty unescape modifier plugin
*
* Type: modifier<br>
* Name: unescape<br>
* Purpose: unescape html entities
*
* @author Rodney Rehm
* @param array $params parameters
* @return string with compiled code
*/
function smarty_modifiercompiler_unescape($params, $compiler)
{
if (!isset($params[1])) {
$params[1] = 'html';
}
if (!isset($params[2])) {
$params[2] = "SMARTY_RESOURCE_CHAR_SET";
} else {
$params[2] = "'" . $params[2] . "'";
}
switch (trim($params[1], '"\'')) {
case 'entity':
return 'mb_convert_encoding(' . $params[0] . ', ' . $params[2] . ', \'HTML-ENTITIES\')';
case 'htmlall':
if (SMARTY_MBSTRING /* ^phpunit */&&empty($_SERVER['SMARTY_PHPUNIT_DISABLE_MBSTRING'])/* phpunit$ */) {
return 'mb_convert_encoding(' . $params[0] . ', ' . $params[2] . ', \'HTML-ENTITIES\')';
}
return 'html_entity_decode(' . $params[0] . ', ENT_QUOTES, ' . $params[2] . ')';
case 'html':
return 'htmlspecialchars_decode(' . $params[0] . ', ENT_QUOTES)';
default:
return $params[0];
}
}
?>

View File

@@ -0,0 +1,30 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsModifierCompiler
*/
/**
* Smarty upper modifier plugin
*
* Type: modifier<br>
* Name: lower<br>
* Purpose: convert string to uppercase
*
* @link http://smarty.php.net/manual/en/language.modifier.upper.php lower (Smarty online manual)
* @author Uwe Tews
* @param array $params parameters
* @return string with compiled code
*/
function smarty_modifiercompiler_upper($params, $compiler)
{
if (SMARTY_MBSTRING /* ^phpunit */&&empty($_SERVER['SMARTY_PHPUNIT_DISABLE_MBSTRING'])/* phpunit$ */) {
return 'mb_strtoupper(' . $params[0] . ',SMARTY_RESOURCE_CHAR_SET)' ;
}
// no MBString fallback
return 'strtoupper(' . $params[0] . ')';
}
?>

View File

@@ -0,0 +1,46 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsModifierCompiler
*/
/**
* Smarty wordwrap modifier plugin
*
* Type: modifier<br>
* Name: wordwrap<br>
* Purpose: wrap a string of text at a given length
*
* @link http://smarty.php.net/manual/en/language.modifier.wordwrap.php wordwrap (Smarty online manual)
* @author Uwe Tews
* @param array $params parameters
* @return string with compiled code
*/
function smarty_modifiercompiler_wordwrap($params, $compiler)
{
if (!isset($params[1])) {
$params[1] = 80;
}
if (!isset($params[2])) {
$params[2] = '"\n"';
}
if (!isset($params[3])) {
$params[3] = 'false';
}
$function = 'wordwrap';
if (SMARTY_MBSTRING /* ^phpunit */&&empty($_SERVER['SMARTY_PHPUNIT_DISABLE_MBSTRING'])/* phpunit$ */) {
if ($compiler->tag_nocache | $compiler->nocache) {
$compiler->template->required_plugins['nocache']['wordwrap']['modifier']['file'] = SMARTY_PLUGINS_DIR .'shared.mb_wordwrap.php';
$compiler->template->required_plugins['nocache']['wordwrap']['modifier']['function'] = 'smarty_mb_wordwrap';
} else {
$compiler->template->required_plugins['compiled']['wordwrap']['modifier']['file'] = SMARTY_PLUGINS_DIR .'shared.mb_wordwrap.php';
$compiler->template->required_plugins['compiled']['wordwrap']['modifier']['function'] = 'smarty_mb_wordwrap';
}
$function = 'smarty_mb_wordwrap';
}
return $function . '(' . $params[0] . ',' . $params[1] . ',' . $params[2] . ',' . $params[3] . ')';
}
?>

View File

@@ -0,0 +1,92 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsFilter
*/
/**
* Smarty trimwhitespace outputfilter plugin
*
* Trim unnecessary whitespace from HTML markup.
*
* @author Rodney Rehm
* @param string $source input string
* @param Smarty_Internal_Template $smarty Smarty object
* @return string filtered output
*/
function smarty_outputfilter_trimwhitespace($source, Smarty_Internal_Template $smarty)
{
$store = array();
$_store = 0;
$_offset = 0;
// Unify Line-Breaks to \n
$source = preg_replace("/\015\012|\015|\012/", "\n", $source);
// capture Internet Explorer Conditional Comments
if (preg_match_all('#<!--\[[^\]]+\]>.*?<!\[[^\]]+\]-->#is', $source, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER)) {
foreach ($matches as $match) {
$store[] = $match[0][0];
$_length = strlen($match[0][0]);
$replace = '@!@SMARTY:' . $_store . ':SMARTY@!@';
$source = substr_replace($source, $replace, $match[0][1] - $_offset, $_length);
$_offset += $_length - strlen($replace);
$_store++;
}
}
// Strip all HTML-Comments
$source = preg_replace( '#<!--.*?-->#ms', '', $source );
// capture html elements not to be messed with
$_offset = 0;
if (preg_match_all('#<(script|pre|textarea)[^>]*>.*?</\\1>#is', $source, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER)) {
foreach ($matches as $match) {
$store[] = $match[0][0];
$_length = strlen($match[0][0]);
$replace = '@!@SMARTY:' . $_store . ':SMARTY@!@';
$source = substr_replace($source, $replace, $match[0][1] - $_offset, $_length);
$_offset += $_length - strlen($replace);
$_store++;
}
}
$expressions = array(
// replace multiple spaces between tags by a single space
// can't remove them entirely, becaue that might break poorly implemented CSS display:inline-block elements
'#(:SMARTY@!@|>)\s+(?=@!@SMARTY:|<)#s' => '\1 \2',
// remove spaces between attributes (but not in attribute values!)
'#(([a-z0-9]\s*=\s*(["\'])[^\3]*?\3)|<[a-z0-9_]+)\s+([a-z/>])#is' => '\1 \4',
// note: for some very weird reason trim() seems to remove spaces inside attributes.
// maybe a \0 byte or something is interfering?
'#^\s+<#Ss' => '<',
'#>\s+$#Ss' => '>',
);
$source = preg_replace( array_keys($expressions), array_values($expressions), $source );
// note: for some very weird reason trim() seems to remove spaces inside attributes.
// maybe a \0 byte or something is interfering?
// $source = trim( $source );
// capture html elements not to be messed with
$_offset = 0;
if (preg_match_all('#@!@SMARTY:([0-9]+):SMARTY@!@#is', $source, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER)) {
foreach ($matches as $match) {
$store[] = $match[0][0];
$_length = strlen($match[0][0]);
$replace = array_shift($store);
$source = substr_replace($source, $replace, $match[0][1] + $_offset, $_length);
$_offset += strlen($replace) - $_length;
$_store++;
}
}
return $source;
}
?>

View File

@@ -0,0 +1,51 @@
<?php
/**
* Smarty shared plugin
*
* @package Smarty
* @subpackage PluginsShared
*/
if (version_compare(PHP_VERSION, '5.2.3', '>=')) {
/**
* escape_special_chars common function
*
* Function: smarty_function_escape_special_chars<br>
* Purpose: used by other smarty functions to escape
* special chars except for already escaped ones
*
* @author Monte Ohrt <monte at ohrt dot com>
* @param string $string text that should by escaped
* @return string
*/
function smarty_function_escape_special_chars($string)
{
if (!is_array($string)) {
$string = htmlspecialchars($string, ENT_COMPAT, SMARTY_RESOURCE_CHAR_SET, false);
}
return $string;
}
} else {
/**
* escape_special_chars common function
*
* Function: smarty_function_escape_special_chars<br>
* Purpose: used by other smarty functions to escape
* special chars except for already escaped ones
*
* @author Monte Ohrt <monte at ohrt dot com>
* @param string $string text that should by escaped
* @return string
*/
function smarty_function_escape_special_chars($string)
{
if (!is_array($string)) {
$string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string);
$string = htmlspecialchars($string);
$string = str_replace(array('%%%SMARTY_START%%%', '%%%SMARTY_END%%%'), array('&', ';'), $string);
}
return $string;
}
}
?>

View File

@@ -0,0 +1,33 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsShared
*/
/**
* evaluate compiler parameter
*
* @param array $params parameter array as given to the compiler function
* @param integer $index array index of the parameter to convert
* @param mixed $default value to be returned if the parameter is not present
* @return mixed evaluated value of parameter or $default
* @throws SmartyException if parameter is not a literal (but an expression, variable, …)
* @author Rodney Rehm
*/
function smarty_literal_compiler_param($params, $index, $default=null)
{
// not set, go default
if (!isset($params[$index])) {
return $default;
}
// test if param is a literal
if (!preg_match('/^([\'"]?)[a-zA-Z0-9]+(\\1)$/', $params[$index])) {
throw new SmartyException('$param[' . $index . '] is not a literal and is thus not evaluatable at compile time');
}
$t = null;
eval("\$t = " . $params[$index] . ";");
return $t;
}

View File

@@ -0,0 +1,42 @@
<?php
/**
* Smarty shared plugin
*
* @package Smarty
* @subpackage PluginsShared
*/
/**
* Function: smarty_make_timestamp<br>
* Purpose: used by other smarty functions to make a timestamp from a string.
*
* @author Monte Ohrt <monte at ohrt dot com>
* @param DateTime|int|string $string date object, timestamp or string that can be converted using strtotime()
* @return int
*/
function smarty_make_timestamp($string)
{
if (empty($string)) {
// use "now":
return time();
} elseif ($string instanceof DateTime) {
return $string->getTimestamp();
} elseif (strlen($string) == 14 && ctype_digit($string)) {
// it is mysql timestamp format of YYYYMMDDHHMMSS?
return mktime(substr($string, 8, 2),substr($string, 10, 2),substr($string, 12, 2),
substr($string, 4, 2),substr($string, 6, 2),substr($string, 0, 4));
} elseif (is_numeric($string)) {
// it is a numeric string, we handle it as timestamp
return (int) $string;
} else {
// strtotime should handle it
$time = strtotime($string);
if ($time == -1 || $time === false) {
// strtotime() was not able to parse $string, use "now":
return time();
}
return $time;
}
}
?>

View File

@@ -0,0 +1,55 @@
<?php
/**
* Smarty shared plugin
*
* @package Smarty
* @subpackage PluginsShared
*/
if (!function_exists('smarty_mb_str_replace')) {
/**
* Multibyte string replace
*
* @param string $search the string to be searched
* @param string $replace the replacement string
* @param string $subject the source string
* @param int &$count number of matches found
* @return string replaced string
* @author Rodney Rehm
*/
function smarty_mb_str_replace($search, $replace, $subject, &$count=0)
{
if (!is_array($search) && is_array($replace)) {
return false;
}
if (is_array($subject)) {
// call mb_replace for each single string in $subject
foreach ($subject as &$string) {
$string = &smarty_mb_str_replace($search, $replace, $string, $c);
$count += $c;
}
} elseif (is_array($search)) {
if (!is_array($replace)) {
foreach ($search as &$string) {
$subject = smarty_mb_str_replace($string, $replace, $subject, $c);
$count += $c;
}
} else {
$n = max(count($search), count($replace));
while ($n--) {
$subject = smarty_mb_str_replace(current($search), current($replace), $subject, $c);
$count += $c;
next($search);
next($replace);
}
}
} else {
$parts = mb_split(preg_quote($search), $subject);
$count = count($parts) - 1;
$subject = implode($replace, $parts);
}
return $subject;
}
}
?>

View File

@@ -0,0 +1,48 @@
<?php
/**
* Smarty shared plugin
*
* @package Smarty
* @subpackage PluginsShared
*/
/**
* convert characters to their decimal unicode equivalents
*
* @link http://www.ibm.com/developerworks/library/os-php-unicode/index.html#listing3 for inspiration
* @param string $string characters to calculate unicode of
* @param string $encoding encoding of $string, if null mb_internal_encoding() is used
* @return array sequence of unicodes
* @author Rodney Rehm
*/
function smarty_mb_to_unicode($string, $encoding=null) {
if ($encoding) {
$expanded = mb_convert_encoding($string, "UTF-32BE", $encoding);
} else {
$expanded = mb_convert_encoding($string, "UTF-32BE");
}
return unpack("N*", $expanded);
}
/**
* convert unicodes to the character of given encoding
*
* @link http://www.ibm.com/developerworks/library/os-php-unicode/index.html#listing3 for inspiration
* @param integer|array $unicode single unicode or list of unicodes to convert
* @param string $encoding encoding of returned string, if null mb_internal_encoding() is used
* @return string unicode as character sequence in given $encoding
* @author Rodney Rehm
*/
function smarty_mb_from_unicode($unicode, $encoding=null) {
$t = '';
if (!$encoding) {
$encoding = mb_internal_encoding();
}
foreach((array) $unicode as $utf32be) {
$character = pack("N*", $utf32be);
$t .= mb_convert_encoding($character, $encoding, "UTF-32BE");
}
return $t;
}
?>

View File

@@ -0,0 +1,83 @@
<?php
/**
* Smarty shared plugin
*
* @package Smarty
* @subpackage PluginsShared
*/
if(!function_exists('smarty_mb_wordwrap')) {
/**
* Wrap a string to a given number of characters
*
* @link http://php.net/manual/en/function.wordwrap.php for similarity
* @param string $str the string to wrap
* @param int $width the width of the output
* @param string $break the character used to break the line
* @param boolean $cut ignored parameter, just for the sake of
* @return string wrapped string
* @author Rodney Rehm
*/
function smarty_mb_wordwrap($str, $width=75, $break="\n", $cut=false)
{
// break words into tokens using white space as a delimiter
$tokens = preg_split('!(\s)!uS', $str, -1, PREG_SPLIT_NO_EMPTY + PREG_SPLIT_DELIM_CAPTURE);
$length = 0;
$t = '';
$_previous = false;
foreach ($tokens as $_token) {
$token_length = mb_strlen($_token, SMARTY_RESOURCE_CHAR_SET);
$_tokens = array($_token);
if ($token_length > $width) {
// remove last space
$t = mb_substr($t, 0, -1, SMARTY_RESOURCE_CHAR_SET);
$_previous = false;
$length = 0;
if ($cut) {
$_tokens = preg_split('!(.{' . $width . '})!uS', $_token, -1, PREG_SPLIT_NO_EMPTY + PREG_SPLIT_DELIM_CAPTURE);
// broken words go on a new line
$t .= $break;
}
}
foreach ($_tokens as $token) {
$_space = !!preg_match('!^\s$!uS', $token);
$token_length = mb_strlen($token, SMARTY_RESOURCE_CHAR_SET);
$length += $token_length;
if ($length > $width) {
// remove space before inserted break
if ($_previous && $token_length < $width) {
$t = mb_substr($t, 0, -1, SMARTY_RESOURCE_CHAR_SET);
}
// add the break before the token
$t .= $break;
$length = $token_length;
// skip space after inserting a break
if ($_space) {
$length = 0;
continue;
}
} else if ($token == "\n") {
// hard break must reset counters
$_previous = 0;
$length = 0;
} else {
// remember if we had a space or not
$_previous = $_space;
}
// add the token
$t .= $token;
}
}
return $t;
}
}
?>

View File

@@ -0,0 +1,21 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsFilter
*/
/**
* Smarty htmlspecialchars variablefilter plugin
*
* @param string $source input string
* @param Smarty_Internal_Template $smarty Smarty object
* @return string filtered output
*/
function smarty_variablefilter_htmlspecialchars($source, $smarty)
{
return htmlspecialchars($source, ENT_QUOTES, SMARTY_RESOURCE_CHAR_SET);
}
?>

View File

@@ -0,0 +1,381 @@
<?php
/**
* Smarty Internal Plugin
*
* @package Smarty
* @subpackage Cacher
*/
/**
* Cache Handler API
*
* @package Smarty
* @subpackage Cacher
* @author Rodney Rehm
*/
abstract class Smarty_CacheResource {
/**
* cache for Smarty_CacheResource instances
* @var array
*/
public static $resources = array();
/**
* resource types provided by the core
* @var array
*/
protected static $sysplugins = array(
'file' => true,
);
/**
* populate Cached Object with meta data from Resource
*
* @param Smarty_Template_Cached $cached cached object
* @param Smarty_Internal_Template $_template template object
* @return void
*/
public abstract function populate(Smarty_Template_Cached $cached, Smarty_Internal_Template $_template);
/**
* populate Cached Object with timestamp and exists from Resource
*
* @param Smarty_Template_Cached $source cached object
* @return void
*/
public abstract function populateTimestamp(Smarty_Template_Cached $cached);
/**
* Read the cached template and process header
*
* @param Smarty_Internal_Template $_template template object
* @param Smarty_Template_Cached $cached cached object
* @return booelan true or false if the cached content does not exist
*/
public abstract function process(Smarty_Internal_Template $_template, Smarty_Template_Cached $cached=null);
/**
* Write the rendered template output to cache
*
* @param Smarty_Internal_Template $_template template object
* @param string $content content to cache
* @return boolean success
*/
public abstract function writeCachedContent(Smarty_Internal_Template $_template, $content);
/**
* Return cached content
*
* @param Smarty_Internal_Template $_template template object
* @param string $content content of cache
*/
public function getCachedContent(Smarty_Internal_Template $_template)
{
if ($_template->cached->handler->process($_template)) {
ob_start();
$_template->properties['unifunc']($_template);
return ob_get_clean();
}
return null;
}
/**
* Empty cache
*
* @param Smarty $smarty Smarty object
* @param integer $exp_time expiration time (number of seconds, not timestamp)
* @return integer number of cache files deleted
*/
public abstract function clearAll(Smarty $smarty, $exp_time=null);
/**
* Empty cache for a specific template
*
* @param Smarty $smarty Smarty object
* @param string $resource_name template name
* @param string $cache_id cache id
* @param string $compile_id compile id
* @param integer $exp_time expiration time (number of seconds, not timestamp)
* @return integer number of cache files deleted
*/
public abstract function clear(Smarty $smarty, $resource_name, $cache_id, $compile_id, $exp_time);
public function locked(Smarty $smarty, Smarty_Template_Cached $cached)
{
// theoretically locking_timeout should be checked against time_limit (max_execution_time)
$start = microtime(true);
$hadLock = null;
while ($this->hasLock($smarty, $cached)) {
$hadLock = true;
if (microtime(true) - $start > $smarty->locking_timeout) {
// abort waiting for lock release
return false;
}
sleep(1);
}
return $hadLock;
}
public function hasLock(Smarty $smarty, Smarty_Template_Cached $cached)
{
// check if lock exists
return false;
}
public function acquireLock(Smarty $smarty, Smarty_Template_Cached $cached)
{
// create lock
return true;
}
public function releaseLock(Smarty $smarty, Smarty_Template_Cached $cached)
{
// release lock
return true;
}
/**
* Load Cache Resource Handler
*
* @param Smarty $smarty Smarty object
* @param string $type name of the cache resource
* @return Smarty_CacheResource Cache Resource Handler
*/
public static function load(Smarty $smarty, $type = null)
{
if (!isset($type)) {
$type = $smarty->caching_type;
}
// try smarty's cache
if (isset($smarty->_cacheresource_handlers[$type])) {
return $smarty->_cacheresource_handlers[$type];
}
// try registered resource
if (isset($smarty->registered_cache_resources[$type])) {
// do not cache these instances as they may vary from instance to instance
return $smarty->_cacheresource_handlers[$type] = $smarty->registered_cache_resources[$type];
}
// try sysplugins dir
if (isset(self::$sysplugins[$type])) {
if (!isset(self::$resources[$type])) {
$cache_resource_class = 'Smarty_Internal_CacheResource_' . ucfirst($type);
self::$resources[$type] = new $cache_resource_class();
}
return $smarty->_cacheresource_handlers[$type] = self::$resources[$type];
}
// try plugins dir
$cache_resource_class = 'Smarty_CacheResource_' . ucfirst($type);
if ($smarty->loadPlugin($cache_resource_class)) {
if (!isset(self::$resources[$type])) {
self::$resources[$type] = new $cache_resource_class();
}
return $smarty->_cacheresource_handlers[$type] = self::$resources[$type];
}
// give up
throw new SmartyException("Unable to load cache resource '{$type}'");
}
/**
* Invalid Loaded Cache Files
*
* @param Smarty $smarty Smarty object
*/
public static function invalidLoadedCache(Smarty $smarty)
{
foreach ($smarty->template_objects as $tpl) {
if (isset($tpl->cached)) {
$tpl->cached->valid = false;
$tpl->cached->processed = false;
}
}
}
}
/**
* Smarty Resource Data Object
*
* Cache Data Container for Template Files
*
* @package Smarty
* @subpackage TemplateResources
* @author Rodney Rehm
*/
class Smarty_Template_Cached {
/**
* Source Filepath
* @var string
*/
public $filepath = false;
/**
* Source Content
* @var string
*/
public $content = null;
/**
* Source Timestamp
* @var integer
*/
public $timestamp = false;
/**
* Source Existance
* @var boolean
*/
public $exists = false;
/**
* Cache Is Valid
* @var boolean
*/
public $valid = false;
/**
* Cache was processed
* @var boolean
*/
public $processed = false;
/**
* CacheResource Handler
* @var Smarty_CacheResource
*/
public $handler = null;
/**
* Template Compile Id (Smarty_Internal_Template::$compile_id)
* @var string
*/
public $compile_id = null;
/**
* Template Cache Id (Smarty_Internal_Template::$cache_id)
* @var string
*/
public $cache_id = null;
/**
* Id for cache locking
* @var string
*/
public $lock_id = null;
/**
* flag that cache is locked by this instance
* @var bool
*/
public $is_locked = false;
/**
* Source Object
* @var Smarty_Template_Source
*/
public $source = null;
/**
* create Cached Object container
*
* @param Smarty_Internal_Template $_template template object
*/
public function __construct(Smarty_Internal_Template $_template)
{
$this->compile_id = $_template->compile_id;
$this->cache_id = $_template->cache_id;
$this->source = $_template->source;
$_template->cached = $this;
$smarty = $_template->smarty;
//
// load resource handler
//
$this->handler = $handler = Smarty_CacheResource::load($smarty); // Note: prone to circular references
//
// check if cache is valid
//
if (!($_template->caching == Smarty::CACHING_LIFETIME_CURRENT || $_template->caching == Smarty::CACHING_LIFETIME_SAVED) || $_template->source->recompiled) {
$handler->populate($this, $_template);
return;
}
while (true) {
while (true) {
$handler->populate($this, $_template);
if ($this->timestamp === false || $smarty->force_compile || $smarty->force_cache) {
$this->valid = false;
} else {
$this->valid = true;
}
if ($this->valid && $_template->caching == Smarty::CACHING_LIFETIME_CURRENT && $_template->cache_lifetime >= 0 && time() > ($this->timestamp + $_template->cache_lifetime)) {
// lifetime expired
$this->valid = false;
}
if ($this->valid || !$_template->smarty->cache_locking) {
break;
}
if (!$this->handler->locked($_template->smarty, $this)) {
$this->handler->acquireLock($_template->smarty, $this);
break 2;
}
}
if ($this->valid) {
if (!$_template->smarty->cache_locking || $this->handler->locked($_template->smarty, $this) === null) {
// load cache file for the following checks
if ($smarty->debugging) {
Smarty_Internal_Debug::start_cache($_template);
}
if($handler->process($_template, $this) === false) {
$this->valid = false;
} else {
$this->processed = true;
}
if ($smarty->debugging) {
Smarty_Internal_Debug::end_cache($_template);
}
} else {
continue;
}
} else {
return;
}
if ($this->valid && $_template->caching === Smarty::CACHING_LIFETIME_SAVED && $_template->properties['cache_lifetime'] >= 0 && (time() > ($_template->cached->timestamp + $_template->properties['cache_lifetime']))) {
$this->valid = false;
}
if (!$this->valid && $_template->smarty->cache_locking) {
$this->handler->acquireLock($_template->smarty, $this);
return;
} else {
return;
}
}
}
/**
* Write this cache object to handler
*
* @param Smarty_Internal_Template $_template template object
* @param string $content content to cache
* @return boolean success
*/
public function write(Smarty_Internal_Template $_template, $content)
{
if (!$_template->source->recompiled) {
if ($this->handler->writeCachedContent($_template, $content)) {
$this->timestamp = time();
$this->exists = true;
$this->valid = true;
if ($_template->smarty->cache_locking) {
$this->handler->releaseLock($_template->smarty, $this);
}
return true;
}
}
return false;
}
}
?>

View File

@@ -0,0 +1,238 @@
<?php
/**
* Smarty Internal Plugin
*
* @package Smarty
* @subpackage Cacher
*/
/**
* Cache Handler API
*
* @package Smarty
* @subpackage Cacher
* @author Rodney Rehm
*/
abstract class Smarty_CacheResource_Custom extends Smarty_CacheResource {
/**
* fetch cached content and its modification time from data source
*
* @param string $id unique cache content identifier
* @param string $name template name
* @param string $cache_id cache id
* @param string $compile_id compile id
* @param string $content cached content
* @param integer $mtime cache modification timestamp (epoch)
* @return void
*/
protected abstract function fetch($id, $name, $cache_id, $compile_id, &$content, &$mtime);
/**
* Fetch cached content's modification timestamp from data source
*
* {@internal implementing this method is optional.
* Only implement it if modification times can be accessed faster than loading the complete cached content.}}
*
* @param string $id unique cache content identifier
* @param string $name template name
* @param string $cache_id cache id
* @param string $compile_id compile id
* @return integer|boolean timestamp (epoch) the template was modified, or false if not found
*/
protected function fetchTimestamp($id, $name, $cache_id, $compile_id)
{
return null;
}
/**
* Save content to cache
*
* @param string $id unique cache content identifier
* @param string $name template name
* @param string $cache_id cache id
* @param string $compile_id compile id
* @param integer|null $exp_time seconds till expiration or null
* @param string $content content to cache
* @return boolean success
*/
protected abstract function save($id, $name, $cache_id, $compile_id, $exp_time, $content);
/**
* Delete content from cache
*
* @param string $name template name
* @param string $cache_id cache id
* @param string $compile_id compile id
* @param integer|null $exp_time seconds till expiration time in seconds or null
* @return integer number of deleted caches
*/
protected abstract function delete($name, $cache_id, $compile_id, $exp_time);
/**
* populate Cached Object with meta data from Resource
*
* @param Smarty_Template_Cached $cached cached object
* @param Smarty_Internal_Template $_template template object
* @return void
*/
public function populate(Smarty_Template_Cached $cached, Smarty_Internal_Template $_template)
{
$_cache_id = isset($cached->cache_id) ? preg_replace('![^\w\|]+!', '_', $cached->cache_id) : null;
$_compile_id = isset($cached->compile_id) ? preg_replace('![^\w\|]+!', '_', $cached->compile_id) : null;
$cached->filepath = sha1($cached->source->filepath . $_cache_id . $_compile_id);
$this->populateTimestamp($cached);
}
/**
* populate Cached Object with timestamp and exists from Resource
*
* @param Smarty_Template_Cached $source cached object
* @return void
*/
public function populateTimestamp(Smarty_Template_Cached $cached)
{
$mtime = $this->fetchTimestamp($cached->filepath, $cached->source->name, $cached->cache_id, $cached->compile_id);
if ($mtime !== null) {
$cached->timestamp = $mtime;
$cached->exists = !!$cached->timestamp;
return;
}
$timestamp = null;
$this->fetch($cached->filepath, $cached->source->name, $cached->cache_id, $cached->compile_id, $cached->content, $timestamp);
$cached->timestamp = isset($timestamp) ? $timestamp : false;
$cached->exists = !!$cached->timestamp;
}
/**
* Read the cached template and process the header
*
* @param Smarty_Internal_Template $_template template object
* @param Smarty_Template_Cached $cached cached object
* @return booelan true or false if the cached content does not exist
*/
public function process(Smarty_Internal_Template $_template, Smarty_Template_Cached $cached=null)
{
if (!$cached) {
$cached = $_template->cached;
}
$content = $cached->content ? $cached->content : null;
$timestamp = $cached->timestamp ? $cached->timestamp : null;
if ($content === null || !$timestamp) {
$this->fetch(
$_template->cached->filepath,
$_template->source->name,
$_template->cache_id,
$_template->compile_id,
$content,
$timestamp
);
}
if (isset($content)) {
$_smarty_tpl = $_template;
eval("?>" . $content);
return true;
}
return false;
}
/**
* Write the rendered template output to cache
*
* @param Smarty_Internal_Template $_template template object
* @param string $content content to cache
* @return boolean success
*/
public function writeCachedContent(Smarty_Internal_Template $_template, $content)
{
return $this->save(
$_template->cached->filepath,
$_template->source->name,
$_template->cache_id,
$_template->compile_id,
$_template->properties['cache_lifetime'],
$content
);
}
/**
* Empty cache
*
* @param Smarty $smarty Smarty object
* @param integer $exp_time expiration time (number of seconds, not timestamp)
* @return integer number of cache files deleted
*/
public function clearAll(Smarty $smarty, $exp_time=null)
{
$this->cache = array();
return $this->delete(null, null, null, $exp_time);
}
/**
* Empty cache for a specific template
*
* @param Smarty $smarty Smarty object
* @param string $resource_name template name
* @param string $cache_id cache id
* @param string $compile_id compile id
* @param integer $exp_time expiration time (number of seconds, not timestamp)
* @return integer number of cache files deleted
*/
public function clear(Smarty $smarty, $resource_name, $cache_id, $compile_id, $exp_time)
{
$this->cache = array();
return $this->delete($resource_name, $cache_id, $compile_id, $exp_time);
}
/**
* Check is cache is locked for this template
*
* @param Smarty $smarty Smarty object
* @param Smarty_Template_Cached $cached cached object
* @return booelan true or false if cache is locked
*/
public function hasLock(Smarty $smarty, Smarty_Template_Cached $cached)
{
$id = $cached->filepath;
$name = $cached->source->name . '.lock';
$mtime = $this->fetchTimestamp($id, $name, null, null);
if ($mtime === null) {
$this->fetch($id, $name, null, null, $content, $mtime);
}
return $mtime && time() - $mtime < $smarty->locking_timeout;
}
/**
* Lock cache for this template
*
* @param Smarty $smarty Smarty object
* @param Smarty_Template_Cached $cached cached object
*/
public function acquireLock(Smarty $smarty, Smarty_Template_Cached $cached)
{
$cached->is_locked = true;
$id = $cached->filepath;
$name = $cached->source->name . '.lock';
$this->save($id, $name, null, null, $smarty->locking_timeout, '');
}
/**
* Unlock cache for this template
*
* @param Smarty $smarty Smarty object
* @param Smarty_Template_Cached $cached cached object
*/
public function releaseLock(Smarty $smarty, Smarty_Template_Cached $cached)
{
$cached->is_locked = false;
$id = $cached->filepath;
$name = $cached->source->name . '.lock';
$this->delete($name, null, null, null);
}
}
?>

View File

@@ -0,0 +1,463 @@
<?php
/**
* Smarty Internal Plugin
*
* @package Smarty
* @subpackage Cacher
*/
/**
* Smarty Cache Handler Base for Key/Value Storage Implementations
*
* This class implements the functionality required to use simple key/value stores
* for hierarchical cache groups. key/value stores like memcache or APC do not support
* wildcards in keys, therefore a cache group cannot be cleared like "a|*" - which
* is no problem to filesystem and RDBMS implementations.
*
* This implementation is based on the concept of invalidation. While one specific cache
* can be identified and cleared, any range of caches cannot be identified. For this reason
* each level of the cache group hierarchy can have its own value in the store. These values
* are nothing but microtimes, telling us when a particular cache group was cleared for the
* last time. These keys are evaluated for every cache read to determine if the cache has
* been invalidated since it was created and should hence be treated as inexistent.
*
* Although deep hierarchies are possible, they are not recommended. Try to keep your
* cache groups as shallow as possible. Anything up 3-5 parents should be ok. So
* »a|b|c« is a good depth where »a|b|c|d|e|f|g|h|i|j|k« isn't. Try to join correlating
* cache groups: if your cache groups look somewhat like »a|b|$page|$items|$whatever«
* consider using »a|b|c|$page-$items-$whatever« instead.
*
* @package Smarty
* @subpackage Cacher
* @author Rodney Rehm
*/
abstract class Smarty_CacheResource_KeyValueStore extends Smarty_CacheResource {
/**
* cache for contents
* @var array
*/
protected $contents = array();
/**
* cache for timestamps
* @var array
*/
protected $timestamps = array();
/**
* populate Cached Object with meta data from Resource
*
* @param Smarty_Template_Cached $cached cached object
* @param Smarty_Internal_Template $_template template object
* @return void
*/
public function populate(Smarty_Template_Cached $cached, Smarty_Internal_Template $_template)
{
$cached->filepath = $_template->source->uid
. '#' . $this->sanitize($cached->source->name)
. '#' . $this->sanitize($cached->cache_id)
. '#' . $this->sanitize($cached->compile_id);
$this->populateTimestamp($cached);
}
/**
* populate Cached Object with timestamp and exists from Resource
*
* @param Smarty_Template_Cached $cached cached object
* @return void
*/
public function populateTimestamp(Smarty_Template_Cached $cached)
{
if (!$this->fetch($cached->filepath, $cached->source->name, $cached->cache_id, $cached->compile_id, $content, $timestamp, $cached->source->uid)) {
return;
}
$cached->content = $content;
$cached->timestamp = (int) $timestamp;
$cached->exists = $cached->timestamp;
}
/**
* Read the cached template and process the header
*
* @param Smarty_Internal_Template $_template template object
* @param Smarty_Template_Cached $cached cached object
* @return booelan true or false if the cached content does not exist
*/
public function process(Smarty_Internal_Template $_template, Smarty_Template_Cached $cached=null)
{
if (!$cached) {
$cached = $_template->cached;
}
$content = $cached->content ? $cached->content : null;
$timestamp = $cached->timestamp ? $cached->timestamp : null;
if ($content === null || !$timestamp) {
if (!$this->fetch($_template->cached->filepath, $_template->source->name, $_template->cache_id, $_template->compile_id, $content, $timestamp, $_template->source->uid)) {
return false;
}
}
if (isset($content)) {
$_smarty_tpl = $_template;
eval("?>" . $content);
return true;
}
return false;
}
/**
* Write the rendered template output to cache
*
* @param Smarty_Internal_Template $_template template object
* @param string $content content to cache
* @return boolean success
*/
public function writeCachedContent(Smarty_Internal_Template $_template, $content)
{
$this->addMetaTimestamp($content);
return $this->write(array($_template->cached->filepath => $content), $_template->properties['cache_lifetime']);
}
/**
* Empty cache
*
* {@internal the $exp_time argument is ignored altogether }}
*
* @param Smarty $smarty Smarty object
* @param integer $exp_time expiration time [being ignored]
* @return integer number of cache files deleted [always -1]
* @uses purge() to clear the whole store
* @uses invalidate() to mark everything outdated if purge() is inapplicable
*/
public function clearAll(Smarty $smarty, $exp_time=null)
{
if (!$this->purge()) {
$this->invalidate(null);
}
return -1;
}
/**
* Empty cache for a specific template
*
* {@internal the $exp_time argument is ignored altogether}}
*
* @param Smarty $smarty Smarty object
* @param string $resource_name template name
* @param string $cache_id cache id
* @param string $compile_id compile id
* @param integer $exp_time expiration time [being ignored]
* @return integer number of cache files deleted [always -1]
* @uses buildCachedFilepath() to generate the CacheID
* @uses invalidate() to mark CacheIDs parent chain as outdated
* @uses delete() to remove CacheID from cache
*/
public function clear(Smarty $smarty, $resource_name, $cache_id, $compile_id, $exp_time)
{
$uid = $this->getTemplateUid($smarty, $resource_name, $cache_id, $compile_id);
$cid = $uid . '#' . $this->sanitize($resource_name) . '#' . $this->sanitize($cache_id) . '#' . $this->sanitize($compile_id);
$this->delete(array($cid));
$this->invalidate($cid, $resource_name, $cache_id, $compile_id, $uid);
return -1;
}
/**
* Get template's unique ID
*
* @param Smarty $smarty Smarty object
* @param string $resource_name template name
* @param string $cache_id cache id
* @param string $compile_id compile id
* @return string filepath of cache file
*/
protected function getTemplateUid(Smarty $smarty, $resource_name, $cache_id, $compile_id)
{
$uid = '';
if (isset($resource_name)) {
$tpl = new $smarty->template_class($resource_name, $smarty);
if ($tpl->source->exists) {
$uid = $tpl->source->uid;
}
// remove from template cache
if ($smarty->allow_ambiguous_resources) {
$_templateId = $tpl->source->unique_resource . $tpl->cache_id . $tpl->compile_id;
} else {
$_templateId = $smarty->joined_template_dir . '#' . $resource_name . $tpl->cache_id . $tpl->compile_id;
}
if (isset($_templateId[150])) {
$_templateId = sha1($_templateId);
}
unset($smarty->template_objects[$_templateId]);
}
return $uid;
}
/**
* Sanitize CacheID components
*
* @param string $string CacheID component to sanitize
* @return string sanitized CacheID component
*/
protected function sanitize($string)
{
// some poeple smoke bad weed
$string = trim($string, '|');
if (!$string) {
return null;
}
return preg_replace('#[^\w\|]+#S', '_', $string);
}
/**
* Fetch and prepare a cache object.
*
* @param string $cid CacheID to fetch
* @param string $resource_name template name
* @param string $cache_id cache id
* @param string $compile_id compile id
* @param string $content cached content
* @param integer &$timestamp cached timestamp (epoch)
* @param string $resource_uid resource's uid
* @return boolean success
*/
protected function fetch($cid, $resource_name = null, $cache_id = null, $compile_id = null, &$content = null, &$timestamp = null, $resource_uid = null)
{
$t = $this->read(array($cid));
$content = !empty($t[$cid]) ? $t[$cid] : null;
$timestamp = null;
if ($content && ($timestamp = $this->getMetaTimestamp($content))) {
$invalidated = $this->getLatestInvalidationTimestamp($cid, $resource_name, $cache_id, $compile_id, $resource_uid);
if ($invalidated > $timestamp) {
$timestamp = null;
$content = null;
}
}
return !!$content;
}
/**
* Add current microtime to the beginning of $cache_content
*
* {@internal the header uses 8 Bytes, the first 4 Bytes are the seconds, the second 4 Bytes are the microseconds}}
*
* @param string &$content the content to be cached
*/
protected function addMetaTimestamp(&$content)
{
$mt = explode(" ", microtime());
$ts = pack("NN", $mt[1], (int) ($mt[0] * 100000000));
$content = $ts . $content;
}
/**
* Extract the timestamp the $content was cached
*
* @param string &$content the cached content
* @return float the microtime the content was cached
*/
protected function getMetaTimestamp(&$content)
{
$s = unpack("N", substr($content, 0, 4));
$m = unpack("N", substr($content, 4, 4));
$content = substr($content, 8);
return $s[1] + ($m[1] / 100000000);
}
/**
* Invalidate CacheID
*
* @param string $cid CacheID
* @param string $resource_name template name
* @param string $cache_id cache id
* @param string $compile_id compile id
* @param string $resource_uid source's uid
* @return void
*/
protected function invalidate($cid = null, $resource_name = null, $cache_id = null, $compile_id = null, $resource_uid = null)
{
$now = microtime(true);
$key = null;
// invalidate everything
if (!$resource_name && !$cache_id && !$compile_id) {
$key = 'IVK#ALL';
}
// invalidate all caches by template
else if ($resource_name && !$cache_id && !$compile_id) {
$key = 'IVK#TEMPLATE#' . $resource_uid . '#' . $this->sanitize($resource_name);
}
// invalidate all caches by cache group
else if (!$resource_name && $cache_id && !$compile_id) {
$key = 'IVK#CACHE#' . $this->sanitize($cache_id);
}
// invalidate all caches by compile id
else if (!$resource_name && !$cache_id && $compile_id) {
$key = 'IVK#COMPILE#' . $this->sanitize($compile_id);
}
// invalidate by combination
else {
$key = 'IVK#CID#' . $cid;
}
$this->write(array($key => $now));
}
/**
* Determine the latest timestamp known to the invalidation chain
*
* @param string $cid CacheID to determine latest invalidation timestamp of
* @param string $resource_name template name
* @param string $cache_id cache id
* @param string $compile_id compile id
* @param string $resource_uid source's filepath
* @return float the microtime the CacheID was invalidated
*/
protected function getLatestInvalidationTimestamp($cid, $resource_name = null, $cache_id = null, $compile_id = null, $resource_uid = null)
{
// abort if there is no CacheID
if (false && !$cid) {
return 0;
}
// abort if there are no InvalidationKeys to check
if (!($_cid = $this->listInvalidationKeys($cid, $resource_name, $cache_id, $compile_id, $resource_uid))) {
return 0;
}
// there are no InValidationKeys
if (!($values = $this->read($_cid))) {
return 0;
}
// make sure we're dealing with floats
$values = array_map('floatval', $values);
return max($values);
}
/**
* Translate a CacheID into the list of applicable InvalidationKeys.
*
* Splits "some|chain|into|an|array" into array( '#clearAll#', 'some', 'some|chain', 'some|chain|into', ... )
*
* @param string $cid CacheID to translate
* @param string $resource_name template name
* @param string $cache_id cache id
* @param string $compile_id compile id
* @param string $resource_uid source's filepath
* @return array list of InvalidationKeys
* @uses $invalidationKeyPrefix to prepend to each InvalidationKey
*/
protected function listInvalidationKeys($cid, $resource_name = null, $cache_id = null, $compile_id = null, $resource_uid = null)
{
$t = array('IVK#ALL');
$_name = $_compile = '#';
if ($resource_name) {
$_name .= $resource_uid . '#' . $this->sanitize($resource_name);
$t[] = 'IVK#TEMPLATE' . $_name;
}
if ($compile_id) {
$_compile .= $this->sanitize($compile_id);
$t[] = 'IVK#COMPILE' . $_compile;
}
$_name .= '#';
// some poeple smoke bad weed
$cid = trim($cache_id, '|');
if (!$cid) {
return $t;
}
$i = 0;
while (true) {
// determine next delimiter position
$i = strpos($cid, '|', $i);
// add complete CacheID if there are no more delimiters
if ($i === false) {
$t[] = 'IVK#CACHE#' . $cid;
$t[] = 'IVK#CID' . $_name . $cid . $_compile;
$t[] = 'IVK#CID' . $_name . $_compile;
break;
}
$part = substr($cid, 0, $i);
// add slice to list
$t[] = 'IVK#CACHE#' . $part;
$t[] = 'IVK#CID' . $_name . $part . $_compile;
// skip past delimiter position
$i++;
}
return $t;
}
/**
* Check is cache is locked for this template
*
* @param Smarty $smarty Smarty object
* @param Smarty_Template_Cached $cached cached object
* @return booelan true or false if cache is locked
*/
public function hasLock(Smarty $smarty, Smarty_Template_Cached $cached)
{
$key = 'LOCK#' . $cached->filepath;
$data = $this->read(array($key));
return $data && time() - $data[$key] < $smarty->locking_timeout;
}
/**
* Lock cache for this template
*
* @param Smarty $smarty Smarty object
* @param Smarty_Template_Cached $cached cached object
*/
public function acquireLock(Smarty $smarty, Smarty_Template_Cached $cached)
{
$cached->is_locked = true;
$key = 'LOCK#' . $cached->filepath;
$this->write(array($key => time()), $smarty->locking_timeout);
}
/**
* Unlock cache for this template
*
* @param Smarty $smarty Smarty object
* @param Smarty_Template_Cached $cached cached object
*/
public function releaseLock(Smarty $smarty, Smarty_Template_Cached $cached)
{
$cached->is_locked = false;
$key = 'LOCK#' . $cached->filepath;
$this->delete(array($key));
}
/**
* Read values for a set of keys from cache
*
* @param array $keys list of keys to fetch
* @return array list of values with the given keys used as indexes
*/
protected abstract function read(array $keys);
/**
* Save values for a set of keys to cache
*
* @param array $keys list of values to save
* @param int $expire expiration time
* @return boolean true on success, false on failure
*/
protected abstract function write(array $keys, $expire=null);
/**
* Remove values from cache
*
* @param array $keys list of keys to delete
* @return boolean true on success, false on failure
*/
protected abstract function delete(array $keys);
/**
* Remove *all* values from cache
*
* @return boolean true on success, false on failure
*/
protected function purge()
{
return false;
}
}
?>

View File

@@ -0,0 +1,95 @@
<?php
/**
* Smarty Internal Plugin
*
* @package Smarty
* @subpackage TemplateResources
*/
/**
* Smarty Resource Data Object
*
* Meta Data Container for Config Files
*
* @package Smarty
* @subpackage TemplateResources
* @author Rodney Rehm
*
* @property string $content
* @property int $timestamp
* @property bool $exists
*/
class Smarty_Config_Source extends Smarty_Template_Source {
/**
* create Config Object container
*
* @param Smarty_Resource $handler Resource Handler this source object communicates with
* @param Smarty $smarty Smarty instance this source object belongs to
* @param string $resource full config_resource
* @param string $type type of resource
* @param string $name resource name
* @param string $unique_resource unqiue resource name
*/
public function __construct(Smarty_Resource $handler, Smarty $smarty, $resource, $type, $name, $unique_resource)
{
$this->handler = $handler; // Note: prone to circular references
// Note: these may be ->config_compiler_class etc in the future
//$this->config_compiler_class = $handler->config_compiler_class;
//$this->config_lexer_class = $handler->config_lexer_class;
//$this->config_parser_class = $handler->config_parser_class;
$this->smarty = $smarty;
$this->resource = $resource;
$this->type = $type;
$this->name = $name;
$this->unique_resource = $unique_resource;
}
/**
* <<magic>> Generic setter.
*
* @param string $property_name valid: content, timestamp, exists
* @param mixed $value newly assigned value (not check for correct type)
* @throws SmartyException when the given property name is not valid
*/
public function __set($property_name, $value)
{
switch ($property_name) {
case 'content':
case 'timestamp':
case 'exists':
$this->$property_name = $value;
break;
default:
throw new SmartyException("invalid config property '$property_name'.");
}
}
/**
* <<magic>> Generic getter.
*
* @param string $property_name valid: content, timestamp, exists
* @throws SmartyException when the given property name is not valid
*/
public function __get($property_name)
{
switch ($property_name) {
case 'timestamp':
case 'exists':
$this->handler->populateTimestamp($this);
return $this->$property_name;
case 'content':
return $this->content = $this->handler->getContent($this);
default:
throw new SmartyException("config property '$property_name' does not exist.");
}
}
}
?>

View File

@@ -0,0 +1,264 @@
<?php
/**
* Smarty Internal Plugin CacheResource File
*
* @package Smarty
* @subpackage Cacher
* @author Uwe Tews
* @author Rodney Rehm
*/
/**
* This class does contain all necessary methods for the HTML cache on file system
*
* Implements the file system as resource for the HTML cache Version ussing nocache inserts.
*
* @package Smarty
* @subpackage Cacher
*/
class Smarty_Internal_CacheResource_File extends Smarty_CacheResource {
/**
* populate Cached Object with meta data from Resource
*
* @param Smarty_Template_Cached $cached cached object
* @param Smarty_Internal_Template $_template template object
* @return void
*/
public function populate(Smarty_Template_Cached $cached, Smarty_Internal_Template $_template)
{
$_source_file_path = str_replace(':', '.', $_template->source->filepath);
$_cache_id = isset($_template->cache_id) ? preg_replace('![^\w\|]+!', '_', $_template->cache_id) : null;
$_compile_id = isset($_template->compile_id) ? preg_replace('![^\w\|]+!', '_', $_template->compile_id) : null;
$_filepath = $_template->source->uid;
// if use_sub_dirs, break file into directories
if ($_template->smarty->use_sub_dirs) {
$_filepath = substr($_filepath, 0, 2) . DS
. substr($_filepath, 2, 2) . DS
. substr($_filepath, 4, 2) . DS
. $_filepath;
}
$_compile_dir_sep = $_template->smarty->use_sub_dirs ? DS : '^';
if (isset($_cache_id)) {
$_cache_id = str_replace('|', $_compile_dir_sep, $_cache_id) . $_compile_dir_sep;
} else {
$_cache_id = '';
}
if (isset($_compile_id)) {
$_compile_id = $_compile_id . $_compile_dir_sep;
} else {
$_compile_id = '';
}
$_cache_dir = $_template->smarty->getCacheDir();
if ($_template->smarty->cache_locking) {
// create locking file name
// relative file name?
if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_cache_dir)) {
$_lock_dir = rtrim(getcwd(), '/\\') . DS . $_cache_dir;
} else {
$_lock_dir = $_cache_dir;
}
$cached->lock_id = $_lock_dir.sha1($_cache_id.$_compile_id.$_template->source->uid).'.lock';
}
$cached->filepath = $_cache_dir . $_cache_id . $_compile_id . $_filepath . '.' . basename($_source_file_path) . '.php';
$cached->timestamp = @filemtime($cached->filepath);
$cached->exists = !!$cached->timestamp;
}
/**
* populate Cached Object with timestamp and exists from Resource
*
* @param Smarty_Template_Cached $cached cached object
* @return void
*/
public function populateTimestamp(Smarty_Template_Cached $cached)
{
$cached->timestamp = @filemtime($cached->filepath);
$cached->exists = !!$cached->timestamp;
}
/**
* Read the cached template and process its header
*
* @param Smarty_Internal_Template $_template template object
* @param Smarty_Template_Cached $cached cached object
* @return booelan true or false if the cached content does not exist
*/
public function process(Smarty_Internal_Template $_template, Smarty_Template_Cached $cached=null)
{
$_smarty_tpl = $_template;
return @include $_template->cached->filepath;
}
/**
* Write the rendered template output to cache
*
* @param Smarty_Internal_Template $_template template object
* @param string $content content to cache
* @return boolean success
*/
public function writeCachedContent(Smarty_Internal_Template $_template, $content)
{
if (Smarty_Internal_Write_File::writeFile($_template->cached->filepath, $content, $_template->smarty) === true) {
$_template->cached->timestamp = filemtime($_template->cached->filepath);
$_template->cached->exists = !!$_template->cached->timestamp;
return true;
}
return false;
}
/**
* Empty cache
*
* @param Smarty_Internal_Template $_template template object
* @param integer $exp_time expiration time (number of seconds, not timestamp)
* @return integer number of cache files deleted
*/
public function clearAll(Smarty $smarty, $exp_time = null)
{
return $this->clear($smarty, null, null, null, $exp_time);
}
/**
* Empty cache for a specific template
*
* @param Smarty $_template template object
* @param string $resource_name template name
* @param string $cache_id cache id
* @param string $compile_id compile id
* @param integer $exp_time expiration time (number of seconds, not timestamp)
* @return integer number of cache files deleted
*/
public function clear(Smarty $smarty, $resource_name, $cache_id, $compile_id, $exp_time)
{
$_cache_id = isset($cache_id) ? preg_replace('![^\w\|]+!', '_', $cache_id) : null;
$_compile_id = isset($compile_id) ? preg_replace('![^\w\|]+!', '_', $compile_id) : null;
$_dir_sep = $smarty->use_sub_dirs ? '/' : '^';
$_compile_id_offset = $smarty->use_sub_dirs ? 3 : 0;
$_dir = $smarty->getCacheDir();
$_dir_length = strlen($_dir);
if (isset($_cache_id)) {
$_cache_id_parts = explode('|', $_cache_id);
$_cache_id_parts_count = count($_cache_id_parts);
if ($smarty->use_sub_dirs) {
foreach ($_cache_id_parts as $id_part) {
$_dir .= $id_part . DS;
}
}
}
if (isset($resource_name)) {
$_save_stat = $smarty->caching;
$smarty->caching = true;
$tpl = new $smarty->template_class($resource_name, $smarty);
$smarty->caching = $_save_stat;
// remove from template cache
$tpl->source; // have the template registered before unset()
if ($smarty->allow_ambiguous_resources) {
$_templateId = $tpl->source->unique_resource . $tpl->cache_id . $tpl->compile_id;
} else {
$_templateId = $smarty->joined_template_dir . '#' . $resource_name . $tpl->cache_id . $tpl->compile_id;
}
if (isset($_templateId[150])) {
$_templateId = sha1($_templateId);
}
unset($smarty->template_objects[$_templateId]);
if ($tpl->source->exists) {
$_resourcename_parts = basename(str_replace('^', '/', $tpl->cached->filepath));
} else {
return 0;
}
}
$_count = 0;
$_time = time();
if (file_exists($_dir)) {
$_cacheDirs = new RecursiveDirectoryIterator($_dir);
$_cache = new RecursiveIteratorIterator($_cacheDirs, RecursiveIteratorIterator::CHILD_FIRST);
foreach ($_cache as $_file) {
if (substr($_file->getBasename(),0,1) == '.' || strpos($_file, '.svn') !== false) continue;
// directory ?
if ($_file->isDir()) {
if (!$_cache->isDot()) {
// delete folder if empty
@rmdir($_file->getPathname());
}
} else {
$_parts = explode($_dir_sep, str_replace('\\', '/', substr((string)$_file, $_dir_length)));
$_parts_count = count($_parts);
// check name
if (isset($resource_name)) {
if ($_parts[$_parts_count-1] != $_resourcename_parts) {
continue;
}
}
// check compile id
if (isset($_compile_id) && (!isset($_parts[$_parts_count-2 - $_compile_id_offset]) || $_parts[$_parts_count-2 - $_compile_id_offset] != $_compile_id)) {
continue;
}
// check cache id
if (isset($_cache_id)) {
// count of cache id parts
$_parts_count = (isset($_compile_id)) ? $_parts_count - 2 - $_compile_id_offset : $_parts_count - 1 - $_compile_id_offset;
if ($_parts_count < $_cache_id_parts_count) {
continue;
}
for ($i = 0; $i < $_cache_id_parts_count; $i++) {
if ($_parts[$i] != $_cache_id_parts[$i]) continue 2;
}
}
// expired ?
if (isset($exp_time) && $_time - @filemtime($_file) < $exp_time) {
continue;
}
$_count += @unlink((string) $_file) ? 1 : 0;
}
}
}
return $_count;
}
/**
* Check is cache is locked for this template
*
* @param Smarty $smarty Smarty object
* @param Smarty_Template_Cached $cached cached object
* @return booelan true or false if cache is locked
*/
public function hasLock(Smarty $smarty, Smarty_Template_Cached $cached)
{
if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
clearstatcache(true, $cached->lock_id);
} else {
clearstatcache();
}
$t = @filemtime($cached->lock_id);
return $t && (time() - $t < $smarty->locking_timeout);
}
/**
* Lock cache for this template
*
* @param Smarty $smarty Smarty object
* @param Smarty_Template_Cached $cached cached object
*/
public function acquireLock(Smarty $smarty, Smarty_Template_Cached $cached)
{
$cached->is_locked = true;
touch($cached->lock_id);
}
/**
* Unlock cache for this template
*
* @param Smarty $smarty Smarty object
* @param Smarty_Template_Cached $cached cached object
*/
public function releaseLock(Smarty $smarty, Smarty_Template_Cached $cached)
{
$cached->is_locked = false;
@unlink($cached->lock_id);
}
}
?>

View File

@@ -0,0 +1,53 @@
<?php
/**
* Smarty Internal Plugin Compile Append
*
* Compiles the {append} tag
*
* @package Smarty
* @subpackage Compiler
* @author Uwe Tews
*/
/**
* Smarty Internal Plugin Compile Append Class
*
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Append extends Smarty_Internal_Compile_Assign {
/**
* Compiles code for the {append} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $parameter array with compilation parameter
* @return string compiled code
*/
public function compile($args, $compiler, $parameter)
{
// the following must be assigned at runtime because it will be overwritten in parent class
$this->required_attributes = array('var', 'value');
$this->shorttag_order = array('var', 'value');
$this->optional_attributes = array('scope', 'index');
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
// map to compile assign attributes
if (isset($_attr['index'])) {
$_params['smarty_internal_index'] = '[' . $_attr['index'] . ']';
unset($_attr['index']);
} else {
$_params['smarty_internal_index'] = '[]';
}
$_new_attr = array();
foreach ($_attr as $key => $value) {
$_new_attr[] = array($key => $value);
}
// call compile assign
return parent::compile($_new_attr, $compiler, $_params);
}
}
?>

View File

@@ -0,0 +1,77 @@
<?php
/**
* Smarty Internal Plugin Compile Assign
*
* Compiles the {assign} tag
*
* @package Smarty
* @subpackage Compiler
* @author Uwe Tews
*/
/**
* Smarty Internal Plugin Compile Assign Class
*
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Assign extends Smarty_Internal_CompileBase {
/**
* Compiles code for the {assign} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $parameter array with compilation parameter
* @return string compiled code
*/
public function compile($args, $compiler, $parameter)
{
// the following must be assigned at runtime because it will be overwritten in Smarty_Internal_Compile_Append
$this->required_attributes = array('var', 'value');
$this->shorttag_order = array('var', 'value');
$this->optional_attributes = array('scope');
$_nocache = 'null';
$_scope = Smarty::SCOPE_LOCAL;
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
// nocache ?
if ($compiler->tag_nocache || $compiler->nocache) {
$_nocache = 'true';
// create nocache var to make it know for further compiling
$compiler->template->tpl_vars[trim($_attr['var'], "'")] = new Smarty_variable(null, true);
}
// scope setup
if (isset($_attr['scope'])) {
$_attr['scope'] = trim($_attr['scope'], "'\"");
if ($_attr['scope'] == 'parent') {
$_scope = Smarty::SCOPE_PARENT;
} elseif ($_attr['scope'] == 'root') {
$_scope = Smarty::SCOPE_ROOT;
} elseif ($_attr['scope'] == 'global') {
$_scope = Smarty::SCOPE_GLOBAL;
} else {
$compiler->trigger_template_error('illegal value for "scope" attribute', $compiler->lex->taglineno);
}
}
// compiled output
if (isset($parameter['smarty_internal_index'])) {
$output = "<?php \$_smarty_tpl->createLocalArrayVariable($_attr[var], $_nocache, $_scope);\n\$_smarty_tpl->tpl_vars[$_attr[var]]->value$parameter[smarty_internal_index] = $_attr[value];";
} else {
$output = "<?php \$_smarty_tpl->tpl_vars[$_attr[var]] = new Smarty_variable($_attr[value], $_nocache, $_scope);";
}
if ($_scope == Smarty::SCOPE_PARENT) {
$output .= "\nif (\$_smarty_tpl->parent != null) \$_smarty_tpl->parent->tpl_vars[$_attr[var]] = clone \$_smarty_tpl->tpl_vars[$_attr[var]];";
} elseif ($_scope == Smarty::SCOPE_ROOT || $_scope == Smarty::SCOPE_GLOBAL) {
$output .= "\n\$_ptr = \$_smarty_tpl->parent; while (\$_ptr != null) {\$_ptr->tpl_vars[$_attr[var]] = clone \$_smarty_tpl->tpl_vars[$_attr[var]]; \$_ptr = \$_ptr->parent; }";
}
if ( $_scope == Smarty::SCOPE_GLOBAL) {
$output .= "\nSmarty::\$global_tpl_vars[$_attr[var]] = clone \$_smarty_tpl->tpl_vars[$_attr[var]];";
}
$output .= '?>';
return $output;
}
}
?>

View File

@@ -0,0 +1,238 @@
<?php
/**
* Smarty Internal Plugin Compile Block
*
* Compiles the {block}{/block} tags
*
* @package Smarty
* @subpackage Compiler
* @author Uwe Tews
*/
/**
* Smarty Internal Plugin Compile Block Class
*
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase {
/**
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
public $required_attributes = array('name');
/**
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
public $shorttag_order = array('name', 'hide');
/**
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
public $optional_attributes = array('hide');
/**
* Compiles code for the {block} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @return boolean true
*/
public function compile($args, $compiler)
{
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
$save = array($_attr, $compiler->parser->current_buffer, $compiler->nocache, $compiler->smarty->merge_compiled_includes);
$this->openTag($compiler, 'block', $save);
if ($_attr['nocache'] == true) {
$compiler->nocache = true;
}
// set flag for {block} tag
$compiler->inheritance = true;
// must merge includes
$compiler->smarty->merge_compiled_includes = true;
$compiler->parser->current_buffer = new _smarty_template_buffer($compiler->parser);
$compiler->has_code = false;
return true;
}
/**
* Save or replace child block source by block name during parsing
*
* @param string $block_content block source content
* @param string $block_tag opening block tag
* @param object $template template object
* @param string $filepath filepath of template source
*/
public static function saveBlockData($block_content, $block_tag, $template, $filepath)
{
$_rdl = preg_quote($template->smarty->right_delimiter);
$_ldl = preg_quote($template->smarty->left_delimiter);
if (0 == preg_match("!({$_ldl}block\s+)(name=)?(\w+|'.*'|\".*\")(\s*?)?((append|prepend|nocache)?(\s*)?(hide)?)?(\s*{$_rdl})!", $block_tag, $_match)) {
$error_text = 'Syntax Error in template "' . $template->source->filepath . '" "' . htmlspecialchars($block_tag) . '" illegal options';
throw new SmartyCompilerException($error_text);
} else {
$_name = trim($_match[3], '\'"');
if ($_match[8] != 'hide' || isset($template->block_data[$_name])) { // replace {$smarty.block.child}
if (strpos($block_content, $template->smarty->left_delimiter . '$smarty.block.child' . $template->smarty->right_delimiter) !== false) {
if (isset($template->block_data[$_name])) {
$block_content = str_replace($template->smarty->left_delimiter . '$smarty.block.child' . $template->smarty->right_delimiter,
$template->block_data[$_name]['source'], $block_content);
unset($template->block_data[$_name]);
} else {
$block_content = str_replace($template->smarty->left_delimiter . '$smarty.block.child' . $template->smarty->right_delimiter,
'', $block_content);
}
}
if (isset($template->block_data[$_name])) {
if (strpos($template->block_data[$_name]['source'], '%%%%SMARTY_PARENT%%%%') !== false) {
$template->block_data[$_name]['source'] =
str_replace('%%%%SMARTY_PARENT%%%%', $block_content, $template->block_data[$_name]['source']);
} elseif ($template->block_data[$_name]['mode'] == 'prepend') {
$template->block_data[$_name]['source'] .= $block_content;
} elseif ($template->block_data[$_name]['mode'] == 'append') {
$template->block_data[$_name]['source'] = $block_content . $template->block_data[$_name]['source'];
}
} else {
$template->block_data[$_name]['source'] = $block_content;
$template->block_data[$_name]['file'] = $filepath;
}
if ($_match[6] == 'append') {
$template->block_data[$_name]['mode'] = 'append';
} elseif ($_match[6] == 'prepend') {
$template->block_data[$_name]['mode'] = 'prepend';
} else {
$template->block_data[$_name]['mode'] = 'replace';
}
}
}
}
/**
* Compile saved child block source
*
* @param object $compiler compiler object
* @param string $_name optional name of child block
* @return string compiled code of schild block
*/
public static function compileChildBlock($compiler, $_name = null)
{
$_output = '';
// if called by {$smarty.block.child} we must search the name of enclosing {block}
if ($_name == null) {
$stack_count = count($compiler->_tag_stack);
while (--$stack_count >= 0) {
if ($compiler->_tag_stack[$stack_count][0] == 'block') {
$_name = trim($compiler->_tag_stack[$stack_count][1][0]['name'] ,"'\"");
break;
}
}
// flag that child is already compile by {$smarty.block.child} inclusion
$compiler->template->block_data[$_name]['compiled'] = true;
}
if ($_name == null) {
$compiler->trigger_template_error('{$smarty.block.child} used out of context', $compiler->lex->taglineno);
}
// undefined child?
if (!isset($compiler->template->block_data[$_name]['source'])) {
return '';
}
$_tpl = new Smarty_Internal_template ('string:' . $compiler->template->block_data[$_name]['source'], $compiler->smarty, $compiler->template, $compiler->template->cache_id,
$compiler->template->compile_id = null, $compiler->template->caching, $compiler->template->cache_lifetime);
$_tpl->variable_filters = $compiler->template->variable_filters;
$_tpl->properties['nocache_hash'] = $compiler->template->properties['nocache_hash'];
$_tpl->source->filepath = $compiler->template->block_data[$_name]['file'];
$_tpl->allow_relative_path = true;
if ($compiler->nocache) {
$_tpl->compiler->forceNocache = 2;
} else {
$_tpl->compiler->forceNocache = 1;
}
$_tpl->compiler->suppressHeader = true;
$_tpl->compiler->suppressTemplatePropertyHeader = true;
$_tpl->compiler->suppressMergedTemplates = true;
if (strpos($compiler->template->block_data[$_name]['source'], '%%%%SMARTY_PARENT%%%%') !== false) {
$_output = str_replace('%%%%SMARTY_PARENT%%%%', $compiler->parser->current_buffer->to_smarty_php(), $_tpl->compiler->compileTemplate($_tpl));
} elseif ($compiler->template->block_data[$_name]['mode'] == 'prepend') {
$_output = $_tpl->compiler->compileTemplate($_tpl) . $compiler->parser->current_buffer->to_smarty_php();
} elseif ($compiler->template->block_data[$_name]['mode'] == 'append') {
$_output = $compiler->parser->current_buffer->to_smarty_php() . $_tpl->compiler->compileTemplate($_tpl);
} elseif (!empty($compiler->template->block_data[$_name])) {
$_output = $_tpl->compiler->compileTemplate($_tpl);
}
$compiler->template->properties['file_dependency'] = array_merge($compiler->template->properties['file_dependency'], $_tpl->properties['file_dependency']);
$compiler->template->properties['function'] = array_merge($compiler->template->properties['function'], $_tpl->properties['function']);
$compiler->merged_templates = array_merge($compiler->merged_templates, $_tpl->compiler->merged_templates);
$compiler->template->variable_filters = $_tpl->variable_filters;
if ($_tpl->has_nocache_code) {
$compiler->template->has_nocache_code = true;
}
foreach($_tpl->required_plugins as $code => $tmp1) {
foreach($tmp1 as $name => $tmp) {
foreach($tmp as $type => $data) {
$compiler->template->required_plugins[$code][$name][$type] = $data;
}
}
}
unset($_tpl);
return $_output;
}
}
/**
* Smarty Internal Plugin Compile BlockClose Class
*
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Blockclose extends Smarty_Internal_CompileBase {
/**
* Compiles code for the {/block} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @return string compiled code
*/
public function compile($args, $compiler)
{
$compiler->has_code = true;
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
$saved_data = $this->closeTag($compiler, array('block'));
$_name = trim($saved_data[0]['name'], "\"'");
if (isset($compiler->template->block_data[$_name]) && !isset($compiler->template->block_data[$_name]['compiled'])) {
$_output = Smarty_Internal_Compile_Block::compileChildBlock($compiler, $_name);
} else {
if (isset($saved_data[0]['hide']) && !isset($compiler->template->block_data[$_name]['source'])) {
$_output = '';
} else {
$_output = $compiler->parser->current_buffer->to_smarty_php();
}
unset ($compiler->template->block_data[$_name]['compiled']);
}
// reset flags
$compiler->parser->current_buffer = $saved_data[1];
$compiler->nocache = $saved_data[2];
$compiler->smarty->merge_compiled_includes = $saved_data[3];
// reset flag for {block} tag
$compiler->inheritance = false;
// $_output content has already nocache code processed
$compiler->suppressNocacheProcessing = true;
return $_output;
}
}
?>

View File

@@ -0,0 +1,77 @@
<?php
/**
* Smarty Internal Plugin Compile Break
*
* Compiles the {break} tag
*
* @package Smarty
* @subpackage Compiler
* @author Uwe Tews
*/
/**
* Smarty Internal Plugin Compile Break Class
*
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Break extends Smarty_Internal_CompileBase {
/**
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
public $optional_attributes = array('levels');
/**
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
public $shorttag_order = array('levels');
/**
* Compiles code for the {break} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $parameter array with compilation parameter
* @return string compiled code
*/
public function compile($args, $compiler, $parameter)
{
static $_is_loopy = array('for' => true, 'foreach' => true, 'while' => true, 'section' => true);
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
if ($_attr['nocache'] === true) {
$compiler->trigger_template_error('nocache option not allowed', $compiler->lex->taglineno);
}
if (isset($_attr['levels'])) {
if (!is_numeric($_attr['levels'])) {
$compiler->trigger_template_error('level attribute must be a numeric constant', $compiler->lex->taglineno);
}
$_levels = $_attr['levels'];
} else {
$_levels = 1;
}
$level_count = $_levels;
$stack_count = count($compiler->_tag_stack) - 1;
while ($level_count > 0 && $stack_count >= 0) {
if (isset($_is_loopy[$compiler->_tag_stack[$stack_count][0]])) {
$level_count--;
}
$stack_count--;
}
if ($level_count != 0) {
$compiler->trigger_template_error("cannot break {$_levels} level(s)", $compiler->lex->taglineno);
}
$compiler->has_code = true;
return "<?php break {$_levels}?>";
}
}
?>

View File

@@ -0,0 +1,130 @@
<?php
/**
* Smarty Internal Plugin Compile Function_Call
*
* Compiles the calls of user defined tags defined by {function}
*
* @package Smarty
* @subpackage Compiler
* @author Uwe Tews
*/
/**
* Smarty Internal Plugin Compile Function_Call Class
*
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Call extends Smarty_Internal_CompileBase {
/**
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
public $required_attributes = array('name');
/**
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
public $shorttag_order = array('name');
/**
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
public $optional_attributes = array('_any');
/**
* Compiles the calls of user defined tags defined by {function}
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $parameter array with compilation parameter
* @return string compiled code
*/
public function compile($args, $compiler)
{
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
// save possible attributes
if (isset($_attr['assign'])) {
// output will be stored in a smarty variable instead of beind displayed
$_assign = $_attr['assign'];
}
$_name = $_attr['name'];
if ($compiler->compiles_template_function) {
$compiler->called_functions[] = trim($_name, "'\"");
}
unset($_attr['name'], $_attr['assign'], $_attr['nocache']);
// set flag (compiled code of {function} must be included in cache file
if ($compiler->nocache || $compiler->tag_nocache) {
$_nocache = 'true';
} else {
$_nocache = 'false';
}
$_paramsArray = array();
foreach ($_attr as $_key => $_value) {
if (is_int($_key)) {
$_paramsArray[] = "$_key=>$_value";
} else {
$_paramsArray[] = "'$_key'=>$_value";
}
}
if (isset($compiler->template->properties['function'][$_name]['parameter'])) {
foreach ($compiler->template->properties['function'][$_name]['parameter'] as $_key => $_value) {
if (!isset($_attr[$_key])) {
if (is_int($_key)) {
$_paramsArray[] = "$_key=>$_value";
} else {
$_paramsArray[] = "'$_key'=>$_value";
}
}
}
} elseif (isset($compiler->smarty->template_functions[$_name]['parameter'])) {
foreach ($compiler->smarty->template_functions[$_name]['parameter'] as $_key => $_value) {
if (!isset($_attr[$_key])) {
if (is_int($_key)) {
$_paramsArray[] = "$_key=>$_value";
} else {
$_paramsArray[] = "'$_key'=>$_value";
}
}
}
}
//varibale name?
if (!(strpos($_name, '$') === false)) {
$call_cache = $_name;
$call_function = '$tmp = "smarty_template_function_".' . $_name . '; $tmp';
} else {
$_name = trim($_name, "'\"");
$call_cache = "'{$_name}'";
$call_function = 'smarty_template_function_' . $_name;
}
$_params = 'array(' . implode(",", $_paramsArray) . ')';
$_hash = str_replace('-', '_', $compiler->template->properties['nocache_hash']);
// was there an assign attribute
if (isset($_assign)) {
if ($compiler->template->caching) {
$_output = "<?php ob_start(); Smarty_Internal_Function_Call_Handler::call ({$call_cache},\$_smarty_tpl,{$_params},'{$_hash}',{$_nocache}); \$_smarty_tpl->assign({$_assign}, ob_get_clean());?>\n";
} else {
$_output = "<?php ob_start(); {$call_function}(\$_smarty_tpl,{$_params}); \$_smarty_tpl->assign({$_assign}, ob_get_clean());?>\n";
}
} else {
if ($compiler->template->caching) {
$_output = "<?php Smarty_Internal_Function_Call_Handler::call ({$call_cache},\$_smarty_tpl,{$_params},'{$_hash}',{$_nocache});?>\n";
} else {
$_output = "<?php {$call_function}(\$_smarty_tpl,{$_params});?>\n";
}
}
return $_output;
}
}
?>

View File

@@ -0,0 +1,98 @@
<?php
/**
* Smarty Internal Plugin Compile Capture
*
* Compiles the {capture} tag
*
* @package Smarty
* @subpackage Compiler
* @author Uwe Tews
*/
/**
* Smarty Internal Plugin Compile Capture Class
*
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Capture extends Smarty_Internal_CompileBase {
/**
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
public $shorttag_order = array('name');
/**
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
public $optional_attributes = array('name', 'assign', 'append');
/**
* Compiles code for the {capture} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @return string compiled code
*/
public function compile($args, $compiler)
{
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
$buffer = isset($_attr['name']) ? $_attr['name'] : "'default'";
$assign = isset($_attr['assign']) ? $_attr['assign'] : 'null';
$append = isset($_attr['append']) ? $_attr['append'] : 'null';
$compiler->_capture_stack[] = array($buffer, $assign, $append, $compiler->nocache);
// maybe nocache because of nocache variables
$compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
$_output = "<?php \$_smarty_tpl->_capture_stack[] = array($buffer, $assign, $append); ob_start(); ?>";
return $_output;
}
}
/**
* Smarty Internal Plugin Compile Captureclose Class
*
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_CaptureClose extends Smarty_Internal_CompileBase {
/**
* Compiles code for the {/capture} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @return string compiled code
*/
public function compile($args, $compiler)
{
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
// must endblock be nocache?
if ($compiler->nocache) {
$compiler->tag_nocache = true;
}
list($buffer, $assign, $append, $compiler->nocache) = array_pop($compiler->_capture_stack);
$_output = "<?php list(\$_capture_buffer, \$_capture_assign, \$_capture_append) = array_pop(\$_smarty_tpl->_capture_stack);\n";
$_output .= "if (!empty(\$_capture_buffer)) {\n";
$_output .= " if (isset(\$_capture_assign)) \$_smarty_tpl->assign(\$_capture_assign, ob_get_contents());\n";
$_output .= " if (isset( \$_capture_append)) \$_smarty_tpl->append( \$_capture_append, ob_get_contents());\n";
$_output .= " Smarty::\$_smarty_vars['capture'][\$_capture_buffer]=ob_get_clean();\n";
$_output .= "} else \$_smarty_tpl->capture_error();?>";
return $_output;
}
}
?>

View File

@@ -0,0 +1,85 @@
<?php
/**
* Smarty Internal Plugin Compile Config Load
*
* Compiles the {config load} tag
*
* @package Smarty
* @subpackage Compiler
* @author Uwe Tews
*/
/**
* Smarty Internal Plugin Compile Config Load Class
*
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Config_Load extends Smarty_Internal_CompileBase {
/**
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
public $required_attributes = array('file');
/**
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
public $shorttag_order = array('file','section');
/**
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
public $optional_attributes = array('section', 'scope');
/**
* Compiles code for the {config_load} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @return string compiled code
*/
public function compile($args, $compiler)
{
static $_is_legal_scope = array('local' => true,'parent' => true,'root' => true,'global' => true);
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
if ($_attr['nocache'] === true) {
$compiler->trigger_template_error('nocache option not allowed', $compiler->lex->taglineno);
}
// save posible attributes
$conf_file = $_attr['file'];
if (isset($_attr['section'])) {
$section = $_attr['section'];
} else {
$section = 'null';
}
$scope = 'local';
// scope setup
if (isset($_attr['scope'])) {
$_attr['scope'] = trim($_attr['scope'], "'\"");
if (isset($_is_legal_scope[$_attr['scope']])) {
$scope = $_attr['scope'];
} else {
$compiler->trigger_template_error('illegal value for "scope" attribute', $compiler->lex->taglineno);
}
}
// create config object
$_output = "<?php \$_config = new Smarty_Internal_Config($conf_file, \$_smarty_tpl->smarty, \$_smarty_tpl);";
$_output .= "\$_config->loadConfigVars($section, '$scope'); ?>";
return $_output;
}
}
?>

View File

@@ -0,0 +1,78 @@
<?php
/**
* Smarty Internal Plugin Compile Continue
*
* Compiles the {continue} tag
*
* @package Smarty
* @subpackage Compiler
* @author Uwe Tews
*/
/**
* Smarty Internal Plugin Compile Continue Class
*
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Continue extends Smarty_Internal_CompileBase {
/**
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
public $optional_attributes = array('levels');
/**
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
public $shorttag_order = array('levels');
/**
* Compiles code for the {continue} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $parameter array with compilation parameter
* @return string compiled code
*/
public function compile($args, $compiler, $parameter)
{
static $_is_loopy = array('for' => true, 'foreach' => true, 'while' => true, 'section' => true);
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
if ($_attr['nocache'] === true) {
$compiler->trigger_template_error('nocache option not allowed', $compiler->lex->taglineno);
}
if (isset($_attr['levels'])) {
if (!is_numeric($_attr['levels'])) {
$compiler->trigger_template_error('level attribute must be a numeric constant', $compiler->lex->taglineno);
}
$_levels = $_attr['levels'];
} else {
$_levels = 1;
}
$level_count = $_levels;
$stack_count = count($compiler->_tag_stack) - 1;
while ($level_count > 0 && $stack_count >= 0) {
if (isset($_is_loopy[$compiler->_tag_stack[$stack_count][0]])) {
$level_count--;
}
$stack_count--;
}
if ($level_count != 0) {
$compiler->trigger_template_error("cannot continue {$_levels} level(s)", $compiler->lex->taglineno);
}
$compiler->has_code = true;
return "<?php continue {$_levels}?>";
}
}
?>

View File

@@ -0,0 +1,43 @@
<?php
/**
* Smarty Internal Plugin Compile Debug
*
* Compiles the {debug} tag.
* It opens a window the the Smarty Debugging Console.
*
* @package Smarty
* @subpackage Compiler
* @author Uwe Tews
*/
/**
* Smarty Internal Plugin Compile Debug Class
*
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Debug extends Smarty_Internal_CompileBase {
/**
* Compiles code for the {debug} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @return string compiled code
*/
public function compile($args, $compiler)
{
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
// compile always as nocache
$compiler->tag_nocache = true;
// display debug template
$_output = "<?php \$_smarty_tpl->smarty->loadPlugin('Smarty_Internal_Debug'); Smarty_Internal_Debug::display_debug(\$_smarty_tpl); ?>";
return $_output;
}
}
?>

View File

@@ -0,0 +1,73 @@
<?php
/**
* Smarty Internal Plugin Compile Eval
*
* Compiles the {eval} tag.
*
* @package Smarty
* @subpackage Compiler
* @author Uwe Tews
*/
/**
* Smarty Internal Plugin Compile Eval Class
*
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Eval extends Smarty_Internal_CompileBase {
/**
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
public $required_attributes = array('var');
/**
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
public $optional_attributes = array('assign');
/**
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
public $shorttag_order = array('var','assign');
/**
* Compiles code for the {eval} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @return string compiled code
*/
public function compile($args, $compiler)
{
$this->required_attributes = array('var');
$this->optional_attributes = array('assign');
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
if (isset($_attr['assign'])) {
// output will be stored in a smarty variable instead of beind displayed
$_assign = $_attr['assign'];
}
// create template object
$_output = "\$_template = new {$compiler->smarty->template_class}('eval:'.".$_attr['var'].", \$_smarty_tpl->smarty, \$_smarty_tpl);";
//was there an assign attribute?
if (isset($_assign)) {
$_output .= "\$_smarty_tpl->assign($_assign,\$_template->fetch());";
} else {
$_output .= "echo \$_template->fetch();";
}
return "<?php $_output ?>";
}
}
?>

View File

@@ -0,0 +1,121 @@
<?php
/**
* Smarty Internal Plugin Compile extend
*
* Compiles the {extends} tag
*
* @package Smarty
* @subpackage Compiler
* @author Uwe Tews
*/
/**
* Smarty Internal Plugin Compile extend Class
*
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Extends extends Smarty_Internal_CompileBase {
/**
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
public $required_attributes = array('file');
/**
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
public $shorttag_order = array('file');
/**
* Compiles code for the {extends} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @return string compiled code
*/
public function compile($args, $compiler)
{
static $_is_stringy = array('string' => true, 'eval' => true);
$this->_rdl = preg_quote($compiler->smarty->right_delimiter);
$this->_ldl = preg_quote($compiler->smarty->left_delimiter);
$filepath = $compiler->template->source->filepath;
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
if ($_attr['nocache'] === true) {
$compiler->trigger_template_error('nocache option not allowed', $compiler->lex->taglineno);
}
$_smarty_tpl = $compiler->template;
$include_file = null;
if (strpos($_attr['file'], '$_tmp') !== false) {
$compiler->trigger_template_error('illegal value for file attribute', $compiler->lex->taglineno);
}
eval('$include_file = ' . $_attr['file'] . ';');
// create template object
$_template = new $compiler->smarty->template_class($include_file, $compiler->smarty, $compiler->template);
// save file dependency
if (isset($_is_stringy[$_template->source->type])) {
$template_sha1 = sha1($include_file);
} else {
$template_sha1 = sha1($_template->source->filepath);
}
if (isset($compiler->template->properties['file_dependency'][$template_sha1])) {
$compiler->trigger_template_error("illegal recursive call of \"{$include_file}\"", $compiler->lex->line - 1);
}
$compiler->template->properties['file_dependency'][$template_sha1] = array($_template->source->filepath, $_template->source->timestamp, $_template->source->type);
$_content = substr($compiler->template->source->content, $compiler->lex->counter - 1);
if (preg_match_all("!({$this->_ldl}block\s(.+?){$this->_rdl})!", $_content, $s) !=
preg_match_all("!({$this->_ldl}/block{$this->_rdl})!", $_content, $c)) {
$compiler->trigger_template_error('unmatched {block} {/block} pairs');
}
preg_match_all("!{$this->_ldl}block\s(.+?){$this->_rdl}|{$this->_ldl}/block{$this->_rdl}|{$this->_ldl}\*([\S\s]*?)\*{$this->_rdl}!", $_content, $_result, PREG_OFFSET_CAPTURE);
$_result_count = count($_result[0]);
$_start = 0;
while ($_start+1 < $_result_count) {
$_end = 0;
$_level = 1;
if (substr($_result[0][$_start][0],0,strlen($compiler->smarty->left_delimiter)+1) == $compiler->smarty->left_delimiter.'*') {
$_start++;
continue;
}
while ($_level != 0) {
$_end++;
if (substr($_result[0][$_start + $_end][0],0,strlen($compiler->smarty->left_delimiter)+1) == $compiler->smarty->left_delimiter.'*') {
continue;
}
if (!strpos($_result[0][$_start + $_end][0], '/')) {
$_level++;
} else {
$_level--;
}
}
$_block_content = str_replace($compiler->smarty->left_delimiter . '$smarty.block.parent' . $compiler->smarty->right_delimiter, '%%%%SMARTY_PARENT%%%%',
substr($_content, $_result[0][$_start][1] + strlen($_result[0][$_start][0]), $_result[0][$_start + $_end][1] - $_result[0][$_start][1] - + strlen($_result[0][$_start][0])));
Smarty_Internal_Compile_Block::saveBlockData($_block_content, $_result[0][$_start][0], $compiler->template, $filepath);
$_start = $_start + $_end + 1;
}
if ($_template->source->type == 'extends') {
$_template->block_data = $compiler->template->block_data;
}
$compiler->template->source->content = $_template->source->content;
if ($_template->source->type == 'extends') {
$compiler->template->block_data = $_template->block_data;
foreach ($_template->source->components as $key => $component) {
$compiler->template->properties['file_dependency'][$key] = array($component->filepath, $component->timestamp, $component->type);
}
}
$compiler->template->source->filepath = $_template->source->filepath;
$compiler->abort_and_recompile = true;
return '';
}
}
?>

View File

@@ -0,0 +1,151 @@
<?php
/**
* Smarty Internal Plugin Compile For
*
* Compiles the {for} {forelse} {/for} tags
*
* @package Smarty
* @subpackage Compiler
* @author Uwe Tews
*/
/**
* Smarty Internal Plugin Compile For Class
*
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_For extends Smarty_Internal_CompileBase {
/**
* Compiles code for the {for} tag
*
* Smarty 3 does implement two different sytaxes:
*
* - {for $var in $array}
* For looping over arrays or iterators
*
* - {for $x=0; $x<$y; $x++}
* For general loops
*
* The parser is gereration different sets of attribute by which this compiler can
* determin which syntax is used.
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $parameter array with compilation parameter
* @return string compiled code
*/
public function compile($args, $compiler, $parameter)
{
if ($parameter == 0) {
$this->required_attributes = array('start', 'to');
$this->optional_attributes = array('max', 'step');
} else {
$this->required_attributes = array('start', 'ifexp', 'var', 'step');
$this->optional_attributes = array();
}
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
$output = "<?php ";
if ($parameter == 1) {
foreach ($_attr['start'] as $_statement) {
$output .= " \$_smarty_tpl->tpl_vars[$_statement[var]] = new Smarty_Variable;";
$output .= " \$_smarty_tpl->tpl_vars[$_statement[var]]->value = $_statement[value];\n";
}
$output .= " if ($_attr[ifexp]){ for (\$_foo=true;$_attr[ifexp]; \$_smarty_tpl->tpl_vars[$_attr[var]]->value$_attr[step]){\n";
} else {
$_statement = $_attr['start'];
$output .= "\$_smarty_tpl->tpl_vars[$_statement[var]] = new Smarty_Variable;";
if (isset($_attr['step'])) {
$output .= "\$_smarty_tpl->tpl_vars[$_statement[var]]->step = $_attr[step];";
} else {
$output .= "\$_smarty_tpl->tpl_vars[$_statement[var]]->step = 1;";
}
if (isset($_attr['max'])) {
$output .= "\$_smarty_tpl->tpl_vars[$_statement[var]]->total = (int)min(ceil((\$_smarty_tpl->tpl_vars[$_statement[var]]->step > 0 ? $_attr[to]+1 - ($_statement[value]) : $_statement[value]-($_attr[to])+1)/abs(\$_smarty_tpl->tpl_vars[$_statement[var]]->step)),$_attr[max]);\n";
} else {
$output .= "\$_smarty_tpl->tpl_vars[$_statement[var]]->total = (int)ceil((\$_smarty_tpl->tpl_vars[$_statement[var]]->step > 0 ? $_attr[to]+1 - ($_statement[value]) : $_statement[value]-($_attr[to])+1)/abs(\$_smarty_tpl->tpl_vars[$_statement[var]]->step));\n";
}
$output .= "if (\$_smarty_tpl->tpl_vars[$_statement[var]]->total > 0){\n";
$output .= "for (\$_smarty_tpl->tpl_vars[$_statement[var]]->value = $_statement[value], \$_smarty_tpl->tpl_vars[$_statement[var]]->iteration = 1;\$_smarty_tpl->tpl_vars[$_statement[var]]->iteration <= \$_smarty_tpl->tpl_vars[$_statement[var]]->total;\$_smarty_tpl->tpl_vars[$_statement[var]]->value += \$_smarty_tpl->tpl_vars[$_statement[var]]->step, \$_smarty_tpl->tpl_vars[$_statement[var]]->iteration++){\n";
$output .= "\$_smarty_tpl->tpl_vars[$_statement[var]]->first = \$_smarty_tpl->tpl_vars[$_statement[var]]->iteration == 1;";
$output .= "\$_smarty_tpl->tpl_vars[$_statement[var]]->last = \$_smarty_tpl->tpl_vars[$_statement[var]]->iteration == \$_smarty_tpl->tpl_vars[$_statement[var]]->total;";
}
$output .= "?>";
$this->openTag($compiler, 'for', array('for', $compiler->nocache));
// maybe nocache because of nocache variables
$compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
// return compiled code
return $output;
}
}
/**
* Smarty Internal Plugin Compile Forelse Class
*
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Forelse extends Smarty_Internal_CompileBase {
/**
* Compiles code for the {forelse} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $parameter array with compilation parameter
* @return string compiled code
*/
public function compile($args, $compiler, $parameter)
{
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
list($openTag, $nocache) = $this->closeTag($compiler, array('for'));
$this->openTag($compiler, 'forelse', array('forelse', $nocache));
return "<?php }} else { ?>";
}
}
/**
* Smarty Internal Plugin Compile Forclose Class
*
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Forclose extends Smarty_Internal_CompileBase {
/**
* Compiles code for the {/for} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $parameter array with compilation parameter
* @return string compiled code
*/
public function compile($args, $compiler, $parameter)
{
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
// must endblock be nocache?
if ($compiler->nocache) {
$compiler->tag_nocache = true;
}
list($openTag, $compiler->nocache) = $this->closeTag($compiler, array('for', 'forelse'));
if ($openTag == 'forelse') {
return "<?php } ?>";
} else {
return "<?php }} ?>";
}
}
}
?>

View File

@@ -0,0 +1,231 @@
<?php
/**
* Smarty Internal Plugin Compile Foreach
*
* Compiles the {foreach} {foreachelse} {/foreach} tags
*
* @package Smarty
* @subpackage Compiler
* @author Uwe Tews
*/
/**
* Smarty Internal Plugin Compile Foreach Class
*
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Foreach extends Smarty_Internal_CompileBase {
/**
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
public $required_attributes = array('from', 'item');
/**
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
public $optional_attributes = array('name', 'key');
/**
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
public $shorttag_order = array('from','item','key','name');
/**
* Compiles code for the {foreach} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $parameter array with compilation parameter
* @return string compiled code
*/
public function compile($args, $compiler, $parameter)
{
$tpl = $compiler->template;
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
$from = $_attr['from'];
$item = $_attr['item'];
if (!strncmp("\$_smarty_tpl->tpl_vars[$item]", $from, strlen($item) + 24)) {
$compiler->trigger_template_error("item variable {$item} may not be the same variable as at 'from'", $compiler->lex->taglineno);
}
if (isset($_attr['key'])) {
$key = $_attr['key'];
} else {
$key = null;
}
$this->openTag($compiler, 'foreach', array('foreach', $compiler->nocache, $item, $key));
// maybe nocache because of nocache variables
$compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
if (isset($_attr['name'])) {
$name = $_attr['name'];
$has_name = true;
$SmartyVarName = '$smarty.foreach.' . trim($name, '\'"') . '.';
} else {
$name = null;
$has_name = false;
}
$ItemVarName = '$' . trim($item, '\'"') . '@';
// evaluates which Smarty variables and properties have to be computed
if ($has_name) {
$usesSmartyFirst = strpos($tpl->source->content, $SmartyVarName . 'first') !== false;
$usesSmartyLast = strpos($tpl->source->content, $SmartyVarName . 'last') !== false;
$usesSmartyIndex = strpos($tpl->source->content, $SmartyVarName . 'index') !== false;
$usesSmartyIteration = strpos($tpl->source->content, $SmartyVarName . 'iteration') !== false;
$usesSmartyShow = strpos($tpl->source->content, $SmartyVarName . 'show') !== false;
$usesSmartyTotal = strpos($tpl->source->content, $SmartyVarName . 'total') !== false;
} else {
$usesSmartyFirst = false;
$usesSmartyLast = false;
$usesSmartyTotal = false;
$usesSmartyShow = false;
}
$usesPropFirst = $usesSmartyFirst || strpos($tpl->source->content, $ItemVarName . 'first') !== false;
$usesPropLast = $usesSmartyLast || strpos($tpl->source->content, $ItemVarName . 'last') !== false;
$usesPropIndex = $usesPropFirst || strpos($tpl->source->content, $ItemVarName . 'index') !== false;
$usesPropIteration = $usesPropLast || strpos($tpl->source->content, $ItemVarName . 'iteration') !== false;
$usesPropShow = strpos($tpl->source->content, $ItemVarName . 'show') !== false;
$usesPropTotal = $usesSmartyTotal || $usesSmartyShow || $usesPropShow || $usesPropLast || strpos($tpl->source->content, $ItemVarName . 'total') !== false;
// generate output code
$output = "<?php ";
$output .= " \$_smarty_tpl->tpl_vars[$item] = new Smarty_Variable; \$_smarty_tpl->tpl_vars[$item]->_loop = false;\n";
if ($key != null) {
$output .= " \$_smarty_tpl->tpl_vars[$key] = new Smarty_Variable;\n";
}
$output .= " \$_from = $from; if (!is_array(\$_from) && !is_object(\$_from)) { settype(\$_from, 'array');}\n";
if ($usesPropTotal) {
$output .= " \$_smarty_tpl->tpl_vars[$item]->total= \$_smarty_tpl->_count(\$_from);\n";
}
if ($usesPropIteration) {
$output .= " \$_smarty_tpl->tpl_vars[$item]->iteration=0;\n";
}
if ($usesPropIndex) {
$output .= " \$_smarty_tpl->tpl_vars[$item]->index=-1;\n";
}
if ($usesPropShow) {
$output .= " \$_smarty_tpl->tpl_vars[$item]->show = (\$_smarty_tpl->tpl_vars[$item]->total > 0);\n";
}
if ($has_name) {
if ($usesSmartyTotal) {
$output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['total'] = \$_smarty_tpl->tpl_vars[$item]->total;\n";
}
if ($usesSmartyIteration) {
$output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['iteration']=0;\n";
}
if ($usesSmartyIndex) {
$output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['index']=-1;\n";
}
if ($usesSmartyShow) {
$output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['show']=(\$_smarty_tpl->tpl_vars[$item]->total > 0);\n";
}
}
$output .= "foreach (\$_from as \$_smarty_tpl->tpl_vars[$item]->key => \$_smarty_tpl->tpl_vars[$item]->value){\n\$_smarty_tpl->tpl_vars[$item]->_loop = true;\n";
if ($key != null) {
$output .= " \$_smarty_tpl->tpl_vars[$key]->value = \$_smarty_tpl->tpl_vars[$item]->key;\n";
}
if ($usesPropIteration) {
$output .= " \$_smarty_tpl->tpl_vars[$item]->iteration++;\n";
}
if ($usesPropIndex) {
$output .= " \$_smarty_tpl->tpl_vars[$item]->index++;\n";
}
if ($usesPropFirst) {
$output .= " \$_smarty_tpl->tpl_vars[$item]->first = \$_smarty_tpl->tpl_vars[$item]->index === 0;\n";
}
if ($usesPropLast) {
$output .= " \$_smarty_tpl->tpl_vars[$item]->last = \$_smarty_tpl->tpl_vars[$item]->iteration === \$_smarty_tpl->tpl_vars[$item]->total;\n";
}
if ($has_name) {
if ($usesSmartyFirst) {
$output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['first'] = \$_smarty_tpl->tpl_vars[$item]->first;\n";
}
if ($usesSmartyIteration) {
$output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['iteration']++;\n";
}
if ($usesSmartyIndex) {
$output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['index']++;\n";
}
if ($usesSmartyLast) {
$output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['last'] = \$_smarty_tpl->tpl_vars[$item]->last;\n";
}
}
$output .= "?>";
return $output;
}
}
/**
* Smarty Internal Plugin Compile Foreachelse Class
*
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Foreachelse extends Smarty_Internal_CompileBase {
/**
* Compiles code for the {foreachelse} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $parameter array with compilation parameter
* @return string compiled code
*/
public function compile($args, $compiler, $parameter)
{
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
list($openTag, $nocache, $item, $key) = $this->closeTag($compiler, array('foreach'));
$this->openTag($compiler, 'foreachelse', array('foreachelse', $nocache, $item, $key));
return "<?php }\nif (!\$_smarty_tpl->tpl_vars[$item]->_loop) {\n?>";
}
}
/**
* Smarty Internal Plugin Compile Foreachclose Class
*
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Foreachclose extends Smarty_Internal_CompileBase {
/**
* Compiles code for the {/foreach} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $parameter array with compilation parameter
* @return string compiled code
*/
public function compile($args, $compiler, $parameter)
{
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
// must endblock be nocache?
if ($compiler->nocache) {
$compiler->tag_nocache = true;
}
list($openTag, $compiler->nocache, $item, $key) = $this->closeTag($compiler, array('foreach', 'foreachelse'));
return "<?php } ?>";
}
}
?>

View File

@@ -0,0 +1,165 @@
<?php
/**
* Smarty Internal Plugin Compile Function
*
* Compiles the {function} {/function} tags
*
* @package Smarty
* @subpackage Compiler
* @author Uwe Tews
*/
/**
* Smarty Internal Plugin Compile Function Class
*
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Function extends Smarty_Internal_CompileBase {
/**
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
public $required_attributes = array('name');
/**
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
public $shorttag_order = array('name');
/**
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
public $optional_attributes = array('_any');
/**
* Compiles code for the {function} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $parameter array with compilation parameter
* @return boolean true
*/
public function compile($args, $compiler, $parameter)
{
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
if ($_attr['nocache'] === true) {
$compiler->trigger_template_error('nocache option not allowed', $compiler->lex->taglineno);
}
unset($_attr['nocache']);
$save = array($_attr, $compiler->parser->current_buffer,
$compiler->template->has_nocache_code, $compiler->template->required_plugins);
$this->openTag($compiler, 'function', $save);
$_name = trim($_attr['name'], "'\"");
unset($_attr['name']);
// set flag that we are compiling a template function
$compiler->compiles_template_function = true;
$compiler->template->properties['function'][$_name]['parameter'] = array();
$_smarty_tpl = $compiler->template;
foreach ($_attr as $_key => $_data) {
eval ('$tmp='.$_data.';');
$compiler->template->properties['function'][$_name]['parameter'][$_key] = $tmp;
}
$compiler->smarty->template_functions[$_name]['parameter'] = $compiler->template->properties['function'][$_name]['parameter'];
if ($compiler->template->caching) {
$output = '';
} else {
$output = "<?php if (!function_exists('smarty_template_function_{$_name}')) {
function smarty_template_function_{$_name}(\$_smarty_tpl,\$params) {
\$saved_tpl_vars = \$_smarty_tpl->tpl_vars;
foreach (\$_smarty_tpl->smarty->template_functions['{$_name}']['parameter'] as \$key => \$value) {\$_smarty_tpl->tpl_vars[\$key] = new Smarty_variable(\$value);};
foreach (\$params as \$key => \$value) {\$_smarty_tpl->tpl_vars[\$key] = new Smarty_variable(\$value);}?>";
}
// Init temporay context
$compiler->template->required_plugins = array('compiled' => array(), 'nocache' => array());
$compiler->parser->current_buffer = new _smarty_template_buffer($compiler->parser);
$compiler->parser->current_buffer->append_subtree(new _smarty_tag($compiler->parser, $output));
$compiler->template->has_nocache_code = false;
$compiler->has_code = false;
$compiler->template->properties['function'][$_name]['compiled'] = '';
return true;
}
}
/**
* Smarty Internal Plugin Compile Functionclose Class
*
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Functionclose extends Smarty_Internal_CompileBase {
/**
* Compiles code for the {/function} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $parameter array with compilation parameter
* @return boolean true
*/
public function compile($args, $compiler, $parameter)
{
$_attr = $this->getAttributes($compiler, $args);
$saved_data = $this->closeTag($compiler, array('function'));
$_name = trim($saved_data[0]['name'], "'\"");
// build plugin include code
$plugins_string = '';
if (!empty($compiler->template->required_plugins['compiled'])) {
$plugins_string = '<?php ';
foreach($compiler->template->required_plugins['compiled'] as $tmp) {
foreach($tmp as $data) {
$plugins_string .= "if (!is_callable('{$data['function']}')) include '{$data['file']}';\n";
}
}
$plugins_string .= '?>';
}
if (!empty($compiler->template->required_plugins['nocache'])) {
$plugins_string .= "<?php echo '/*%%SmartyNocache:{$compiler->template->properties['nocache_hash']}%%*/<?php ";
foreach($compiler->template->required_plugins['nocache'] as $tmp) {
foreach($tmp as $data) {
$plugins_string .= "if (!is_callable(\'{$data['function']}\')) include \'{$data['file']}\';\n";
}
}
$plugins_string .= "?>/*/%%SmartyNocache:{$compiler->template->properties['nocache_hash']}%%*/';?>\n";
}
// remove last line break from function definition
$last = count($compiler->parser->current_buffer->subtrees) - 1;
if ($compiler->parser->current_buffer->subtrees[$last] instanceof _smarty_linebreak) {
unset($compiler->parser->current_buffer->subtrees[$last]);
}
// if caching save template function for possible nocache call
if ($compiler->template->caching) {
$compiler->template->properties['function'][$_name]['compiled'] .= $plugins_string
. $compiler->parser->current_buffer->to_smarty_php();
$compiler->template->properties['function'][$_name]['nocache_hash'] = $compiler->template->properties['nocache_hash'];
$compiler->template->properties['function'][$_name]['has_nocache_code'] = $compiler->template->has_nocache_code;
$compiler->template->properties['function'][$_name]['called_functions'] = $compiler->called_functions;
$compiler->called_functions = array();
$compiler->smarty->template_functions[$_name] = $compiler->template->properties['function'][$_name];
$compiler->has_code = false;
$output = true;
} else {
$output = $plugins_string . $compiler->parser->current_buffer->to_smarty_php() . "<?php \$_smarty_tpl->tpl_vars = \$saved_tpl_vars;}}?>\n";
}
// reset flag that we are compiling a template function
$compiler->compiles_template_function = false;
// restore old compiler status
$compiler->parser->current_buffer = $saved_data[1];
$compiler->template->has_nocache_code = $compiler->template->has_nocache_code | $saved_data[2];
$compiler->template->required_plugins = $saved_data[3];
return $output;
}
}
?>

View File

@@ -0,0 +1,207 @@
<?php
/**
* Smarty Internal Plugin Compile If
*
* Compiles the {if} {else} {elseif} {/if} tags
*
* @package Smarty
* @subpackage Compiler
* @author Uwe Tews
*/
/**
* Smarty Internal Plugin Compile If Class
*
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_If extends Smarty_Internal_CompileBase {
/**
* Compiles code for the {if} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $parameter array with compilation parameter
* @return string compiled code
*/
public function compile($args, $compiler, $parameter)
{
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
$this->openTag($compiler, 'if', array(1, $compiler->nocache));
// must whole block be nocache ?
$compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
if (!array_key_exists("if condition",$parameter)) {
$compiler->trigger_template_error("missing if condition", $compiler->lex->taglineno);
}
if (is_array($parameter['if condition'])) {
if ($compiler->nocache) {
$_nocache = ',true';
// create nocache var to make it know for further compiling
if (is_array($parameter['if condition']['var'])) {
$compiler->template->tpl_vars[trim($parameter['if condition']['var']['var'], "'")] = new Smarty_variable(null, true);
} else {
$compiler->template->tpl_vars[trim($parameter['if condition']['var'], "'")] = new Smarty_variable(null, true);
}
} else {
$_nocache = '';
}
if (is_array($parameter['if condition']['var'])) {
$_output = "<?php if (!isset(\$_smarty_tpl->tpl_vars[".$parameter['if condition']['var']['var']."]) || !is_array(\$_smarty_tpl->tpl_vars[".$parameter['if condition']['var']['var']."]->value)) \$_smarty_tpl->createLocalArrayVariable(".$parameter['if condition']['var']['var']."$_nocache);\n";
$_output .= "if (\$_smarty_tpl->tpl_vars[".$parameter['if condition']['var']['var']."]->value".$parameter['if condition']['var']['smarty_internal_index']." = ".$parameter['if condition']['value']."){?>";
} else {
$_output = "<?php if (!isset(\$_smarty_tpl->tpl_vars[".$parameter['if condition']['var']."])) \$_smarty_tpl->tpl_vars[".$parameter['if condition']['var']."] = new Smarty_Variable(null{$_nocache});";
$_output .= "if (\$_smarty_tpl->tpl_vars[".$parameter['if condition']['var']."]->value = ".$parameter['if condition']['value']."){?>";
}
return $_output;
} else {
return "<?php if ({$parameter['if condition']}){?>";
}
}
}
/**
* Smarty Internal Plugin Compile Else Class
*
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Else extends Smarty_Internal_CompileBase {
/**
* Compiles code for the {else} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $parameter array with compilation parameter
* @return string compiled code
*/
public function compile($args, $compiler, $parameter)
{
list($nesting, $compiler->tag_nocache) = $this->closeTag($compiler, array('if', 'elseif'));
$this->openTag($compiler, 'else', array($nesting, $compiler->tag_nocache));
return "<?php }else{ ?>";
}
}
/**
* Smarty Internal Plugin Compile ElseIf Class
*
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Elseif extends Smarty_Internal_CompileBase {
/**
* Compiles code for the {elseif} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $parameter array with compilation parameter
* @return string compiled code
*/
public function compile($args, $compiler, $parameter)
{
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
list($nesting, $compiler->tag_nocache) = $this->closeTag($compiler, array('if', 'elseif'));
if (!array_key_exists("if condition",$parameter)) {
$compiler->trigger_template_error("missing elseif condition", $compiler->lex->taglineno);
}
if (is_array($parameter['if condition'])) {
$condition_by_assign = true;
if ($compiler->nocache) {
$_nocache = ',true';
// create nocache var to make it know for further compiling
if (is_array($parameter['if condition']['var'])) {
$compiler->template->tpl_vars[trim($parameter['if condition']['var']['var'], "'")] = new Smarty_variable(null, true);
} else {
$compiler->template->tpl_vars[trim($parameter['if condition']['var'], "'")] = new Smarty_variable(null, true);
}
} else {
$_nocache = '';
}
} else {
$condition_by_assign = false;
}
if (empty($compiler->prefix_code)) {
if ($condition_by_assign) {
$this->openTag($compiler, 'elseif', array($nesting + 1, $compiler->tag_nocache));
if (is_array($parameter['if condition']['var'])) {
$_output = "<?php }else{ if (!isset(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]) || !is_array(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]->value)) \$_smarty_tpl->createLocalArrayVariable(" . $parameter['if condition']['var']['var'] . "$_nocache);\n";
$_output .= "if (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]->value" . $parameter['if condition']['var']['smarty_internal_index'] . " = " . $parameter['if condition']['value'] . "){?>";
} else {
$_output = "<?php }else{ if (!isset(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "])) \$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "] = new Smarty_Variable(null{$_nocache});";
$_output .= "if (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "]->value = " . $parameter['if condition']['value'] . "){?>";
}
return $_output;
} else {
$this->openTag($compiler, 'elseif', array($nesting, $compiler->tag_nocache));
return "<?php }elseif({$parameter['if condition']}){?>";
}
} else {
$tmp = '';
foreach ($compiler->prefix_code as $code)
$tmp .= $code;
$compiler->prefix_code = array();
$this->openTag($compiler, 'elseif', array($nesting + 1, $compiler->tag_nocache));
if ($condition_by_assign) {
if (is_array($parameter['if condition']['var'])) {
$_output = "<?php }else{?>{$tmp}<?php if (!isset(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]) || !is_array(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]->value)) \$_smarty_tpl->createLocalArrayVariable(" . $parameter['if condition']['var']['var'] . "$_nocache);\n";
$_output .= "if (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]->value" . $parameter['if condition']['var']['smarty_internal_index'] . " = " . $parameter['if condition']['value'] . "){?>";
} else {
$_output = "<?php }else{?>{$tmp}<?php if (!isset(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "])) \$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "] = new Smarty_Variable(null{$_nocache});";
$_output .= "if (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "]->value = " . $parameter['if condition']['value'] . "){?>";
}
return $_output;
} else {
return "<?php }else{?>{$tmp}<?php if ({$parameter['if condition']}){?>";
}
}
}
}
/**
* Smarty Internal Plugin Compile Ifclose Class
*
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Ifclose extends Smarty_Internal_CompileBase {
/**
* Compiles code for the {/if} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $parameter array with compilation parameter
* @return string compiled code
*/
public function compile($args, $compiler, $parameter)
{
// must endblock be nocache?
if ($compiler->nocache) {
$compiler->tag_nocache = true;
}
list($nesting, $compiler->nocache) = $this->closeTag($compiler, array('if', 'else', 'elseif'));
$tmp = '';
for ($i = 0; $i < $nesting; $i++) {
$tmp .= '}';
}
return "<?php {$tmp}?>";
}
}
?>

View File

@@ -0,0 +1,215 @@
<?php
/**
* Smarty Internal Plugin Compile Include
*
* Compiles the {include} tag
*
* @package Smarty
* @subpackage Compiler
* @author Uwe Tews
*/
/**
* Smarty Internal Plugin Compile Include Class
*
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase {
/**
* caching mode to create nocache code but no cache file
*/
const CACHING_NOCACHE_CODE = 9999;
/**
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
public $required_attributes = array('file');
/**
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
public $shorttag_order = array('file');
/**
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
public $option_flags = array('nocache', 'inline', 'caching');
/**
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
public $optional_attributes = array('_any');
/**
* Compiles code for the {include} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $parameter array with compilation parameter
* @return string compiled code
*/
public function compile($args, $compiler, $parameter)
{
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
// save posible attributes
$include_file = $_attr['file'];
if (isset($_attr['assign'])) {
// output will be stored in a smarty variable instead of beind displayed
$_assign = $_attr['assign'];
}
$_parent_scope = Smarty::SCOPE_LOCAL;
if (isset($_attr['scope'])) {
$_attr['scope'] = trim($_attr['scope'], "'\"");
if ($_attr['scope'] == 'parent') {
$_parent_scope = Smarty::SCOPE_PARENT;
} elseif ($_attr['scope'] == 'root') {
$_parent_scope = Smarty::SCOPE_ROOT;
} elseif ($_attr['scope'] == 'global') {
$_parent_scope = Smarty::SCOPE_GLOBAL;
}
}
$_caching = 'null';
if ($compiler->nocache || $compiler->tag_nocache) {
$_caching = Smarty::CACHING_OFF;
}
// default for included templates
if ($compiler->template->caching && !$compiler->nocache && !$compiler->tag_nocache) {
$_caching = self::CACHING_NOCACHE_CODE;
}
/*
* if the {include} tag provides individual parameter for caching
* it will not be included into the common cache file and treated like
* a nocache section
*/
if (isset($_attr['cache_lifetime'])) {
$_cache_lifetime = $_attr['cache_lifetime'];
$compiler->tag_nocache = true;
$_caching = Smarty::CACHING_LIFETIME_CURRENT;
} else {
$_cache_lifetime = 'null';
}
if (isset($_attr['cache_id'])) {
$_cache_id = $_attr['cache_id'];
$compiler->tag_nocache = true;
$_caching = Smarty::CACHING_LIFETIME_CURRENT;
} else {
$_cache_id = '$_smarty_tpl->cache_id';
}
if (isset($_attr['compile_id'])) {
$_compile_id = $_attr['compile_id'];
} else {
$_compile_id = '$_smarty_tpl->compile_id';
}
if ($_attr['caching'] === true) {
$_caching = Smarty::CACHING_LIFETIME_CURRENT;
}
if ($_attr['nocache'] === true) {
$compiler->tag_nocache = true;
$_caching = Smarty::CACHING_OFF;
}
$has_compiled_template = false;
if (($compiler->smarty->merge_compiled_includes || $_attr['inline'] === true) && !$compiler->template->source->recompiled
&& !($compiler->template->caching && ($compiler->tag_nocache || $compiler->nocache)) && $_caching != Smarty::CACHING_LIFETIME_CURRENT) {
// check if compiled code can be merged (contains no variable part)
if (!$compiler->has_variable_string && (substr_count($include_file, '"') == 2 or substr_count($include_file, "'") == 2)
and substr_count($include_file, '(') == 0 and substr_count($include_file, '$_smarty_tpl->') == 0) {
$tpl_name = null;
eval("\$tpl_name = $include_file;");
if (!isset($compiler->smarty->merged_templates_func[$tpl_name]) || $compiler->inheritance) {
$tpl = new $compiler->smarty->template_class ($tpl_name, $compiler->smarty, $compiler->template, $compiler->template->cache_id, $compiler->template->compile_id);
// save unique function name
$compiler->smarty->merged_templates_func[$tpl_name]['func'] = $tpl->properties['unifunc'] = 'content_'.uniqid('', false);
// use current nocache hash for inlined code
$compiler->smarty->merged_templates_func[$tpl_name]['nocache_hash'] = $tpl->properties['nocache_hash'] = $compiler->template->properties['nocache_hash'];
if ($compiler->template->caching) {
// needs code for cached page but no cache file
$tpl->caching = self::CACHING_NOCACHE_CODE;
}
// make sure whole chain gest compiled
$tpl->mustCompile = true;
if (!($tpl->source->uncompiled) && $tpl->source->exists) {
// get compiled code
$compiled_code = $tpl->compiler->compileTemplate($tpl);
// release compiler object to free memory
unset($tpl->compiler);
// merge compiled code for {function} tags
$compiler->template->properties['function'] = array_merge($compiler->template->properties['function'], $tpl->properties['function']);
// merge filedependency
$tpl->properties['file_dependency'][$tpl->source->uid] = array($tpl->source->filepath, $tpl->source->timestamp,$tpl->source->type);
$compiler->template->properties['file_dependency'] = array_merge($compiler->template->properties['file_dependency'], $tpl->properties['file_dependency']);
// remove header code
$compiled_code = preg_replace("/(<\?php \/\*%%SmartyHeaderCode:{$tpl->properties['nocache_hash']}%%\*\/(.+?)\/\*\/%%SmartyHeaderCode%%\*\/\?>\n)/s", '', $compiled_code);
if ($tpl->has_nocache_code) {
// replace nocache_hash
$compiled_code = preg_replace("/{$tpl->properties['nocache_hash']}/", $compiler->template->properties['nocache_hash'], $compiled_code);
$compiler->template->has_nocache_code = true;
}
$compiler->merged_templates[$tpl->properties['unifunc']] = $compiled_code;
$has_compiled_template = true;
}
} else {
$has_compiled_template = true;
}
}
}
// delete {include} standard attributes
unset($_attr['file'], $_attr['assign'], $_attr['cache_id'], $_attr['compile_id'], $_attr['cache_lifetime'], $_attr['nocache'], $_attr['caching'], $_attr['scope'], $_attr['inline']);
// remaining attributes must be assigned as smarty variable
if (!empty($_attr)) {
if ($_parent_scope == Smarty::SCOPE_LOCAL) {
// create variables
foreach ($_attr as $key => $value) {
$_pairs[] = "'$key'=>$value";
}
$_vars = 'array('.join(',',$_pairs).')';
$_has_vars = true;
} else {
$compiler->trigger_template_error('variable passing not allowed in parent/global scope', $compiler->lex->taglineno);
}
} else {
$_vars = 'array()';
$_has_vars = false;
}
if ($has_compiled_template) {
$_hash = $compiler->smarty->merged_templates_func[$tpl_name]['nocache_hash'];
$_output = "<?php /* Call merged included template \"" . $tpl_name . "\" */\n";
$_output .= "\$_tpl_stack[] = \$_smarty_tpl;\n";
$_output .= " \$_smarty_tpl = \$_smarty_tpl->setupInlineSubTemplate($include_file, $_cache_id, $_compile_id, $_caching, $_cache_lifetime, $_vars, $_parent_scope, '$_hash');\n";
if (isset($_assign)) {
$_output .= 'ob_start(); ';
}
$_output .= $compiler->smarty->merged_templates_func[$tpl_name]['func']. "(\$_smarty_tpl);\n";
$_output .= "\$_smarty_tpl = array_pop(\$_tpl_stack); ";
if (isset($_assign)) {
$_output .= " \$_smarty_tpl->tpl_vars[$_assign] = new Smarty_variable(ob_get_clean());";
}
$_output .= "/* End of included template \"" . $tpl_name . "\" */?>";
return $_output;
}
// was there an assign attribute
if (isset($_assign)) {
$_output = "<?php \$_smarty_tpl->tpl_vars[$_assign] = new Smarty_variable(\$_smarty_tpl->getSubTemplate ($include_file, $_cache_id, $_compile_id, $_caching, $_cache_lifetime, $_vars, $_parent_scope));?>\n";;
} else {
$_output = "<?php echo \$_smarty_tpl->getSubTemplate ($include_file, $_cache_id, $_compile_id, $_caching, $_cache_lifetime, $_vars, $_parent_scope);?>\n";
}
return $_output;
}
}
?>

View File

@@ -0,0 +1,108 @@
<?php
/**
* Smarty Internal Plugin Compile Include PHP
*
* Compiles the {include_php} tag
*
* @package Smarty
* @subpackage Compiler
* @author Uwe Tews
*/
/**
* Smarty Internal Plugin Compile Insert Class
*
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Include_Php extends Smarty_Internal_CompileBase {
/**
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
public $required_attributes = array('file');
/**
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
public $shorttag_order = array('file');
/**
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
public $optional_attributes = array('once', 'assign');
/**
* Compiles code for the {include_php} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @return string compiled code
*/
public function compile($args, $compiler)
{
if (!($compiler->smarty instanceof SmartyBC)) {
throw new SmartyException("{include_php} is deprecated, use SmartyBC class to enable");
}
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
$_output = '<?php ';
$_smarty_tpl = $compiler->template;
$_filepath = false;
eval('$_file = ' . $_attr['file'] . ';');
if (!isset($compiler->smarty->security_policy) && file_exists($_file)) {
$_filepath = $_file;
} else {
if (isset($compiler->smarty->security_policy)) {
$_dir = $compiler->smarty->security_policy->trusted_dir;
} else {
$_dir = $compiler->smarty->trusted_dir;
}
if (!empty($_dir)) {
foreach((array)$_dir as $_script_dir) {
$_script_dir = rtrim($_script_dir, '/\\') . DS;
if (file_exists($_script_dir . $_file)) {
$_filepath = $_script_dir . $_file;
break;
}
}
}
}
if ($_filepath == false) {
$compiler->trigger_template_error("{include_php} file '{$_file}' is not readable", $compiler->lex->taglineno);
}
if (isset($compiler->smarty->security_policy)) {
$compiler->smarty->security_policy->isTrustedPHPDir($_filepath);
}
if (isset($_attr['assign'])) {
// output will be stored in a smarty variable instead of being displayed
$_assign = $_attr['assign'];
}
$_once = '_once';
if (isset($_attr['once'])) {
if ($_attr['once'] == 'false') {
$_once = '';
}
}
if (isset($_assign)) {
return "<?php ob_start(); include{$_once} ('{$_filepath}'); \$_smarty_tpl->assign({$_assign},ob_get_contents()); ob_end_clean();?>";
} else {
return "<?php include{$_once} ('{$_filepath}');?>\n";
}
}
}
?>

View File

@@ -0,0 +1,142 @@
<?php
/**
* Smarty Internal Plugin Compile Insert
*
* Compiles the {insert} tag
*
* @package Smarty
* @subpackage Compiler
* @author Uwe Tews
*/
/**
* Smarty Internal Plugin Compile Insert Class
*
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Insert extends Smarty_Internal_CompileBase {
/**
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
public $required_attributes = array('name');
/**
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
public $shorttag_order = array('name');
/**
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
public $optional_attributes = array('_any');
/**
* Compiles code for the {insert} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @return string compiled code
*/
public function compile($args, $compiler)
{
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
// never compile as nocache code
$compiler->suppressNocacheProcessing = true;
$compiler->tag_nocache = true;
$_smarty_tpl = $compiler->template;
$_name = null;
$_script = null;
$_output = '<?php ';
// save posible attributes
eval('$_name = ' . $_attr['name'] . ';');
if (isset($_attr['assign'])) {
// output will be stored in a smarty variable instead of being displayed
$_assign = $_attr['assign'];
// create variable to make shure that the compiler knows about its nocache status
$compiler->template->tpl_vars[trim($_attr['assign'], "'")] = new Smarty_Variable(null, true);
}
if (isset($_attr['script'])) {
// script which must be included
$_function = "smarty_insert_{$_name}";
$_smarty_tpl = $compiler->template;
$_filepath = false;
eval('$_script = ' . $_attr['script'] . ';');
if (!isset($compiler->smarty->security_policy) && file_exists($_script)) {
$_filepath = $_script;
} else {
if (isset($compiler->smarty->security_policy)) {
$_dir = $compiler->smarty->security_policy->trusted_dir;
} else {
$_dir = $compiler->smarty->trusted_dir;
}
if (!empty($_dir)) {
foreach((array)$_dir as $_script_dir) {
$_script_dir = rtrim($_script_dir, '/\\') . DS;
if (file_exists($_script_dir . $_script)) {
$_filepath = $_script_dir . $_script;
break;
}
}
}
}
if ($_filepath == false) {
$compiler->trigger_template_error("{insert} missing script file '{$_script}'", $compiler->lex->taglineno);
}
// code for script file loading
$_output .= "require_once '{$_filepath}' ;";
require_once $_filepath;
if (!is_callable($_function)) {
$compiler->trigger_template_error(" {insert} function '{$_function}' is not callable in script file '{$_script}'", $compiler->lex->taglineno);
}
} else {
$_filepath = 'null';
$_function = "insert_{$_name}";
// function in PHP script ?
if (!is_callable($_function)) {
// try plugin
if (!$_function = $compiler->getPlugin($_name, 'insert')) {
$compiler->trigger_template_error("{insert} no function or plugin found for '{$_name}'", $compiler->lex->taglineno);
}
}
}
// delete {insert} standard attributes
unset($_attr['name'], $_attr['assign'], $_attr['script'], $_attr['nocache']);
// convert attributes into parameter array string
$_paramsArray = array();
foreach ($_attr as $_key => $_value) {
$_paramsArray[] = "'$_key' => $_value";
}
$_params = 'array(' . implode(", ", $_paramsArray) . ')';
// call insert
if (isset($_assign)) {
if ($_smarty_tpl->caching) {
$_output .= "echo Smarty_Internal_Nocache_Insert::compile ('{$_function}',{$_params}, \$_smarty_tpl, '{$_filepath}',{$_assign});?>";
} else {
$_output .= "\$_smarty_tpl->assign({$_assign} , {$_function} ({$_params},\$_smarty_tpl), true);?>";
}
} else {
$compiler->has_output = true;
if ($_smarty_tpl->caching) {
$_output .= "echo Smarty_Internal_Nocache_Insert::compile ('{$_function}',{$_params}, \$_smarty_tpl, '{$_filepath}');?>";
} else {
$_output .= "echo {$_function}({$_params},\$_smarty_tpl);?>";
}
}
return $_output;
}
}
?>

Some files were not shown because too many files have changed in this diff Show More